TdiDispatchCreate routine
The TdiDispatchCreate routine opens a file object that represents an address, connection endpoint, or control channel, setting up driver-allocated state to track subsequent I/O operations on the open file object.
Syntax
NTSTATUS TdiDispatchCreate(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
);
Parameters
DeviceObject [in]
Pointer to the device object created by the TDI transport.Irp [in]
Pointer to the IRP with IRP_MJ_CREATE set as the MajorFunctionCode in the I/O stack location of the transport driver.A transport calls IoGetCurrentIrpStackLocation with the given IRP to get a pointer to its own stack location in the IRP, shown in the following list as IrpSp. The transport can use the information set in the following members of the IRP in processing a create request:
Value Meaning Irp->IoStatus.Status Specifies the final status of the create/open operation. The transport sets this member to the same value that will be returned by TdiDispatchCreate and Irp->IoStatus.Information is set to zero.
Irp->AssociatedIrp.SystemBuffer Pointer to a FILE_FULL_EA_INFORMATION structured buffer if the file object represents an address or a connection endpoint to be opened.
Always verify the values in the FILE_FULL_EA_INFORMATION structure before using them. Do not assume the structure was formatted by a trusted source. Verify that the EaNameLength and EaValueLength members are within the expected range. For more information, see the Remarks section.
For an address, the EaName member is set to the system-defined constant TdiTransportAddress and the EA value following the EaName array is of type TRANSPORT_ADDRESS, set up by the client to specify the address to be opened. For some transports, this value can be a symbolic netBIOS or DNS name to be translated by the transport.
For a connection endpoint, the EaName member is set to the system-defined constant TdiConnectionContext and the EA value following the EaName array is a client-supplied handle, opaque to the transport driver. The transport must save this handle and subsequently pass it back to the client's registered event handlers for this connection.
If the given file object represents a control channel, this member is NULL.
IrpSp->MajorFunction Specifies IRP_MJ_CREATE. The transport can ignore this member if it exports a TdiDispatchCreate routine that handles only create requests.
IrpSp->FileObject Pointer to a file object that the I/O manager creates to represent the address, connection endpoint, or control channel. The transport driver sets the FsContext and possibly FsContext2 fields in this file object to access driver-allocated context areas set up in TdiDispatchCreate to track subsequent I/O requests on the address, connection endpoint, or control channel.
IrpSp->Parameters.Create.EaLength Specifies the size in bytes of the buffer at Irp->AssociatedIrp.SystemBuffer. If the given file object represents a control channel, specifies zero.
IrpSp->Parameters.Create.ShareAccess If the given file object represents an address, specifies whether the client has requested an exclusive open of the file object. If the initial client to open an address sets either of FILE_SHARE_READ or FILE_SHARE_WRITE in the ShareAccess parameter to ZwCreateFile, the same address can be opened by other clients subsequently.
IrpSp->Parameters.Create.SecurityContext->AccessState If the given file object represents a sharable address, defines the requested access to that address. The initial client to open a file object representing a particular address sets the access control list for that address. A TDI transport driver calls Security Reference Monitor (Se Xxx) routines to check this member against the original ACL assigned to the corresponding file object when subsequent open-address requests occur. The transport fails subsequent open requests if the requested access is incompatible with the access rights granted in the original ACL.
Return value
TdiDispatchCreate returns STATUS_SUCCESS if the create/open operation succeeds and the transport has set up whatever state it uses to track subsequent I/O operations for the address, connection endpoint, or control channel. Otherwise, it can return any driver-determined status, such as one of the following:
Return code | Description |
---|---|
STATUS_INVALID_PARAMETER | A transport might return this value if it found EaName entries set with both TdiTransportAddress and TdiConnectionContext in the buffer at Irp->AssociatedIrp.SystemBuffer. |
STATUS_SHARING_VIOLATION | A transport might return this value if an attempt is made to open a file object representing an address that has already been opened for exclusive access. |
STATUS_NONEXISTENT_EA_ENTRY | A transport might return this value if an entry's EaName array is not followed by a valid address value of the given EaValueLength in the buffer at Irp->AssociatedIrp.SystemBuffer. |
STATUS_INSUFFICIENT_RESOURCES | A transport might return this status if it could not allocate sufficient memory in which to maintain state information about the address, connection endpoint, or control channel. |
STATUS_INVALID_DEVICE_REQUEST | A transport might return this status as a default error return or if the next lower driver's device currently is being closed. |
Remarks
Opening an address, connection endpoint, or control channel object is an inherently synchronous operation. TdiDispatchCreate can block waiting for internal driver functions to handle particular subtasks, such as initializing structures in driver-allocated context areas or checking the ACL for an address. However, TdiDispatchCreate should either set IoStatus.Status in the IRP to STATUS_SUCCESS or to an appropriate error status before it returns control.
A transport driver should fail any create/open request in which the buffer at Irp->AssociatedIrp.SystemBuffer contains EaName members set with both TdiTransportAddress and TdiConnectionContext. Clients must make separate calls to ZwCreateFile to open an address and a connection endpoint because a single file object cannot represent a combined address and connection endpoint.
The TDI provider must ensure that the EaNameLength specified by the caller is large enough to contain the expected EaName object. For example, use TDI_TRANSPORT_ADDRESS_LENGTH for the TdiTransportAddress constant and TDI_CONNECTION_CONTEXT_LENGTH for the TdiConnectionContext constant. The EaValueLength must be large enough to contain the expected EaValue object. For example, a TRANSPORT_ADDRESS object must be able to contain a given address family for address objects and a CONNECTION_CONTEXT object must be able to contain connection objects.
A client opens a file object representing an address to indicate its transport address to the TDI driver. The first client to open such a file object can specify that it be either exclusive or shared. If the initial client specifies an exclusively opened file object, the transport driver fails all subsequent client requests to open that address. If the initial client specifies a shared file object, the transport driver also fails all subsequent client requests for an exclusive open of that address. Otherwise, any number of clients can open the same file object for shared access of the same address.
Depending on the transport, a client can specify a transport address to be opened or allow the transport driver to select an address. For example, a client might specify a TDI driver's broadcast address to receive datagrams in connectionless mode.
Opening a connection endpoint defines a client's end of a network connection. When TdiDispatchCreate processes such a request, it sets up the connection endpoint in an idle state. The client must eventually associate the open connection endpoint with an opened file object representing an address. That is, a transport does no I/O on an opened connection endpoint until it has been associated with an open address.
Opening a control channel sets up a control channel between a client and the TDI transport driver. A client can use an open control channel to query and set information not specifically tied to an address or connection endpoint. For example, a client might use an opened control channel to query the transport driver's broadcast address (used to receive broadcast datagrams) or to query performance statistics maintained in the transport.
Note The TDI feature is deprecated and will be removed in future versions of Microsoft Windows. Depending on how you use TDI, use either the Winsock Kernel (WSK) or Windows Filtering Platform (WFP). For more information about WFP and WSK, see Windows Filtering Platform and Winsock Kernel. For a Windows Core Networking blog entry about WSK and TDI, see Introduction to Winsock Kernel (WSK).
Requirements
Target platform |
Desktop |
Header |
Wdm.h (include Ntddk.h, Wdm.h, or Ntddk.h) |
IRQL |
PASSIVE_LEVEL |
See also
TdiDispatchInternalDeviceControl