tanchenghui
驱动牛犊
驱动牛犊
  • 注册日期2009-04-28
  • 最后登录2009-08-01
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1921回复:0

TDI发送速率的问题

楼主#
更多 发布于:2009-06-06 21:56
TDI发送速率的问题,求助

现在用TDI发送TCP数据,但是大约每200ms才发出去一个包,调试以后发现在
KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL);
这儿会一直等待直到数据发出去。

我把KeWaitForSingleObject去掉以后发送速度很快但发到网络上的数据却出错了,
在坛子里搜索了一下发现其他人也有这样的问题。

谁知道到底怎么解决这个问题,代码贴出来了:
NTSTATUS    TDISendData(
                PDEVICE_OBJECT    TDI_Device_Object,
                PFILE_OBJECT    TDI_Endpoint_FileObj,
                PIRP            Irp
                )
{
    PIRP                pIrp;
    PMDL                pMdl;
    KEVENT            Event;
    NTSTATUS            Status;
    IO_STATUS_BLOCK        IoStatus;
    PVOID                pSendBuffer;
    ULONG            SendBfrLength;

    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    // This code is necessary if buffer is in the paged pool.
    // Must run at <= DISPATCH_LEVEL.
    pSendBuffer = MmGetMdlVirtualAddress ( Irp->MdlAddress );
    SendBfrLength = MmGetMdlByteCount( Irp->MdlAddress );
    
    ASSERT( KeGetCurrentIrql() <= DISPATCH_LEVEL );
    
    pMdl = IoAllocateMdl(pSendBuffer, SendBfrLength, FALSE, FALSE, NULL);
    if(NULL==pMdl) {
        DbgPrint("Could not get an MDL for TDI_SEND");
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

  // Must run at < DISPATCH_LEVEL for pageable memory.
    ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
    __try
  {
    MmProbeAndLockPages(
        pMdl,      // (Try to) fix buffer.
        KernelMode,
        IoModifyAccess );
    }
  __except(EXCEPTION_EXECUTE_HANDLER)
  {
    DbgPrint("Exception calling MmProbeAndLockPages");
    return STATUS_UNSUCCESSFUL;
    }

  if(pMdl) {
        // Build an IRP to connect to a remote host.
        pIrp = TdiBuildInternalDeviceControlIrp(
                TDI_SEND,
                TDI_Device_Object,          // TDI driver's device object
                TDI_Endpoint_FileObj,      // connection (endpoint) file object
                &Event,          // event to be signalled when IRP completes
                &IoStatus            // I/O status block
                );
        
        if(pIrp){
            TdiBuildSend(
                pIrp,
                TDI_Device_Object,    // TDI driver's device object
                TDI_Endpoint_FileObj,    // connection (endpoint) file object
                NULL,          // I/O completion routine
                NULL,          // context for I/O completion routine
                pMdl,          // MDL address
                0,              // Flags. 0 => send as normal TSDU.
                SendBfrLength  // length of buffer mapped by MDL
            );

            ASSERT( KeGetCurrentIrql() <= DISPATCH_LEVEL );
            // Send the command to the underlying TDI driver.
            Status = IoCallDriver(TDI_Device_Object,  pIrp);

            if ( Status == STATUS_PENDING )
            {
                KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL);
            }

            Status = IoStatus.Status;
            Irp->IoStatus.Information = IoStatus.Information;

            if ( (Status != STATUS_SUCCESS) && (Status != STATUS_PENDING)) {
                // Something is wrong.
                DbgPrint("IoCallDriver failed (send), status 0x%08X", Status);
                return STATUS_UNSUCCESSFUL;
            }
            
            if ((Status == STATUS_PENDING) && (IoStatus.Status != STATUS_SUCCESS)) {
                // Something is wrong.
                DbgPrint("Completion of IRP failed (send), status 0x%08X", IoStatus.Status);
                return STATUS_UNSUCCESSFUL;
            }
        }  
  }
    
    return Status;
}
游客

返回顶部