/*++ Copyright (c) Microsoft Corporation. All rights reserved. Module Name: tdikrnl.h Abstract: This header file contains interface definitions for NT transport providers running in kernel mode. This interface is documented in the NT Transport Driver Interface (TDI) Specification, Version 2. Revision History: --*/ #ifndef _TDI_KRNL_ #define _TDI_KRNL_ #pragma once #include // get the user mode includes #include #pragma warning(push) #pragma warning(disable:4201) // nameless struct/union // // In this TDI, a kernel mode client calls TDI using IoCallDriver with the // current Irp stack pointer set to 16 bytes of pointers to other structures. // each of the supported NtDeviceIoControlFile analogs has a somehat different // structure, laid out below. // // The IrpSP information passed by kernel mode clients looks like: // typedef struct _TDI_REQUEST_KERNEL { ULONG_PTR RequestFlags; PTDI_CONNECTION_INFORMATION RequestConnectionInformation; PTDI_CONNECTION_INFORMATION ReturnConnectionInformation; PVOID RequestSpecific; } TDI_REQUEST_KERNEL, *PTDI_REQUEST_KERNEL; // // defined request codes for the kernel clients. We make these the same // as the IOCTL codes mostly for convenience; either can be used with // the same results. // #define TDI_ASSOCIATE_ADDRESS (0x01) #define TDI_DISASSOCIATE_ADDRESS (0x02) #define TDI_CONNECT (0x03) #define TDI_LISTEN (0x04) #define TDI_ACCEPT (0x05) #define TDI_DISCONNECT (0x06) #define TDI_SEND (0x07) #define TDI_RECEIVE (0x08) #define TDI_SEND_DATAGRAM (0x09) #define TDI_RECEIVE_DATAGRAM (0x0A) #define TDI_SET_EVENT_HANDLER (0x0B) #define TDI_QUERY_INFORMATION (0x0C) #define TDI_SET_INFORMATION (0x0D) #define TDI_ACTION (0x0E) #define TDI_DIRECT_SEND (0x27) #define TDI_DIRECT_SEND_DATAGRAM (0x29) #define TDI_DIRECT_ACCEPT (0x2A) // // TdiOpenAddress (Not Used) // TdiCloseAddress (Not Used) // TdiOpenConnection (Not Used) // TdiCloseConnection (Not Used) // // // some useful constants for comparison when determining the file type; // not required. // #define TDI_TRANSPORT_ADDRESS_FILE 1 #define TDI_CONNECTION_FILE 2 #define TDI_CONTROL_CHANNEL_FILE 3 // // Internal TDI IOCTLS // #define IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER _TDI_CONTROL_CODE( 0x80, METHOD_NEITHER ) #define IOCTL_TDI_QUERY_DIRECT_SENDDG_HANDLER _TDI_CONTROL_CODE( 0x81, METHOD_NEITHER ) // // TdiAssociateAddress // typedef struct _TDI_REQUEST_KERNEL_ASSOCIATE { HANDLE AddressHandle; } TDI_REQUEST_KERNEL_ASSOCIATE, *PTDI_REQUEST_KERNEL_ASSOCIATE; // // TdiDisassociateAddress -- None supplied // typedef TDI_REQUEST_KERNEL TDI_REQUEST_KERNEL_DISASSOCIATE, *PTDI_REQUEST_KERNEL_DISASSOCIATE; // // TdiConnect uses the structure given above (TDI_REQUEST_KERNEL); it's // defined again below for convenience // typedef TDI_REQUEST_KERNEL TDI_REQUEST_KERNEL_CONNECT, *PTDI_REQUEST_KERNEL_CONNECT; // // TdiDisconnect uses the structure given above (TDI_REQUEST_KERNEL); it's // defined again below for convenience // typedef TDI_REQUEST_KERNEL TDI_REQUEST_KERNEL_DISCONNECT, *PTDI_REQUEST_KERNEL_DISCONNECT; // // TdiListen uses the structure given above (TDI_REQUEST_KERNEL); it's // defined again below for convenience // typedef TDI_REQUEST_KERNEL TDI_REQUEST_KERNEL_LISTEN, *PTDI_REQUEST_KERNEL_LISTEN; // // TdiAccept // typedef struct _TDI_REQUEST_KERNEL_ACCEPT { PTDI_CONNECTION_INFORMATION RequestConnectionInformation; PTDI_CONNECTION_INFORMATION ReturnConnectionInformation; } TDI_REQUEST_KERNEL_ACCEPT, *PTDI_REQUEST_KERNEL_ACCEPT; // // TdiSend // typedef struct _TDI_REQUEST_KERNEL_SEND { ULONG SendLength; ULONG SendFlags; } TDI_REQUEST_KERNEL_SEND, *PTDI_REQUEST_KERNEL_SEND; // // TdiReceive // typedef struct _TDI_REQUEST_KERNEL_RECEIVE { ULONG ReceiveLength; ULONG ReceiveFlags; } TDI_REQUEST_KERNEL_RECEIVE, *PTDI_REQUEST_KERNEL_RECEIVE; // // TdiSendDatagram // typedef struct _TDI_REQUEST_KERNEL_SENDDG { ULONG SendLength; _Field_size_bytes_(SendLength) PTDI_CONNECTION_INFORMATION SendDatagramInformation; } TDI_REQUEST_KERNEL_SENDDG, *PTDI_REQUEST_KERNEL_SENDDG; // // TdiReceiveDatagram // typedef struct _TDI_REQUEST_KERNEL_RECEIVEDG { ULONG ReceiveLength; PTDI_CONNECTION_INFORMATION ReceiveDatagramInformation; PTDI_CONNECTION_INFORMATION ReturnDatagramInformation; ULONG ReceiveFlags; } TDI_REQUEST_KERNEL_RECEIVEDG, *PTDI_REQUEST_KERNEL_RECEIVEDG; // // TdiSetEventHandler // typedef struct _TDI_REQUEST_KERNEL_SET_EVENT { LONG EventType; PVOID EventHandler; PVOID EventContext; } TDI_REQUEST_KERNEL_SET_EVENT, *PTDI_REQUEST_KERNEL_SET_EVENT; // // TdiQueryInformation // typedef struct _TDI_REQUEST_KERNEL_QUERY_INFO { LONG QueryType; PTDI_CONNECTION_INFORMATION RequestConnectionInformation; } TDI_REQUEST_KERNEL_QUERY_INFORMATION, *PTDI_REQUEST_KERNEL_QUERY_INFORMATION; // // TdiSetInformation // typedef struct _TDI_REQUEST_KERNEL_SET_INFO { LONG SetType; PTDI_CONNECTION_INFORMATION RequestConnectionInformation; } TDI_REQUEST_KERNEL_SET_INFORMATION, *PTDI_REQUEST_KERNEL_SET_INFORMATION; // // Event types that are known // #define TDI_EVENT_CONNECT ((USHORT)0) // TDI_IND_CONNECT event handler. #define TDI_EVENT_DISCONNECT ((USHORT)1) // TDI_IND_DISCONNECT event handler. #define TDI_EVENT_ERROR ((USHORT)2) // TDI_IND_ERROR event handler. #define TDI_EVENT_RECEIVE ((USHORT)3) // TDI_IND_RECEIVE event handler. #define TDI_EVENT_RECEIVE_DATAGRAM ((USHORT)4) // TDI_IND_RECEIVE_DATAGRAM event handler. #define TDI_EVENT_RECEIVE_EXPEDITED ((USHORT)5) // TDI_IND_RECEIVE_EXPEDITED event handler. #define TDI_EVENT_SEND_POSSIBLE ((USHORT)6) // TDI_IND_SEND_POSSIBLE event handler #if defined(_M_IX86) || defined(_M_AMD64) // Chained receives are not available on new platforms #define TDI_EVENT_CHAINED_RECEIVE ((USHORT)7) // TDI_IND_CHAINED_RECEIVE event handler. #define TDI_EVENT_CHAINED_RECEIVE_DATAGRAM ((USHORT)8) // TDI_IND_CHAINED_RECEIVE_DATAGRAM event handler. #define TDI_EVENT_CHAINED_RECEIVE_EXPEDITED ((USHORT)9) // TDI_IND_CHAINED_RECEIVE_EXPEDITED event handler. #endif // defined(_M_IX86) || defined(_M_AMD64) #define TDI_EVENT_ERROR_EX ((USHORT)10) // TDI_IND_UNREACH_ERROR event handler. // // indicate connection event prototype. This is invoked when a request for // connection has been received by the provider and the user wishes to either // accept or reject that request. // typedef NTSTATUS (*PTDI_IND_CONNECT)( _In_opt_ PVOID TdiEventContext, _In_ LONG RemoteAddressLength, _In_reads_bytes_(RemoteAddressLength) PVOID RemoteAddress, _In_ LONG UserDataLength, _In_reads_bytes_opt_(UserDataLength) PVOID UserData, _In_ LONG OptionsLength, _In_reads_bytes_opt_(OptionsLength) PVOID Options, _Out_ CONNECTION_CONTEXT *ConnectionContext, _Out_ PIRP *AcceptIrp ); NTSTATUS TdiDefaultConnectHandler ( _In_opt_ PVOID TdiEventContext, _In_ LONG RemoteAddressLength, _In_reads_bytes_(RemoteAddressLength) PVOID RemoteAddress, _In_ LONG UserDataLength, _In_reads_bytes_opt_(UserDataLength) PVOID UserData, _In_ LONG OptionsLength, _In_reads_bytes_opt_(OptionsLength) PVOID Options, _Out_ CONNECTION_CONTEXT *ConnectionContext, _Out_ PIRP *AcceptIrp ); // // Disconnection indication prototype. This is invoked when a connection is // being disconnected for a reason other than the user requesting it. Note that // this is a change from TDI V1, which indicated only when the remote caused // a disconnection. Any non-directed disconnection will cause this indication. // typedef NTSTATUS (*PTDI_IND_DISCONNECT)( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ LONG DisconnectDataLength, _In_reads_bytes_opt_(DisconnectDataLength) PVOID DisconnectData, _In_ LONG DisconnectInformationLength, _In_reads_bytes_opt_(DisconnectInformationLength) PVOID DisconnectInformation, _In_ ULONG DisconnectFlags ); NTSTATUS TdiDefaultDisconnectHandler ( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ LONG DisconnectDataLength, _In_reads_bytes_opt_(DisconnectDataLength) PVOID DisconnectData, _In_ LONG DisconnectInformationLength, _In_reads_bytes_opt_(DisconnectInformationLength) PVOID DisconnectInformation, _In_ ULONG DisconnectFlags ); // // A protocol error has occurred when this indication happens. This indication // occurs only for errors of the worst type; the address this indication is // delivered to is no longer usable for protocol-related operations, and // should not be used for operations henceforth. All connections associated // it are invalid. // For NetBIOS-type providers, this indication is also delivered when a name // in conflict or duplicate name occurs. // typedef NTSTATUS (*PTDI_IND_ERROR)( _In_opt_ PVOID TdiEventContext, // the endpoint's file object. _In_ NTSTATUS Status // status code indicating error type. ); typedef NTSTATUS (*PTDI_IND_ERROR_EX)( _In_opt_ PVOID TdiEventContext, // the endpoint's file object. _In_ NTSTATUS Status, // status code indicating error type. _In_ PVOID Buffer ); NTSTATUS TdiDefaultErrorHandler ( _In_opt_ PVOID TdiEventContext, // the endpoint's file object. _In_ NTSTATUS Status // status code indicating error type. ); // // TDI_IND_RECEIVE indication handler definition. This client routine is // called by the transport provider when a connection-oriented TSDU is received // that should be presented to the client. // typedef NTSTATUS (*PTDI_IND_RECEIVE)( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, _In_ ULONG BytesIndicated, _In_ ULONG BytesAvailable, _Out_ ULONG *BytesTaken, _In_ PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes _Out_opt_ PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED. ); NTSTATUS TdiDefaultReceiveHandler ( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, _In_ ULONG BytesIndicated, _In_ ULONG BytesAvailable, _Out_ ULONG *BytesTaken, _In_ PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes _Out_opt_ PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED. ); // // TDI_IND_RECEIVE_DATAGRAM indication handler definition. This client routine // is called by the transport provider when a connectionless TSDU is received // that should be presented to the client. // typedef NTSTATUS (*PTDI_IND_RECEIVE_DATAGRAM)( _In_opt_ PVOID TdiEventContext, // the event context _In_ LONG SourceAddressLength, // length of the originator of the datagram _In_reads_bytes_(SourceAddressLength) PVOID SourceAddress, // originator of the datagram _In_ LONG OptionsLength, // options for the receive _In_reads_bytes_opt_(OptionsLength) PVOID Options, // _In_ ULONG ReceiveDatagramFlags, // _In_ ULONG BytesIndicated, // number of bytes this indication _In_ ULONG BytesAvailable, // number of bytes in complete Tsdu _Out_ ULONG *BytesTaken, // number of bytes used _In_ PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes _Out_opt_ PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED. ); NTSTATUS TdiDefaultRcvDatagramHandler ( _In_opt_ PVOID TdiEventContext, // the event context _In_ LONG SourceAddressLength, // length of the originator of the datagram _In_reads_bytes_(SourceAddressLength) PVOID SourceAddress, // originator of the datagram _In_ LONG OptionsLength, // options for the receive _In_reads_bytes_opt_(OptionsLength) PVOID Options, // _In_ ULONG ReceiveDatagramFlags, // _In_ ULONG BytesIndicated, // number of bytes this indication _In_ ULONG BytesAvailable, // number of bytes in complete Tsdu _Out_ ULONG *BytesTaken, // number of bytes used _In_ PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes _Out_opt_ PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED. ); // // This indication is delivered if expedited data is received on the connection. // This will only occur in providers that support expedited data. // typedef NTSTATUS (*PTDI_IND_RECEIVE_EXPEDITED)( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, // _In_ ULONG BytesIndicated, // number of bytes in this indication _In_ ULONG BytesAvailable, // number of bytes in complete Tsdu _Out_ ULONG *BytesTaken, // number of bytes used by indication routine _In_ PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes _Out_opt_ PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED. ); NTSTATUS TdiDefaultRcvExpeditedHandler ( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, // _In_ ULONG BytesIndicated, // number of bytes in this indication _In_ ULONG BytesAvailable, // number of bytes in complete Tsdu _Out_ ULONG *BytesTaken, // number of bytes used by indication routine _In_ PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes _Out_opt_ PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED. ); // // TDI_IND_CHAINED_RECEIVE indication handler definition. This client routine // is called by the transport provider when a connection-oriented TSDU is // received that should be presented to the client. The TSDU is stored in an // MDL chain. The client may take ownership of the TSDU and return it at a // later time. // typedef NTSTATUS (*PTDI_IND_CHAINED_RECEIVE)( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, _In_ ULONG ReceiveLength, // length of client data in TSDU _In_ ULONG StartingOffset, // offset of start of client data in TSDU _In_ PMDL Tsdu, // TSDU data chain _In_ PVOID TsduDescriptor // for call to TdiReturnChainedReceives ); NTSTATUS TdiDefaultChainedReceiveHandler ( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, _In_ ULONG ReceiveLength, // length of client data in TSDU _In_ ULONG StartingOffset, // offset of start of client data in TSDU _In_ PMDL Tsdu, // TSDU data chain _In_ PVOID TsduDescriptor // for call to TdiReturnChainedReceives ); // // TDI_IND_CHAINED_RECEIVE_DATAGRAM indication handler definition. This client // routine is called by the transport provider when a connectionless TSDU is // received that should be presented to the client. The TSDU is stored in an // MDL chain. The client may take ownership of the TSDU and return it at a // later time. // typedef NTSTATUS (*PTDI_IND_CHAINED_RECEIVE_DATAGRAM)( _In_opt_ PVOID TdiEventContext, // the event context _In_ LONG SourceAddressLength, // length of the originator of the datagram _In_reads_bytes_(SourceAddressLength) PVOID SourceAddress, // originator of the datagram _In_ LONG OptionsLength, // options for the receive _In_reads_bytes_opt_(OptionsLength) PVOID Options, // _In_ ULONG ReceiveDatagramFlags, // _In_ ULONG ReceiveDatagramLength, // length of client data in TSDU _In_ ULONG StartingOffset, // offset of start of client data in TSDU _In_ PMDL Tsdu, // TSDU data chain _In_ PVOID TsduDescriptor // for call to TdiReturnChainedReceives ); NTSTATUS TdiDefaultChainedRcvDatagramHandler ( _In_opt_ PVOID TdiEventContext, // the event context _In_ LONG SourceAddressLength, // length of the originator of the datagram _In_reads_bytes_(SourceAddressLength) PVOID SourceAddress, // originator of the datagram _In_ LONG OptionsLength, // options for the receive _In_reads_bytes_opt_(OptionsLength) PVOID Options, // _In_ ULONG ReceiveDatagramFlags, // _In_ ULONG ReceiveDatagramLength, // length of client data in TSDU _In_ ULONG StartingOffset, // offset of start of client data in TSDU _In_ PMDL Tsdu, // TSDU data chain _In_ PVOID TsduDescriptor // for call to TdiReturnChainedReceives ); // // This indication is delivered if expedited data is received on the connection. // This will only occur in providers that support expedited data. The TSDU is // stored in an MDL chain. The client may take ownership of the TSDU and // return it at a later time. // typedef NTSTATUS (*PTDI_IND_CHAINED_RECEIVE_EXPEDITED)( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, _In_ ULONG ReceiveLength, // length of client data in TSDU _In_ ULONG StartingOffset, // offset of start of client data in TSDU _In_ PMDL Tsdu, // TSDU data chain _In_ PVOID TsduDescriptor// for call to TdiReturnChainedReceives ); NTSTATUS TdiDefaultChainedRcvExpeditedHandler ( _In_opt_ PVOID TdiEventContext, _In_opt_ CONNECTION_CONTEXT ConnectionContext, _In_ ULONG ReceiveFlags, _In_ ULONG ReceiveLength, // length of client data in TSDU _In_ ULONG StartingOffset, // offset of start of client data in TSDU _In_ PMDL Tsdu, // TSDU data chain _In_ PVOID TsduDescriptor// for call to TdiReturnChainedReceives ); // // This indication is delivered if there is room for a send in the buffer of // a buffering protocol. // typedef NTSTATUS (*PTDI_IND_SEND_POSSIBLE)( _In_opt_ PVOID TdiEventContext, _In_opt_ PVOID ConnectionContext, _In_ ULONG BytesAvailable); NTSTATUS TdiDefaultSendPossibleHandler ( _In_opt_ PVOID TdiEventContext, _In_opt_ PVOID ConnectionContext, _In_ ULONG BytesAvailable); // // defined MACROS to allow the kernel mode client to easily build an IRP for // any function. // #define TdiBuildAssociateAddress(Irp, DevObj, FileObj, CompRoutine, Contxt, AddrHandle) \ { \ PTDI_REQUEST_KERNEL_ASSOCIATE p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_ASSOCIATE_ADDRESS; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_ASSOCIATE)&_IRPSP->Parameters; \ p->AddressHandle = (HANDLE)(AddrHandle); \ } #define TdiBuildDisassociateAddress(Irp, DevObj, FileObj, CompRoutine, Contxt) \ { \ PTDI_REQUEST_KERNEL_DISASSOCIATE p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_DISASSOCIATE_ADDRESS; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_DISASSOCIATE)&_IRPSP->Parameters; \ } #define TdiBuildConnect(Irp, DevObj, FileObj, CompRoutine, Contxt, Time, RequestConnectionInfo, ReturnConnectionInfo)\ { \ PTDI_REQUEST_KERNEL p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_CONNECT; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL)&_IRPSP->Parameters; \ p->RequestConnectionInformation = RequestConnectionInfo; \ p->ReturnConnectionInformation = ReturnConnectionInfo; \ p->RequestSpecific = (PVOID)Time; \ } #define TdiBuildListen(Irp, DevObj, FileObj, CompRoutine, Contxt, Flags, RequestConnectionInfo, ReturnConnectionInfo)\ { \ PTDI_REQUEST_KERNEL p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_LISTEN; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL)&_IRPSP->Parameters; \ p->RequestFlags = Flags; \ p->RequestConnectionInformation = RequestConnectionInfo; \ p->ReturnConnectionInformation = ReturnConnectionInfo; \ } #define TdiBuildAccept(Irp, DevObj, FileObj, CompRoutine, Contxt, RequestConnectionInfo, ReturnConnectionInfo)\ { \ PTDI_REQUEST_KERNEL_ACCEPT p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_ACCEPT; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_ACCEPT)&_IRPSP->Parameters; \ p->RequestConnectionInformation = RequestConnectionInfo; \ p->ReturnConnectionInformation = ReturnConnectionInfo; \ } #if (NTDDI_VERSION < NTDDI_WINXP) #define TdiBuildDirectAccept(Irp, DevObj, FileObj, CompRoutine, Contxt, RequestConnectionInfo, ReturnConnectionInfo)\ { \ PTDI_REQUEST_KERNEL_ACCEPT p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_DIRECT_ACCEPT; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_ACCEPT)&_IRPSP->Parameters; \ p->RequestConnectionInformation = RequestConnectionInfo; \ p->ReturnConnectionInformation = ReturnConnectionInfo; \ } #endif #define TdiBuildDisconnect(Irp, DevObj, FileObj, CompRoutine, Contxt, Time, Flags, RequestConnectionInfo, ReturnConnectionInfo)\ { \ PTDI_REQUEST_KERNEL p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_DISCONNECT; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL)&_IRPSP->Parameters; \ p->RequestFlags = Flags; \ p->RequestConnectionInformation = RequestConnectionInfo; \ p->ReturnConnectionInformation = ReturnConnectionInfo; \ p->RequestSpecific = (PVOID)Time; \ } #define TdiBuildReceive(Irp, DevObj, FileObj, CompRoutine, Contxt, MdlAddr, InFlags, ReceiveLen)\ { \ PTDI_REQUEST_KERNEL_RECEIVE p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_RECEIVE; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_RECEIVE)&_IRPSP->Parameters; \ p->ReceiveFlags = InFlags; \ p->ReceiveLength = ReceiveLen; \ Irp->MdlAddress = MdlAddr; \ } #define TdiBuildSend(Irp, DevObj, FileObj, CompRoutine, Contxt, MdlAddr, InFlags, SendLen)\ { \ PTDI_REQUEST_KERNEL_SEND p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_SEND; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_SEND)&_IRPSP->Parameters; \ p->SendFlags = InFlags; \ p->SendLength = SendLen; \ Irp->MdlAddress = MdlAddr; \ } #define TdiBuildSendDatagram(Irp, DevObj, FileObj, CompRoutine, Contxt, MdlAddr, SendLen, SendDatagramInfo)\ { \ PTDI_REQUEST_KERNEL_SENDDG p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_SEND_DATAGRAM; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_SENDDG)&_IRPSP->Parameters; \ p->SendLength = SendLen; \ p->SendDatagramInformation = SendDatagramInfo; \ Irp->MdlAddress = MdlAddr; \ } #define TdiBuildReceiveDatagram(Irp, DevObj, FileObj, CompRoutine, Contxt, MdlAddr, ReceiveLen, ReceiveDatagramInfo, ReturnInfo, InFlags)\ { \ PTDI_REQUEST_KERNEL_RECEIVEDG p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_RECEIVE_DATAGRAM; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_RECEIVEDG)&_IRPSP->Parameters; \ p->ReceiveLength = ReceiveLen; \ p->ReceiveDatagramInformation = ReceiveDatagramInfo; \ p->ReturnDatagramInformation = ReturnInfo; \ p->ReceiveFlags = InFlags; \ Irp->MdlAddress = MdlAddr; \ } #define TdiBuildSetEventHandler(Irp, DevObj, FileObj, CompRoutine, Contxt, InEventType, InEventHandler, InEventContext) \ { \ PTDI_REQUEST_KERNEL_SET_EVENT p; \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_SET_EVENT_HANDLER; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_SET_EVENT)&_IRPSP->Parameters; \ p->EventType = InEventType; \ p->EventHandler = (PVOID)InEventHandler; \ p->EventContext = (PVOID)InEventContext; \ } #define TdiBuildQueryInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, QType, MdlAddr, ConnInfo)\ { \ PTDI_REQUEST_KERNEL_QUERY_INFORMATION p; \ PIO_STACK_LOCATION _IRPSP; \ Irp->MdlAddress = MdlAddr; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_QUERY_INFORMATION; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&_IRPSP->Parameters; \ p->QueryType = (ULONG)QType; \ p->RequestConnectionInformation = ConnInfo; \ } #define TdiBuildQueryInformation(Irp, DevObj, FileObj, CompRoutine, Contxt, QType, MdlAddr)\ TdiBuildQueryInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, QType, MdlAddr, NULL); #define TdiBuildSetInformation(Irp, DevObj, FileObj, CompRoutine, Contxt, SType, MdlAddr)\ { \ PTDI_REQUEST_KERNEL_SET_INFORMATION p; \ PIO_STACK_LOCATION _IRPSP; \ Irp->MdlAddress = MdlAddr; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_SET_INFORMATION; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ p = (PTDI_REQUEST_KERNEL_SET_INFORMATION)&_IRPSP->Parameters; \ p->SetType = (ULONG)SType; \ p->RequestConnectionInformation = NULL; \ } #define TdiBuildAction(Irp, DevObj, FileObj, CompRoutine, Contxt, MdlAddr)\ { \ PIO_STACK_LOCATION _IRPSP; \ if ( CompRoutine != NULL) { \ IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\ } else { \ IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \ } \ _IRPSP = IoGetNextIrpStackLocation (Irp); \ _IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; \ _IRPSP->MinorFunction = TDI_ACTION; \ _IRPSP->DeviceObject = DevObj; \ _IRPSP->FileObject = FileObj; \ Irp->MdlAddress = MdlAddr; \ } // // definitions for the helper routines for TDI compliant transports and clients // // Note that the IOCTL used here for the Irp Function is not real; it is used // to avoid this IO routine having to map buffers (which we don't want). // //PIRP //TdiBuildInternalDeviceControlIrp ( // IN CCHAR IrpSubFunction, // IN PDEVICE_OBJECT DeviceObject, // IN PFILE_OBJECT FileObject, // IN PKEVENT Event, // IN PIO_STATUS_BLOCK IoStatusBlock // ); #define TdiBuildInternalDeviceControlIrp(IrpSubFunction,DeviceObject,FileObject,Event,IoStatusBlock) \ IoBuildDeviceIoControlRequest (\ 0x00000003,\ DeviceObject, \ NULL, \ 0, \ NULL, \ 0, \ TRUE, \ Event, \ IoStatusBlock) // // VOID // TdiCopyLookaheadData( // IN PVOID Destination, // IN PVOID Source, // IN ULONG Length, // IN ULONG ReceiveFlags // ); // #ifdef _M_IX86 #define TdiCopyLookaheadData(_Destination,_Source,_Length,_ReceiveFlags) \ RtlCopyMemory(_Destination,_Source,_Length) #else #define TdiCopyLookaheadData(_Destination,_Source,_Length,_ReceiveFlags) { \ if ((_ReceiveFlags) & TDI_RECEIVE_COPY_LOOKAHEAD) { \ RtlCopyMemory(_Destination,_Source,_Length); \ } else { \ PUCHAR _Src = (PUCHAR)(_Source); \ PUCHAR _Dest = (PUCHAR)(_Destination); \ PUCHAR _End = _Dest + (_Length); \ while (_Dest < _End) { \ *_Dest++ = *_Src++; \ } \ } \ } #endif _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS TdiMapUserRequest( _In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PIO_STACK_LOCATION IrpSp ); #if (NTDDI_VERSION < NTDDI_WINXP) __drv_preferredFunction("(see documentation)", "Obsolete") VOID TdiMapBuffer ( _In_ PMDL MdlChain ); __drv_preferredFunction("(see documentation)", "Obsolete") VOID TdiUnmapBuffer ( _In_ PMDL MdlChain ); #endif _IRQL_requires_max_(DISPATCH_LEVEL) NTSTATUS TdiCopyBufferToMdl ( _In_ PVOID SourceBuffer, _In_ ULONG SourceOffset, _In_ ULONG SourceBytesToCopy, _In_ PMDL DestinationMdlChain, _In_ ULONG DestinationOffset, _Out_ PULONG BytesCopied ); _IRQL_requires_max_(DISPATCH_LEVEL) NTSTATUS TdiCopyMdlToBuffer( _In_ PMDL SourceMdlChain, _In_ ULONG SourceOffset, _Out_writes_bytes_(DestinationBufferSize) PVOID DestinationBuffer, _In_ ULONG DestinationOffset, _In_ ULONG DestinationBufferSize, _Out_ PULONG BytesCopied ); #if (NTDDI_VERSION >= NTDDI_WINXP) _IRQL_requires_max_(DISPATCH_LEVEL) NTSTATUS TdiCopyMdlChainToMdlChain( _In_ PMDL SourceMdlChain, _In_ ULONG SourceOffset, _In_ PMDL DestinationMdlChain, _In_ ULONG DestinationOffset, _Out_ PULONG BytesCopied ); #endif #if (NTDDI_VERSION >= NTDDI_WS03) VOID TdiCopyBufferToMdlWithReservedMappingAtDpcLevel( _In_ PVOID SourceBuffer, _In_ PMDL DestinationMdl, _In_ ULONG DestinationOffset, _In_ ULONG BytesToCopy ); __inline VOID TdiCopyBufferToMdlWithReservedMapping( _In_ PVOID SourceBuffer, _In_ PMDL DestinationMdl, _In_ ULONG DestinationOffset, _In_ ULONG BytesToCopy ) { KIRQL OldIrql; KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); TdiCopyBufferToMdlWithReservedMappingAtDpcLevel(SourceBuffer, DestinationMdl, DestinationOffset, BytesToCopy); KeLowerIrql(OldIrql); } #endif VOID TdiBuildNetbiosAddress ( _In_ PUCHAR NetbiosName, _In_ BOOLEAN IsGroupName, _Inout_ PTA_NETBIOS_ADDRESS NetworkName ); _At_(Buffer, _Out_writes_bytes_( sizeof(FILE_FULL_EA_INFORMATION) + TDI_TRANSPORT_ADDRESS_LENGTH + sizeof(TA_NETBIOS_ADDRESS))) NTSTATUS TdiBuildNetbiosAddressEa ( PUCHAR Buffer, _In_ BOOLEAN IsGroupName, _In_ PUCHAR NetbiosName ); //++ // // VOID // TdiCompleteRequest ( // IN PIRP Irp, // IN NTSTATUS Status // ); // // Routine Description: // // This routine is used to complete an IRP with the indicated // status. // // Arguments: // // Irp - Supplies a pointer to the Irp to complete // // Status - Supplies the completion status for the Irp // // Return Value: // // None. // //-- #define TdiCompleteRequest(IRP,STATUS) { \ (IRP)->IoStatus.Status = (STATUS); \ IoCompleteRequest( (IRP), IO_NETWORK_INCREMENT ); \ } #if defined(_M_IX86) || defined(_M_AMD64) _IRQL_requires_max_(DISPATCH_LEVEL) VOID TdiReturnChainedReceives( _In_ PVOID *TsduDescriptors, _In_ ULONG NumberOfTsdus ); #endif // The type definition for a TDI Bind handler callout. This callout is // called when a new transport device arrives. typedef VOID (*TDI_BIND_HANDLER)( _In_ PUNICODE_STRING DeviceName ); typedef VOID (*TDI_UNBIND_HANDLER)( _In_ PUNICODE_STRING DeviceName ); // The type definition for a TDI address handler callout. // This is typedefed defined at the end (with the others) typedef VOID (*TDI_ADD_ADDRESS_HANDLER)( _In_ PTA_ADDRESS Address ); typedef VOID (*TDI_DEL_ADDRESS_HANDLER)( _In_ PTA_ADDRESS Address ); typedef VOID (* TDI_NET_READY_HANDLER)( _In_ NTSTATUS ProviderStatus ); typedef VOID (* ProviderPnPPowerComplete)( _In_ PNET_PNP_EVENT NetEvent, _In_ NTSTATUS ProviderStatus ); __drv_preferredFunction("TdiRegisterPnPHandlers", "Obsolete") NTSTATUS TdiRegisterAddressChangeHandler( _In_ TDI_ADD_ADDRESS_HANDLER AddHandler, _In_ TDI_DEL_ADDRESS_HANDLER DeleteHandler, _Out_ HANDLE *BindingHandle ); __drv_preferredFunction("TdiDeregisterPnPHandlers", "Obsolete") NTSTATUS TdiDeregisterAddressChangeHandler( _In_ HANDLE BindingHandle ); __drv_preferredFunction("TdiRegisterPnPHandlers", "Obsolete") NTSTATUS TdiRegisterNotificationHandler( _In_ TDI_BIND_HANDLER BindHandler, _In_ TDI_UNBIND_HANDLER UnbindHandler, _Out_ HANDLE *BindingHandle ); __drv_preferredFunction("TdiDeregisterPnPHandlers", "Obsolete") NTSTATUS TdiDeregisterNotificationHandler( _In_ HANDLE BindingHandle ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiRegisterDeviceObject( _In_ PUNICODE_STRING DeviceName, _Out_ HANDLE *RegistrationHandle ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiDeregisterDeviceObject( _In_ HANDLE RegistrationHandle ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiDeregisterNetAddress( _In_ HANDLE RegistrationHandle ); _IRQL_requires_max_(PASSIVE_LEVEL) VOID TdiInitialize( VOID ); // PnP extensions to TDI. Spec : TdiPnp.doc : MunilS typedef enum _TDI_PNP_OPCODE { TDI_PNP_OP_MIN, TDI_PNP_OP_ADD, TDI_PNP_OP_DEL, TDI_PNP_OP_UPDATE, TDI_PNP_OP_PROVIDERREADY, TDI_PNP_OP_NETREADY, TDI_PNP_OP_ADD_IGNORE_BINDING, TDI_PNP_OP_DELETE_IGNORE_BINDING, TDI_PNP_OP_MAX, } TDI_PNP_OPCODE; typedef struct _TDI_PNP_CONTEXT_WIN2K { USHORT ContextSize; USHORT ContextType; UCHAR POINTER_ALIGNMENT ContextData[1]; } TDI_PNP_CONTEXT_WIN2K, *PTDI_PNP_CONTEXT_WIN2K; typedef struct _TDI_PNP_CONTEXT_XP { USHORT ContextSize; USHORT ContextType; UCHAR POINTER_ALIGNMENT ContextData[1]; } TDI_PNP_CONTEXT_XP, *PTDI_PNP_CONTEXT_XP; #if (NTDDI_VERSION >= NTDDI_WINXP) typedef TDI_PNP_CONTEXT_XP TDI_PNP_CONTEXT; #else typedef TDI_PNP_CONTEXT_WIN2K TDI_PNP_CONTEXT; #endif typedef TDI_PNP_CONTEXT* PTDI_PNP_CONTEXT; typedef VOID (*TDI_BINDING_HANDLER)( _In_ TDI_PNP_OPCODE PnPOpcode, _In_ PUNICODE_STRING DeviceName, _In_ PWSTR MultiSZBindList ); typedef VOID (*TDI_ADD_ADDRESS_HANDLER_V2)( _In_ PTA_ADDRESS Address, _In_ PUNICODE_STRING DeviceName, _In_ PTDI_PNP_CONTEXT Context ); typedef VOID (*TDI_DEL_ADDRESS_HANDLER_V2)( _In_ PTA_ADDRESS Address, _In_ PUNICODE_STRING DeviceName, _In_ PTDI_PNP_CONTEXT Context ); typedef NTSTATUS (*TDI_PNP_POWER_HANDLER)( _In_ PUNICODE_STRING DeviceName, _In_ PNET_PNP_EVENT PowerEvent, _In_ PTDI_PNP_CONTEXT Context1, _In_ PTDI_PNP_CONTEXT Context2 ); // When the user makes changes using the NCPA, a TdiMakeNCPAChanges request // is generated through NDIS. The following structure is used to communicate // these changes. typedef struct _TDI_NCPA_BINDING_INFO { PUNICODE_STRING TdiClientName; PUNICODE_STRING TdiProviderName; PUNICODE_STRING BindList; PVOID ReconfigBuffer; unsigned int ReconfigBufferSize; TDI_PNP_OPCODE PnpOpcode; } TDI_NCPA_BINDING_INFO, *PTDI_NCPA_BINDING_INFO; // // The following structure makes it easy for consistency/integrity checking // typedef struct _TDI_VERSION_ { union { struct { UCHAR MajorTdiVersion; UCHAR MinorTdiVersion; }; USHORT TdiVersion; }; } TDI_VERSION, *PTDI_VERSION; #define TDI20 typedef struct _TDI20_CLIENT_INTERFACE_INFO { union { struct { UCHAR MajorTdiVersion; UCHAR MinorTdiVersion; }; USHORT TdiVersion; }; //TDI_VERSION TdiVersion; USHORT Unused; PUNICODE_STRING ClientName; TDI_PNP_POWER_HANDLER PnPPowerHandler; union { TDI_BINDING_HANDLER BindingHandler; struct { // // Putting these back in for backward compatibility. // TDI_BIND_HANDLER BindHandler; TDI_UNBIND_HANDLER UnBindHandler; }; }; union { struct { TDI_ADD_ADDRESS_HANDLER_V2 AddAddressHandlerV2; TDI_DEL_ADDRESS_HANDLER_V2 DelAddressHandlerV2; }; struct { // // Putting these back in for backward compatibility. // TDI_ADD_ADDRESS_HANDLER AddAddressHandler; TDI_DEL_ADDRESS_HANDLER DelAddressHandler; }; }; // TDI_NET_READY_HANDLER NetReadyHandler; } TDI20_CLIENT_INTERFACE_INFO, *PTDI20_CLIENT_INTERFACE_INFO; #ifdef TDI20 #define TDI_CURRENT_MAJOR_VERSION (2) #define TDI_CURRENT_MINOR_VERSION (0) typedef TDI20_CLIENT_INTERFACE_INFO TDI_CLIENT_INTERFACE_INFO; #define TDI_CURRENT_VERSION ((TDI_CURRENT_MINOR_VERSION) << 8 | \ (TDI_CURRENT_MAJOR_VERSION)) #endif // TDI20 #define TDI_VERSION_ONE 0x0001 typedef TDI_CLIENT_INTERFACE_INFO *PTDI_CLIENT_INTERFACE_INFO; _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiRegisterPnPHandlers( _In_reads_bytes_(InterfaceInfoSize) PTDI_CLIENT_INTERFACE_INFO ClientInterfaceInfo, _In_ ULONG InterfaceInfoSize, _Out_ HANDLE *BindingHandle ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiDeregisterPnPHandlers( _In_ HANDLE BindingHandle ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiPnPPowerRequest( _In_ PUNICODE_STRING DeviceName, _In_ PNET_PNP_EVENT PowerEvent, _In_ PTDI_PNP_CONTEXT Context1, _In_ PTDI_PNP_CONTEXT Context2, _In_ ProviderPnPPowerComplete ProtocolCompletionHandler ); _IRQL_requires_max_(APC_LEVEL) VOID TdiPnPPowerComplete( _In_ HANDLE BindingHandle, _In_ PNET_PNP_EVENT PowerEvent, _In_ NTSTATUS Status ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiRegisterNetAddress( _In_ PTA_ADDRESS Address, _In_ PUNICODE_STRING DeviceName, _In_ PTDI_PNP_CONTEXT Context, _Out_ HANDLE *RegistrationHandle ); NTSTATUS TdiMakeNCPAChanges( _In_ TDI_NCPA_BINDING_INFO NcpaBindingInfo ); // // Enumerate all TDI addresses for a client // _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiEnumerateAddresses( _In_ HANDLE BindingHandle ); // // Introducing the concept of Transport provider. // _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiRegisterProvider( _In_ PUNICODE_STRING ProviderName, _Out_ HANDLE *ProviderHandle ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiProviderReady( _In_ HANDLE ProviderHandle ); _IRQL_requires_max_(APC_LEVEL) NTSTATUS TdiDeregisterProvider( _In_ HANDLE ProviderHandle ); #if defined(_M_IX86) || defined(_M_AMD64) BOOLEAN TdiMatchPdoWithChainedReceiveContext( _In_ PVOID TsduDescriptor, _In_ PVOID PDO ); #endif // defined(_M_IX86) || defined(_M_AMD64) VOID TdiGet9FTriageBlock( OUT PVOID *TriageBlockAddress ); #define TDI_STATUS_BAD_VERSION 0xC0010004L // same as NDIS, is that OK? #define TDI_STATUS_BAD_CHARACTERISTICS 0xC0010005L // ,, // // PNP context types // #define TDI_PNP_CONTEXT_TYPE_IF_NAME 0x1 #define TDI_PNP_CONTEXT_TYPE_IF_ADDR 0x2 #define TDI_PNP_CONTEXT_TYPE_PDO 0x3 #define TDI_PNP_CONTEXT_TYPE_FIRST_OR_LAST_IF 0x4 // The following structures and macros are for handlers that support returning // ancillary data via a control structure // // // Layout of ancillary data objects in the control buffer // typedef struct _TDI_CMSGHDR_XP { SIZE_T cmsg_len; LONG cmsg_level; LONG cmsg_type; /* followed by UCHAR cmsg_data[] */ } TDI_CMSGHDR_XP, *PTDI_CMSGHDR_XP; #if (NTDDI_VERSION >= NTDDI_WINXP) typedef TDI_CMSGHDR_XP TDI_CMSGHDR; typedef TDI_CMSGHDR* PTDI_CMSGHDR; #endif // // Alignment macros for header and data members of // the control buffer. // #define TDI_CMSGHDR_ALIGN(length) \ ( ((length) + TYPE_ALIGNMENT(TDI_CMSGHDR)-1) & \ (~(TYPE_ALIGNMENT(TDI_CMSGHDR)-1)) ) \ #define TDI_CMSGDATA_ALIGN(length) \ ( ((length) + MAX_NATURAL_ALIGNMENT-1) & \ (~(MAX_NATURAL_ALIGNMENT-1)) ) // Returns a pointer to the first byte of data (what is referred // to as the cmsg_data member though it is not defined in // the structure). // // UCHAR * // TDI_CMSG_DATA ( // PTDI_CMSGHDR pcmsg // ); // #define TDI_CMSG_DATA(cmsg) \ ( (UCHAR *)(cmsg) + TDI_CMSGDATA_ALIGN(sizeof(TDI_CMSGHDR)) ) // // Returns total size of an ancillary data object given // the amount of data. Used to allocate the correct amount // of space. // // SIZE_T // TDI_CMSG_SPACE ( // SIZE_T length // ); // #define TDI_CMSG_SPACE(length) \ (TDI_CMSGDATA_ALIGN(sizeof(TDI_CMSGHDR) + TDI_CMSGHDR_ALIGN(length))) // Returns the value to store in cmsg_len given the amount of data. // // SIZE_T // TDI_CMSG_LEN ( // SIZE_T length // ); // #define TDI_CMSG_LEN(length) \ (TDI_CMSGDATA_ALIGN(sizeof(TDI_CMSGHDR)) + length) // Initializes the members of a TDI_CMSGHDR structure // // VOID // TDI_INIT_CMSGHDR ( // PTDI_CMSGHDR cmsg, // INT level, // INT type, // SIZE_T length, // ); // #define TDI_INIT_CMSGHDR(cmsg, level, type, length) { \ ((TDI_CMSGHDR *) cmsg)->cmsg_level = level; \ ((TDI_CMSGHDR *) cmsg)->cmsg_type = type; \ ((TDI_CMSGHDR *) cmsg)->cmsg_len = TDI_CMSG_LEN(length); \ } #pragma warning(pop) #endif // _TDI_KRNL_