Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

812 lines
38 KiB

  1. /*++ BUILD Version: 0009 // Increment this if a change has global effects
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. smbcedbp.h
  5. Abstract:
  6. This is the include file that defines all constants and types for
  7. implementing the SMB mini redirector connection engine.
  8. This module contains all the implementation details of the connection engine
  9. data structures and should be included only by the implementation modules.
  10. Revision History:
  11. Balan Sethu Raman (SethuR) 06-Mar-95 Created
  12. Notes:
  13. --*/
  14. #ifndef _SMBCEDBP_H_
  15. #define _SMBCEDBP_H_
  16. // Partial Directory constants
  17. #define NAME_CACHE_PARTIAL_DIR_BUFFER_SIZE 4096
  18. #define DIR_CACHE_LIFE_TIME 10
  19. #define MAX_CHAR_INVALIDATES_FULL_DIR 8
  20. #define FLAG_FDC_NAMES_INFO_ONLY 0x01
  21. typedef struct _FULL_DIR_CACHE_ {
  22. USHORT CharInvalidates;
  23. USHORT Flags;
  24. ULONG CharFlags;
  25. ULONG NiBufferLength;
  26. MRX_SMB_FOBX smbFobx;
  27. BYTE Buffer[NAME_CACHE_PARTIAL_DIR_BUFFER_SIZE];
  28. // A Sid is a variable length data structure. This way we allocate the max
  29. // number of bytes we could need, while still making it so we can just access
  30. // FULL_DIR_CACHE.Sid.whatever
  31. union {
  32. SID Sid;
  33. BYTE SidBuffer[SECURITY_MAX_SID_SIZE];
  34. };
  35. BYTE NiBuffer[NAME_CACHE_PARTIAL_DIR_BUFFER_SIZE];
  36. } FULL_DIR_CACHE, *PFULL_DIR_CACHE;
  37. //
  38. // There is reliance on the fact that SMBCEDB_OT_SENTINEL is the last entry in the
  39. // enumerated type and the types have a range of values from 0. Please ensure that
  40. // this is always true.
  41. //
  42. typedef struct _REFERENCE_RECORD_ {
  43. PVOID FileName;
  44. ULONG FileLine;
  45. } REFERENCE_RECORD,*PREFERENCE_RECORD;
  46. #define REFERENCE_RECORD_SIZE 20
  47. typedef enum _SMBCEDB_OBJECT_TYPE {
  48. SMBCEDB_OT_SERVER,
  49. SMBCEDB_OT_NETROOT,
  50. SMBCEDB_OT_SESSION,
  51. SMBCEDB_OT_REQUEST,
  52. SMBCEDB_OT_VNETROOTCONTEXT,
  53. SMBCEDB_OT_SENTINEL,
  54. SMBCEDB_OT_TRANSPORT
  55. } SMBCEDB_OBJECT_TYPE, *PSMBCEDB_OBJECT_TYPE;
  56. typedef enum _SMBCEDB_OBJECT_STATE_ {
  57. SMBCEDB_ACTIVE, // the instance is in use
  58. SMBCEDB_INVALID, // the instance has been invalidated/disconnected.
  59. SMBCEDB_MARKED_FOR_DELETION, // the instance has been marked for deletion.
  60. SMBCEDB_RECYCLE, // the instance is available for recycling
  61. SMBCEDB_START_CONSTRUCTION, // Initiate construction.
  62. SMBCEDB_CONSTRUCTION_IN_PROGRESS, // the instance construction is in progress
  63. SMBCEDB_DESTRUCTION_IN_PROGRESS, // the instance destruction is in progress
  64. SMBCEDB_RECOVER // the instance need to be recovered
  65. } SMBCEDB_OBJECT_STATE, *PSMBCEDB_OBJECT_STATE;
  66. typedef struct _SMBCE_OBJECT_HEADER_ {
  67. union {
  68. struct {
  69. UCHAR ObjectType; // type of the object
  70. UCHAR ObjectCategory; // Node type for debugging
  71. };
  72. USHORT NodeType;
  73. };
  74. UCHAR Flags; // flags associated with the object, This is implementation dependent
  75. UCHAR Reserved; // padding
  76. LONG SwizzleCount; // Number of swizzled references to this object
  77. LONG State; // State of the object
  78. } SMBCE_OBJECT_HEADER, *PSMBCE_OBJECT_HEADER;
  79. typedef struct _SMBCE_SERVERS_LIST_ {
  80. LIST_ENTRY ListHead;
  81. } SMBCEDB_SERVERS, *PSMBCEDB_SERVERS;
  82. typedef struct _SMBCEDB_SESSIONS_ {
  83. LIST_ENTRY ListHead;
  84. LIST_ENTRY DefaultSessionList;
  85. } SMBCEDB_SESSIONS, *PSMBCEDB_SESSIONS;
  86. typedef struct _SMBCEDB_NET_ROOTS_ {
  87. LIST_ENTRY ListHead;
  88. } SMBCEDB_NET_ROOTS, *PSMBCEDB_NET_ROOTS;
  89. typedef struct _MRX_SMB_V_NET_ROOT_CONTEXTS {
  90. LIST_ENTRY ListHead;
  91. } SMBCE_V_NET_ROOT_CONTEXTS, *PSMBCE_V_NET_ROOT_CONTEXTS;
  92. typedef struct _SMBCEDB_REQUESTS_ {
  93. LIST_ENTRY ListHead;
  94. SMB_MPX_ID NextRequestId;
  95. } SMBCEDB_REQUESTS, *PSMBCEDB_REQUESTS;
  96. typedef enum _SMBCEDB_SERVER_TYPE_ {
  97. SMBCEDB_MAILSLOT_SERVER = 1,
  98. SMBCEDB_FILE_SERVER = 2
  99. } SMBCEDB_SERVER_TYPE, *PSMBCEDB_SERVER_TYPE;
  100. //
  101. // The SMBCEDB_SERVER_ENTRY is the data structure which encapsulates all the information
  102. // w.r.t a remote server for the connection engine. This information includes the dialect
  103. // details as well as the operational data structures required to communicate with the server.
  104. //
  105. // All the dialect related details are further encapsulated in SMBCE_SERVER while the operational
  106. // data structures constitute the remaining parts of the server entry. A pointer to a
  107. // SMBCEDB_SERVER_ENTRY instance is associated with every SRV_CALL that has been hooked
  108. // onto this mini redirector by the wrapper. It is stored in the Context field of MRX_SRV_CALL.
  109. //
  110. // The operational information associated with a server entry includes the Transport related
  111. // information, a collection of requests and a mechanism for associating MID's ( See SMB
  112. // protocol spec.) and a mechanism for posting to threads ( WORK_QUEUE_ITEM ).
  113. //
  114. typedef struct _SMBCEDB_SERVER_ENTRY {
  115. SMBCE_OBJECT_HEADER Header; // struct header.
  116. LIST_ENTRY ServersList; // list of server instances.
  117. PMRX_SRV_CALL pRdbssSrvCall;
  118. UNICODE_STRING Name; // the server name.
  119. UNICODE_STRING DomainName; // the server domain name.
  120. SMBCEDB_SESSIONS Sessions; // the sessions associated with the server
  121. SMBCEDB_NET_ROOTS NetRoots; // the net roots associated with the server.
  122. SMBCE_V_NET_ROOT_CONTEXTS VNetRootContexts; // the V_NET_ROOT contexts
  123. LIST_ENTRY ActiveExchanges; // list of exchanges active for this server
  124. LIST_ENTRY ExpiredExchanges; // exchanges that have been timed out
  125. RX_WORK_QUEUE_ITEM WorkQueueItem; // work queue item for posting
  126. NTSTATUS ServerStatus; // the status of the server as determined by negotiate response
  127. struct _SMBCE_TRANSPORT_ *PreferredTransport;
  128. LONG TransportSpecifiedByUser; // ture if the connection is established on the tranport
  129. // with the name specified
  130. struct SMBCE_SERVER_TRANSPORT *pTransport;
  131. struct SMBCE_SERVER_TRANSPORT *pMailSlotTransport;
  132. SMBCEDB_REQUESTS MidAssignmentRequests;
  133. SMBCEDB_REQUESTS OutstandingRequests;
  134. PMID_ATLAS pMidAtlas;
  135. struct _SMB_EXCHANGE *pNegotiateExchange;
  136. SMBCE_SERVER Server; // the server data structure.
  137. UNICODE_STRING DfsRootName;
  138. UNICODE_STRING DnsName;
  139. PVOID ConstructionContext; // debug only
  140. KEVENT MailSlotTransportRundownEvent;
  141. KEVENT TransportRundownEvent;
  142. BOOLEAN IsTransportDereferenced; // prevent transport from being dereferenced more than once
  143. BOOLEAN NegotiateInProgress; // a negotiate is in progress for this server
  144. BOOLEAN SecuritySignaturesActive; // process the security signature if it is active
  145. BOOLEAN SecuritySignaturesEnabled; // true if the security signature is required by either the
  146. // client or server, and both have the capability.
  147. BOOLEAN ExtSessionSetupInProgress; // a probe server is in progress for security signature
  148. BOOLEAN ResumeRequestsInProgress;
  149. RX_WORK_QUEUE_ITEM WorkQueueItemForResume; // work queue item for posting resume requests
  150. SMBCEDB_REQUESTS SecuritySignatureSyncRequests; // requests waiting on extended session setup for security signature
  151. REFERENCE_RECORD ReferenceRecord[REFERENCE_RECORD_SIZE]; // debug only
  152. RX_WORK_QUEUE_ITEM WorkQueueItemForDisconnect; // work queue item for posting dereference server entry requests
  153. BOOLEAN DisconnectWorkItemOutstanding; // is the disconnect work item in the queue?
  154. RX_CONNECTION_ID ConnectionId;
  155. } SMBCEDB_SERVER_ENTRY, *PSMBCEDB_SERVER_ENTRY;
  156. // The SMBCEDB_NET_ROOT_ENTRY encapsulates all the information associated with a particular
  157. // TREE_CONNECT ( Net use ) made on a server. As with the server entry this data structure
  158. // encapsulates the dialect oriented details as well as the opertaional information
  159. // associated with handling the requests on a net root.
  160. //
  161. // The dialect specific information is encapsulated in the SMBCE_NET_ROOT data structure. A
  162. // pointer to an instance of this data structure is associated with every MRX_NET_ROOT call
  163. // associated with a MRX_SRV_CALL hooked to this mini redirector.
  164. // ********** code.improvement ******* The Name cache control structs should be replaced
  165. // ************************************ with pointers to alloced structs so their size remains the
  166. // ************************************ province of the wrapper.
  167. //
  168. typedef struct _SMBCEDB_NET_ROOT_ENTRY {
  169. SMBCE_OBJECT_HEADER Header; // the struct header
  170. LIST_ENTRY NetRootsList; // the list of net roots asssociated with a server
  171. PMRX_NET_ROOT pRdbssNetRoot; // the associated net root ( purely as a debug aid )
  172. PSMBCEDB_SERVER_ENTRY pServerEntry; // the associated server entry
  173. struct _SMB_EXCHANGE *pExchange; // the exchange which is responsible for construction
  174. SMBCEDB_REQUESTS Requests; // the pending requests for this net root
  175. UNICODE_STRING Name;
  176. ACCESS_MASK MaximalAccessRights;
  177. ACCESS_MASK GuestMaximalAccessRights;
  178. SMBCE_NET_ROOT NetRoot; // the net root data structure.
  179. NAME_CACHE_CONTROL NameCacheCtlGFABasic; // The basic file information name cache control.
  180. NAME_CACHE_CONTROL NameCacheCtlGFAStandard; // The standard file information name cache control.
  181. NAME_CACHE_CONTROL NameCacheCtlGFAInternal; // The internal file information name cache control.
  182. NAME_CACHE_CONTROL NameCacheCtlFNF; // The File not found name cache control.
  183. NAME_CACHE_CONTROL NameCacheCtlPartialDir; // The Partial Directory name cache control.
  184. PFILE_FS_VOLUME_INFORMATION VolumeInfo; // The FS Volume Information cache.
  185. LONG VolumeInfoLength;
  186. LARGE_INTEGER VolumeInfoExpiryTime;
  187. BOOLEAN IsRemoteBoot;
  188. } SMBCEDB_NET_ROOT_ENTRY, *PSMBCEDB_NET_ROOT_ENTRY;
  189. // The SMBCEDB_SESSION_ENTRY encapsulates all the information associated with a session
  190. // established to a remote machine. The session encapsulates all the security information.
  191. // The dialect specific details are encapsulated in teh SMBCE_SESSION data structure. The
  192. // SMBCE_SESSION data structure is available in many flavours depending on the security
  193. // package used. Currently there is support for handling LSA and KERBEROS sessions.
  194. //
  195. // A pointer to an instance of this data structure is associated with every MRX_V_NET_ROOT
  196. // data structure hooked to this mini redirector by the wrapper.
  197. typedef struct _SMBCEDB_SESSION_ENTRY {
  198. SMBCE_OBJECT_HEADER Header; // the struct header
  199. LIST_ENTRY SessionsList; // the list of sessions associated with the server
  200. LIST_ENTRY DefaultSessionLink; // the list of explicit credentials for this server
  201. PSMBCEDB_SERVER_ENTRY pServerEntry; // the associated server entry
  202. struct _SMB_EXCHANGE *pExchange; // the exchange which is responsible for construction
  203. SMBCEDB_REQUESTS Requests; // pending requests
  204. LIST_ENTRY SerializationList; // session construction serialization
  205. PKEVENT pSerializationEvent;
  206. ULONG SessionVCNumber; // the VC number to be packaged with session setup
  207. SMBCE_SESSION Session; // the Session
  208. PUNICODE_STRING pNetRootName; // for share level security only
  209. BOOLEAN SessionRecoverInProgress;
  210. BOOLEAN SessionRecoveryInitiated;
  211. } SMBCEDB_SESSION_ENTRY, *PSMBCEDB_SESSION_ENTRY;
  212. //
  213. // The wrapper exposes three data structures for manipulating and describing
  214. // name spaces set up on remote servers, Viz., MRX_SRV_CALL, MRX_NET_ROOT and
  215. // MRX_V_NET_ROOT. The SRV_CALL corresponds to a remote server, the MRX_NET_ROOT
  216. // corresponds to a share on that machine and V_NET_ROOT encapsulates
  217. // the notion of a view of a MRX_NET_ROOT ( share in SMB terminology)
  218. //
  219. // The mapping between the wrapper level data structures and the SMB notion
  220. // of SMBCEDB_SERVER_ENTRY, SMBCEDB_SESSION_ENTRY and SMBCEDB_NET_ROOT_ENTRY
  221. // is not one to one in all cases.
  222. //
  223. // It is one to one between MRX_SRV_CALL and SMBCEDB_SERVER_ENTRY. It is for this
  224. // reason that a pointer to SMBCEDB_SERVER_ENTRY is stored in the context field
  225. // of the MRX_SRV_CALL instance.
  226. //
  227. // SMBCEDB_SESSION_ENTRY has a one to one mapping with the set of credentials
  228. // supplied to establish a connection to a server. Having established a session
  229. // one can have access to all the shares available on the server.
  230. //
  231. // SMBCEDB_NET_ROOT_ENTRY has a one to one mapping with a share on a given
  232. // server. Since this closely corresponds to the wrappers interpretation of
  233. // MRX_NET_ROOT a pointer to SMBCEDB_NET_ROOT_ENTRY is stored as part of the
  234. // MRX_NET_ROOT instance.
  235. //
  236. // The context associated with every MRX_V_NET_ROOT instance is a pointer to
  237. // an instance of SMBCE_V_NET_ROOT_CONTEXT. This encapsulates the associated session
  238. // entry, the net root entry and the relevant book keeping information.
  239. //
  240. // The bookkeeping information is the UID/TID used in the SMB protocol, a
  241. // reference count and a LIST_ENTRY to thread the instance into the appropriate
  242. // list.
  243. //
  244. #define SMBCE_V_NET_ROOT_CONTEXT_FLAG_VALID_TID (0x1)
  245. #define SMBCE_V_NET_ROOT_CONTEXT_CSCAGENT_INSTANCE (0x2)
  246. typedef struct _SMBCE_V_NET_ROOT_CONTEXT {
  247. SMBCE_OBJECT_HEADER Header;
  248. PMRX_V_NET_ROOT pRdbssVNetRoot; // the associated VNetRoot ( purely as a debug aid)
  249. struct _SMB_EXCHANGE *pExchange; // the exchange which is responsible for construction
  250. SMBCEDB_REQUESTS Requests;
  251. LIST_ENTRY ListEntry;
  252. LARGE_INTEGER ExpireTime;
  253. struct _SMBCEDB_SERVER_ENTRY *pServerEntry;
  254. struct _SMBCEDB_SESSION_ENTRY *pSessionEntry;
  255. struct _SMBCEDB_NET_ROOT_ENTRY *pNetRootEntry;
  256. USHORT Flags;
  257. SMB_TREE_ID TreeId;
  258. DWORD SessionSetupRetryCount;
  259. REFERENCE_RECORD ReferenceRecord[REFERENCE_RECORD_SIZE]; // debug only
  260. } SMBCE_V_NET_ROOT_CONTEXT, *PSMBCE_V_NET_ROOT_CONTEXT;
  261. //
  262. // An SMBCEDB_REQUEST_ENTRY encapsulates an action being processed by the SMBCE connection
  263. // engine. The requests come in vairous flavours and each of these flavours is associated
  264. // with the appropriate context required for resumption. In order to provide better memory
  265. // management mechanisms the REQUEST_ENTRY encapsulates a union of the requests of various
  266. // flavours. Each SERVER_ENTRY in the connection engine is associated with a list or
  267. // request entries. In order to hide the abstraction of a list which does not scale well to
  268. // the case of GATEWAY redirectors a set of routines are provided to manipulate the
  269. // collection of requests. They provide a mechanism for intializing the collection of requests,
  270. // adding a request, deleting a request and enumeratiung requests in a collection.
  271. //
  272. // Special mechanisms are built in to handle batching of operations. Each operation on the
  273. // collection of requests come in two flavours, a vanila version and a lite version. In the
  274. // lite version it is assumed that the appropriate concurrency control action has been taken
  275. //
  276. // One common scenario that is often encountered in processing the requests is invocation
  277. // of a specific function on the requests in the collection. As an example if a disconnect
  278. // request is received on a server entry then all the outstanding requests must be resumed
  279. // with the appropriate error. Since these indications can potentially occur at DPC levels in
  280. // NT it is not desirable to manipulate the collection while holding onto a spinlock, nor is
  281. // it desirable to repeatedly release and accquire the spin lock. A special operation is
  282. // provided for transferring the requests enmasse from one collection to another and resetting
  283. // the original. With the help of this operation it is sufficient to hold the spinlock only
  284. // for the duration of the transfer. The remainder of the processing can be done on the newly
  285. // created collection.
  286. //
  287. //
  288. // NT Specific Implementation Note:
  289. //
  290. // On NT the transport indications are at DPC level, therefore it is required to protect
  291. // the manipulation of the requests data structure with a spinlock.
  292. //
  293. //
  294. typedef struct _SMBCEDB_REQUEST_ENTRY_ {
  295. SMBCE_OBJECT_HEADER Header; // the struct header
  296. LIST_ENTRY RequestsList; // the next request for the VC.
  297. union {
  298. SMBCE_GENERIC_REQUEST GenericRequest;
  299. SMBCE_REQUEST Request; // the next request.
  300. SMBCE_COPY_DATA_REQUEST CopyDataRequest;
  301. SMBCE_RECONNECT_REQUEST ReconnectRequest;
  302. SMBCE_MID_REQUEST MidRequest;
  303. SMBCE_HOLD_REQUEST HoldRequest;
  304. };
  305. } SMBCEDB_REQUEST_ENTRY, *PSMBCEDB_REQUEST_ENTRY;
  306. #define SmbCeInitializeRequests(pRequests) \
  307. InitializeListHead(&(pRequests)->ListHead); \
  308. (pRequests)->NextRequestId = 0
  309. #define SmbCeAddRequestEntry(pRequestList,pRequestEntry) \
  310. SmbCeAcquireSpinLock(); \
  311. InsertTailList(&(pRequestList)->ListHead,&(pRequestEntry)->RequestsList); \
  312. SmbCeReleaseSpinLock()
  313. #define SmbCeAddRequestEntryLite(pRequestList,pRequestEntry) \
  314. InsertTailList(&(pRequestList)->ListHead,&(pRequestEntry)->RequestsList)
  315. #define SmbCeRemoveRequestEntry(pRequests,pEntry) \
  316. SmbCeAcquireSpinLock(); \
  317. RemoveEntryList(&(pEntry)->RequestsList); \
  318. SmbCeReleaseSpinLock()
  319. #define SmbCeRemoveRequestEntryLite(pRequests,pEntry) \
  320. RemoveEntryList(&(pEntry)->RequestsList)
  321. #define SmbCeGetFirstRequestEntry(pRequestList) \
  322. (IsListEmpty(&(pRequestList)->ListHead) \
  323. ? NULL \
  324. : (PSMBCEDB_REQUEST_ENTRY) \
  325. (CONTAINING_RECORD((pRequestList)->ListHead.Flink, \
  326. SMBCEDB_REQUEST_ENTRY, \
  327. RequestsList)))
  328. #define SmbCeGetNextRequestEntry(pRequestList,pRequestEntry) \
  329. (((pRequestEntry)->RequestsList.Flink == &(pRequestList)->ListHead) \
  330. ? NULL \
  331. : (PSMBCEDB_REQUEST_ENTRY) \
  332. (CONTAINING_RECORD((pRequestEntry)->RequestsList.Flink, \
  333. SMBCEDB_REQUEST_ENTRY, \
  334. RequestsList)))
  335. #define SmbCeTransferRequests(pDestination,pSource) \
  336. if (IsListEmpty(&(pSource)->ListHead)) { \
  337. SmbCeInitializeRequests((pDestination)); \
  338. } else { \
  339. *(pDestination) = *(pSource); \
  340. (pDestination)->ListHead.Flink->Blink = &(pDestination)->ListHead; \
  341. (pDestination)->ListHead.Blink->Flink = &(pDestination)->ListHead; \
  342. SmbCeInitializeRequests((pSource)); \
  343. }
  344. // Much along the lines of a collection of request a collection of all server entries is
  345. // maintained as part of the connection engine. The following operations are supported on
  346. // the colection of server entries
  347. // 1) adding a server entry to the collection
  348. // 2) removing a server entry from the colection
  349. // 3) enumerating the entries in the collection
  350. //
  351. // As in the case of the collection of requests all these operations come in two flavours
  352. // the vanila version in which concurrency control is enforced and the lite version in
  353. // which the concurrency control is left to the user's discretion.
  354. #define SmbCeAddServerEntry(pServerEntry) \
  355. SmbCeAcquireSpinLock(); \
  356. InsertTailList(&s_DbServers.ListHead,&pServerEntry->ServersList); \
  357. SmbCeReleaseSpinLock()
  358. #define SmbCeAddServerEntryLite(pServerEntry) \
  359. InsertTailList(&s_DbServers.ListHead,&pServerEntry->ServersList)
  360. #define SmbCeRemoveServerEntry(pServerEntry) \
  361. SmbCeAcquireSpinLock(); \
  362. RemoveEntryList(&(pServerEntry)->ServersList); \
  363. SmbCeReleaseSpinLock()
  364. #define SmbCeRemoveServerEntryLite(pServerEntry) \
  365. RemoveEntryList(&(pServerEntry)->ServersList)
  366. #define SmbCeGetFirstServerEntry() \
  367. (IsListEmpty(&s_DbServers.ListHead) \
  368. ? NULL \
  369. : (PSMBCEDB_SERVER_ENTRY) \
  370. (CONTAINING_RECORD(s_DbServers.ListHead.Flink, \
  371. SMBCEDB_SERVER_ENTRY, \
  372. ServersList)))
  373. #define SmbCeGetNextServerEntry(pServerEntry) \
  374. (((pServerEntry)->ServersList.Flink == &s_DbServers.ListHead) \
  375. ? NULL \
  376. : (PSMBCEDB_SERVER_ENTRY) \
  377. (CONTAINING_RECORD((pServerEntry)->ServersList.Flink, \
  378. SMBCEDB_SERVER_ENTRY, \
  379. ServersList)))
  380. // Since the mapping between V_NET_ROOT's in the RDBSS and the session entries in the mini
  381. // redirector is a many to one mapping a collection of session entries is maintained as part
  382. // of each server entry. The following operations are supported on the collection of session
  383. // entries
  384. // 1) adding a session entry to the collection
  385. // 2) removing a session entry from the colection
  386. // 3) enumerating the entries in the collection
  387. //
  388. // As in the case of the collection of requests all these operations come in two flavours
  389. // the vanila version in which concurrency control is enforced and the lite version in
  390. // which the concurrency control is left to the user's discretion.
  391. //
  392. // In addition two more methods are specified for retrieving the default session entry and
  393. // setting the default session entry for any given server.
  394. #define SmbCeAddSessionEntry(pServerEntry,pSessionEntry) \
  395. SmbCeAcquireSpinLock(); \
  396. InsertTailList(&(pServerEntry)->Sessions.ListHead,&(pSessionEntry)->SessionsList); \
  397. SmbCeReleaseSpinLock()
  398. #define SmbCeAddSessionEntryLite(pServerEntry,pSessionEntry) \
  399. InsertTailList(&(pServerEntry)->Sessions.ListHead,&(pSessionEntry)->SessionsList)
  400. #define SmbCeRemoveSessionEntry(pServerEntry,pSessionEntry) \
  401. SmbCeAcquireSpinLock(); \
  402. if ((pSessionEntry)->DefaultSessionLink.Flink != NULL) { \
  403. RemoveEntryList(&(pSessionEntry)->DefaultSessionLink); \
  404. pSessionEntry->DefaultSessionLink.Flink = NULL; \
  405. pSessionEntry->DefaultSessionLink.Blink = NULL; \
  406. }; \
  407. RemoveEntryList(&(pSessionEntry)->SessionsList); \
  408. SmbCeReleaseSpinLock()
  409. #define SmbCeRemoveSessionEntryLite(pServerEntry,pSessionEntry) \
  410. ASSERT( SmbCeSpinLockAcquired() ); \
  411. if ((pSessionEntry)->DefaultSessionLink.Flink != NULL) { \
  412. RemoveEntryList(&(pSessionEntry)->DefaultSessionLink); \
  413. pSessionEntry->DefaultSessionLink.Flink = NULL; \
  414. pSessionEntry->DefaultSessionLink.Blink = NULL; \
  415. }; \
  416. RemoveEntryList(&(pSessionEntry)->SessionsList);
  417. #define SmbCeGetFirstSessionEntry(pServerEntry) \
  418. (IsListEmpty(&(pServerEntry)->Sessions.ListHead) \
  419. ? NULL \
  420. : (PSMBCEDB_SESSION_ENTRY) \
  421. (CONTAINING_RECORD((pServerEntry)->Sessions.ListHead.Flink, \
  422. SMBCEDB_SESSION_ENTRY, \
  423. SessionsList)))
  424. #define SmbCeGetNextSessionEntry(pServerEntry,pSessionEntry) \
  425. (((pSessionEntry)->SessionsList.Flink == \
  426. &(pServerEntry)->Sessions.ListHead) \
  427. ? NULL \
  428. : (PSMBCEDB_SESSION_ENTRY) \
  429. (CONTAINING_RECORD((pSessionEntry)->SessionsList.Flink, \
  430. SMBCEDB_SESSION_ENTRY, \
  431. SessionsList)))
  432. #define SmbCeSetDefaultSessionEntry(pServerEntry,pSessionEntry) \
  433. SmbCeAcquireSpinLock(); \
  434. if ((pSessionEntry)->DefaultSessionLink.Flink == NULL) { \
  435. ASSERT( pSessionEntry->DefaultSessionLink.Blink == NULL ); \
  436. InsertHeadList(&(pServerEntry)->Sessions.DefaultSessionList,&(pSessionEntry)->DefaultSessionLink); \
  437. }; \
  438. SmbCeReleaseSpinLock()
  439. extern PSMBCEDB_SESSION_ENTRY
  440. SmbCeGetDefaultSessionEntry(
  441. PSMBCEDB_SERVER_ENTRY pServerEntry,
  442. ULONG SessionId,
  443. PLUID pLogonId
  444. );
  445. VOID
  446. SmbCeRemoveDefaultSessionEntry(
  447. PSMBCEDB_SESSION_ENTRY pDefaultSessionEntry
  448. );
  449. // In order to encapsulate the notion of reconnects and to provide for hot reconnects,
  450. // i.e., reconnection attempts in which the saved state in the server/client prior to
  451. // a transport level disconnect can be reused it is required to mark each net root
  452. // entry associated with a server as invalid on receipt of a transport level disconnect.
  453. //
  454. // Therefore an abstraction of a collection of net root entries is provided and is associated
  455. // with each server entry.
  456. //
  457. // The following operations are supported on the collection of net root entries
  458. // 1) adding a net root entry to the collection
  459. // 2) removing a net root entry from the colection
  460. // 3) enumerating the entries in the collection
  461. //
  462. // As in the case of the collection of requests all these operations come in two flavours
  463. // the vanila version in which concurrency control is enforced and the lite version in
  464. // which the concurrency control is left to the user's discretion.
  465. //
  466. #define SmbCeAddNetRootEntry(pServerEntry,pNetRootEntry) \
  467. SmbCeAcquireSpinLock(); \
  468. InsertTailList(&(pServerEntry)->NetRoots.ListHead,&(pNetRootEntry)->NetRootsList); \
  469. SmbCeReleaseSpinLock()
  470. #define SmbCeAddNetRootEntryLite(pServerEntry,pNetRootEntry) \
  471. InsertTailList(&(pServerEntry)->NetRoots.ListHead,&(pNetRootEntry)->NetRootsList)
  472. #define SmbCeRemoveNetRootEntry(pServerEntry,pNetRootEntry) \
  473. SmbCeAcquireSpinLock(); \
  474. RemoveEntryList(&(pNetRootEntry)->NetRootsList); \
  475. SmbCeReleaseSpinLock()
  476. #define SmbCeRemoveNetRootEntryLite(pServerEntry,pNetRootEntry) \
  477. RemoveEntryList(&(pNetRootEntry)->NetRootsList)
  478. #define SmbCeGetFirstNetRootEntry(pServerEntry) \
  479. (IsListEmpty(&(pServerEntry)->NetRoots.ListHead) \
  480. ? NULL \
  481. : (PSMBCEDB_NET_ROOT_ENTRY) \
  482. (CONTAINING_RECORD((pServerEntry)->NetRoots.ListHead.Flink, \
  483. SMBCEDB_NET_ROOT_ENTRY, \
  484. NetRootsList)))
  485. #define SmbCeGetNextNetRootEntry(pServerEntry,pNetRootEntry) \
  486. (((pNetRootEntry)->NetRootsList.Flink == \
  487. &(pServerEntry)->NetRoots.ListHead) \
  488. ? NULL \
  489. : (PSMBCEDB_NET_ROOT_ENTRY) \
  490. (CONTAINING_RECORD((pNetRootEntry)->NetRootsList.Flink, \
  491. SMBCEDB_NET_ROOT_ENTRY, \
  492. NetRootsList)))
  493. // Macros to manipulate the collection of SMBCE_V_NET_ROOT_CONTEXT instances.
  494. #define SmbCeAddVNetRootContext(pVNetRootContexts,pVNetRootContext) \
  495. SmbCeAcquireSpinLock(); \
  496. InsertTailList(&(pVNetRootContexts)->ListHead,&(pVNetRootContext)->ListEntry); \
  497. SmbCeReleaseSpinLock()
  498. #define SmbCeAddVNetRootContextLite(pVNetRootContexts,pVNetRootContext) \
  499. InsertTailList(&(pVNetRootContexts)->ListHead,&(pVNetRootContext)->ListEntry)
  500. #define SmbCeRemoveVNetRootContext(pVNetRootContexts,pVNetRootContext) \
  501. SmbCeAcquireSpinLock(); \
  502. RemoveEntryList(&(pVNetRootContext)->ListEntry); \
  503. SmbCeReleaseSpinLock()
  504. #define SmbCeRemoveVNetRootContextLite(pVNetRootContexts,pVNetRootContext) \
  505. RemoveEntryList(&(pVNetRootContext)->ListEntry)
  506. #define SmbCeGetFirstVNetRootContext(pVNetRootContexts) \
  507. (IsListEmpty(&((pVNetRootContexts)->ListHead)) \
  508. ? NULL \
  509. : (PSMBCE_V_NET_ROOT_CONTEXT) \
  510. (CONTAINING_RECORD((pVNetRootContexts)->ListHead.Flink, \
  511. SMBCE_V_NET_ROOT_CONTEXT, \
  512. ListEntry)))
  513. #define SmbCeGetNextVNetRootContext(pVNetRootContexts,pVNetRootContext) \
  514. (((pVNetRootContext)->ListEntry.Flink == \
  515. &(pVNetRootContexts)->ListHead) \
  516. ? NULL \
  517. : (PSMBCE_V_NET_ROOT_CONTEXT) \
  518. (CONTAINING_RECORD((pVNetRootContext)->ListEntry.Flink, \
  519. SMBCE_V_NET_ROOT_CONTEXT, \
  520. ListEntry)))
  521. //
  522. // SmbCe database initialization
  523. //
  524. extern NTSTATUS
  525. SmbCeDbInit();
  526. extern VOID
  527. SmbCeDbTearDown();
  528. //
  529. // Object allocation and deallocation
  530. //
  531. extern PSMBCE_OBJECT_HEADER
  532. SmbCeDbAllocateObject(
  533. SMBCEDB_OBJECT_TYPE ObjectType);
  534. extern VOID
  535. SmbCeDbFreeObject(
  536. PVOID pObject);
  537. //
  538. // Object destruction
  539. //
  540. extern VOID
  541. SmbCeTearDownServerEntry(PSMBCEDB_SERVER_ENTRY pServerEntry);
  542. extern VOID
  543. SmbCeTearDownNetRootEntry(PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry);
  544. extern VOID
  545. SmbCeTearDownSessionEntry(PSMBCEDB_SESSION_ENTRY pSessionEntry);
  546. extern VOID
  547. SmbCeTearDownRequestEntry(PSMBCEDB_REQUEST_ENTRY pRequestEntry);
  548. //
  549. // The routines for mapping a MID with an exchange and for associating an exchange with
  550. // a MID
  551. //
  552. extern NTSTATUS
  553. SmbCeAssociateExchangeWithMid(
  554. PSMBCEDB_SERVER_ENTRY pServerEntry,
  555. struct _SMB_EXCHANGE *pExchange);
  556. extern struct _SMB_EXCHANGE *
  557. SmbCeMapMidToExchange(
  558. PSMBCEDB_SERVER_ENTRY pServerEntry,
  559. SMB_MPX_ID Mid);
  560. extern NTSTATUS
  561. SmbCeDissociateMidFromExchange(
  562. PSMBCEDB_SERVER_ENTRY pServerEntry,
  563. struct _SMB_EXCHANGE *pExchange);
  564. extern struct _SMB_EXCHANGE *
  565. SmbCeGetExchangeAssociatedWithBuffer(
  566. PSMBCEDB_SERVER_ENTRY pServerEntry,
  567. PVOID pBuffer);
  568. extern NTSTATUS
  569. SmbCeAssociateBufferWithExchange(
  570. PSMBCEDB_SERVER_ENTRY pServerEntry,
  571. struct _SMB_EXCHANGE * pExchange,
  572. PVOID pBuffer);
  573. extern VOID
  574. SmbCePurgeBuffersAssociatedWithExchange(
  575. PSMBCEDB_SERVER_ENTRY pServerEntry,
  576. struct _SMB_EXCHANGE * pExchange);
  577. extern NTSTATUS
  578. SmbCepDiscardMidAssociatedWithExchange(
  579. struct _SMB_EXCHANGE * pExchange);
  580. extern VOID
  581. SmbCeResumeDiscardedMidAssignmentRequests(
  582. PSMBCEDB_REQUESTS pMidRequests,
  583. NTSTATUS ResumptionStatus);
  584. //
  585. // Routines for handling transport disconnects/invalidation.
  586. //
  587. extern VOID
  588. SmbCeTransportDisconnectIndicated(
  589. PSMBCEDB_SERVER_ENTRY pServerEntry);
  590. extern VOID
  591. SmbCeResumeAllOutstandingRequestsOnError(
  592. PSMBCEDB_SERVER_ENTRY pServerEntry);
  593. extern VOID
  594. SmbCeHandleTransportInvalidation(
  595. struct _SMBCE_TRANSPORT_ *pTransport);
  596. extern VOID
  597. SmbCeFinalizeAllExchangesForNetRoot(
  598. PMRX_NET_ROOT pNetRoot);
  599. extern NTSTATUS
  600. MRxSmbCheckForLoopBack(
  601. IN PSMBCEDB_SERVER_ENTRY pServerEntry);
  602. //
  603. // Resource acquistion/release
  604. //
  605. PVOID SmbCeDbResourceAcquireFile;
  606. ULONG SmbCeDbResourceAcquireLine;
  607. #define SmbCeAcquireResource() \
  608. KeEnterCriticalRegion(); \
  609. ExAcquireResourceExclusiveLite(&s_SmbCeDbResource,TRUE);\
  610. SmbCeDbResourceAcquireFile = __FILE__;\
  611. SmbCeDbResourceAcquireLine = __LINE__
  612. #define SmbCeReleaseResource() \
  613. SmbCeDbResourceAcquireFile = NULL;\
  614. SmbCeDbResourceAcquireLine = 0;\
  615. ExReleaseResourceLite(&s_SmbCeDbResource);\
  616. KeLeaveCriticalRegion()
  617. #define SmbCeIsResourceOwned() ExIsResourceAcquiredExclusiveLite(&s_SmbCeDbResource)
  618. #define SmbCeAcquireSpinLock() \
  619. KeAcquireSpinLock(&s_SmbCeDbSpinLock,&s_SmbCeDbSpinLockSavedIrql); \
  620. s_SmbCeDbSpinLockAcquired = TRUE
  621. #define SmbCeReleaseSpinLock() \
  622. s_SmbCeDbSpinLockAcquired = FALSE; \
  623. KeReleaseSpinLock(&s_SmbCeDbSpinLock,s_SmbCeDbSpinLockSavedIrql)
  624. #define SmbCeSpinLockAcquired() \
  625. (s_SmbCeDbSpinLockAcquired == TRUE)
  626. #define SmbCeAcquireSecuritySignatureResource() \
  627. ExAcquireResourceExclusiveLite(&s_SmbSecuritySignatureResource,TRUE)
  628. #define SmbCeReleaseSecuritySignatureResource() \
  629. ExReleaseResourceLite(&s_SmbSecuritySignatureResource)
  630. //INLINE BOOLEAN SmbCeDbIsEntryInUse(PSMBCE_OBJECT_HEADER pHeader)
  631. /*++
  632. Routine Description:
  633. This routine determines if a SmbCe database entry is in use.
  634. Arguments:
  635. pHeader - the entry header
  636. Return Value:
  637. TRUE if the entry is in use otherwise FALSE
  638. --*/
  639. #define SmbCeIsEntryInUse(pHeader) \
  640. (((PSMBCE_OBJECT_HEADER)(pHeader))->State == SMBCEDB_ACTIVE || \
  641. ((PSMBCE_OBJECT_HEADER)(pHeader))->State == SMBCEDB_INVALID || \
  642. ((PSMBCE_OBJECT_HEADER)(pHeader))->State == SMBCEDB_CONSTRUCTION_IN_PROGRESS)
  643. #define SmbCeSetServerType(pServerEntry,ServerType) \
  644. (pServerEntry)->Header.Flags = (UCHAR)(ServerType)
  645. #define SmbCeGetServerType(pServerEntry) \
  646. ((SMBCEDB_SERVER_TYPE)(pServerEntry)->Header.Flags)
  647. //
  648. // Static variable declarations that constitute the SmbCe database.
  649. //
  650. extern SMBCEDB_SERVERS s_DbServers;
  651. //
  652. // Currently there is only one resource for synchronizing the access to all the
  653. // entities in the connection engine database. It is possible to customize it
  654. // subsequently since the acquistion/release methods take the type of the object
  655. // as a parameter.
  656. //
  657. extern ERESOURCE s_SmbCeDbResource;
  658. extern RX_SPIN_LOCK s_SmbCeDbSpinLock;
  659. extern KIRQL s_SmbCeDbSpinLockSavedIrql;
  660. extern BOOLEAN s_SmbCeDbSpinLockAcquired;
  661. #endif // _SMBCEDBP_H_