阅读:1427回复:0
驱动 通过UDP发送数据信息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环境下调试~! |
|