📄 smbcedbp.h
字号:
// management mechanisms the REQUEST_ENTRY encapsulates a union of the requests of various
// flavours. Each SERVER_ENTRY in the connection engine is associated with a list or
// request entries. In order to hide the abstraction of a list which does not scale well to
// the case of GATEWAY redirectors a set of routines are provided to manipulate the
// collection of requests. They provide a mechanism for intializing the collection of requests,
// adding a request, deleting a request and enumeratiung requests in a collection.
//
// Special mechanisms are built in to handle batching of operations. Each operation on the
// collection of requests come in two flavours, a vanila version and a lite version. In the
// lite version it is assumed that the appropriate concurrency control action has been taken
//
// One common scenario that is often encountered in processing the requests is invocation
// of a specific function on the requests in the collection. As an example if a disconnect
// request is received on a server entry then all the outstanding requests must be resumed
// with the appropriate error. Since these indications can potentially occur at DPC levels in
// NT it is not desirable to manipulate the collection while holding onto a spinlock, nor is
// it desirable to repeatedly release and accquire the spin lock. A special operation is
// provided for transferring the requests enmasse from one collection to another and resetting
// the original. With the help of this operation it is sufficient to hold the spinlock only
// for the duration of the transfer. The remainder of the processing can be done on the newly
// created collection.
//
//
// NT Specific Implementation Note:
//
// On NT the transport indications are at DPC level, therefore it is required to protect
// the manipulation of the requests data structure with a spinlock.
//
//
typedef struct _SMBCEDB_REQUEST_ENTRY_ {
SMBCE_OBJECT_HEADER Header; // the struct header
LIST_ENTRY RequestsList; // the next request for the VC.
union {
SMBCE_GENERIC_REQUEST GenericRequest;
SMBCE_REQUEST Request; // the next request.
SMBCE_COPY_DATA_REQUEST CopyDataRequest;
SMBCE_RECONNECT_REQUEST ReconnectRequest;
SMBCE_MID_REQUEST MidRequest;
};
} SMBCEDB_REQUEST_ENTRY, *PSMBCEDB_REQUEST_ENTRY;
#define SmbCeInitializeRequests(pRequests) \
InitializeListHead(&(pRequests)->ListHead); \
(pRequests)->NextRequestId = 0
#define SmbCeAddRequestEntry(pRequestList,pRequestEntry) \
SmbCeAcquireSpinLock(); \
InsertTailList(&(pRequestList)->ListHead,&(pRequestEntry)->RequestsList); \
SmbCeReleaseSpinLock()
#define SmbCeAddRequestEntryLite(pRequestList,pRequestEntry) \
InsertTailList(&(pRequestList)->ListHead,&(pRequestEntry)->RequestsList);
#define SmbCeRemoveRequestEntry(pRequests,pEntry) \
SmbCeAcquireSpinLock(); \
RemoveEntryList(&(pEntry)->RequestsList); \
SmbCeReleaseSpinLock()
#define SmbCeRemoveRequestEntryLite(pRequests,pEntry) \
RemoveEntryList(&(pEntry)->RequestsList);
#define SmbCeGetFirstRequestEntry(pRequestList) \
(IsListEmpty(&(pRequestList)->ListHead) \
? NULL \
: (PSMBCEDB_REQUEST_ENTRY) \
(CONTAINING_RECORD((pRequestList)->ListHead.Flink, \
SMBCEDB_REQUEST_ENTRY, \
RequestsList)))
#define SmbCeGetNextRequestEntry(pRequestList,pRequestEntry) \
(((pRequestEntry)->RequestsList.Flink == &(pRequestList)->ListHead) \
? NULL \
: (PSMBCEDB_REQUEST_ENTRY) \
(CONTAINING_RECORD((pRequestEntry)->RequestsList.Flink, \
SMBCEDB_REQUEST_ENTRY, \
RequestsList)))
#define SmbCeTransferRequests(pDestination,pSource) \
if (IsListEmpty(&(pSource)->ListHead)) { \
SmbCeInitializeRequests((pDestination)); \
} else { \
*(pDestination) = *(pSource); \
(pDestination)->ListHead.Flink->Blink = &(pDestination)->ListHead; \
(pDestination)->ListHead.Blink->Flink = &(pDestination)->ListHead; \
SmbCeInitializeRequests((pSource)); \
}
// Much along the lines of a collection of request a collection of all server entries is
// maintained as part of the connection engine. The following operations are supported on
// the colection of server entries
// 1) adding a server entry to the collection
// 2) removing a server entry from the colection
// 3) enumerating the entries in the collection
//
// As in the case of the collection of requests all these operations come in two flavours
// the vanila version in which concurrency control is enforced and the lite version in
// which the concurrency control is left to the user's discretion.
#define SmbCeAddServerEntry(pServerEntry) \
SmbCeAcquireSpinLock(); \
InsertTailList(&s_DbServers.ListHead,&pServerEntry->ServersList); \
SmbCeReleaseSpinLock()
#define SmbCeAddServerEntryLite(pServerEntry) \
InsertTailList(&s_DbServers.ListHead,&pServerEntry->ServersList);
#define SmbCeRemoveServerEntry(pServerEntry) \
SmbCeAcquireSpinLock(); \
RemoveEntryList(&(pServerEntry)->ServersList); \
SmbCeReleaseSpinLock()
#define SmbCeRemoveServerEntryLite(pServerEntry) \
RemoveEntryList(&(pServerEntry)->ServersList);
#define SmbCeGetFirstServerEntry() \
(IsListEmpty(&s_DbServers.ListHead) \
? NULL \
: (PSMBCEDB_SERVER_ENTRY) \
(CONTAINING_RECORD(s_DbServers.ListHead.Flink, \
SMBCEDB_SERVER_ENTRY, \
ServersList)))
#define SmbCeGetNextServerEntry(pServerEntry) \
(((pServerEntry)->ServersList.Flink == &s_DbServers.ListHead) \
? NULL \
: (PSMBCEDB_SERVER_ENTRY) \
(CONTAINING_RECORD((pServerEntry)->ServersList.Flink, \
SMBCEDB_SERVER_ENTRY, \
ServersList)))
// Since the mapping between V_NET_ROOT's in the RDBSS and the session entries in the mini
// redirector is a many to one mapping a collection of session entries is maintained as part
// of each server entry. The following operations are supported on the collection of session
// entries
// 1) adding a session entry to the collection
// 2) removing a session entry from the colection
// 3) enumerating the entries in the collection
//
// As in the case of the collection of requests all these operations come in two flavours
// the vanila version in which concurrency control is enforced and the lite version in
// which the concurrency control is left to the user's discretion.
//
// In addition two more methods are specified for retrieving the default session entry and
// setting the default session entry for any given server.
#define SmbCeAddSessionEntry(pServerEntry,pSessionEntry) \
SmbCeAcquireSpinLock(); \
InsertTailList(&(pServerEntry)->Sessions.ListHead,&(pSessionEntry)->SessionsList); \
SmbCeReleaseSpinLock()
#define SmbCeAddSessionEntryLite(pServerEntry,pSessionEntry) \
InsertTailList(&(pServerEntry)->Sessions.ListHead,&(pSessionEntry)->SessionsList);
#define SmbCeRemoveSessionEntry(pServerEntry,pSessionEntry) \
SmbCeAcquireSpinLock(); \
if ((pSessionEntry)->DefaultSessionLink.Flink != NULL) { \
RemoveEntryList(&(pSessionEntry)->DefaultSessionLink); \
pSessionEntry->DefaultSessionLink.Flink = NULL; \
pSessionEntry->DefaultSessionLink.Blink = NULL; \
}; \
RemoveEntryList(&(pSessionEntry)->SessionsList); \
SmbCeReleaseSpinLock()
#define SmbCeRemoveSessionEntryLite(pServerEntry,pSessionEntry) \
ASSERT( SmbCeSpinLockAcquired(); ); \
if ((pSessionEntry)->DefaultSessionLink.Flink != NULL) { \
RemoveEntryList(&(pSessionEntry)->DefaultSessionLink); \
pSessionEntry->DefaultSessionLink.Flink = NULL; \
pSessionEntry->DefaultSessionLink.Blink = NULL; \
}; \
RemoveEntryList(&(pSessionEntry)->SessionsList);
#define SmbCeGetFirstSessionEntry(pServerEntry) \
(IsListEmpty(&(pServerEntry)->Sessions.ListHead) \
? NULL \
: (PSMBCEDB_SESSION_ENTRY) \
(CONTAINING_RECORD((pServerEntry)->Sessions.ListHead.Flink, \
SMBCEDB_SESSION_ENTRY, \
SessionsList)))
#define SmbCeGetNextSessionEntry(pServerEntry,pSessionEntry) \
(((pSessionEntry)->SessionsList.Flink == \
&(pServerEntry)->Sessions.ListHead) \
? NULL \
: (PSMBCEDB_SESSION_ENTRY) \
(CONTAINING_RECORD((pSessionEntry)->SessionsList.Flink, \
SMBCEDB_SESSION_ENTRY, \
SessionsList)))
#define SmbCeSetDefaultSessionEntry(pServerEntry,pSessionEntry) \
SmbCeAcquireSpinLock(); \
if ((pSessionEntry)->DefaultSessionLink.Flink == NULL) { \
ASSERT( pSessionEntry->DefaultSessionLink.Blink == NULL ); \
InsertHeadList(&(pServerEntry)->Sessions.DefaultSessionList,&(pSessionEntry)->DefaultSessionLink); \
}; \
SmbCeReleaseSpinLock()
extern PSMBCEDB_SESSION_ENTRY
SmbCeGetDefaultSessionEntry(
PSMBCEDB_SERVER_ENTRY pServerEntry,
ULONG SessionId,
PLUID pLogonId
);
VOID
SmbCeRemoveDefaultSessionEntry(
PSMBCEDB_SESSION_ENTRY pDefaultSessionEntry
);
// In order to encapsulate the notion of reconnects and to provide for hot reconnects,
// i.e., reconnection attempts in which the saved state in the server/client prior to
// a transport level disconnect can be reused it is required to mark each net root
// entry associated with a server as invalid on receipt of a transport level disconnect.
//
// Therefore an abstraction of a collection of net root entries is provided and is associated
// with each server entry.
//
// The following operations are supported on the collection of net root entries
// 1) adding a net root entry to the collection
// 2) removing a net root entry from the colection
// 3) enumerating the entries in the collection
//
// As in the case of the collection of requests all these operations come in two flavours
// the vanila version in which concurrency control is enforced and the lite version in
// which the concurrency control is left to the user's discretion.
//
#define SmbCeAddNetRootEntry(pServerEntry,pNetRootEntry) \
SmbCeAcquireSpinLock(); \
InsertTailList(&(pServerEntry)->NetRoots.ListHead,&(pNetRootEntry)->NetRootsList); \
SmbCeReleaseSpinLock()
#define SmbCeAddNetRootEntryLite(pServerEntry,pNetRootEntry) \
InsertTailList(&(pServerEntry)->NetRoots.ListHead,&(pNetRootEntry)->NetRootsList);
#define SmbCeRemoveNetRootEntry(pServerEntry,pNetRootEntry) \
SmbCeAcquireSpinLock(); \
RemoveEntryList(&(pNetRootEntry)->NetRootsList); \
SmbCeReleaseSpinLock()
#define SmbCeRemoveNetRootEntryLite(pServerEntry,pNetRootEntry) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -