NTSTATUS TdiSendto( PFILE_OBJECT AddressObject, PVOID Data, ULONG Length, ULONG Addr, USHORT Port, PKEVENT WriteEvent ) { KEVENT Event; PIRP Irp; PMDL Mdl; NTSTATUS ntStatus; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(AddressObject); IO_STATUS_BLOCK IoStatus; TA_IP_ADDRESS DstAddr = {1, {TDI_ADDRESS_LENGTH_IP, TDI_ADDRESS_TYPE_IP, {Port, Addr}}}; TDI_CONNECTION_INFORMATION Dst = {0, 0, 0, 0, sizeof DstAddr, &DstAddr}; PKEVENT pEvent = WriteEvent; if (!WriteEvent) { KeInitializeEvent(&Event, NotificationEvent, FALSE); pEvent = &Event; } if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, DeviceObject, AddressObject, pEvent, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; if (!(Mdl = IoAllocateMdl(Data, Length, FALSE, FALSE, Irp))) { IoFreeIrp(Irp); return STATUS_INSUFFICIENT_RESOURCES; } MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); TdiBuildSendDatagram(Irp, DeviceObject, AddressObject, 0, 0, Mdl, Length, &Dst); ntStatus = IoCallDriver(DeviceObject, Irp); if ((ntStatus == STATUS_PENDING) && (!WriteEvent)) ntStatus = KeWaitForSingleObject(pEvent, UserRequest, KernelMode, FALSE, 0); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS LpxTdiSendDataGram( IN PFILE_OBJECT AddressFileObject, PLPX_ADDRESS LpxRemoteAddress, IN PUCHAR SendBuffer, IN ULONG SendLength, IN ULONG Flags, OUT PLONG Result ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; PMDL mdl; TDI_CONNECTION_INFORMATION SendDatagramInfo; UCHAR AddrBuffer[256]; PTRANSPORT_ADDRESS RemoteAddress = (PTRANSPORT_ADDRESS)AddrBuffer; UNREFERENCED_PARAMETER(Flags); LtDebugPrint (3, ("LpxTdiSendDataGram: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(AddressFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_SEND_DATAGRAM, deviceObject, AddressFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendDataGram: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } // // Make MDL. // mdl = IoAllocateMdl( SendBuffer, SendLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendDataGram: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } MmBuildMdlForNonPagedPool(mdl); mdl->Next = NULL; // MmProbeAndLockPages( // mdl, // KernelMode, // IoReadAccess // ); RemoteAddress->TAAddressCount = 1; RemoteAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_LPX; RemoteAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_LPX; RtlCopyMemory(RemoteAddress->Address[0].Address, LpxRemoteAddress, sizeof(LPX_ADDRESS)); SendDatagramInfo.UserDataLength = 0; SendDatagramInfo.UserData = NULL; SendDatagramInfo.OptionsLength = 0; SendDatagramInfo.Options = NULL; SendDatagramInfo.RemoteAddressLength = TPADDR_LPX_LENGTH; SendDatagramInfo.RemoteAddress = RemoteAddress; TdiBuildSendDatagram( irp, deviceObject, AddressFileObject, LpxTdiSendCompletionRoutine, NULL, mdl, SendLength, &SendDatagramInfo ); ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, NULL ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendDataGram: Failed.\n")); *Result = -1; return ntStatus; } *Result = ioStatusBlock.Information; return ntStatus; }
NTSTATUS tdi_send_dgram(PFILE_OBJECT addressFileObject, ULONG addr, USHORT port, const char *buf, int len) { PDEVICE_OBJECT devObj; KEVENT event; PTDI_CONNECTION_INFORMATION remoteInfo; PTA_IP_ADDRESS remoteAddr; PIRP irp; PMDL mdl; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(addressFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); remoteInfo = HttpDiskMalloc( sizeof (TDI_CONNECTION_INFORMATION) + sizeof (TA_IP_ADDRESS) ); if (remoteInfo == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(remoteInfo, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); remoteInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); remoteInfo->RemoteAddress = (PUCHAR)remoteInfo + sizeof(TDI_CONNECTION_INFORMATION); remoteAddr = (PTA_IP_ADDRESS) remoteInfo->RemoteAddress; remoteAddr->TAAddressCount = 1; remoteAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; remoteAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; remoteAddr->Address[0].Address[0].sin_port = port; remoteAddr->Address[0].Address[0].in_addr = addr; irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, devObj, addressFileObject, &event, &iosb); if (irp == NULL) { ExFreePool(remoteInfo); return STATUS_INSUFFICIENT_RESOURCES; } if (len) { mdl = IoAllocateMdl((void*) buf, len, FALSE, FALSE, NULL); if (mdl == NULL) { IoFreeIrp(irp); ExFreePool(remoteInfo); return STATUS_INSUFFICIENT_RESOURCES; } __try { MmProbeAndLockPages(mdl, KernelMode, IoReadAccess); status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(mdl); IoFreeIrp(irp); ExFreePool(remoteInfo); status = STATUS_INVALID_USER_BUFFER; } if (!NT_SUCCESS(status)) { return status; } } TdiBuildSendDatagram(irp, devObj, addressFileObject, NULL, NULL, len ? mdl : 0, len, remoteInfo); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } ExFreePool(remoteInfo); return NT_SUCCESS(status) ? iosb.Information : status; }
NTSTATUS TdiSendDatagram( PIRP *Irp, PFILE_OBJECT TransportObject, PCHAR Buffer, UINT BufferLength, PTDI_CONNECTION_INFORMATION Addr, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext) /* * FUNCTION: Sends a datagram * ARGUMENTS: * TransportObject = Pointer to transport object * From = Send filter (NULL if none) * Address = Address of buffer to place remote address * Buffer = Address of buffer to place send data * BufferSize = Address of buffer with length of Buffer (updated) * RETURNS: * Status of operation */ { PDEVICE_OBJECT DeviceObject; PMDL Mdl; ASSERT(*Irp == NULL); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); return STATUS_INVALID_PARAMETER; } AFD_DbgPrint(MID_TRACE,("Called(TransportObject %p)\n", TransportObject)); DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } *Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */ DeviceObject, /* Device object */ TransportObject, /* File object */ NULL, /* Event */ NULL); /* Status */ if (!*Irp) { AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; } AFD_DbgPrint(MID_TRACE, ("Allocating irp for %p:%u\n", Buffer,BufferLength)); Mdl = IoAllocateMdl(Buffer, /* Virtual address */ BufferLength, /* Length of buffer */ FALSE, /* Not secondary */ FALSE, /* Don't charge quota */ NULL); /* Don't use IRP */ if (!Mdl) { AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); IoCompleteRequest(*Irp, IO_NO_INCREMENT); *Irp = NULL; return STATUS_INSUFFICIENT_RESOURCES; } _SEH2_TRY { MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); IoFreeMdl(Mdl); IoCompleteRequest(*Irp, IO_NO_INCREMENT); *Irp = NULL; _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); } _SEH2_END; AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\n", Mdl)); TdiBuildSendDatagram(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ TransportObject, /* File object */ CompletionRoutine, /* Completion routine */ CompletionContext, /* Completion context */ Mdl, /* Data buffer */ BufferLength, /* Bytes to send */ Addr); /* Address */ TdiCall(*Irp, DeviceObject, NULL, NULL); /* Does not block... The MDL is deleted in the send completion routine. */ return STATUS_PENDING; }