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.

460 lines
17 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. smbcedb.h
  5. Abstract:
  6. This module defines all functions, along with implementations for inline functions
  7. related to accessing the SMB connection engine
  8. Notes:
  9. The various data structures created by the mini rdr (Server Entries, Session Entries
  10. and Net Root Entries) are used in asynchronous operations. Hence a reference count
  11. mechanism is used to keep track of the creation/use/destruction of these data structures.
  12. The usage patterns for these data structures falls into one of two cases
  13. 1) A prior reference exists and access is required
  14. 2) A new reference need be created.
  15. These two scenarios are dealt with by two sets of access routines
  16. SmbCeGetAssociatedServerEntry,
  17. SmbCeGetAssociatedNetRootEntry
  18. and
  19. SmbCeReferenceAssociatedServerEntry,
  20. SmbCeReferenceAssociatedNetRootEntry.
  21. The first set of routines include the necessary asserts in a debug build to ensure that a
  22. reference does exist.
  23. The dereferencing mechanism is provided by the following routines
  24. SmbCeDereferenceServerEntry,
  25. SmbCeDereferenceSessionEntry,
  26. SmbCeDereferenceNetRootEntry.
  27. The dereferencing routines also ensure that the data structures are deleted if the reference
  28. count is zero.
  29. The construction of the various SMB mini redirector structures ( Server,Session and Net root entries )
  30. follow a two phase protocol since network traffic is involved. The first set of routines
  31. initiate the construction while the second set of routines complete the construction.
  32. These routines are
  33. SmbCeInitializeServerEntry,
  34. SmbCeCompleteServerEntryInitialization,
  35. SmbCeInitializeSessionEntry,
  36. SmbCeCompleteSessionEntryInitialization,
  37. SmbCeInitializeNetRootEntry,
  38. and SmbCeCompleteNetRootEntryInitialization.
  39. Each of the SMB mini redirector data structures embodies a state diagram that consist of
  40. the following states
  41. SMBCEDB_ACTIVE, // the instance is in use
  42. SMBCEDB_INVALID, // the instance has been invalidated/disconnected.
  43. SMBCEDB_MARKED_FOR_DELETION, // the instance has been marked for deletion.
  44. SMBCEDB_RECYCLE, // the instance is available for recycling
  45. SMBCEDB_START_CONSTRUCTION, // Initiate construction.
  46. SMBCEDB_CONSTRUCTION_IN_PROGRESS, // the instance construction is in progress
  47. SMBCEDB_DESTRUCTION_IN_PROGRESS // the instance destruction is in progress
  48. A SMB MRX data structure instance begins its life in SMBCEDB_START_CONSTRUCTION state.
  49. When the construction is initiated the state transitions to SMBCEDB_CONSTRUCTION_IN_PROGRESS.
  50. On completion of the construction the state is either transitioned to SMBCEDB_ACTIVE if the
  51. construction was successful. If the construction was not successful the state transitions to
  52. SMBCEDB_MARKED_FOR_DELETION if scavenging is to be done or SMBCEDB_DESTRUCTION_IN_PROGRESS
  53. if the tear down has been initiated.
  54. An instance in the SMBCEDB_ACTIVE state transitions to SMBCEDB_INVALID when the transport/remote server
  55. information associated with it has been invalidated due to disconnects etc. This state is a
  56. cue for a reconnect attempt to be initiated.
  57. The SMBCEDB_RECYCLE state is not in use currently.
  58. All the state transitions are accomplished by the following set of routines which ensure that
  59. the appropriate concurrency control action is taken.
  60. SmbCeUpdateServerEntryState,
  61. SmbCeUpdateSessionEntryState,
  62. and SmbCeUpdateNetRootEntryState.
  63. Since the Server,Session and NetRoot entries are often referenced together the following
  64. two routines provide a batching mechanism to minimize the concurrency control overhead.
  65. SmbCeReferenceAssociatedEntries,
  66. SmbCeDereferenceEntries
  67. In addition this file also contains helper functions to access certain fields of
  68. MRX_SRV_CALL,MRX_NET_ROOT and MRX_V_NET_ROOT which are intrepreted differently by the SMB
  69. mini redirector.
  70. --*/
  71. #ifndef _SMBCEDB_H_
  72. #define _SMBCEDB_H_
  73. #include <smbcedbp.h> // To accomodate inline routines.
  74. //
  75. // All the routines below return the referenced object if successful. It is the caller's
  76. // responsibility to dereference them subsequently.
  77. //
  78. PSMBCEDB_SERVER_ENTRY
  79. SmbCeFindServerEntry(
  80. PUNICODE_STRING pServerName,
  81. SMBCEDB_SERVER_TYPE ServerType);
  82. extern NTSTATUS
  83. SmbCeFindOrConstructServerEntry(
  84. PUNICODE_STRING pServerName,
  85. SMBCEDB_SERVER_TYPE ServerType,
  86. PSMBCEDB_SERVER_ENTRY *pServerEntryPtr,
  87. PBOOLEAN pNewServerEntry);
  88. extern NTSTATUS
  89. SmbCeInitializeServerEntry(
  90. IN PMRX_SRV_CALL pSrvCall,
  91. IN OUT PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext,
  92. IN BOOLEAN DeferNetworkInitialization);
  93. extern NTSTATUS
  94. SmbCeFindOrConstructSessionEntry(
  95. IN PMRX_V_NET_ROOT pVirtualNetRoot,
  96. OUT PSMBCEDB_SESSION_ENTRY *pSessionEntryPtr);
  97. extern NTSTATUS
  98. SmbCeFindOrConstructNetRootEntry(
  99. IN PMRX_NET_ROOT pNetRoot,
  100. OUT PSMBCEDB_NET_ROOT_ENTRY *pNetRootEntryPtr);
  101. extern NTSTATUS
  102. SmbCeFindOrConstructVNetRootContext(
  103. IN OUT PMRX_V_NET_ROOT pVNetRoot,
  104. IN BOOLEAN fDeferNetworkInitialization);
  105. //
  106. // The finalization routines are invoked in the context of a worker thread to finalize
  107. // the construction of an entry as well as resume other entries waiting for it.
  108. //
  109. extern VOID
  110. SmbCeCompleteServerEntryInitialization(
  111. PSMBCEDB_SERVER_ENTRY pServerEntry,
  112. NTSTATUS Status);
  113. extern VOID
  114. SmbCeCompleteSessionEntryInitialization(
  115. PVOID pSessionEntry,
  116. NTSTATUS Status);
  117. extern VOID
  118. SmbCeCompleteVNetRootContextInitialization(
  119. PVOID pVNetRootContextEntry);
  120. extern VOID
  121. SmbReferenceRecord(
  122. PREFERENCE_RECORD pReferenceRecord,
  123. PVOID FileName,
  124. ULONG FileLine);
  125. //
  126. // Routines for referencing/dereferencing SMB Mini redirector information associated with
  127. // the wrapper data structures.
  128. //
  129. INLINE PSMBCEDB_SERVER_ENTRY
  130. SmbCeGetAssociatedServerEntry(
  131. PMRX_SRV_CALL pSrvCall)
  132. {
  133. ASSERT(pSrvCall->Context != NULL);
  134. return (PSMBCEDB_SERVER_ENTRY)(pSrvCall->Context);
  135. }
  136. INLINE PSMBCE_V_NET_ROOT_CONTEXT
  137. SmbCeGetAssociatedVNetRootContext(
  138. PMRX_V_NET_ROOT pVNetRoot)
  139. {
  140. ASSERT(pVNetRoot != NULL);
  141. return (PSMBCE_V_NET_ROOT_CONTEXT)(pVNetRoot->Context);
  142. }
  143. INLINE PSMBCEDB_NET_ROOT_ENTRY
  144. SmbCeGetAssociatedNetRootEntry(
  145. PMRX_NET_ROOT pNetRoot)
  146. {
  147. ASSERT(pNetRoot->Context != NULL);
  148. return (PSMBCEDB_NET_ROOT_ENTRY)(pNetRoot->Context);
  149. }
  150. //
  151. // All the macros for referencing and dereferencing begin with a prefix SmbCep...
  152. // The p stands for a private version which is used for implementing reference tracking.
  153. // By selectively turning on the desired flag it is possible to track every instance
  154. // of a given type as the reference count is modified.
  155. //
  156. #define MRXSMB_REF_TRACE_SERVER_ENTRY (0x00000001)
  157. #define MRXSMB_REF_TRACE_NETROOT_ENTRY (0x00000002)
  158. #define MRXSMB_REF_TRACE_SESSION_ENTRY (0x00000004)
  159. #define MRXSMB_REF_TRACE_VNETROOT_CONTEXT (0x00000008)
  160. extern ULONG MRxSmbReferenceTracingValue;
  161. #define MRXSMB_REF_TRACING_ON(TraceMask) (TraceMask & MRxSmbReferenceTracingValue)
  162. #define MRXSMB_PRINT_REF_COUNT(TYPE,Count) \
  163. if (MRXSMB_REF_TRACING_ON( MRXSMB_REF_TRACE_ ## TYPE )) { \
  164. DbgPrint("%ld\n",Count); \
  165. }
  166. INLINE VOID
  167. SmbCepReferenceServerEntry(
  168. PSMBCEDB_SERVER_ENTRY pServerEntry)
  169. {
  170. ASSERT(pServerEntry->Header.ObjectType == SMBCEDB_OT_SERVER);
  171. InterlockedIncrement(&pServerEntry->Header.SwizzleCount);
  172. MRXSMB_PRINT_REF_COUNT(SERVER_ENTRY,pServerEntry->Header.SwizzleCount)
  173. }
  174. INLINE VOID
  175. SmbCepReferenceSessionEntry(
  176. PSMBCEDB_SESSION_ENTRY pSessionEntry)
  177. {
  178. ASSERT(pSessionEntry->Header.ObjectType == SMBCEDB_OT_SESSION);
  179. InterlockedIncrement(&(pSessionEntry->Header.SwizzleCount));
  180. MRXSMB_PRINT_REF_COUNT(SESSION_ENTRY,pSessionEntry->Header.SwizzleCount)
  181. }
  182. INLINE VOID
  183. SmbCepReferenceNetRootEntry(
  184. PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry,
  185. PVOID FileName,
  186. ULONG FileLine)
  187. {
  188. ASSERT(pNetRootEntry->Header.ObjectType == SMBCEDB_OT_NETROOT);
  189. InterlockedIncrement(&(pNetRootEntry->Header.SwizzleCount));
  190. MRXSMB_PRINT_REF_COUNT(NETROOT_ENTRY,pNetRootEntry->Header.SwizzleCount);
  191. SmbReferenceRecord(&pNetRootEntry->ReferenceRecord[0],FileName,FileLine);
  192. }
  193. INLINE VOID
  194. SmbCepReferenceVNetRootContext(
  195. PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext)
  196. {
  197. ASSERT(pVNetRootContext->Header.ObjectType == SMBCEDB_OT_VNETROOTCONTEXT);
  198. InterlockedIncrement(&(pVNetRootContext->Header.SwizzleCount));
  199. MRXSMB_PRINT_REF_COUNT(VNETROOT_CONTEXT,pVNetRootContext->Header.SwizzleCount)
  200. }
  201. INLINE PSMBCEDB_SERVER_ENTRY
  202. SmbCeReferenceAssociatedServerEntry(
  203. PMRX_SRV_CALL pSrvCall)
  204. {
  205. PSMBCEDB_SERVER_ENTRY pServerEntry;
  206. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_SERVER_ENTRY)) {
  207. DbgPrint("Reference SrvCall's(%lx) Server Entry %lx %s %ld ",
  208. pSrvCall,pSrvCall->Context,__FILE__,__LINE__); \
  209. }
  210. if ((pServerEntry = pSrvCall->Context) != NULL) {
  211. ASSERT(pServerEntry->Header.SwizzleCount > 0);
  212. SmbCepReferenceServerEntry(pServerEntry);
  213. }
  214. return pServerEntry;
  215. }
  216. INLINE PSMBCEDB_NET_ROOT_ENTRY
  217. SmbCeReferenceAssociatedNetRootEntry(
  218. PMRX_NET_ROOT pNetRoot)
  219. {
  220. PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry;
  221. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_NETROOT_ENTRY)) {
  222. DbgPrint("Reference NetRoot's(%lx) Net Root Entry %lx %s %ld ",
  223. pNetRoot,pNetRoot->Context,__FILE__,__LINE__); \
  224. }
  225. if ((pNetRootEntry = pNetRoot->Context) != NULL) {
  226. ASSERT(pNetRootEntry->Header.SwizzleCount > 0);
  227. SmbCepReferenceNetRootEntry(pNetRootEntry,__FILE__,__LINE__);
  228. }
  229. return pNetRootEntry;
  230. }
  231. extern VOID
  232. SmbCepDereferenceServerEntry(
  233. PSMBCEDB_SERVER_ENTRY pServerEntry);
  234. extern VOID
  235. SmbCepDereferenceSessionEntry(
  236. PSMBCEDB_SESSION_ENTRY pSessionEntry);
  237. extern VOID
  238. SmbCepDereferenceNetRootEntry(
  239. PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry,
  240. PVOID FileName,
  241. ULONG FileLine);
  242. extern VOID
  243. SmbCepDereferenceVNetRootContext(
  244. PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext);
  245. #define SmbCeReferenceServerEntry(pServerEntry) \
  246. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_SERVER_ENTRY)) { \
  247. DbgPrint("Reference Server Entry(%lx) %s %ld ",pServerEntry,__FILE__,__LINE__); \
  248. } \
  249. SmbCepReferenceServerEntry(pServerEntry)
  250. #define SmbCeReferenceNetRootEntry(pNetRootEntry) \
  251. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_NETROOT_ENTRY)) { \
  252. DbgPrint("Reference NetRoot Entry(%lx) %s %ld ",pNetRootEntry,__FILE__,__LINE__); \
  253. } \
  254. SmbCepReferenceNetRootEntry(pNetRootEntry,__FILE__,__LINE__)
  255. #define SmbCeReferenceVNetRootContext(pVNetRootContext) \
  256. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_VNETROOT_CONTEXT)) { \
  257. DbgPrint("Reference VNetRootContext(%lx) %s %ld ",pVNetRootContext,__FILE__,__LINE__); \
  258. } \
  259. SmbCepReferenceVNetRootContext(pVNetRootContext)
  260. #define SmbCeReferenceSessionEntry(pSessionEntry) \
  261. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_SESSION_ENTRY)) { \
  262. DbgPrint("Reference Session Entry(%lx) %s %ld ",pSessionEntry,__FILE__,__LINE__); \
  263. } \
  264. SmbCepReferenceSessionEntry(pSessionEntry)
  265. #define SmbCeDereferenceServerEntry(pServerEntry) \
  266. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_SERVER_ENTRY)) { \
  267. DbgPrint("Dereference Server Entry(%lx) %s %ld ",pServerEntry,__FILE__,__LINE__); \
  268. } \
  269. SmbCepDereferenceServerEntry(pServerEntry)
  270. #define SmbCeDereferenceNetRootEntry(pNetRootEntry) \
  271. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_NETROOT_ENTRY)) { \
  272. DbgPrint("Dereference NetRoot Entry(%lx) %s %ld ",pNetRootEntry,__FILE__,__LINE__); \
  273. } \
  274. SmbCepDereferenceNetRootEntry(pNetRootEntry,__FILE__,__LINE__)
  275. #define SmbCeDereferenceSessionEntry(pSessionEntry) \
  276. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_SESSION_ENTRY)) { \
  277. DbgPrint("Dereference Session Entry(%lx) %s %ld ",pSessionEntry,__FILE__,__LINE__); \
  278. } \
  279. SmbCepDereferenceSessionEntry(pSessionEntry)
  280. #define SmbCeDereferenceVNetRootContext(pVNetRootContext) \
  281. if (MRXSMB_REF_TRACING_ON(MRXSMB_REF_TRACE_VNETROOT_CONTEXT)) { \
  282. DbgPrint("Dereference VNetRootContext Entry(%lx) %s %ld ",pVNetRootContext,__FILE__,__LINE__); \
  283. } \
  284. SmbCepDereferenceVNetRootContext(pVNetRootContext)
  285. INLINE VOID
  286. SmbCeDereferenceEntries(
  287. PSMBCEDB_SERVER_ENTRY pServerEntry,
  288. PSMBCEDB_SESSION_ENTRY pSessionEntry,
  289. PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry)
  290. {
  291. SmbCeDereferenceNetRootEntry(pNetRootEntry);
  292. SmbCeDereferenceSessionEntry(pSessionEntry);
  293. SmbCeDereferenceServerEntry(pServerEntry);
  294. }
  295. //
  296. // Routines for updating the state of SMB MRX data structures
  297. //
  298. #define SmbCeUpdateServerEntryState(pServerEntry,NEWSTATE) \
  299. InterlockedExchange(&pServerEntry->Header.State,(NEWSTATE))
  300. #define SmbCeUpdateSessionEntryState(pSessionEntry,NEWSTATE) \
  301. InterlockedExchange(&pSessionEntry->Header.State,(NEWSTATE))
  302. #define SmbCeUpdateNetRootEntryState(pNetRootEntry,NEWSTATE) \
  303. InterlockedExchange(&pNetRootEntry->Header.State,(NEWSTATE))
  304. #define SmbCeUpdateVNetRootContextState(pVNetRootContext,NEWSTATE) \
  305. InterlockedExchange(&pVNetRootContext->Header.State,(NEWSTATE))
  306. //
  307. // The RDBSS wrapper stores all the server names with a backslash prepended to
  308. // them. This helps synthesize UNC names easily. In order to manipulate the
  309. // Server name in the SMB protocol the \ needs to be stripped off.
  310. INLINE VOID
  311. SmbCeGetServerName(
  312. PMRX_SRV_CALL pSrvCall,
  313. PUNICODE_STRING pServerName)
  314. {
  315. ASSERT(pSrvCall->pSrvCallName != NULL);
  316. pServerName->Buffer = pSrvCall->pSrvCallName->Buffer + 1;
  317. pServerName->Length = pSrvCall->pSrvCallName->Length - sizeof(WCHAR);
  318. pServerName->MaximumLength = pSrvCall->pSrvCallName->MaximumLength - sizeof(WCHAR);
  319. }
  320. INLINE VOID
  321. SmbCeGetNetRootName(
  322. PMRX_NET_ROOT pNetRoot,
  323. PUNICODE_STRING pNetRootName)
  324. {
  325. ASSERT(pNetRoot->pNetRootName != NULL);
  326. *pNetRootName = *pNetRoot->pNetRootName;
  327. }
  328. extern NTSTATUS
  329. SmbCeDestroyAssociatedVNetRootContext(
  330. PMRX_V_NET_ROOT pVNetRoot);
  331. extern VOID
  332. SmbCeTearDownVNetRootContext(
  333. PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext);
  334. extern NTSTATUS
  335. SmbCeGetUserNameAndDomainName(
  336. PSMBCEDB_SESSION_ENTRY pSessionEntry,
  337. PUNICODE_STRING pUserName,
  338. PUNICODE_STRING pUserDomainName);
  339. extern NTSTATUS
  340. SmbCeUpdateSrvCall(
  341. IN PSMBCEDB_SERVER_ENTRY pServerEntry);
  342. extern NTSTATUS
  343. SmbCeUpdateNetRoot(
  344. PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry,
  345. PMRX_NET_ROOT pNetRoot);
  346. extern NTSTATUS
  347. SmbCeScavengeRelatedContexts(
  348. IN PSMBCEDB_SERVER_ENTRY pServerEntry);
  349. extern VOID
  350. SmbCeResumeOutstandingRequests(
  351. IN OUT PSMBCEDB_REQUESTS pRequests,
  352. IN NTSTATUS Status);
  353. // given \\server\share, this routine returns a refcounted serverentry
  354. NTSTATUS
  355. FindServerEntryFromCompleteUNCPath(
  356. USHORT *lpuServerShareName,
  357. PSMBCEDB_SERVER_ENTRY *ppServerEntry);
  358. // given \\server\share, this routine returns a refcounted netroot entry
  359. NTSTATUS
  360. FindNetRootEntryFromCompleteUNCPath(
  361. USHORT *lpuServerShareName,
  362. PSMBCEDB_NET_ROOT_ENTRY *ppNetRootEntry);
  363. #endif // _SMBCEDB_H_