tanran
驱动牛犊
驱动牛犊
  • 注册日期2008-04-29
  • 最后登录2008-12-24
  • 粉丝0
  • 关注0
  • 积分141分
  • 威望30点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
阅读:1427回复:0

驱动 通过UDP发送数据信息

楼主#
更多 发布于:2008-05-29 18:24
NTSTATUS    TDISendDatagram(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

  This function is called in SampleWrite. It builds a internel irp and send down 
  to the underlying transport. Until the irp completes or timeout, it will return.
  The remote peer's IP address and port are indicated by RemoteAddress and 
  RemotePort in deviceExtension.

    1. TdiBuildInternalDeviceControlIrp for TDI_SEND_DATAGRAM
    2. Allocate and lockpage a MDL based on Irp->MdlAddress
    3. TdiBuildSendDatagram and pass down to the underlying transport device.
    4. Wait 3 seconds for the completion. If timeout, cancel the irp
    5. Set the Irp according with the completed irp.

Note:
    This routine is synchronous.
    It must be running at IRQL = PASSIVE_LEVEL

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet for IRP_MJ_WRITE.

Return Value:

    NT status code.

--*/
{
    NTSTATUS    status;
    PIRP        pIrp;
    PDEVICE_EXTENSION    deviceExtension;
    KEVENT        Event;
    IO_STATUS_BLOCK    IoStatus;
    PMDL        pMdl;
    PVOID        VirtualAddress;
    ULONG        Length;
    EXCEPTION_POINTERS        * pExceptionInfo;
    ULONG                       lclExceptionCode;
    PVOID                       lclExceptionAddr;
    PVOID        SystemAddress;

    TA_IP_ADDRESS    RmtAddress = {1, {TDI_ADDRESS_LENGTH_IP, TDI_ADDRESS_TYPE_IP, { REMOTE_PORT, REMOTE_ADDRESS}}};
    TDI_CONNECTION_INFORMATION RmtInfo = {0, 0, 0, 0, sizeof(RmtAddress), &RmtAddress};

    deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;
    RmtAddress.Address->Address->sin_port    = deviceExtension->RemotePort;
    RmtAddress.Address->Address->in_addr    = deviceExtension->RemoteAddress;
    status        = STATUS_SUCCESS;
    KeInitializeEvent( &Event, NotificationEvent, FALSE);
    pIrp = TdiBuildInternalDeviceControlIrp(
        TDI_SEND_DATAGRAM,
        deviceExtension->TDILowerDeviceObject,
        deviceExtension->lpTransAddrFileObject,
        &Event,
        &IoStatus );
    if ( NULL == pIrp )
    {
        DebugPrint(("TDISendDatagram: Allocate Irp failed\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    VirtualAddress    = MmGetMdlVirtualAddress ( Irp->MdlAddress );
    Length            = MmGetMdlByteCount( Irp->MdlAddress );
    ASSERT ( VirtualAddress && Length );

    pMdl = IoAllocateMdl ( VirtualAddress, Length, FALSE, FALSE, pIrp );
    if ( NULL == pMdl )
    {
        DebugPrint(("TDISendDatagram: Allocate Mdl failed\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    _try
    {
        MmProbeAndLockPages(pMdl,                     // (Try to) fix buffer.
            KernelMode,
            IoModifyAccess
            );
    }
    _except(
        pExceptionInfo = GetExceptionInformation(),                                                                                                                                                                                                    
        lclExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode,                                                                                                                                                                             
        lclExceptionAddr = pExceptionInfo->ExceptionRecord->ExceptionAddress,                                                                                                                                                                          
        EXCEPTION_EXECUTE_HANDLER                                                                                                                                                                                                                      
        )                                                                                                                                                                                                                                               
    {                                                                                                                                                                                                                                                    
        DebugPrint((".TDISendDatagram:  MmProbeAndLockPages() failed.  Error = 0x%08x at 0x%08x\n",
            lclExceptionCode, lclExceptionAddr));
        status = STATUS_UNSUCCESSFUL;
        IoFreeMdl ( pMdl );
        CompleteRequest ( pIrp, status, 0 );
        Irp->IoStatus.Information = 0;
        return status;
    }
    TdiBuildSendDatagram(
        pIrp,
        deviceExtension->TDILowerDeviceObject,
        deviceExtension->lpTransAddrFileObject,
        NULL,
        NULL,
        pMdl,
        Length,
        &RmtInfo
        );
    status = IoCallDriver ( deviceExtension->TDILowerDeviceObject, pIrp );
    if( ( status != STATUS_SUCCESS ) || ( STATUS_PENDING != status ) )
    {
        DebugPrint(("TDISendDatagram: Problem in IoCallDriver with status %x\n", status ));
    }
    if ( status == STATUS_PENDING )
    {
        LARGE_INTEGER TimeOut;
        NTSTATUS        waitStatus;
        DebugPrint(("Send data pending... wait for 3 seconds\n"));
        TimeOut.QuadPart = -30000 * 1000;         // Calculate timeout value (5 seconds from now).
        waitStatus = KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, &TimeOut);
        if ( STATUS_TIMEOUT == waitStatus )
        {
            DebugPrint(("TDISendDatagram: Send data time out...\n"));
            IoCancelIrp ( pIrp );
            KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, 0);
        }
    }
    Irp->IoStatus.Information = IoStatus.Information;
    DebugPrint(("TDISendDatagram: Send %d bytes\n", Irp->IoStatus.Information ));
    status = ((STATUS_SUCCESS==status) || (STATUS_PENDING== status)) ? IoStatus.Status : status;
    return status;
}
调用该函数出现蓝屏,看了半天也没看出来问题...?
现在是在XP SP2环境下调试~!
游客

返回顶部