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.

734 lines
23 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. mm.c
  5. Abstract:
  6. This module implements the memory managment routines for the SMB mini
  7. redirector
  8. Author:
  9. Balan Sethu Raman [SethuR] 7-March-1995
  10. Revision History:
  11. Notes:
  12. The SMB mini redirector manipulates entities which have very different usage
  13. patterns. They range from very static entities ( which are allocated and freed
  14. with a very low frequency ) to very dynamic entities.
  15. The entities manipulated in the SMB mini redirector are SMBCE_SERVER, SMBCE_NET_ROOT,
  16. SMBCE_VC, SMBCE_SESSION. These represent a connection to a server, a share on
  17. a particular server, a virtual circuit used in the connection and a session
  18. for a particular user.
  19. These are not very dynamic, i.e., the allocation/deallocation is very infrequent.
  20. The SMB_EXCHANGE and SMBCE_REQUEST map to the SMB's that are sent along that
  21. a connection. Every file operation in turn maps to a certain number of calls
  22. for allocationg/freeing exchanges and requests. Therefore it is imperative
  23. that some form of scavenging/caching of recently freed entries be maintained
  24. to satisfy requests quickly.
  25. In the current implementation the exchanges and requests are implemented
  26. using the zone allocation primitives.
  27. The exchange allocation and free routines are currently implemented as wrappers
  28. around the RxAllocate and RxFree routines. It would be far more efficient if
  29. a look aside cache of some exchange instances are maintained.
  30. --*/
  31. #include "precomp.h"
  32. #pragma hdrstop
  33. #include <exsessup.h>
  34. #include <mssndrcv.h>
  35. #include <vcsndrcv.h>
  36. #ifdef ALLOC_PRAGMA
  37. #pragma alloc_text(PAGE, SmbMmAllocateSessionEntry)
  38. #pragma alloc_text(PAGE, SmbMmFreeSessionEntry)
  39. #pragma alloc_text(PAGE, SmbMmAllocateServerTransport)
  40. #pragma alloc_text(PAGE, SmbMmFreeServerTransport)
  41. #pragma alloc_text(PAGE, SmbMmInit)
  42. #pragma alloc_text(PAGE, SmbMmTearDown)
  43. #endif
  44. #define SMBMM_ZONE_ALLOCATION 0x10
  45. // The memory management package addresses a number of concerns w.r.t debugging
  46. // and performance. By centralizing all the allocation/deallocation routines to
  47. // thsi one module it is possible to build up profiles regarding various data
  48. // structures used by the connection engine. In addition debugging support is
  49. // provided by thereading together all allocated objects of a particular type
  50. // are threaded together in a linked list according to type.
  51. //
  52. // At any stage by inspecting these lists the currently active instances of a
  53. // particular type can be enumerated.
  54. //
  55. // Each type handled by this module is provided with two routines, e.g., for
  56. // server entries there are SmbMmInitializeEntry and SmbMmUninitializeEntry. The
  57. // first routine is called before handing over a pointer of a newly created
  58. // instance. This will ensure that the instance is in a wll known initial state.
  59. // Similarly the second routine is called just before deallocating the pool
  60. // associated with the instance. This helps enforce the necessary integrity
  61. // constraints, e.g., all enclosed pointers must be NULL etc.
  62. //
  63. // The pool allocation/deallocation is handled by the following routines
  64. //
  65. // SmbMmAllocateObjectPool/SmbMmFreeObjectPool
  66. //
  67. // SmbMmAllocateExchange/SmbMmFreeExchange
  68. //
  69. // The Object allocation routines are split up into two parts so as to be able to
  70. // handle the session allocationson par with other objects even though they are
  71. // further subtyped.
  72. //
  73. // On debug builds additional pool is allocated and the appropriate linking is
  74. // done into the corresponding list. On retail builds these map to the regular
  75. // pool allocation wrappers.
  76. //
  77. // Zone allocation to speed up memory management of RxCe entities.
  78. //
  79. ULONG SmbMmRequestZoneEntrySize;
  80. ZONE_HEADER SmbMmRequestZone;
  81. PVOID SmbMmRequestZoneSegmentPtr;
  82. //
  83. // Pool allocation resources and spin locks
  84. //
  85. KSPIN_LOCK SmbMmSpinLock;
  86. ULONG SmbMmExchangeId;
  87. //
  88. // List of the various objects/exchanges allocated.
  89. //
  90. LIST_ENTRY SmbMmExchangesInUse[SENTINEL_EXCHANGE];
  91. LIST_ENTRY SmbMmObjectsInUse[SMBCEDB_OT_SENTINEL];
  92. ULONG ObjectSizeInBytes[SMBCEDB_OT_SENTINEL];
  93. ULONG ExchangeSizeInBytes[SENTINEL_EXCHANGE];
  94. //
  95. // Lookaside lists for Exchange allocation
  96. //
  97. NPAGED_LOOKASIDE_LIST SmbMmExchangesLookasideList[SENTINEL_EXCHANGE];
  98. INLINE PSMBCE_OBJECT_HEADER
  99. SmbMmAllocateObjectPool(
  100. SMBCEDB_OBJECT_TYPE ObjectType,
  101. ULONG PoolType,
  102. ULONG PoolSize)
  103. {
  104. KIRQL SavedIrql;
  105. PVOID pv = NULL;
  106. UCHAR Flags = 0;
  107. PSMBCE_OBJECT_HEADER pHeader = NULL;
  108. ASSERT((ObjectType >= 0) && (ObjectType < SMBCEDB_OT_SENTINEL));
  109. if (ObjectType == SMBCEDB_OT_REQUEST) {
  110. // Acquire the resource lock.
  111. KeAcquireSpinLock( &SmbMmSpinLock, &SavedIrql );
  112. if (!ExIsFullZone( &SmbMmRequestZone )) {
  113. pv = ExAllocateFromZone( &SmbMmRequestZone );
  114. Flags = SMBMM_ZONE_ALLOCATION;
  115. }
  116. // Release the resource lock.
  117. KeReleaseSpinLock( &SmbMmSpinLock, SavedIrql );
  118. }
  119. if (pv == NULL) {
  120. PLIST_ENTRY pListEntry;
  121. pv = RxAllocatePoolWithTag(
  122. PoolType,
  123. PoolSize + sizeof(LIST_ENTRY),
  124. MRXSMB_MM_POOLTAG);
  125. if (pv != NULL) {
  126. pListEntry = (PLIST_ENTRY)pv;
  127. pHeader = (PSMBCE_OBJECT_HEADER)(pListEntry + 1);
  128. ExInterlockedInsertTailList(
  129. &SmbMmObjectsInUse[ObjectType],
  130. pListEntry,
  131. &SmbMmSpinLock);
  132. }
  133. } else {
  134. pHeader = (PSMBCE_OBJECT_HEADER)pv;
  135. }
  136. if (pHeader != NULL) {
  137. // Zero the memory.
  138. RtlZeroMemory( pHeader, PoolSize);
  139. pHeader->Flags = Flags;
  140. }
  141. return pHeader;
  142. }
  143. VOID
  144. SmbMmFreeObjectPool(
  145. PSMBCE_OBJECT_HEADER pHeader)
  146. {
  147. KIRQL SavedIrql;
  148. BOOLEAN ZoneAllocation = FALSE;
  149. PLIST_ENTRY pListEntry;
  150. ASSERT((pHeader->ObjectType >= 0) && (pHeader->ObjectType < SMBCEDB_OT_SENTINEL));
  151. // Acquire the resource lock.
  152. KeAcquireSpinLock( &SmbMmSpinLock, &SavedIrql );
  153. // Check if it was a zone allocation
  154. if (pHeader->Flags & SMBMM_ZONE_ALLOCATION) {
  155. ZoneAllocation = TRUE;
  156. ExFreeToZone(&SmbMmRequestZone,pHeader);
  157. } else {
  158. pListEntry = (PLIST_ENTRY)((PCHAR)pHeader - sizeof(LIST_ENTRY));
  159. RemoveEntryList(pListEntry);
  160. }
  161. // Release the resource lock.
  162. KeReleaseSpinLock( &SmbMmSpinLock, SavedIrql );
  163. if (!ZoneAllocation) {
  164. RxFreePool(pListEntry);
  165. }
  166. }
  167. // Construction and destruction of various SMB connection engine objects
  168. //
  169. #define SmbMmInitializeServerEntry(pServerEntry) \
  170. InitializeListHead(&(pServerEntry)->OutstandingRequests.ListHead); \
  171. InitializeListHead(&(pServerEntry)->MidAssignmentRequests.ListHead); \
  172. InitializeListHead(&(pServerEntry)->SecuritySignatureSyncRequests.ListHead); \
  173. InitializeListHead(&(pServerEntry)->Sessions.ListHead); \
  174. InitializeListHead(&(pServerEntry)->NetRoots.ListHead); \
  175. InitializeListHead(&(pServerEntry)->VNetRootContexts.ListHead); \
  176. InitializeListHead(&(pServerEntry)->ActiveExchanges); \
  177. InitializeListHead(&(pServerEntry)->ExpiredExchanges); \
  178. InitializeListHead(&(pServerEntry)->Sessions.DefaultSessionList); \
  179. (pServerEntry)->pTransport = NULL; \
  180. (pServerEntry)->pMidAtlas = NULL
  181. #define SmbMmInitializeSessionEntry(pSessionEntry) \
  182. InitializeListHead(&(pSessionEntry)->Requests.ListHead); \
  183. InitializeListHead(&(pSessionEntry)->SerializationList); \
  184. (pSessionEntry)->DefaultSessionLink.Flink = NULL; \
  185. (pSessionEntry)->DefaultSessionLink.Blink = NULL
  186. #define SmbMmInitializeNetRootEntry(pNetRootEntry) \
  187. InitializeListHead(&(pNetRootEntry)->Requests.ListHead)
  188. #define SmbMmUninitializeServerEntry(pServerEntry) \
  189. ASSERT(IsListEmpty(&(pServerEntry)->OutstandingRequests.ListHead) && \
  190. IsListEmpty(&(pServerEntry)->MidAssignmentRequests.ListHead) && \
  191. IsListEmpty(&(pServerEntry)->SecuritySignatureSyncRequests.ListHead) && \
  192. IsListEmpty(&(pServerEntry)->Sessions.ListHead) && \
  193. IsListEmpty(&(pServerEntry)->NetRoots.ListHead) && \
  194. ((pServerEntry)->pMidAtlas == NULL))
  195. #define SmbMmUninitializeSessionEntry(pSessionEntry) \
  196. ASSERT(IsListEmpty(&(pSessionEntry)->Requests.ListHead) && \
  197. ((pSessionEntry)->DefaultSessionLink.Flink == NULL))
  198. #define SmbMmUninitializeNetRootEntry(pNetRootEntry) \
  199. ASSERT(IsListEmpty(&(pNetRootEntry)->Requests.ListHead))
  200. #define SmbMmInitializeRequestEntry(pRequestEntry)
  201. #define SmbMmUninitializeRequestEntry(pRequestEntry)
  202. PVOID
  203. SmbMmAllocateObject(
  204. SMBCEDB_OBJECT_TYPE ObjectType)
  205. {
  206. PSMBCE_OBJECT_HEADER pHeader;
  207. ASSERT((ObjectType >= 0) && (ObjectType < SMBCEDB_OT_SENTINEL));
  208. pHeader = SmbMmAllocateObjectPool(
  209. ObjectType,
  210. NonPagedPool,
  211. ObjectSizeInBytes[ObjectType]);
  212. if (pHeader != NULL) {
  213. pHeader->NodeType = SMB_CONNECTION_ENGINE_NTC(ObjectType);
  214. pHeader->State = SMBCEDB_START_CONSTRUCTION;
  215. switch (ObjectType) {
  216. case SMBCEDB_OT_SERVER :
  217. SmbMmInitializeServerEntry((PSMBCEDB_SERVER_ENTRY)pHeader);
  218. break;
  219. case SMBCEDB_OT_NETROOT :
  220. SmbMmInitializeNetRootEntry((PSMBCEDB_NET_ROOT_ENTRY)pHeader);
  221. break;
  222. case SMBCEDB_OT_REQUEST :
  223. SmbMmInitializeRequestEntry((PSMBCEDB_REQUEST_ENTRY)pHeader);
  224. break;
  225. default:
  226. ASSERT(!"Valid Type for SmbMmAllocateObject");
  227. break;
  228. }
  229. }
  230. return pHeader;
  231. }
  232. VOID
  233. SmbMmFreeObject(
  234. PVOID pv)
  235. {
  236. PSMBCE_OBJECT_HEADER pHeader = (PSMBCE_OBJECT_HEADER)pv;
  237. switch (pHeader->ObjectType) {
  238. case SMBCEDB_OT_SERVER :
  239. SmbMmUninitializeServerEntry((PSMBCEDB_SERVER_ENTRY)pHeader);
  240. break;
  241. case SMBCEDB_OT_NETROOT :
  242. SmbMmUninitializeNetRootEntry((PSMBCEDB_NET_ROOT_ENTRY)pHeader);
  243. break;
  244. case SMBCEDB_OT_REQUEST :
  245. SmbMmUninitializeRequestEntry((PSMBCEDB_REQUEST_ENTRY)pHeader);
  246. break;
  247. default:
  248. ASSERT(!"Valid Type for SmbMmFreeObject");
  249. break;
  250. }
  251. SmbMmFreeObjectPool(pHeader);
  252. }
  253. PSMBCEDB_SESSION_ENTRY
  254. SmbMmAllocateSessionEntry(
  255. PSMBCEDB_SERVER_ENTRY pServerEntry,
  256. BOOLEAN RemoteBootSession)
  257. {
  258. PSMBCEDB_SESSION_ENTRY pSessionEntry;
  259. SESSION_TYPE SessionType;
  260. ULONG SessionSize;
  261. PAGED_CODE();
  262. SessionSize = sizeof(SMBCEDB_SESSION_ENTRY) -
  263. sizeof(SMBCE_SESSION);
  264. if (pServerEntry->Header.State != SMBCEDB_INVALID) {
  265. if ((pServerEntry->Server.DialectFlags & DF_EXTENDED_SECURITY) && !RemoteBootSession) {
  266. SessionSize += sizeof(SMBCE_EXTENDED_SESSION);
  267. SessionType = EXTENDED_NT_SESSION;
  268. } else {
  269. // allocate a LANMAN session
  270. SessionSize += sizeof(SMBCE_SESSION);
  271. SessionType = LANMAN_SESSION;
  272. }
  273. } else {
  274. SessionSize += sizeof(SMBCE_EXTENDED_SESSION);
  275. SessionType = UNINITIALIZED_SESSION;
  276. }
  277. pSessionEntry = (PSMBCEDB_SESSION_ENTRY)
  278. SmbMmAllocateObjectPool(
  279. SMBCEDB_OT_SESSION,
  280. NonPagedPool,
  281. SessionSize);
  282. if (pSessionEntry != NULL) {
  283. pSessionEntry->Header.NodeType = SMB_CONNECTION_ENGINE_NTC(SMBCEDB_OT_SESSION);
  284. pSessionEntry->Header.State = SMBCEDB_START_CONSTRUCTION;
  285. pSessionEntry->Session.Type = SessionType;
  286. SmbMmInitializeSessionEntry(pSessionEntry);
  287. SecInvalidateHandle( &pSessionEntry->Session.CredentialHandle );
  288. SecInvalidateHandle( &pSessionEntry->Session.SecurityContextHandle );
  289. if (SessionType == EXTENDED_NT_SESSION) {
  290. PSMBCE_EXTENDED_SESSION pExtSecuritySession = (PSMBCE_EXTENDED_SESSION)&pSessionEntry->Session;
  291. pExtSecuritySession->pServerResponseBlob = NULL;
  292. pExtSecuritySession->ServerResponseBlobLength = 0;
  293. }
  294. }
  295. return pSessionEntry;
  296. }
  297. VOID
  298. SmbMmFreeSessionEntry(
  299. PSMBCEDB_SESSION_ENTRY pSessionEntry)
  300. {
  301. PAGED_CODE();
  302. if (pSessionEntry->Session.Type == EXTENDED_NT_SESSION) {
  303. // KERBEROS specific asserts
  304. }
  305. SmbMmUninitializeSessionEntry(pSessionEntry);
  306. SmbMmFreeObjectPool(&pSessionEntry->Header);
  307. }
  308. PVOID
  309. SmbMmAllocateExchange(
  310. SMB_EXCHANGE_TYPE ExchangeType,
  311. PVOID pv)
  312. {
  313. KIRQL SavedIrql;
  314. ULONG SizeInBytes;
  315. USHORT Flags = 0;
  316. PSMB_EXCHANGE pExchange = NULL;
  317. PLIST_ENTRY pListEntry;
  318. ASSERT((ExchangeType >= 0) && (ExchangeType < SENTINEL_EXCHANGE));
  319. if (pv==NULL) {
  320. pv = ExAllocateFromNPagedLookasideList(
  321. &SmbMmExchangesLookasideList[ExchangeType]);
  322. } else {
  323. Flags |= SMBCE_EXCHANGE_NOT_FROM_POOL;
  324. }
  325. if (pv != NULL) {
  326. // Initialize the object header
  327. pExchange = (PSMB_EXCHANGE)(pv);
  328. // Zero the memory.
  329. RtlZeroMemory(
  330. pExchange,
  331. ExchangeSizeInBytes[ExchangeType]);
  332. pExchange->NodeTypeCode = SMB_EXCHANGE_NTC(ExchangeType);
  333. pExchange->NodeByteSize = (USHORT)ExchangeSizeInBytes[ExchangeType];
  334. pExchange->SmbCeState = SMBCE_EXCHANGE_INITIALIZATION_START;
  335. pExchange->SmbCeFlags = Flags;
  336. InitializeListHead(&pExchange->ExchangeList);
  337. InitializeListHead(&pExchange->CancelledList);
  338. switch (pExchange->Type) {
  339. case CONSTRUCT_NETROOT_EXCHANGE:
  340. pExchange->pDispatchVector = &ConstructNetRootExchangeDispatch;
  341. break;
  342. case TRANSACT_EXCHANGE :
  343. pExchange->pDispatchVector = &TransactExchangeDispatch;
  344. break;
  345. case EXTENDED_SESSION_SETUP_EXCHANGE:
  346. pExchange->pDispatchVector = &ExtendedSessionSetupExchangeDispatch;
  347. break;
  348. case ADMIN_EXCHANGE:
  349. pExchange->pDispatchVector = &AdminExchangeDispatch;
  350. break;
  351. }
  352. // Acquire the resource lock.
  353. KeAcquireSpinLock( &SmbMmSpinLock, &SavedIrql );
  354. InsertTailList(
  355. &SmbMmExchangesInUse[pExchange->Type],
  356. &pExchange->SmbMmInUseListEntry);
  357. pExchange->Id = SmbMmExchangeId++;
  358. // Release the resource lock.
  359. KeReleaseSpinLock( &SmbMmSpinLock, SavedIrql );
  360. }
  361. return pExchange;
  362. }
  363. VOID
  364. SmbMmFreeExchange(
  365. PSMB_EXCHANGE pExchange)
  366. {
  367. if (pExchange != NULL) {
  368. SMB_EXCHANGE_TYPE ExchangeType;
  369. KIRQL SavedIrql;
  370. ExchangeType = pExchange->Type;
  371. ASSERT((ExchangeType >= 0) && (ExchangeType < SENTINEL_EXCHANGE));
  372. if (pExchange->WorkQueueItem.List.Flink != NULL) {
  373. //DbgBreakPoint();
  374. }
  375. // Acquire the resource lock.
  376. KeAcquireSpinLock( &SmbMmSpinLock, &SavedIrql );
  377. RemoveEntryList(&pExchange->SmbMmInUseListEntry);
  378. // Release the resource lock.
  379. KeReleaseSpinLock( &SmbMmSpinLock, SavedIrql );
  380. if (!FlagOn(pExchange->SmbCeFlags,SMBCE_EXCHANGE_NOT_FROM_POOL)) {
  381. ExFreeToNPagedLookasideList(
  382. &SmbMmExchangesLookasideList[ExchangeType],
  383. pExchange);
  384. }
  385. }
  386. }
  387. PVOID
  388. SmbMmAllocateServerTransport(
  389. SMBCE_SERVER_TRANSPORT_TYPE ServerTransportType)
  390. {
  391. PSMBCE_OBJECT_HEADER pHeader;
  392. ULONG AllocationSize;
  393. ULONG PoolTag;
  394. PAGED_CODE();
  395. switch (ServerTransportType) {
  396. case SMBCE_STT_VC:
  397. AllocationSize = sizeof(SMBCE_SERVER_VC_TRANSPORT);
  398. PoolTag = MRXSMB_VC_POOLTAG;
  399. break;
  400. case SMBCE_STT_MAILSLOT:
  401. AllocationSize = sizeof(SMBCE_SERVER_MAILSLOT_TRANSPORT);
  402. PoolTag = MRXSMB_MAILSLOT_POOLTAG;
  403. break;
  404. default:
  405. ASSERT(!"Valid Server Transport Type");
  406. return NULL;
  407. }
  408. pHeader = (PSMBCE_OBJECT_HEADER)
  409. RxAllocatePoolWithTag(
  410. NonPagedPool,
  411. AllocationSize,
  412. PoolTag);
  413. if (pHeader != NULL) {
  414. PSMBCE_SERVER_TRANSPORT pServerTransport;
  415. RtlZeroMemory(pHeader,AllocationSize);
  416. pHeader->ObjectCategory = SMB_SERVER_TRANSPORT_CATEGORY;
  417. pHeader->ObjectType = (UCHAR)ServerTransportType;
  418. pHeader->SwizzleCount = 0;
  419. pHeader->State = 0;
  420. pHeader->Flags = 0;
  421. pServerTransport = (PSMBCE_SERVER_TRANSPORT)pHeader;
  422. pServerTransport->pRundownEvent = NULL;
  423. switch (ServerTransportType) {
  424. case SMBCE_STT_MAILSLOT:
  425. break;
  426. case SMBCE_STT_VC:
  427. {
  428. PSMBCE_SERVER_VC_TRANSPORT pVcTransport;
  429. pVcTransport = (PSMBCE_SERVER_VC_TRANSPORT)pHeader;
  430. }
  431. break;
  432. default:
  433. break;
  434. }
  435. }
  436. return pHeader;
  437. }
  438. VOID
  439. SmbMmFreeServerTransport(
  440. PSMBCE_SERVER_TRANSPORT pServerTransport)
  441. {
  442. PAGED_CODE();
  443. ASSERT((pServerTransport->SwizzleCount == 0) &&
  444. (pServerTransport->ObjectCategory == SMB_SERVER_TRANSPORT_CATEGORY));
  445. RxFreePool(pServerTransport);
  446. }
  447. NTSTATUS SmbMmInit()
  448. /*++
  449. Routine Description:
  450. This routine initialises the connection engine structures for memory management
  451. Return Value:
  452. STATUS_SUCCESS if successful, otherwise an informative error code.
  453. --*/
  454. {
  455. NTSTATUS Status = STATUS_SUCCESS;
  456. ULONG ZoneSegmentSize;
  457. PAGED_CODE();
  458. // Initialize the resource lock for the zone allocator.
  459. KeInitializeSpinLock( &SmbMmSpinLock );
  460. SmbMmRequestZoneEntrySize = QuadAlign(sizeof(SMBCEDB_REQUEST_ENTRY));
  461. // Currently the request zone size is restricted to that of a page. This can and should
  462. // be fine tuned.
  463. ZoneSegmentSize = PAGE_SIZE;
  464. SmbMmRequestZoneSegmentPtr = RxAllocatePoolWithTag(
  465. NonPagedPool,
  466. ZoneSegmentSize,
  467. MRXSMB_MM_POOLTAG);
  468. if (SmbMmRequestZoneSegmentPtr != NULL) {
  469. SMB_EXCHANGE_TYPE ExchangeType;
  470. ExInitializeZone(
  471. &SmbMmRequestZone,
  472. SmbMmRequestZoneEntrySize,
  473. SmbMmRequestZoneSegmentPtr,
  474. ZoneSegmentSize );
  475. // set up the sizes for allocation.
  476. ObjectSizeInBytes[SMBCEDB_OT_SERVER] = sizeof(SMBCEDB_SERVER_ENTRY);
  477. ObjectSizeInBytes[SMBCEDB_OT_NETROOT] = sizeof(SMBCEDB_NET_ROOT_ENTRY);
  478. ObjectSizeInBytes[SMBCEDB_OT_SESSION] = sizeof(SMBCEDB_SESSION_ENTRY);
  479. ObjectSizeInBytes[SMBCEDB_OT_REQUEST] = sizeof(SMBCEDB_REQUEST_ENTRY);
  480. ExchangeSizeInBytes[CONSTRUCT_NETROOT_EXCHANGE] = sizeof(SMB_CONSTRUCT_NETROOT_EXCHANGE);
  481. ExchangeSizeInBytes[TRANSACT_EXCHANGE] = sizeof(SMB_TRANSACT_EXCHANGE);
  482. ExchangeSizeInBytes[ORDINARY_EXCHANGE] = sizeof(SMB_PSE_ORDINARY_EXCHANGE);
  483. ExchangeSizeInBytes[EXTENDED_SESSION_SETUP_EXCHANGE]
  484. = sizeof(SMB_EXTENDED_SESSION_SETUP_EXCHANGE);
  485. ExchangeSizeInBytes[ADMIN_EXCHANGE] = sizeof(SMB_ADMIN_EXCHANGE);
  486. InitializeListHead(&SmbMmExchangesInUse[CONSTRUCT_NETROOT_EXCHANGE]);
  487. ExInitializeNPagedLookasideList(
  488. &SmbMmExchangesLookasideList[CONSTRUCT_NETROOT_EXCHANGE],
  489. ExAllocatePoolWithTag,
  490. ExFreePool,
  491. 0,
  492. sizeof(SMB_CONSTRUCT_NETROOT_EXCHANGE),
  493. MRXSMB_MM_POOLTAG,
  494. 1);
  495. InitializeListHead(&SmbMmExchangesInUse[TRANSACT_EXCHANGE]);
  496. ExInitializeNPagedLookasideList(
  497. &SmbMmExchangesLookasideList[TRANSACT_EXCHANGE],
  498. ExAllocatePoolWithTag,
  499. ExFreePool,
  500. 0,
  501. sizeof(SMB_TRANSACT_EXCHANGE),
  502. MRXSMB_MM_POOLTAG,
  503. 2);
  504. InitializeListHead(&SmbMmExchangesInUse[ORDINARY_EXCHANGE]);
  505. ExInitializeNPagedLookasideList(
  506. &SmbMmExchangesLookasideList[ORDINARY_EXCHANGE],
  507. ExAllocatePoolWithTag,
  508. ExFreePool,
  509. 0,
  510. sizeof(SMB_PSE_ORDINARY_EXCHANGE),
  511. MRXSMB_MM_POOLTAG,
  512. 4);
  513. InitializeListHead(&SmbMmExchangesInUse[EXTENDED_SESSION_SETUP_EXCHANGE]);
  514. ExInitializeNPagedLookasideList(
  515. &SmbMmExchangesLookasideList[EXTENDED_SESSION_SETUP_EXCHANGE],
  516. ExAllocatePoolWithTag,
  517. ExFreePool,
  518. 0,
  519. sizeof(SMB_EXTENDED_SESSION_SETUP_EXCHANGE),
  520. MRXSMB_MM_POOLTAG,
  521. 1);
  522. InitializeListHead(&SmbMmExchangesInUse[ADMIN_EXCHANGE]);
  523. ExInitializeNPagedLookasideList(
  524. &SmbMmExchangesLookasideList[ADMIN_EXCHANGE],
  525. ExAllocatePoolWithTag,
  526. ExFreePool,
  527. 0,
  528. sizeof(SMB_ADMIN_EXCHANGE),
  529. MRXSMB_MM_POOLTAG,
  530. 1);
  531. InitializeListHead(&SmbMmObjectsInUse[SMBCEDB_OT_SERVER]);
  532. InitializeListHead(&SmbMmObjectsInUse[SMBCEDB_OT_SESSION]);
  533. InitializeListHead(&SmbMmObjectsInUse[SMBCEDB_OT_NETROOT]);
  534. InitializeListHead(&SmbMmObjectsInUse[SMBCEDB_OT_REQUEST]);
  535. SmbMmExchangeId = 1;
  536. } else {
  537. Status = STATUS_INSUFFICIENT_RESOURCES;
  538. }
  539. return Status;
  540. }
  541. VOID SmbMmTearDown()
  542. /*++
  543. Routine Description:
  544. This routine tears down the memory management structures in the SMB connection
  545. engine
  546. --*/
  547. {
  548. NTSTATUS Status;
  549. PAGED_CODE();
  550. // free the segment associated with RxCe object allocation.
  551. RxFreePool(SmbMmRequestZoneSegmentPtr);
  552. ExDeleteNPagedLookasideList(
  553. &SmbMmExchangesLookasideList[CONSTRUCT_NETROOT_EXCHANGE]);
  554. ExDeleteNPagedLookasideList(
  555. &SmbMmExchangesLookasideList[TRANSACT_EXCHANGE]);
  556. ExDeleteNPagedLookasideList(
  557. &SmbMmExchangesLookasideList[ORDINARY_EXCHANGE]);
  558. ExDeleteNPagedLookasideList(
  559. &SmbMmExchangesLookasideList[EXTENDED_SESSION_SETUP_EXCHANGE]);
  560. ExDeleteNPagedLookasideList(
  561. &SmbMmExchangesLookasideList[ADMIN_EXCHANGE]);
  562. }