NTSTATUS tdi_associate_address(PFILE_OBJECT connectionFileObject, HANDLE addressHandle) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(connectionFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_ASSOCIATE_ADDRESS, devObj, connectionFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildAssociateAddress(irp, devObj, connectionFileObject, NULL, NULL, addressHandle); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return status; }
NTSTATUS TcpSetDisconnectHandler( IN PFILE_OBJECT AddressFileObject, IN PVOID InEventHandler, IN PVOID InEventContext ) { PDEVICE_OBJECT deviceObject; PIRP irp; KEVENT event; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; TCPLtDebugPrint (3, ("[TcpTdi]TcpSetDisconnectHandler: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(AddressFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_SET_EVENT_HANDLER, deviceObject, AddressFileObject, &event, &ioStatusBlock ); if(irp == NULL) { TCPLtDebugPrint(1, ("[TcpTdi]TcpSetDisconnectHandler: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildSetEventHandler( irp, deviceObject, AddressFileObject, NULL, NULL, TDI_EVENT_DISCONNECT, InEventHandler, InEventContext ); ntStatus = TcpTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event ); if(!NT_SUCCESS(ntStatus)) { TCPLtDebugPrint(1, ("[TcpTdi]TcpSetDisconnectHandler: Failed.\n")); } return ntStatus; }
NTSTATUS tdi_set_event_handler(PFILE_OBJECT addressFileObject, LONG eventType, PVOID eventHandler, PVOID eventContext) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(addressFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, devObj, addressFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildSetEventHandler(irp, devObj, addressFileObject, NULL, NULL, eventType, eventHandler, eventContext); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return status; }
NTSTATUS tdi_recv_stream(PFILE_OBJECT connectionFileObject, char *buf, int len, ULONG flags) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; PMDL mdl; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(connectionFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE, devObj, connectionFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } if (len) { mdl = IoAllocateMdl((void*) buf, len, FALSE, FALSE, NULL); if (mdl == NULL) { IoFreeIrp(irp); return STATUS_INSUFFICIENT_RESOURCES; } __try { MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess); status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(mdl); IoFreeIrp(irp); status = STATUS_INVALID_USER_BUFFER; } if (!NT_SUCCESS(status)) { return status; } } TdiBuildReceive(irp, devObj, connectionFileObject, NULL, NULL, len ? mdl : 0, flags, len); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return NT_SUCCESS(status) ? iosb.Information : status; }
NTSTATUS tdi_disconnect(PFILE_OBJECT connectionFileObject, ULONG flags) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(connectionFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT, devObj, connectionFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildDisconnect(irp, devObj, connectionFileObject, NULL, NULL, NULL, flags, NULL, NULL); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return status; }
NTSTATUS TdiQueryAddress( PFILE_OBJECT AddressObject, PTDI_ADDRESS_INFO AddressInfo, PULONG pInfoLength ) { NTSTATUS ntStatus; PIRP Irp; PMDL Mdl; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(AddressObject); IO_STATUS_BLOCK IoStatus; if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, DeviceObject, FileObject, NULL, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; if (!(Mdl = IoAllocateMdl(AddressInfo, *pInfoLength, FALSE, FALSE, Irp))) { IoFreeIrp(Irp); return STATUS_INSUFFICIENT_RESOURCES; } MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); TdiBuildQueryInformation(Irp, DeviceObject, AddressObject, NULL, NULL, TDI_QUERY_ADDRESS_INFO, Mdl); ntStatus = IoCallDriver(DeviceObject, Irp); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS TdiDisconnect( PFILE_OBJECT ConnectionObject ) { NTSTATUS ntStatus; KEVENT Event; PIRP Irp; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); IO_STATUS_BLOCK IoStatus; KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT, DeviceObject, ConnectionObject, &Event, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; TdiBuildDisconnect(Irp, DeviceObject, ConnectionObject, 0, 0, 0, TDI_DISCONNECT_RELEASE, 0, 0); ntStatus = IoCallDriver(DeviceObject, Irp); if (ntStatus == STATUS_PENDING) ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS TdiSetEventHandler( PFILE_OBJECT AddressObject, LONG EventType, PVOID EventHandler, PVOID EventContext ) { NTSTATUS ntStatus; KEVENT Event; PIRP Irp; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(AddressObject); IO_STATUS_BLOCK IoStatus; KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, DeviceObject, AddressObject, &Event, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; TdiBuildSetEventHandler(Irp, DeviceObject, AddressObject, 0, 0, EventType, EventHandler, EventContext); ntStatus = IoCallDriver(DeviceObject, Irp); if (ntStatus == STATUS_PENDING) ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS LpxTdiDisassociateAddress( IN PFILE_OBJECT ConnectionFileObject ) { PDEVICE_OBJECT deviceObject; PIRP irp; KEVENT event; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; LtDebugPrint (3, ("[LpxTdi] LpxTdiDisassociateAddress: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_DISASSOCIATE_ADDRESS, deviceObject, ConnectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi] TdiDisassociateAddress: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildDisassociateAddress( irp, deviceObject, ConnectionFileObject, NULL, NULL ); irp->MdlAddress = NULL; ntStatus = LpxTdiIoCallDriver( deviceObject, irp, NULL, NULL, TRUE); #if DBG if(ntStatus != STATUS_SUCCESS) { LtDebugPrint(1, ("[LpxTdi] TdiDisassociateAddress: Failed. STATUS=%08lx\n", ntStatus)); } #endif return ntStatus; }
VOID DestroyNodeEventHandlerVisitor(PVOID context, UINT key, PVOID value) { NTSTATUS status; PIRP irp = NULL; unsigned int i = 0; KEVENT irp_complete_event; IO_STATUS_BLOCK io_status_block; NodeEventHandler* node_event_handler = NULL; EventHandlerManager* event_handler_manager = NULL; node_event_handler = (NodeEventHandler*)value; event_handler_manager = (EventHandlerManager*)context; if(node_event_handler == NULL || event_handler_manager == NULL ) return; KeInitializeEvent(&irp_complete_event, NotificationEvent, FALSE); // For each hooked event handler send an IRP to set the event handler // back to what it originally was for(i = 0; i < TDI_EVENT_HANDLERS_MAX; i++) { PFILE_OBJECT node = node_event_handler->handlers[i].node; TdiEventHandler* original_handler = &node_event_handler->handlers[i].original_handler; if(original_handler->EventHandler == NULL) continue; irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, event_handler_manager->connection_manager->device, node, &irp_complete_event, &io_status_block); if(irp == NULL) continue; TdiBuildSetEventHandler(irp, event_handler_manager->connection_manager->device, node, NULL, NULL, original_handler->EventType, original_handler->EventHandler, original_handler->EventContext); status = IoCallDriver(event_handler_manager->connection_manager->next_device, irp); if(status == STATUS_PENDING) { // Wait for the IRP to finish KeWaitForSingleObject((PVOID)&irp_complete_event, Executive, KernelMode, TRUE, NULL); status = io_status_block.Status; } if(status == STATUS_SUCCESS) { DbgPrint("EventHandlerManager: Successfully set original event handler n=%08x t=%08x\n", node, original_handler->EventType); } else { DbgPrint("EventHandlerManager: Failed to set original event handler - code=%08x n=%08x t=%08x\n", status, node, original_handler->EventType); } KeResetEvent(&irp_complete_event); } }
NTSTATUS TdiSetEventHandler( PFILE_OBJECT FileObject, LONG EventType, PVOID Handler, PVOID Context) /* * FUNCTION: Sets or resets an event handler * ARGUMENTS: * FileObject = Pointer to file object * EventType = Event code * Handler = Event handler to be called when the event occurs * Context = Context input to handler when the event occurs * RETURNS: * Status of operation * NOTES: * Specify NULL for Handler to stop calling event handler */ { PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK Iosb; KEVENT Event; PIRP Irp; AFD_DbgPrint(MAX_TRACE, ("Called\n")); if (!FileObject) { AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(FileObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */ DeviceObject, /* Device object */ FileObject, /* File object */ &Event, /* Event */ &Iosb); /* Status */ if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; TdiBuildSetEventHandler(Irp, DeviceObject, FileObject, NULL, NULL, EventType, Handler, Context); return TdiCall(Irp, DeviceObject, &Event, &Iosb); }
BOOLEAN KTdiStreamSocket::Unbind() { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = TRUE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; IO_STATUS_BLOCK IoStatusBlock; __try { if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && m_bListen == FALSE) { bRes = FALSE; pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pIrp = TdiBuildInternalDeviceControlIrp( TDI_DISASSOCIATE_ADDRESS, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildDisassociateAddress( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = NULL; NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock); if (NT_SUCCESS(NtStatus)) { m_bBind = FALSE; bRes = TRUE; } else { DbgPrint ("TdiUnbind: ERROR (%08x)!!!\n", NtStatus); } } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); } return bRes; }
NTSTATUS TdiListen( PIRP *Irp, PFILE_OBJECT ConnectionObject, PTDI_CONNECTION_INFORMATION *RequestConnectionInfo, PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext) /* * FUNCTION: Listen on a connection endpoint for a connection request from a remote peer * ARGUMENTS: * CompletionRoutine = Routine to be called when IRP is completed * CompletionContext = Context for CompletionRoutine * RETURNS: * Status of operation * May return STATUS_PENDING */ { PDEVICE_OBJECT DeviceObject; AFD_DbgPrint(MAX_TRACE, ("Called\n")); ASSERT(*Irp == NULL); if (!ConnectionObject) { AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } *Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ NULL, /* Event */ NULL); /* Status */ if (*Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES; TdiBuildListen(*Irp, /* IRP */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ CompletionRoutine, /* Completion routine */ CompletionContext, /* Completion routine context */ 0, /* Flags */ *RequestConnectionInfo, /* Request connection information */ *ReturnConnectionInfo); /* Return connection information */ TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, NULL); return STATUS_PENDING; }
NTSTATUS TdiConnect( PIRP *Irp, PFILE_OBJECT ConnectionObject, PTDI_CONNECTION_INFORMATION ConnectionCallInfo, PTDI_CONNECTION_INFORMATION ConnectionReturnInfo, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext) /* * FUNCTION: Connect a connection endpoint to a remote peer * ARGUMENTS: * ConnectionObject = Pointer to connection endpoint file object * RemoteAddress = Pointer to remote address * RETURNS: * Status of operation */ { PDEVICE_OBJECT DeviceObject; AFD_DbgPrint(MAX_TRACE, ("Called\n")); ASSERT(*Irp == NULL); if (!ConnectionObject) { AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } *Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, /* Sub function */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ NULL, /* Event */ NULL); /* Status */ if (!*Irp) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildConnect(*Irp, /* IRP */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ CompletionRoutine, /* Completion routine */ CompletionContext, /* Completion routine context */ NULL, /* Time */ ConnectionCallInfo, /* Request connection information */ ConnectionReturnInfo); /* Return connection information */ TdiCall(*Irp, DeviceObject, NULL, NULL); return STATUS_PENDING; }
NTSTATUS TdiQueryInformation( PFILE_OBJECT FileObject, LONG QueryType, PMDL MdlBuffer) /* * FUNCTION: Query for information * ARGUMENTS: * FileObject = Pointer to file object * QueryType = Query type * MdlBuffer = Pointer to MDL buffer specific for query type * RETURNS: * Status of operation */ { PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK Iosb; KEVENT Event; PIRP Irp; if (!FileObject) { AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(FileObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, /* Sub function */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ &Event, /* Event */ &Iosb); /* Status */ if (!Irp) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildQueryInformation(Irp, DeviceObject, FileObject, NULL, NULL, QueryType, MdlBuffer); return TdiCall(Irp, DeviceObject, &Event, &Iosb); }
NTSTATUS TdiAssociateAddressFile( HANDLE AddressHandle, PFILE_OBJECT ConnectionObject) /* * FUNCTION: Associates a connection endpoint to an address file object * ARGUMENTS: * AddressHandle = Handle to address file object * ConnectionObject = Connection endpoint file object * RETURNS: * Status of operation */ { PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK Iosb; KEVENT Event; PIRP Irp; AFD_DbgPrint(MAX_TRACE, ("Called. AddressHandle (%p) ConnectionObject (%p)\n", AddressHandle, ConnectionObject)); if (!ConnectionObject) { AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = TdiBuildInternalDeviceControlIrp(TDI_ASSOCIATE_ADDRESS, /* Sub function */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ &Event, /* Event */ &Iosb); /* Status */ if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; TdiBuildAssociateAddress(Irp, DeviceObject, ConnectionObject, NULL, NULL, AddressHandle); return TdiCall(Irp, DeviceObject, &Event, &Iosb); }
NTSTATUS TdiRecvfrom( PFILE_OBJECT AddressObject, PVOID Data, ULONG Length, ULONG Addr, USHORT Port, PULONG pRead, PKEVENT ReadEvent ) { KEVENT Event; PIRP Irp; PMDL Mdl; NTSTATUS ntStatus; IO_STATUS_BLOCK IoStatus; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(AddressObject); TA_IP_ADDRESS SrcAddr = {1, {TDI_ADDRESS_LENGTH_IP, TDI_ADDRESS_TYPE_IP, {Port, Addr}}}; TDI_CONNECTION_INFORMATION Src = {0, 0, 0, 0, sizeof SrcAddr, &SrcAddr}; PKEVENT pEvent = ReadEvent; if (!ReadEvent) { KeInitializeEvent(&Event, NotificationEvent, FALSE); pEvent = &Event; } if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, DeviceObject, AddressObject, pEvent, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; if (!(Mdl = IoAllocateMdl(Data, Length, FALSE, FALSE, Irp))) return STATUS_INSUFFICIENT_RESOURCES; MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); TdiBuildReceiveDatagram(Irp, DeviceObject, AddressObject, 0, 0, Mdl, Length, &Src, &Src, TDI_RECEIVE_NORMAL); ntStatus = IoCallDriver(DeviceObject, Irp); if ((ntStatus == STATUS_PENDING) && (!ReadEvent)) ntStatus = KeWaitForSingleObject(pEvent, UserRequest, KernelMode, FALSE, 0); if (ntStatus == STATUS_SUCCESS) { *pRead = IoStatus.Status; } return(ntStatus); }
NTSTATUS TdiDisconnect( PIRP *Irp, PFILE_OBJECT TransportObject, PLARGE_INTEGER Time, USHORT Flags, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext, PTDI_CONNECTION_INFORMATION RequestConnectionInfo, PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) { PDEVICE_OBJECT DeviceObject; 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_DISCONNECT, /* 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; } TdiBuildDisconnect(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ TransportObject, /* File object */ CompletionRoutine, /* Completion routine */ CompletionContext, /* Completion context */ Time, /* Time */ Flags, /* Disconnect flags */ RequestConnectionInfo, /* Indication of who to disconnect */ ReturnConnectionInfo); /* Indication of who disconnected */ TdiCall(*Irp, DeviceObject, NULL, NULL); return STATUS_PENDING; }
static FORCEINLINE PIRP xTdiBuildInternalIrp( __in PDEVICE_OBJECT ConnectionDeviceObject, __in PFILE_OBJECT ConnectionFileObject, __in PKEVENT Event, __in PIO_STATUS_BLOCK IoStatus) { return TdiBuildInternalDeviceControlIrp( TDI_CONNECT, /* anything will be fine */ ConnectionDeviceObject, NULL, /* ConnectionFileObject is not used */ Event, IoStatus); }
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 TdiConnect( PFILE_OBJECT ConnectionObject, ULONG Addr, USHORT Port, PIO_STATUS_BLOCK AsyncIoStatus ) { NTSTATUS ntStatus; PIRP Irp; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); 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}; KEVENT Event; IO_STATUS_BLOCK IoStatus = {0, (ULONG_PTR)&Event}; PIO_STATUS_BLOCK pIoStatus = &IoStatus; if (AsyncIoStatus) pIoStatus = AsyncIoStatus; else KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, DeviceObject, ConnectionObject, (PKEVENT)pIoStatus->Information, pIoStatus))) return STATUS_INSUFFICIENT_RESOURCES; TdiBuildConnect(Irp, DeviceObject, ConnectionObject, 0, 0, 0, &Dst, 0); ntStatus = IoCallDriver(DeviceObject, Irp); if ((ntStatus == STATUS_PENDING) && (!AsyncIoStatus)) ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); return(ntStatus); }
NTSTATUS TdiRecv( PFILE_OBJECT ConnectionObject, PVOID Data, ULONG Length ) { NTSTATUS ntStatus; IO_STATUS_BLOCK IoStatus; KEVENT Event; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); PIRP Irp; PMDL Mdl; KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE, DeviceObject, ConnectionObject, &Event, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; if (!(Mdl = IoAllocateMdl(Data, Length, FALSE, FALSE, Irp))) { IoFreeIrp(Irp); return STATUS_INSUFFICIENT_RESOURCES; } MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); TdiBuildReceive(Irp, DeviceObject, ConnectionObject, 0, 0, Mdl, TDI_RECEIVE_NORMAL, Length); ntStatus = IoCallDriver(DeviceObject, Irp); if (ntStatus == STATUS_PENDING) ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS LpxTdiConnect( IN PFILE_OBJECT ConnectionFileObject, IN PTDI_ADDRESS_LPX Address ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; UCHAR buffer[ FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX ]; PTRANSPORT_ADDRESS serverTransportAddress; PTA_ADDRESS taAddress; PTDI_ADDRESS_LPX addressName; NTSTATUS ntStatus; TDI_CONNECTION_INFORMATION connectionInfomation; LtDebugPrint (3, ("[LpxTdi] LpxTdiConnect: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_CONNECT, deviceObject, connectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiConnect: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } serverTransportAddress = (PTRANSPORT_ADDRESS)buffer; serverTransportAddress->TAAddressCount = 1; taAddress = (PTA_ADDRESS)serverTransportAddress->Address; taAddress->AddressType = TDI_ADDRESS_TYPE_LPX; taAddress->AddressLength = TDI_ADDRESS_LENGTH_LPX; addressName = (PTDI_ADDRESS_LPX)taAddress->Address; RtlCopyMemory( addressName, Address, TDI_ADDRESS_LENGTH_LPX ); // // Make Connection Info... // RtlZeroMemory( &connectionInfomation, sizeof(TDI_CONNECTION_INFORMATION) ); connectionInfomation.UserDataLength = 0; connectionInfomation.UserData = NULL; connectionInfomation.OptionsLength = 0; connectionInfomation.Options = NULL; connectionInfomation.RemoteAddress = serverTransportAddress; connectionInfomation.RemoteAddressLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX; TdiBuildConnect( irp, deviceObject, ConnectionFileObject, NULL, NULL, NULL, &connectionInfomation, NULL ); irp->MdlAddress = NULL; ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, NULL ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]TdiConnect: Failed.\n")); } return ntStatus; }
NTSTATUS LpxTdiAssociateAddress( IN PFILE_OBJECT ConnectionFileObject, IN HANDLE AddressFileHandle ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; LtDebugPrint (3, ("[LpxTdi] LpxTdiAssociateAddress: Entered\n")); // // Make Event. // KeInitializeEvent( &event, NotificationEvent, FALSE ); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_ASSOCIATE_ADDRESS, deviceObject, ConnectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi] LpxTdiAssociateAddress: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildAssociateAddress( irp, deviceObject, ConnectionFileObject, NULL, NULL, AddressFileHandle ); irp->MdlAddress = NULL; ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, NULL ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi] LpxTdiAssociateAddress: Failed.\n")); } return ntStatus; }
NTSTATUS LpxTdiSetReceiveDatagramHandler( IN PFILE_OBJECT AddressFileObject, IN PVOID InEventHandler, IN PVOID InEventContext ) { PDEVICE_OBJECT deviceObject; PIRP irp; KEVENT event; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; LtDebugPrint (1, ("[LxpTdi]LpxSetReceiveDatagramHandler: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(AddressFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_SET_EVENT_HANDLER, deviceObject, AddressFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxSetReceiveDatagramHandler: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildSetEventHandler( irp, deviceObject, AddressFileObject, NULL, NULL, TDI_EVENT_RECEIVE_DATAGRAM, InEventHandler, InEventContext ); ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, NULL ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]LpxSetReceiveDatagramHandler: Can't Build IRP.\n")); } LtDebugPrint(3, ("[LpxTdi] Leave LpxSetReceiveDatagramHandler\n")); return 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 LpxTdiRecvWithCompletionEvent_TimeOut( IN PFILE_OBJECT ConnectionFileObject, IN PTDI_RECEIVE_CONTEXT TdiReceiveContext, OUT PUCHAR RecvBuffer, IN ULONG RecvLength, IN ULONG Flags, IN PLARGE_INTEGER TimeOut ) { PDEVICE_OBJECT deviceObject; PIRP irp; NTSTATUS ntStatus; PMDL mdl; ASSERT(ConnectionFileObject); LtDebugPrint (3, ("LpxTdiRecvWithCompletionEvent: Entered\n")); if((RecvBuffer == NULL) || (RecvLength == 0)) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Rcv buffer == NULL or RcvLen == 0.\n")); return STATUS_NOT_IMPLEMENTED; } deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_RECEIVE, deviceObject, connectionFileObject, NULL, NULL ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl = IoAllocateMdl( RecvBuffer, RecvLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Allocate MDL.\n")); IoFreeIrp(irp); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); TdiBuildReceive( irp, deviceObject, ConnectionFileObject, LpxTdiRecvWithCompletionEventCompletionRoutine, TdiReceiveContext, mdl, Flags, RecvLength ); if(TimeOut) SET_IRP_EXPTIME(irp, CurrentTime().QuadPart + TimeOut->QuadPart); else SET_IRP_EXPTIME(irp, 0); ntStatus = IoCallDriver( deviceObject, irp ); if(!NT_SUCCESS(ntStatus)) { TdiReceiveContext->Irp = NULL; LtDebugPrint(1, ("[LpxTdi]LpxTdiRecv: Failed.\n")); return ntStatus; } TdiReceiveContext->Irp = irp; return ntStatus; }
NTSTATUS LpxTdiListenWithCompletionEvent( IN PFILE_OBJECT ConnectionFileObject, IN PTDI_LISTEN_CONTEXT TdiListenContext, IN PULONG Flags ) { PDEVICE_OBJECT deviceObject; PIRP irp; NTSTATUS ntStatus; LtDebugPrint (1, ("[LpxTdi]LpxTdiListen: Entered.\n")); // // Make Event. // //KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_LISTEN, deviceObject, ConnectionFileObject, NULL, NULL ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxTdiListen: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } TdiListenContext->RequestConnectionInfo.UserData = NULL; TdiListenContext->RequestConnectionInfo.UserDataLength = 0; TdiListenContext->RequestConnectionInfo.Options = Flags; TdiListenContext->RequestConnectionInfo.OptionsLength = sizeof(ULONG); TdiListenContext->RequestConnectionInfo.RemoteAddress = NULL; TdiListenContext->RequestConnectionInfo.RemoteAddressLength = 0; TdiListenContext->ReturnConnectionInfo.UserData = NULL; TdiListenContext->ReturnConnectionInfo.UserDataLength = 0; TdiListenContext->ReturnConnectionInfo.Options = Flags; TdiListenContext->ReturnConnectionInfo.OptionsLength = sizeof(ULONG); TdiListenContext->ReturnConnectionInfo.RemoteAddress = TdiListenContext->AddressBuffer; TdiListenContext->ReturnConnectionInfo.RemoteAddressLength = TPADDR_LPX_LENGTH; TdiBuildListen( irp, deviceObject, ConnectionFileObject, LpxTdiListenCompletionRoutine, TdiListenContext, *Flags, &TdiListenContext->RequestConnectionInfo, &TdiListenContext->ReturnConnectionInfo ); ntStatus = IoCallDriver( deviceObject, irp ); if(!NT_SUCCESS(ntStatus)) { TdiListenContext->Irp = NULL; LtDebugPrint(1, ("[LpxTdi]LpxTdiListen: Failed.\n")); return ntStatus; } TdiListenContext->Irp = irp; return ntStatus; }
NTSTATUS LpxTdiRecv_TimeOut( IN PFILE_OBJECT ConnectionFileObject, OUT PUCHAR RecvBuffer, IN ULONG RecvLength, IN ULONG Flags, IN PLONG Result, IN PLARGE_INTEGER TimeOut ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; PMDL mdl; if((RecvBuffer == NULL) || (RecvLength == 0)) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Rcv buffer == NULL or RcvLen == 0.\n")); return STATUS_INSUFFICIENT_RESOURCES; } LtDebugPrint (3, ("LpxTdiRecv: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_RECEIVE, deviceObject, connectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } /* try { // // Make MDL. // */ mdl = IoAllocateMdl( RecvBuffer, RecvLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); /* MmProbeAndLockPages( mdl, KernelMode, IoWriteAccess ); } except (EXCEPTION_EXECUTE_HANDLER) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Convert Non-Paged Memory MDL.\n")); if(mdl){ IoFreeMdl(mdl); //IoFreeIrp(irp); } return STATUS_INSUFFICIENT_RESOURCES; } */ TdiBuildReceive( irp, deviceObject, ConnectionFileObject, LpxTdiRcvCompletionRoutine, NULL, mdl, Flags, RecvLength ); ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, TimeOut ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]LpxTdiRecv: Failed.\n")); *Result = -1; return ntStatus; } *Result = ioStatusBlock.Information; return ntStatus; }
NTSTATUS LpxTdiSendEx( IN PFILE_OBJECT ConnectionFileObject, IN PUCHAR SendBuffer, IN ULONG SendLength, IN ULONG Flags, IN PKEVENT CompEvent, IN PLARGE_INTEGER TimeOut, IN OUT PVOID CompletionContext, OUT PIO_STATUS_BLOCK IoStatusBlock ) { PDEVICE_OBJECT deviceObject; PIRP irp; NTSTATUS ntStatus; PMDL mdl; LtDebugPrint (3, ("[LPXTDI]LpxTdiSendEx: Entered\n")); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_SEND, deviceObject, ConnectionFileObject, CompEvent, IoStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendEx: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl = IoAllocateMdl( SendBuffer, SendLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendEx: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); if(CompletionContext) { TdiBuildSend( irp, deviceObject, ConnectionFileObject, LpxTdiSendCompletionRoutine, CompletionContext, mdl, Flags, SendLength ); } else { TdiBuildSend( irp, deviceObject, ConnectionFileObject, NULL, NULL, mdl, Flags, SendLength ); } ntStatus = LpxTdiIoCallDriver( deviceObject, irp, IoStatusBlock, CompEvent, TimeOut ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendEx: Failed.\n")); } return ntStatus; }