2025-04-27 07:49:33 -04:00

340 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
transport.c
Abstract:
This module implements all transport related functions in the SMB connection
engine
--*/
#ifndef _TRANSPRT_H_
#define _TRANSPRT_H_
// The SMBCE_TRANSPORT data structure encapsulates all the information w.r.t a
// particular transport for the connection engine. All the transports that are
// of interest to the SMB mini redirector are maintained in a doubly linked list
//
// The connection engine tries all the transports in this list when trying to
// establish a connection to a server. Currently only connection oriented
// transports are handled.
typedef struct _SMBCE_TRANSPORT_ {
SMBCE_OBJECT_HEADER;
LIST_ENTRY TransportsList;
RXCE_TRANSPORT_HANDLE hTransport;
RXCE_ADDRESS_HANDLE hAddress;
ULONG Priority; // the priority in the binding list.
BOOLEAN Active;
// Additional information regarding quality of service and other selection
// criterion for a transport will be included here.
} SMBCE_TRANSPORT, *PSMBCE_TRANSPORT;
typedef struct _SMBCE_TRANSPORTS_ {
RX_SPIN_LOCK Lock;
LONG Count;
LIST_ENTRY ListHead;
} SMBCE_TRANSPORTS, *PSMBCE_TRANSPORTS;
extern SMBCE_TRANSPORTS MRxSmbTransports;
// Transport entries are added to the list of known transports upon receipt of
// PnP notifications. Currently the list is static since transport disabling
// notifications are not handled by the underlying TDI/PnP layer.
// The following routines provide the ability for adding/deleting entries to
// this list.
extern VOID
SmbCeAddTransport(PSMBCE_TRANSPORT pTransport);
extern VOID
SmbCeRemoveTransport(PSMBCE_TRANSPORT pTransport);
extern
PSMBCE_TRANSPORT
SmbCeGetNextTransport(PSMBCE_TRANSPORT pTransport);
// The connection engine maintains a reference count associated with each transport
// which indicates the number of servers that are using the transport. This will
// eventually provide the mechanism for disabling/enabling transport on receipt
// of PnP notifications.
#define SmbCeReferenceTransport(pTransport) \
InterlockedIncrement(&pTransport->SwizzleCount)
#define SmbCeDereferenceTransport(pTransport) \
InterlockedDecrement(&pTransport->SwizzleCount)
// The server transport types encapsulate the various usages of the underlying
// transport to communicate with a server. For example the type of interactions
// with a mailslot server ( primarily datagrams ) is very different from the
// interactions with a FILE SERVER ( connection oriented send/receives). The
// type of interactions can be further classified by the underlying connection
// characterstics, e.g., connecting to a FILE_SERVER over a RAS connection as
// opposed to connecting to a file server over EtherNet.
//
// The interactions are currently classified into four types, MAILSOT, Virtual
// Circuit, Datagram and Htbrid ( VC + Datagram ).
//
// The type chosen will depend upon the characterstics of the available
// connection. Each type is associated with its own dispatch vector which
// encapsulates the interaction between the connection engine and the transport.
//
// This includes Send,Receive, Receive Ind. etc. These are modelled after the
// TDI interfaces.
typedef enum _SMBCE_SERVER_TRANSPORT_TYPE_ {
SMBCE_STT_MAILSLOT,
SMBCE_STT_VC,
SMBCE_STT_DATAGRAM,
SMBCE_STT_HYBRID
} SMBCE_SERVER_TRANSPORT_TYPE, *PSMBCE_SERVER_TRANSPORT_TYPE;
typedef struct SMBCE_SERVER_TRANSPORT {
SMBCE_OBJECT_HEADER;
struct TRANSPORT_DISPATCH_VECTOR *pDispatchVector;
struct _SMBCE_TRANSPORT_ *pTransport;
PKEVENT pRundownEvent; // used for finalization.
ULONG MaximumSendSize; // max data size for bulk I/O
} SMBCE_SERVER_TRANSPORT, *PSMBCE_SERVER_TRANSPORT;
// The SMBCE_SERVER_TRANSPORT instances are reference counted. The following
// routines provide the referencing mechanism. Defining them as macros also
// provides us with a easy debugging capability, i.e., it can be easily modified
// to include a FILE/LINE number each time an instance is referenced and
// dereferenced
#define SmbCeReferenceServerTransport(pServerEntry) \
SmbCepReferenceServerTransport(pServerEntry)
#define SmbCeDereferenceServerTransport(pServerEntry) \
SmbCepDereferenceServerTransport(pServerEntry)
// The SERVER transport dispatch vector prototypes
typedef
NTSTATUS
(*PTRANSPORT_DISPATCH_SEND)(
PSMBCEDB_SERVER_ENTRY pServerEntry,
ULONG SendOptions,
PMDL pSmbMdl,
ULONG SendLength,
PVOID pSendCompletionContext);
typedef
NTSTATUS
(*PTRANSPORT_DISPATCH_SEND_DATAGRAM)(
PSMBCEDB_SERVER_ENTRY pServerEntry,
ULONG SendOptions,
PMDL pSmbMdl,
ULONG SendLength,
PVOID pSendCompletionContext);
typedef
NTSTATUS
(*PTRANSPORT_DISPATCH_TRANCEIVE)(
PSMBCEDB_SERVER_ENTRY pServerEntry,
PSMB_EXCHANGE pExchange,
ULONG SendOptions,
PMDL pSmbMdl,
ULONG SendLength,
PVOID pSendCompletionContext);
typedef
NTSTATUS
(*PTRANSPORT_DISPATCH_RECEIVE)(
PSMBCEDB_SERVER_ENTRY pServerEntry,
PSMB_EXCHANGE pExchange);
typedef
NTSTATUS
(*PTRANSPORT_DISPATCH_INITIALIZE_EXCHANGE)(
PSMB_EXCHANGE pExchange);
typedef
NTSTATUS
(*PTRANSPORT_DISPATCH_UNINITIALIZE_EXCHANGE)(
PSMB_EXCHANGE pExchange);
typedef
VOID
(*PTRANSPORT_DISPATCH_TEARDOWN)(
PSMBCE_SERVER_TRANSPORT pTransport);
typedef struct TRANSPORT_DISPATCH_VECTOR {
PTRANSPORT_DISPATCH_SEND Send;
PTRANSPORT_DISPATCH_SEND_DATAGRAM SendDatagram;
PTRANSPORT_DISPATCH_TRANCEIVE Tranceive;
PTRANSPORT_DISPATCH_RECEIVE Receive;
PRX_WORKERTHREAD_ROUTINE TimerEventHandler;
PTRANSPORT_DISPATCH_INITIALIZE_EXCHANGE InitializeExchange;
PTRANSPORT_DISPATCH_UNINITIALIZE_EXCHANGE UninitializeExchange;
PTRANSPORT_DISPATCH_TEARDOWN TearDown;
} TRANSPORT_DISPATCH_VECTOR, *PTRANSPORT_DISPATCH_VECTOR;
// A macro for invoking a routine through the SMBCE_SERVER_TRANSPORT
// dispatch vector.
#define SMBCE_TRANSPORT_DISPATCH(pServerEntry,Routine,Arguments) \
(*((pServerEntry)->pTransport->pDispatchVector->Routine))##Arguments
// The currently known transport type dispatch vectors and the mechanisms
// for instanting an instance.
extern TRANSPORT_DISPATCH_VECTOR MRxSmbVctTransportDispatch;
extern TRANSPORT_DISPATCH_VECTOR MRxSmbMsTransportDispatch;
extern NTSTATUS
MsInstantiateServerTransport(
IN OUT PSMBCEDB_SERVER_ENTRY pServerEntry,
OUT PSMBCE_SERVER_TRANSPORT *pServerTransportPtr);
extern NTSTATUS
VctInstantiateServerTransport(
IN OUT PSMBCEDB_SERVER_ENTRY pServerEntry,
OUT PSMBCE_SERVER_TRANSPORT *pServerTransportPtr);
// The following routines constitute the interface by which the clients of
// the connection engine initialize/send/receive/uninitialize data to the
// remote servers
extern NTSTATUS
SmbCeInitializeServerTransport(
IN OUT PSMBCEDB_SERVER_ENTRY pServerEntry);
extern NTSTATUS
SmbCeUninitializeServerTransport(
IN OUT PSMBCEDB_SERVER_ENTRY pServerEntry);
extern NTSTATUS
SmbCepReferenceServerTransport(
IN OUT PSMBCEDB_SERVER_ENTRY pServerEntry);
extern NTSTATUS
SmbCepDereferenceServerTransport(
IN OUT PSMBCEDB_SERVER_ENTRY pServerEntry);
//
// INLINE functions to hide dispatch vector related details for invoking Transport methods
//
INLINE NTSTATUS
SmbCeInitializeExchangeTransport(
PSMB_EXCHANGE pExchange)
{
if (pExchange->SmbStatus == STATUS_SUCCESS) {
if (pExchange->SmbCeContext.pServerEntry->pTransport != NULL) {
pExchange->SmbCeFlags |= SMBCE_EXCHANGE_TRANSPORT_INITIALIZED;
return (pExchange->SmbCeContext.pServerEntry->pTransport->pDispatchVector->InitializeExchange)(
pExchange);
} else {
return STATUS_CONNECTION_DISCONNECTED;
}
} else {
return pExchange->SmbStatus;
}
}
INLINE NTSTATUS
SmbCeUninitializeExchangeTransport(
PSMB_EXCHANGE pExchange)
{
if (FlagOn(pExchange->SmbCeFlags,SMBCE_EXCHANGE_TRANSPORT_INITIALIZED)) {
if (pExchange->SmbCeContext.pServerEntry->pTransport != NULL) {
return (pExchange->SmbCeContext.pServerEntry->pTransport->pDispatchVector->UninitializeExchange)(
pExchange);
} else {
return STATUS_CONNECTION_DISCONNECTED;
}
} else {
return pExchange->SmbStatus;
}
}
extern NTSTATUS
SmbCeSend(
PSMB_EXCHANGE pExchange,
ULONG SendOptions,
PMDL pSmbMdl,
ULONG SendLength);
extern NTSTATUS
SmbCeSendToServer(
PSMBCEDB_SERVER_ENTRY pServerEntry,
ULONG SendOptions,
PMDL pSmbMdl,
ULONG SendLength);
extern NTSTATUS
SmbCeSendDatagram(
PSMB_EXCHANGE pExchange,
ULONG SendOptions,
PMDL pSmbMdl,
ULONG SendLength);
extern NTSTATUS
SmbCeTranceive(
PSMB_EXCHANGE pExchange,
ULONG SendOptions,
PMDL pRxCeDataBuffer,
ULONG SendLength);
extern NTSTATUS
SmbCeReceive(
PSMB_EXCHANGE pExchange);
//
// Call ups from the transport to the connection engine
//
extern NTSTATUS
SmbCeReceiveInd(
IN PSMBCEDB_SERVER_ENTRY pServerEntry,
IN ULONG BytesIndicated,
IN ULONG BytesAvailable,
OUT ULONG *pBytesTaken,
IN PVOID pTsdu, // pointer describing this TSDU, typically a lump of bytes
OUT PMDL *pDataBufferPointer, // the buffer in which data is to be copied.
OUT PULONG pDataBufferSize // amount of data to copy
);
extern NTSTATUS
SmbCeDataReadyInd(
IN PSMBCEDB_SERVER_ENTRY pServerEntry,
IN PMDL pBuffer,
IN ULONG DataSize,
IN NTSTATUS DataReadyStatus
);
extern NTSTATUS
SmbCeErrorInd(
IN PSMBCEDB_SERVER_ENTRY pServerEntry,
IN NTSTATUS IndicatedStatus
);
extern NTSTATUS
SmbCeSendCompleteInd(
IN PSMBCEDB_SERVER_ENTRY pServerEntry,
IN PVOID pCompletionContext,
IN NTSTATUS SendCompletionStatus
);
#endif // _TRANSPRT_H_