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); }
NTSTATUS TdiQueryDeviceControl( PFILE_OBJECT FileObject, ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, PULONG Return) /* * FUNCTION: Queries a device for information * ARGUMENTS: * FileObject = Pointer to file object * IoControlCode = I/O control code * InputBuffer = Pointer to buffer with input data * InputBufferLength = Length of InputBuffer * OutputBuffer = Address of buffer to place output data * OutputBufferLength = Length of OutputBuffer * RETURNS: * Status of operation */ { PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK Iosb; NTSTATUS Status; 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 = IoBuildDeviceIoControlRequest(IoControlCode, DeviceObject, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, FALSE, &Event, &Iosb); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; Status = TdiCall(Irp, DeviceObject, &Event, &Iosb); if (Return) *Return = Iosb.Information; return Status; }
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 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; }
NTSTATUS TdiReceive( PIRP *Irp, PFILE_OBJECT TransportObject, USHORT Flags, PCHAR Buffer, UINT BufferLength, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext) { PDEVICE_OBJECT DeviceObject; PMDL Mdl; ASSERT(*Irp == NULL); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } *Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE, /* 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 { AFD_DbgPrint(MID_TRACE, ("probe and lock\n")); MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); AFD_DbgPrint(MID_TRACE, ("probe and lock done\n")); } _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)); TdiBuildReceive(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ TransportObject, /* File object */ CompletionRoutine, /* Completion routine */ CompletionContext, /* Completion context */ Mdl, /* Data buffer */ Flags, /* Flags */ BufferLength); /* Length of data */ TdiCall(*Irp, DeviceObject, NULL, NULL); /* Does not block... The MDL is deleted in the receive completion routine. */ return STATUS_PENDING; }
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; }
/* BOOLEAN KTdiStreamSocket::Listen(IN USHORT wRemotePort, IN ULONG dwRemoteAddress) { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = FALSE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; //PTDI_CONNECTION_INFORMATION pRequestListenInfo = NULL; //PTDI_CONNECTION_INFORMATION pReturnConnectionInfo; PTA_IP_ADDRESS pRequestAddress; PTDI_ADDRESS_IP pIp; IO_STATUS_BLOCK IoStatusBlock; __try { if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && Disconnect() == TRUE) { m_nRemotePort = wPort; m_nRemoteAddress = dwAddress; pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); m_pRequestListenInfo = (PTDI_CONNECTION_INFORMATION) new char[2*sizeof(TDI_CONNECTION_INFORMATION) + 2*sizeof(TA_IP_ADDRESS) + sizeof(ULONG)]; if (m_pRequestListenInfo != NULL) { memset(m_pRequestListenInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS) + sizeof(ULONG)); m_pReturnListenInfo = (PTDI_CONNECTION_INFORMATION)((PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); m_pReturnListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); m_pReturnListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION); m_pRequestListenInfo->Options = (PVOID) ((PUCHAR)m_pReturnListenInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); *((ULONG*)(m_pRequestListenInfo->Options)) = TDI_QUERY_ACCEPT; m_pRequestListenInfo->OptionsLength = sizeof(ULONG); if (m_nRemoteAddress != 0) { m_pRequestListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); m_pRequestListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION); pRequestAddress = (PTA_IP_ADDRESS)(m_pRequestListenInfo->RemoteAddress); pRequestAddress->TAAddressCount = 1; pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address); pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort); pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress);; } else { m_pRequestListenInfo->RemoteAddressLength = 0; m_pRequestListenInfo->RemoteAddress = NULL; } pIrp = TdiBuildInternalDeviceControlIrp( TDI_LISTEN, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildListen( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, TDI_QUERY_ACCEPT, // flags m_pRequestListenInfo, m_pReturnListenInfo); pIrpError = NULL; KeInitializeEvent(&m_kAcceptDestroyEvent, NotificationEvent, FALSE); KeInitializeEvent(&m_kListenEvent, NotificationEvent, FALSE); pIrp->UserEvent = &m_kListenEvent; NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock, FALSE); if (NT_SUCCESS(NtStatus)) { DbgPrint ("TdiListen: OK (%08x)!!!\n", NtStatus); m_bListen = TRUE; bRes = TRUE; } else { DbgPrint ("TdiListen: ERROR (%08x)!!!\n", NtStatus); delete[] m_pRequestListenInfo; m_pRequestListenInfo = NULL; } } } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); if (m_bListen == FALSE && m_pRequestListenInfo != NULL) delete[] m_pRequestListenInfo; } return bRes; } BOOLEAN KTdiStreamSocket::Accept(ULONG dwTimeOut) { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = FALSE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; PTA_IP_ADDRESS pReturnAddress; PTDI_ADDRESS_IP pIp; IO_STATUS_BLOCK IoStatusBlock; PVOID pkEvents[2]; LARGE_INTEGER TimeOut; PLARGE_INTEGER pTimeOut = NULL; //m_KSynchroObject.Lock(); __try { if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && m_bListen == TRUE) { if (dwTimeOut != 0) { pTimeOut = &TimeOut; TimeOut.QuadPart = dwTimeOut * 10000; // msec -> 100 nsec intervals TimeOut.QuadPart = -TimeOut.QuadPart; } pkEvents[0] = &m_kListenEvent; pkEvents[1] = &m_kAcceptDestroyEvent; NtStatus = KeWaitForMultipleObjects(2, pkEvents, WaitAny, Suspended, KernelMode, FALSE, pTimeOut, NULL); if (NtStatus == 0) { pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pReturnAddress = (PTA_IP_ADDRESS)(m_pReturnListenInfo->RemoteAddress); pReturnAddress->TAAddressCount = 1; pReturnAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); pReturnAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; pIrp = TdiBuildInternalDeviceControlIrp( TDI_ACCEPT, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildAccept( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, m_pRequestListenInfo, m_pReturnListenInfo); pIrpError = NULL; NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock, TRUE); if (NT_SUCCESS(NtStatus)) { m_bConnected = TRUE; bRes = TRUE; pIp = (PTDI_ADDRESS_IP)(pReturnAddress->Address[0].Address); m_nRemotePort = W_BIG_TO_LITTLE_ENDIAN(pIp->sin_port); m_nRemoteAddress = D_BIG_TO_LITTLE_ENDIAN(pIp->in_addr); DbgPrint ("TdiAccept: OK (%08x : %04x)!!!\n", m_nRemoteAddress, m_nRemotePort); } else { DbgPrint ("TdiAccept: ERROR (%08x)!!!\n", NtStatus); } } } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); } //m_KSynchroObject.UnLock(); return bRes; } */ ULONG KTdiStreamSocket::Send(PVOID pData, ULONG dwSize) { //KLocker locker(&m_KSynchroObject); PIRP pIrp = NULL, pIrpError = NULL; PMDL pMdl; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; IO_STATUS_BLOCK IoStatusBlock; ULONG dwBytesSended = 0; //m_KSynchroObject.Lock(); __try { if (m_bOpen == TRUE && m_bConnected == TRUE && dwSize != 0) { pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pIrp = TdiBuildInternalDeviceControlIrp ( TDI_SEND, // sub function pDeviceObject, // pointer to device object m_pTdiConnectionObject, // pointer to control object NULL, // pointer to event NULL); // pointer to return buffer pIrpError = pIrp; if (pIrp == NULL) // validate pointer { NtStatus = STATUS_INSUFFICIENT_RESOURCES; } else { pMdl = IoAllocateMdl( pData, // buffer pointer - virtual address dwSize, // length FALSE, // not secondary FALSE, // don't charge quota NULL); // don't use irp if (pMdl != NULL) // validate mdl pointer { __try { MmProbeAndLockPages(pMdl, KernelMode, IoModifyAccess); // probe & lock } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("EXCEPTION: MmProbeAndLockPages\n"); IoFreeMdl(pMdl); pMdl = NULL; } } if (pMdl != NULL) { TdiBuildSend( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, pMdl, 0, dwSize); pIrpError = NULL; //m_KSynchroObject.UnLock(); NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock); //m_KSynchroObject.Lock(); if (NT_SUCCESS(NtStatus)) { dwBytesSended = IoStatusBlock.Information; } else { DbgPrint ("TdiSend: ERROR (%08x)!!!\n", NtStatus); Disconnect(); } } } }
BOOLEAN KTdiStreamSocket::Disconnect() { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = TRUE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; PTDI_CONNECTION_INFORMATION pRequestConnectionInfo = NULL; PTDI_CONNECTION_INFORMATION pReturnConnectionInfo; PTA_IP_ADDRESS pRequestAddress; PTDI_ADDRESS_IP pIp; IO_STATUS_BLOCK IoStatusBlock; __try { if (m_bOpen == TRUE && (m_bConnected == TRUE || m_bListen == TRUE)) { bRes = FALSE; pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pRequestConnectionInfo = (PTDI_CONNECTION_INFORMATION) new char[sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)]; if (pRequestConnectionInfo != NULL) { memset(pRequestConnectionInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); pReturnConnectionInfo = NULL; pRequestConnectionInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); pRequestConnectionInfo->RemoteAddress = (PUCHAR)pRequestConnectionInfo + sizeof(TDI_CONNECTION_INFORMATION); pRequestAddress = (PTA_IP_ADDRESS)(pRequestConnectionInfo->RemoteAddress); pRequestAddress->TAAddressCount = 1; pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address); pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort); pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress); pIrp = TdiBuildInternalDeviceControlIrp( TDI_DISCONNECT, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildDisconnect( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, NULL, // timeout TDI_DISCONNECT_ABORT, //TDI_DISCONNECT_RELEASE, pRequestConnectionInfo, pReturnConnectionInfo); pIrpError = NULL; BOOLEAN bConnected = m_bConnected; BOOLEAN bListen = m_bListen; m_bConnected = FALSE; m_bListen = FALSE; if (bListen == TRUE) { KeSetEvent(&m_kAcceptDestroyEvent, 0, FALSE); SetEventHandler(TDI_EVENT_CONNECT, (PVOID)NULL, (PVOID)NULL); } NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock); if (NT_SUCCESS(NtStatus)) { DbgPrint ("TdiDisconnect: SUCCESS (%08x)!!!\n", NtStatus); } else { DbgPrint ("TdiDisconnect: ERROR (%08x)!!!\n", NtStatus); } if (bConnected == TRUE) m_bConnected = FALSE; if (bListen == TRUE) { m_bListen = FALSE; delete[] m_pRequestListenInfo; m_pRequestListenInfo = NULL; } bRes = TRUE; } delete[] pRequestConnectionInfo; pRequestConnectionInfo = NULL; } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); if (pRequestConnectionInfo != NULL) delete[] pRequestConnectionInfo; } return bRes; }
BOOLEAN KTdiStreamSocket::Connect(IN USHORT wPort, IN ULONG dwAddress, ULONG dwTimeOut) { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = FALSE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; PTDI_CONNECTION_INFORMATION pRequestConnectionInfo = NULL; PTDI_CONNECTION_INFORMATION pReturnConnectionInfo; PTA_IP_ADDRESS pRequestAddress; PTDI_ADDRESS_IP pIp; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER TimeOut; PLARGE_INTEGER pTimeOut = NULL; __try { if (m_bOpen == TRUE && m_bBind == TRUE && m_bListen == FALSE && Disconnect() == TRUE) { m_nRemotePort = wPort; m_nRemoteAddress = dwAddress; if (dwTimeOut != 0) { pTimeOut = &TimeOut; TimeOut.QuadPart = dwTimeOut * 10000; // msec -> 100 nsec intervals TimeOut.QuadPart = -TimeOut.QuadPart; } pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pRequestConnectionInfo = (PTDI_CONNECTION_INFORMATION) new char[sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)]; if (pRequestConnectionInfo != NULL) { memset(pRequestConnectionInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); pReturnConnectionInfo = NULL; pRequestConnectionInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); pRequestConnectionInfo->RemoteAddress = (PUCHAR)pRequestConnectionInfo + sizeof(TDI_CONNECTION_INFORMATION); pRequestAddress = (PTA_IP_ADDRESS)(pRequestConnectionInfo->RemoteAddress); pRequestAddress->TAAddressCount = 1; pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address); pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort); pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress);; pIrp = TdiBuildInternalDeviceControlIrp( TDI_CONNECT, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildConnect( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, pTimeOut, pRequestConnectionInfo, pReturnConnectionInfo); pIrpError = NULL; NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock); if (NT_SUCCESS(NtStatus)) { m_bConnected = TRUE; bRes = TRUE; } else { DbgPrint ("TdiConnect: ERROR (%08x)!!!\n", NtStatus); } } delete[] pRequestConnectionInfo; pRequestConnectionInfo = NULL; } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); if (pRequestConnectionInfo != NULL) delete[] pRequestConnectionInfo; } return bRes; }