NTSTATUS
TdiDispatchCreate (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
TdiDispatchCreate 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.
Parameters
DeviceObject
Points to the device object created by the TDI transport.
Irp
Points 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:
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. (IoStatus.Information is set to zero.)
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
Points 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(s) in this file object to access driver-allocated context area(s) set up in TdiDispatchCreate to track subsequent I/O requests on the address, connection endpoint, or control channel.
Irp->AssociatedIrp.SystemBuffer
Points to a FILE_FULL_EA_INFORMATION-structured buffer if the file object represents an address or a connection endpoint to be opened.
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->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 shareable 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 (SeXxx) routine(s) 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:
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.
Comments
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 area(s) 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 TransportAddress and ConnectionContext. 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.
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 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 tranport, 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.
By default, TdiDispatchCreate runs at IRQL PASSIVE_LEVEL.
See Also
TdiDispatchCleanup, TdiDispatchDeviceControl, TdiDispatchInternalDeviceControl, TRANSPORT_ADDRESS