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.

1525 lines
44 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module performs initialization for the AFD device driver.
  7. Author:
  8. David Treadwell (davidtr) 21-Feb-1992
  9. Revision History:
  10. --*/
  11. #include "afdp.h"
  12. //
  13. // Location of AFD configurable parameters in the registyr.
  14. //
  15. #define REGISTRY_AFD_INFORMATION \
  16. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Afd"
  17. #define REGISTRY_PARAMETERS L"Parameters"
  18. //
  19. // Parameter value names.
  20. //
  21. #define REGISTRY_BUFFER_ALIGNMENT L"BufferAlignment"
  22. #define REGISTRY_IRP_STACK_SIZE L"IrpStackSize"
  23. #define REGISTRY_PRIORITY_BOOST L"PriorityBoost"
  24. #define REGISTRY_IGNORE_PUSH_BIT L"IgnorePushBitOnReceives"
  25. #define REGISTRY_NO_RAW_SECURITY L"DisableRawSecurity"
  26. #define REGISTRY_NO_DIRECT_ACCEPTEX L"DisableDirectAcceptEx"
  27. #define REGISTRY_DISABLE_CHAINED_RECV L"DisableChainedReceive"
  28. #ifdef TDI_SERVICE_SEND_AND_DISCONNECT
  29. #define REGISTRY_USE_TDI_SEND_AND_DISCONNECT L"UseTdiSendAndDisconnect"
  30. #endif // TDI_SERVICE_SEND_AND_DISCONNECT
  31. #define REGISTRY_STANDARD_ADDRESS_LENGTH L"StandardAddressLength"
  32. #define REGISTRY_DEFAULT_RECEIVE_WINDOW L"DefaultReceiveWindow"
  33. #define REGISTRY_DEFAULT_SEND_WINDOW L"DefaultSendWindow"
  34. #define REGISTRY_LARGE_BUFFER_SIZE L"LargeBufferSize"
  35. #define REGISTRY_LARGE_BUFFER_LIST_DEPTH L"LargeBufferListDepth"
  36. #define REGISTRY_MEDIUM_BUFFER_SIZE L"MediumBufferSize"
  37. #define REGISTRY_MEDIUM_BUFFER_LIST_DEPTH L"MediumBufferListDepth"
  38. #define REGISTRY_SMALL_BUFFER_SIZE L"SmallBufferSize"
  39. #define REGISTRY_SMALL_BUFFER_LIST_DEPTH L"SmallBufferListDepth"
  40. #define REGISTRY_BUFFER_TAG_LIST_DEPTH L"BufferTagListDepth"
  41. #define REGISTRY_MAX_ACTIVE_TRANSMIT_FILE_COUNT L"MaxActiveTransmitFileCount"
  42. #define REGISTRY_DEFAULT_PACKET_ELEMENT_COUNT L"DefaultPacketElementCount"
  43. #define REGISTRY_TRANSMIT_WORKER L"TransmitWorker"
  44. #define REGISTRY_ENABLE_DYNAMIC_BACKLOG L"EnableDynamicBacklog"
  45. #define REGISTRY_MINIMUM_DYNAMIC_BACKLOG L"MinimumDynamicBacklog"
  46. #define REGISTRY_MAXIMUM_DYNAMIC_BACKLOG L"MaximumDynamicBacklog"
  47. #define REGISTRY_DYNAMIC_BACKLOG_GROWTH_DELTA L"DynamicBacklogGrowthDelta"
  48. #define REGISTRY_VOLATILE_PARAMETERS L"VolatileParameters"
  49. #define REGISTRY_BLOCKING_SEND_COPY_THRESHOLD L"BlockingSendCopyThreshold"
  50. #define REGISTRY_FAST_SEND_DATAGRAM_THRESHOLD L"FastSendDatagramThreshold"
  51. #define REGISTRY_PACKET_FRAGMENT_COPY_THRESHOLD L"PacketFragmentCopyThreshold"
  52. #define REGISTRY_TRANSMIT_IO_LENGTH L"TransmitIoLength"
  53. #define REGISTRY_MAX_FAST_TRANSMIT L"MaxFastTransmit"
  54. #define REGISTRY_MAX_FAST_COPY_TRANSMIT L"MaxFastCopyTransmit"
  55. #if DBG
  56. #define REGISTRY_DEBUG_FLAGS L"DebugFlags"
  57. #define REGISTRY_BREAK_ON_STARTUP L"BreakOnStartup"
  58. #define REGISTRY_USE_PRIVATE_ASSERT L"UsePrivateAssert"
  59. #endif
  60. #if AFD_PERF_DBG
  61. #define REGISTRY_DISABLE_FAST_IO L"DisableFastIO"
  62. #define REGISTRY_DISABLE_CONN_REUSE L"DisableConnectionReuse"
  63. #endif
  64. //
  65. // A list of longwords that are configured by the registry.
  66. //
  67. struct _AfdConfigInfo {
  68. PWCHAR RegistryValueName;
  69. PULONG Variable;
  70. } AfdConfigInfo[] = {
  71. { REGISTRY_STANDARD_ADDRESS_LENGTH, &AfdStandardAddressLength },
  72. { REGISTRY_DEFAULT_RECEIVE_WINDOW, &AfdReceiveWindowSize },
  73. { REGISTRY_DEFAULT_SEND_WINDOW, &AfdSendWindowSize },
  74. { REGISTRY_LARGE_BUFFER_SIZE, &AfdLargeBufferSize },
  75. { REGISTRY_LARGE_BUFFER_LIST_DEPTH, &AfdLargeBufferListDepth },
  76. { REGISTRY_MEDIUM_BUFFER_SIZE, &AfdMediumBufferSize },
  77. { REGISTRY_MEDIUM_BUFFER_LIST_DEPTH, &AfdMediumBufferListDepth },
  78. { REGISTRY_SMALL_BUFFER_SIZE, &AfdSmallBufferSize },
  79. { REGISTRY_SMALL_BUFFER_LIST_DEPTH, &AfdSmallBufferListDepth },
  80. { REGISTRY_BUFFER_TAG_LIST_DEPTH, &AfdBufferTagListDepth },
  81. { REGISTRY_BLOCKING_SEND_COPY_THRESHOLD, &AfdBlockingSendCopyThreshold },
  82. { REGISTRY_FAST_SEND_DATAGRAM_THRESHOLD, &AfdFastSendDatagramThreshold },
  83. { REGISTRY_PACKET_FRAGMENT_COPY_THRESHOLD, &AfdTPacketsCopyThreshold },
  84. { REGISTRY_TRANSMIT_IO_LENGTH, &AfdTransmitIoLength },
  85. { REGISTRY_MAX_FAST_TRANSMIT, &AfdMaxFastTransmit },
  86. { REGISTRY_MAX_FAST_COPY_TRANSMIT, &AfdMaxFastCopyTransmit },
  87. { REGISTRY_DEFAULT_PACKET_ELEMENT_COUNT, &AfdDefaultTpInfoElementCount },
  88. { REGISTRY_TRANSMIT_WORKER, &AfdDefaultTransmitWorker},
  89. { REGISTRY_MINIMUM_DYNAMIC_BACKLOG, (PULONG)&AfdMinimumDynamicBacklog },
  90. { REGISTRY_MAXIMUM_DYNAMIC_BACKLOG, (PULONG)&AfdMaximumDynamicBacklog },
  91. { REGISTRY_DYNAMIC_BACKLOG_GROWTH_DELTA, (PULONG)&AfdDynamicBacklogGrowthDelta }
  92. },
  93. //
  94. // A list of volatile longword parameters.
  95. //
  96. AfdVolatileConfigInfo []= {
  97. { REGISTRY_BLOCKING_SEND_COPY_THRESHOLD, &AfdBlockingSendCopyThreshold },
  98. { REGISTRY_FAST_SEND_DATAGRAM_THRESHOLD, &AfdFastSendDatagramThreshold },
  99. { REGISTRY_PACKET_FRAGMENT_COPY_THRESHOLD, &AfdTPacketsCopyThreshold },
  100. { REGISTRY_TRANSMIT_IO_LENGTH, &AfdTransmitIoLength },
  101. { REGISTRY_MAX_FAST_TRANSMIT, &AfdMaxFastTransmit },
  102. { REGISTRY_MAX_FAST_COPY_TRANSMIT, &AfdMaxFastCopyTransmit },
  103. };
  104. #define AFD_CONFIG_VAR_COUNT (sizeof(AfdConfigInfo) / sizeof(AfdConfigInfo[0]))
  105. #define AFD_VOLATILE_CONFIG_VAR_COUNT (sizeof(AfdVolatileConfigInfo) / sizeof(AfdVolatileConfigInfo[0]))
  106. VOID
  107. AfdReadVolatileParameters (
  108. PVOID Parameter
  109. );
  110. VOID
  111. AfdReleaseRegistryHandleWait (
  112. IN PDEVICE_OBJECT DeviceObject,
  113. IN PVOID Context
  114. );
  115. ULONG
  116. AfdReadSingleParameter(
  117. IN HANDLE ParametersHandle,
  118. IN PWCHAR ValueName,
  119. IN LONG DefaultValue
  120. );
  121. NTSTATUS
  122. AfdOpenRegistry(
  123. IN PUNICODE_STRING BaseName,
  124. OUT PHANDLE ParametersHandle
  125. );
  126. VOID
  127. AfdReadRegistry (
  128. VOID
  129. );
  130. VOID
  131. AfdUnload (
  132. IN PDRIVER_OBJECT DriverObject
  133. );
  134. NTSTATUS
  135. DriverEntry (
  136. IN PDRIVER_OBJECT DriverObject,
  137. IN PUNICODE_STRING RegistryPath
  138. );
  139. NTSTATUS
  140. AfdCreateSecurityDescriptor(
  141. VOID
  142. );
  143. NTSTATUS
  144. AfdBuildDeviceAcl(
  145. OUT PACL *DeviceAcl
  146. );
  147. #ifdef ALLOC_PRAGMA
  148. #pragma alloc_text( INIT, DriverEntry )
  149. #pragma alloc_text( PAGE, AfdReadSingleParameter )
  150. #pragma alloc_text( INIT, AfdOpenRegistry )
  151. #pragma alloc_text( INIT, AfdReadRegistry )
  152. #pragma alloc_text( INIT, AfdCreateSecurityDescriptor )
  153. #pragma alloc_text( INIT, AfdBuildDeviceAcl )
  154. #pragma alloc_text( PAGE, AfdUnload )
  155. #pragma alloc_text( PAGE, AfdReadVolatileParameters )
  156. #pragma alloc_text( PAGE, AfdReleaseRegistryHandleWait )
  157. #endif
  158. NTSTATUS
  159. DriverEntry (
  160. IN PDRIVER_OBJECT DriverObject,
  161. IN PUNICODE_STRING RegistryPath
  162. )
  163. /*++
  164. Routine Description:
  165. This is the initialization routine for the AFD device driver.
  166. Arguments:
  167. DriverObject - Pointer to driver object created by the system.
  168. Return Value:
  169. The function value is the final status from the initialization operation.
  170. --*/
  171. {
  172. NTSTATUS status;
  173. UNICODE_STRING deviceName;
  174. CLONG i;
  175. BOOLEAN success;
  176. ULONG size;
  177. UNREFERENCED_PARAMETER (RegistryPath);
  178. PAGED_CODE( );
  179. //
  180. // Create the device object. (IoCreateDevice zeroes the memory
  181. // occupied by the object.)
  182. //
  183. // !!! Apply an ACL to the device object.
  184. //
  185. RtlInitUnicodeString( &deviceName, AFD_DEVICE_NAME );
  186. status = IoCreateDevice(
  187. DriverObject, // DriverObject
  188. 0, // DeviceExtension
  189. &deviceName, // DeviceName
  190. FILE_DEVICE_NAMED_PIPE, // DeviceType
  191. 0, // DeviceCharacteristics
  192. FALSE, // Exclusive
  193. &AfdDeviceObject // DeviceObject
  194. );
  195. if ( !NT_SUCCESS(status) ) {
  196. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_ERROR_LEVEL,
  197. "AFD DriverEntry: unable to create device object: %lx\n",
  198. status ));
  199. goto error_exit;
  200. }
  201. AfdWorkQueueItem = IoAllocateWorkItem (AfdDeviceObject);
  202. if (AfdWorkQueueItem==NULL) {
  203. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  204. "AFD DriverEntry: unable to allocate work queue item\n" ));
  205. status = STATUS_INSUFFICIENT_RESOURCES;
  206. goto error_exit;
  207. }
  208. KeInitializeEvent (&AfdContextWaitEvent, NotificationEvent, FALSE);
  209. //
  210. // Create the security descriptor used for socket access checks.
  211. //
  212. status = AfdCreateSecurityDescriptor();
  213. if (!NT_SUCCESS(status)) {
  214. goto error_exit;
  215. }
  216. //
  217. // Initialize global data.
  218. //
  219. AfdInitializeData( );
  220. //
  221. // Read registry information.
  222. // This may override hard-coded global
  223. // initialization above.
  224. //
  225. AfdReadRegistry( );
  226. #ifdef AFD_CHECK_ALIGNMENT
  227. AfdGlobalData = AFD_ALLOCATE_POOL_PRIORITY(
  228. NonPagedPool,
  229. FIELD_OFFSET (AFD_GLOBAL_DATA, BufferAlignmentTable[AfdAlignmentTableSize])
  230. // Note that although we have an array of UCHARs above
  231. // we do not need to align the array of ULONGs
  232. // since the UCHAR array size is aligned
  233. // to processor requirement.
  234. + AfdAlignmentTableSize*sizeof(LONG),
  235. AFD_RESOURCE_POOL_TAG,
  236. HighPoolPriority
  237. );
  238. #else
  239. AfdGlobalData = AFD_ALLOCATE_POOL_PRIORITY(
  240. NonPagedPool,
  241. FIELD_OFFSET (AFD_GLOBAL_DATA, BufferAlignmentTable[AfdAlignmentTableSize]),
  242. AFD_RESOURCE_POOL_TAG,
  243. HighPoolPriority
  244. );
  245. #endif
  246. if ( AfdGlobalData == NULL ) {
  247. status = STATUS_INSUFFICIENT_RESOURCES;
  248. goto error_exit;
  249. }
  250. ExInitializeResourceLite( AfdResource );
  251. AfdInitializeBufferManager();
  252. //
  253. // Initialize the AFD buffer lookaside lists. These must be
  254. // initialized *after* the registry data has been read.
  255. //
  256. size = AfdCalculateBufferSize (AfdLargeBufferSize,
  257. AfdStandardAddressLength,
  258. AfdTdiStackSize);
  259. ExInitializeNPagedLookasideList(
  260. &AfdLookasideLists->LargeBufferList,
  261. AfdAllocateBuffer,
  262. AfdFreeBuffer,
  263. 0,
  264. size,
  265. AFD_DATA_BUFFER_POOL_TAG,
  266. (USHORT)AfdLargeBufferListDepth
  267. );
  268. //
  269. // Make sure that if as the result of alignment the allocation size is adjusted
  270. // to equal to the larger one, the actual buffer sizes are adjusted as well.
  271. // This is necessary to avoid confusing block allocator which determines
  272. // buffer size based on the allocation size passed by the lookaside list
  273. // code.
  274. //
  275. size = AfdCalculateBufferSize (AfdMediumBufferSize,
  276. AfdStandardAddressLength,
  277. AfdTdiStackSize);
  278. if (size==AfdLookasideLists->LargeBufferList.L.Size) {
  279. AfdMediumBufferSize = AfdLargeBufferSize;
  280. }
  281. else {
  282. ASSERT (size<AfdLookasideLists->LargeBufferList.L.Size);
  283. }
  284. ExInitializeNPagedLookasideList(
  285. &AfdLookasideLists->MediumBufferList,
  286. AfdAllocateBuffer,
  287. AfdFreeBuffer,
  288. 0,
  289. size,
  290. AFD_DATA_BUFFER_POOL_TAG,
  291. (USHORT)AfdMediumBufferListDepth
  292. );
  293. size = AfdCalculateBufferSize (AfdSmallBufferSize,
  294. AfdStandardAddressLength,
  295. AfdTdiStackSize);
  296. if (size==AfdLookasideLists->MediumBufferList.L.Size) {
  297. AfdSmallBufferSize = AfdMediumBufferSize;
  298. }
  299. else {
  300. ASSERT (size<AfdLookasideLists->MediumBufferList.L.Size);
  301. }
  302. ExInitializeNPagedLookasideList(
  303. &AfdLookasideLists->SmallBufferList,
  304. AfdAllocateBuffer,
  305. AfdFreeBuffer,
  306. 0,
  307. size,
  308. AFD_DATA_BUFFER_POOL_TAG,
  309. (USHORT)AfdSmallBufferListDepth
  310. );
  311. ExInitializeNPagedLookasideList(
  312. &AfdLookasideLists->BufferTagList,
  313. AfdAllocateBufferTag,
  314. AfdFreeBufferTag,
  315. 0,
  316. sizeof (AFD_BUFFER_TAG),
  317. AFD_DATA_BUFFER_POOL_TAG,
  318. (USHORT)AfdBufferTagListDepth
  319. );
  320. ExInitializeNPagedLookasideList(
  321. &AfdLookasideLists->TpInfoList,
  322. AfdAllocateTpInfo,
  323. AfdFreeTpInfo,
  324. 0,
  325. AfdComputeTpInfoSize (AfdDefaultTpInfoElementCount,
  326. AfdTdiStackSize),
  327. AFD_TRANSMIT_INFO_POOL_TAG,
  328. 0
  329. );
  330. ExInitializeNPagedLookasideList(
  331. &AfdLookasideLists->RemoteAddrList,
  332. AfdAllocateRemoteAddress,
  333. AfdFreeRemoteAddress,
  334. 0,
  335. AfdStandardAddressLength,
  336. AFD_REMOTE_ADDRESS_POOL_TAG,
  337. (USHORT)AfdBufferTagListDepth
  338. );
  339. AfdLookasideLists->TrimFlags = 0;
  340. //
  341. // Initialize group ID manager.
  342. //
  343. success = AfdInitializeGroup();
  344. if ( !success ) {
  345. status = STATUS_INSUFFICIENT_RESOURCES;
  346. goto error_exit;
  347. }
  348. //
  349. // Initialize the driver object for this file system driver.
  350. //
  351. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  352. DriverObject->MajorFunction[i] = AfdDispatch;
  353. }
  354. //
  355. // Special case for IRP_MJ_DEVICE_CONTROL since it is
  356. // the most often used function in AFD.
  357. //
  358. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
  359. AfdDispatchDeviceControl;
  360. DriverObject->FastIoDispatch = &AfdFastIoDispatch;
  361. DriverObject->DriverUnload = AfdUnload;
  362. //
  363. // Initialize our device object.
  364. //
  365. AfdDeviceObject->Flags |= DO_DIRECT_IO;
  366. AfdDeviceObject->StackSize = AfdIrpStackSize;
  367. //
  368. // Remember a pointer to the system process. We'll use this pointer
  369. // for KeAttachProcess() calls so that we can open handles in the
  370. // context of the system process.
  371. //
  372. AfdSystemProcess = (PKPROCESS)IoGetCurrentProcess();
  373. //
  374. // Start notification for volatile parameters if necessary.
  375. //
  376. if (AfdParametersNotifyHandle) {
  377. AfdReadVolatileParameters (NULL);
  378. }
  379. //
  380. // Tell MM that it can page all of AFD it is desires. We will reset
  381. // to normal paging of AFD code as soon as an AFD endpoint is
  382. // opened.
  383. //
  384. AfdLoaded = NULL;
  385. MmPageEntireDriver( (PVOID)DriverEntry );
  386. return (status);
  387. error_exit:
  388. //
  389. // Terminate the group ID manager.
  390. //
  391. AfdTerminateGroup();
  392. if (AfdAdminSecurityDescriptor!=NULL) {
  393. ExFreePool (AfdAdminSecurityDescriptor);
  394. AfdAdminSecurityDescriptor = NULL;
  395. }
  396. if( AfdGlobalData != NULL ) {
  397. ExDeleteNPagedLookasideList( &AfdLookasideLists->LargeBufferList );
  398. ExDeleteNPagedLookasideList( &AfdLookasideLists->MediumBufferList );
  399. ExDeleteNPagedLookasideList( &AfdLookasideLists->SmallBufferList );
  400. ExDeleteNPagedLookasideList( &AfdLookasideLists->BufferTagList );
  401. ExDeleteNPagedLookasideList( &AfdLookasideLists->TpInfoList );
  402. ExDeleteNPagedLookasideList( &AfdLookasideLists->RemoteAddrList );
  403. ExDeleteResourceLite( AfdResource );
  404. AFD_FREE_POOL(
  405. AfdGlobalData,
  406. AFD_RESOURCE_POOL_TAG
  407. );
  408. AfdGlobalData = NULL;
  409. }
  410. if (AfdWorkQueueItem!=NULL) {
  411. IoFreeWorkItem (AfdWorkQueueItem);
  412. AfdWorkQueueItem = NULL;
  413. }
  414. if (AfdDeviceObject!=NULL) {
  415. IoDeleteDevice(AfdDeviceObject);
  416. AfdDeviceObject = NULL;
  417. }
  418. return status;
  419. } // DriverEntry
  420. VOID
  421. AfdUnload (
  422. IN PDRIVER_OBJECT DriverObject
  423. )
  424. {
  425. PLIST_ENTRY listEntry;
  426. KEVENT event;
  427. BOOLEAN wait;
  428. UNREFERENCED_PARAMETER( DriverObject );
  429. PAGED_CODE( );
  430. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_INFO_LEVEL,
  431. "AfdUnload called.\n" ));
  432. if (AfdParametersNotifyHandle!=NULL) {
  433. NTSTATUS status;
  434. KeEnterCriticalRegion ();
  435. ExAcquireResourceExclusiveLite( AfdResource, TRUE );
  436. ZwClose (AfdParametersNotifyHandle);
  437. AfdParametersNotifyHandle = NULL;
  438. KeInitializeEvent( &event, SynchronizationEvent, FALSE );
  439. AfdParametersUnloadEvent = &event;
  440. ExReleaseResourceLite( AfdResource );
  441. KeLeaveCriticalRegion ();
  442. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_INFO_LEVEL,
  443. "AfdUnload: Waiting for registry notification to fire...\n"));
  444. status = KeWaitForSingleObject( (PVOID)&event, Executive, KernelMode, FALSE, NULL );
  445. ASSERT (NT_SUCCESS (status));
  446. }
  447. //
  448. // Check if AFD has already cleaned up all endpoints and
  449. // is ready to get unloaded.
  450. //
  451. KeEnterCriticalRegion ();
  452. ExAcquireResourceExclusiveLite( AfdResource, TRUE );
  453. if (AfdLoaded!=NULL) {
  454. //
  455. // Some work still needs to be done. Setup the wait.
  456. //
  457. ASSERT (AfdLoaded==(PKEVENT)1);
  458. KeInitializeEvent( &event, SynchronizationEvent, FALSE );
  459. AfdLoaded = &event;
  460. wait = TRUE;
  461. }
  462. else
  463. wait = FALSE;
  464. ExReleaseResourceLite( AfdResource );
  465. KeLeaveCriticalRegion ();
  466. if (wait) {
  467. NTSTATUS status;
  468. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_INFO_LEVEL,
  469. "AfdUnload: Waiting for endpoints to cleanup...\n"));
  470. status = KeWaitForSingleObject( (PVOID)&event, Executive, KernelMode, FALSE, NULL );
  471. ASSERT (NT_SUCCESS (status));
  472. }
  473. //
  474. // Kill the transport info list.
  475. //
  476. while( !IsListEmpty( &AfdTransportInfoListHead ) ) {
  477. PAFD_TRANSPORT_INFO transportInfo;
  478. listEntry = RemoveHeadList( &AfdTransportInfoListHead );
  479. transportInfo = CONTAINING_RECORD(
  480. listEntry,
  481. AFD_TRANSPORT_INFO,
  482. TransportInfoListEntry
  483. );
  484. ASSERT (transportInfo->ReferenceCount == 1);
  485. AFD_FREE_POOL(
  486. transportInfo,
  487. AFD_TRANSPORT_INFO_POOL_TAG
  488. );
  489. }
  490. //
  491. // Free address list and associated structures
  492. //
  493. AfdDeregisterPnPHandlers (NULL);
  494. if (AfdAddressListLock) {
  495. ExDeleteResourceLite( AfdAddressListLock );
  496. AFD_FREE_POOL(
  497. AfdAddressListLock,
  498. AFD_RESOURCE_POOL_TAG
  499. );
  500. }
  501. if (AfdTdiPnPHandlerLock) {
  502. ExDeleteResourceLite( AfdTdiPnPHandlerLock );
  503. AFD_FREE_POOL(
  504. AfdTdiPnPHandlerLock,
  505. AFD_RESOURCE_POOL_TAG
  506. );
  507. }
  508. //
  509. // Do some cleanup for SAN
  510. //
  511. if (IoCompletionObjectType!=NULL) {
  512. ObDereferenceObject (IoCompletionObjectType);
  513. IoCompletionObjectType = NULL;
  514. }
  515. if (AfdAdminSecurityDescriptor!=NULL) {
  516. ExFreePool (AfdAdminSecurityDescriptor);
  517. AfdAdminSecurityDescriptor = NULL;
  518. }
  519. //
  520. // Terminate the group ID manager.
  521. //
  522. AfdTerminateGroup();
  523. #if DBG || REFERENCE_DEBUG
  524. AfdFreeDebugData ();
  525. #endif
  526. //
  527. // Kill the lookaside lists and resource in the global data
  528. //
  529. if( AfdGlobalData != NULL ) {
  530. ExDeleteNPagedLookasideList( &AfdLookasideLists->LargeBufferList );
  531. ExDeleteNPagedLookasideList( &AfdLookasideLists->MediumBufferList );
  532. ExDeleteNPagedLookasideList( &AfdLookasideLists->SmallBufferList );
  533. ExDeleteNPagedLookasideList( &AfdLookasideLists->BufferTagList );
  534. ExDeleteNPagedLookasideList( &AfdLookasideLists->TpInfoList );
  535. ExDeleteNPagedLookasideList( &AfdLookasideLists->RemoteAddrList );
  536. ExDeleteResourceLite( AfdResource );
  537. AFD_FREE_POOL(
  538. AfdGlobalData,
  539. AFD_RESOURCE_POOL_TAG
  540. );
  541. AfdGlobalData = NULL;
  542. }
  543. //
  544. // Delete our device object.
  545. //
  546. IoDeleteDevice( AfdDeviceObject );
  547. } // AfdUnload
  548. VOID
  549. AfdReadRegistry (
  550. VOID
  551. )
  552. /*++
  553. Routine Description:
  554. Reads the AFD section of the registry. Any values listed in the
  555. registry override defaults.
  556. Arguments:
  557. None.
  558. Return Value:
  559. None -- if anything fails, the default value is used.
  560. --*/
  561. {
  562. HANDLE parametersHandle;
  563. NTSTATUS status;
  564. ULONG stackSize;
  565. ULONG priorityBoost;
  566. ULONG bufferAlignment;
  567. UNICODE_STRING registryPath;
  568. ULONG i;
  569. PAGED_CODE( );
  570. RtlInitUnicodeString( &registryPath, REGISTRY_AFD_INFORMATION );
  571. status = AfdOpenRegistry( &registryPath, &parametersHandle );
  572. if (status != STATUS_SUCCESS) {
  573. return;
  574. }
  575. #if DBG
  576. //
  577. // Read the debug flags from the registry.
  578. //
  579. AfdDebug = AfdReadSingleParameter(
  580. parametersHandle,
  581. REGISTRY_DEBUG_FLAGS,
  582. AfdDebug
  583. );
  584. //
  585. // Force a breakpoint if so requested.
  586. //
  587. if( AfdReadSingleParameter(
  588. parametersHandle,
  589. REGISTRY_BREAK_ON_STARTUP,
  590. 0 ) != 0 ) {
  591. DbgBreakPoint();
  592. }
  593. //
  594. // Enable private assert function if requested.
  595. //
  596. AfdUsePrivateAssert = (BOOLEAN)(AfdReadSingleParameter(
  597. parametersHandle,
  598. REGISTRY_USE_PRIVATE_ASSERT,
  599. (LONG)AfdUsePrivateAssert
  600. ) != 0);
  601. #endif
  602. #if AFD_PERF_DBG
  603. //
  604. // Read a flag from the registry that allows us to disable Fast IO.
  605. //
  606. AfdDisableFastIo = (BOOLEAN)(AfdReadSingleParameter(
  607. parametersHandle,
  608. REGISTRY_DISABLE_FAST_IO,
  609. (LONG)AfdDisableFastIo
  610. ) != 0);
  611. //
  612. // Read a flag from the registry that allows us to disable connection
  613. // reuse.
  614. //
  615. AfdDisableConnectionReuse = (BOOLEAN)(AfdReadSingleParameter(
  616. parametersHandle,
  617. REGISTRY_DISABLE_CONN_REUSE,
  618. (LONG)AfdDisableConnectionReuse
  619. ) != 0);
  620. #endif
  621. //
  622. // Read the stack size and priority boost values from the registry.
  623. //
  624. stackSize = AfdReadSingleParameter(
  625. parametersHandle,
  626. REGISTRY_IRP_STACK_SIZE,
  627. (ULONG)AfdIrpStackSize
  628. );
  629. //
  630. // We do not support more than 63 layers below us.
  631. // (The system allows for 127, but some can be sitting above us
  632. // as well.
  633. //
  634. if ( stackSize > 64 ) {
  635. stackSize = 64;
  636. }
  637. if (stackSize<2) {
  638. //
  639. // Can't be less than two since we have to call
  640. // at least one driver below us.
  641. //
  642. stackSize = 2;
  643. }
  644. AfdIrpStackSize = (CCHAR)stackSize;
  645. AfdTdiStackSize = AfdIrpStackSize-1;
  646. #ifdef _AFD_VARIABLE_STACK_
  647. AfdMaxStackSize = AfdTdiStackSize;
  648. #endif // _AFD_VARIABLE_STACK_
  649. priorityBoost = AfdReadSingleParameter(
  650. parametersHandle,
  651. REGISTRY_PRIORITY_BOOST,
  652. (ULONG)AfdPriorityBoost
  653. );
  654. if ( priorityBoost > 16 ) {
  655. priorityBoost = AFD_DEFAULT_PRIORITY_BOOST;
  656. }
  657. AfdPriorityBoost = (CCHAR)priorityBoost;
  658. //
  659. // Read other config variables from the registry.
  660. //
  661. for ( i = 0; i < AFD_CONFIG_VAR_COUNT; i++ ) {
  662. *AfdConfigInfo[i].Variable =
  663. AfdReadSingleParameter(
  664. parametersHandle,
  665. AfdConfigInfo[i].RegistryValueName,
  666. *AfdConfigInfo[i].Variable
  667. );
  668. }
  669. //
  670. // Validate standard buffer sizes.
  671. // (we use buffer for KAPC or WORK_QUEUE_ITEM storage
  672. // in fast transmit file processing).
  673. //
  674. if (AfdSmallBufferSize<max (sizeof(KAPC),sizeof (WORK_QUEUE_ITEM))) {
  675. DbgPrint("AFD: Too small %ls registry parameter value: %ld\n"
  676. "AFD: Adjusting to %ld\n",
  677. REGISTRY_SMALL_BUFFER_SIZE,
  678. AfdSmallBufferSize,
  679. max (sizeof(KAPC),sizeof (WORK_QUEUE_ITEM)));
  680. AfdSmallBufferSize = max (sizeof(KAPC),sizeof (WORK_QUEUE_ITEM));
  681. }
  682. if (AfdMediumBufferSize<AfdSmallBufferSize) {
  683. DbgPrint("AFD: Too small %ls registry parameter value: %ld\n"
  684. "AFD: Adjusting to %ld\n",
  685. REGISTRY_MEDIUM_BUFFER_SIZE,
  686. AfdMediumBufferSize,
  687. AfdSmallBufferSize);
  688. AfdMediumBufferSize = AfdSmallBufferSize;
  689. }
  690. if (AfdLargeBufferSize<AfdMediumBufferSize) {
  691. DbgPrint("AFD: Too small %ls registry parameter value: %ld\n"
  692. "AFD: Adjusting to %ld\n",
  693. REGISTRY_LARGE_BUFFER_SIZE,
  694. AfdLargeBufferSize,
  695. AfdMediumBufferSize);
  696. AfdLargeBufferSize = AfdMediumBufferSize;
  697. }
  698. AfdIgnorePushBitOnReceives = (BOOLEAN)(AfdReadSingleParameter(
  699. parametersHandle,
  700. REGISTRY_IGNORE_PUSH_BIT,
  701. (LONG)AfdIgnorePushBitOnReceives
  702. )!=0);
  703. AfdDisableRawSecurity = (BOOLEAN)(AfdReadSingleParameter(
  704. parametersHandle,
  705. REGISTRY_NO_RAW_SECURITY,
  706. (LONG)AfdDisableRawSecurity
  707. )!=0);
  708. AfdDisableDirectSuperAccept = (BOOLEAN)(AfdReadSingleParameter(
  709. parametersHandle,
  710. REGISTRY_NO_DIRECT_ACCEPTEX,
  711. (LONG)AfdDisableDirectSuperAccept
  712. )!=0);
  713. AfdDisableChainedReceive = (BOOLEAN)(AfdReadSingleParameter(
  714. parametersHandle,
  715. REGISTRY_DISABLE_CHAINED_RECV,
  716. (LONG)AfdDisableChainedReceive
  717. ) != 0);
  718. #ifdef TDI_SERVICE_SEND_AND_DISCONNECT
  719. AfdUseTdiSendAndDisconnect = (BOOLEAN)(AfdReadSingleParameter(
  720. parametersHandle,
  721. REGISTRY_USE_TDI_SEND_AND_DISCONNECT,
  722. (LONG)AfdUseTdiSendAndDisconnect
  723. ) != 0);
  724. #endif //TDI_SERVICE_SEND_AND_DISCONNECT
  725. if( MmIsThisAnNtAsSystem() ) {
  726. //
  727. // On the NT Server product, make the maximum active TransmitFile
  728. // count configurable. This value is fixed (not configurable) on
  729. // the NT Workstation product.
  730. //
  731. AfdMaxActiveTransmitFileCount = AfdReadSingleParameter(
  732. parametersHandle,
  733. REGISTRY_MAX_ACTIVE_TRANSMIT_FILE_COUNT,
  734. (LONG)AfdMaxActiveTransmitFileCount
  735. );
  736. //
  737. // Dynamic backlog is only possible on NT Server.
  738. //
  739. AfdEnableDynamicBacklog = (BOOLEAN)(AfdReadSingleParameter(
  740. parametersHandle,
  741. REGISTRY_ENABLE_DYNAMIC_BACKLOG,
  742. (LONG)AfdEnableDynamicBacklog
  743. ) != 0);
  744. } else {
  745. AfdEnableDynamicBacklog = FALSE;
  746. }
  747. switch (AfdDefaultTransmitWorker) {
  748. case AFD_TF_USE_SYSTEM_THREAD:
  749. case AFD_TF_USE_KERNEL_APC:
  750. break;
  751. default:
  752. DbgPrint ("AFD: Invalid %ls registry parameter value: %ld\n"
  753. "AFD: Using default - %ld\n",
  754. REGISTRY_TRANSMIT_WORKER,
  755. AfdDefaultTransmitWorker,
  756. AFD_DEFAULT_TRANSMIT_WORKER);
  757. AfdDefaultTransmitWorker = AFD_DEFAULT_TRANSMIT_WORKER;
  758. break;
  759. }
  760. bufferAlignment = AfdReadSingleParameter(
  761. parametersHandle,
  762. REGISTRY_BUFFER_ALIGNMENT,
  763. (LONG)AfdBufferAlignment
  764. );
  765. if (bufferAlignment!=AfdBufferAlignment) {
  766. if (bufferAlignment<AFD_MINIMUM_BUFFER_ALIGNMENT ||
  767. bufferAlignment>PAGE_SIZE ||
  768. (bufferAlignment & (bufferAlignment-1))!=0) {
  769. DbgPrint("AFD: Invalid %ls registry parameter value: %ld\n"
  770. "AFD: Using default - %ld\n",
  771. REGISTRY_BUFFER_ALIGNMENT,
  772. bufferAlignment,
  773. AfdBufferAlignment);
  774. }
  775. else {
  776. AfdBufferAlignment = bufferAlignment;
  777. AfdAlignmentTableSize = AfdBufferAlignment/AFD_MINIMUM_BUFFER_ALIGNMENT;
  778. }
  779. }
  780. AfdVolatileConfig = (BOOLEAN)(AfdReadSingleParameter (
  781. parametersHandle,
  782. REGISTRY_VOLATILE_PARAMETERS,
  783. (LONG)AfdVolatileConfig)!=0);
  784. if (AfdVolatileConfig) {
  785. AfdParametersNotifyHandle = parametersHandle;
  786. ExInitializeWorkItem (&AfdParametersNotifyWorker, AfdReadVolatileParameters, NULL);
  787. }
  788. else {
  789. ZwClose( parametersHandle );
  790. }
  791. //
  792. // Need to recalculate size of the page-long buffer if standard
  793. // address length has changed
  794. //
  795. if (AfdStandardAddressLength!=AFD_DEFAULT_STD_ADDRESS_LENGTH) {
  796. CLONG oldBufferLengthForOnePage = AfdBufferLengthForOnePage;
  797. AfdBufferOverhead = AfdCalculateBufferSize( PAGE_SIZE,
  798. AfdStandardAddressLength,
  799. AfdTdiStackSize) - PAGE_SIZE;
  800. AfdBufferLengthForOnePage = ALIGN_DOWN_A(
  801. PAGE_SIZE-AfdBufferOverhead,
  802. AFD_MINIMUM_BUFFER_ALIGNMENT);
  803. if (AfdLargeBufferSize==oldBufferLengthForOnePage) {
  804. AfdLargeBufferSize = AfdBufferLengthForOnePage;
  805. }
  806. }
  807. if (AfdBlockingSendCopyThreshold < AfdBufferLengthForOnePage) {
  808. DbgPrint("AFD: Too small %ls registry parameter value: %ld\n"
  809. "AFD: Adjusting to %ld\n",
  810. REGISTRY_BLOCKING_SEND_COPY_THRESHOLD,
  811. AfdBlockingSendCopyThreshold,
  812. AfdBufferLengthForOnePage);
  813. AfdBlockingSendCopyThreshold = AfdBufferLengthForOnePage;
  814. }
  815. return;
  816. } // AfdReadRegistry
  817. NTSTATUS
  818. AfdOpenRegistry(
  819. IN PUNICODE_STRING BaseName,
  820. OUT PHANDLE ParametersHandle
  821. )
  822. /*++
  823. Routine Description:
  824. This routine is called by AFD to open the registry. If the registry
  825. tree exists, then it opens it and returns an error. If not, it
  826. creates the appropriate keys in the registry, opens it, and
  827. returns STATUS_SUCCESS.
  828. Arguments:
  829. BaseName - Where in the registry to start looking for the information.
  830. LinkageHandle - Returns the handle used to read linkage information.
  831. ParametersHandle - Returns the handle used to read other
  832. parameters.
  833. Return Value:
  834. The status of the request.
  835. --*/
  836. {
  837. HANDLE configHandle;
  838. NTSTATUS status;
  839. PWSTR parametersString = REGISTRY_PARAMETERS;
  840. UNICODE_STRING parametersKeyName;
  841. OBJECT_ATTRIBUTES objectAttributes;
  842. ULONG disposition;
  843. PAGED_CODE( );
  844. //
  845. // Open the registry for the initial string.
  846. //
  847. InitializeObjectAttributes(
  848. &objectAttributes,
  849. BaseName, // name
  850. OBJ_CASE_INSENSITIVE, // attributes
  851. NULL, // root
  852. NULL // security descriptor
  853. );
  854. status = ZwCreateKey(
  855. &configHandle,
  856. KEY_WRITE,
  857. &objectAttributes,
  858. 0, // title index
  859. NULL, // class
  860. 0, // create options
  861. &disposition // disposition
  862. );
  863. if (!NT_SUCCESS(status)) {
  864. return STATUS_UNSUCCESSFUL;
  865. }
  866. //
  867. // Now open the parameters key.
  868. //
  869. RtlInitUnicodeString (&parametersKeyName, parametersString);
  870. InitializeObjectAttributes(
  871. &objectAttributes,
  872. &parametersKeyName, // name
  873. OBJ_CASE_INSENSITIVE, // attributes
  874. configHandle, // root
  875. NULL // security descriptor
  876. );
  877. status = ZwOpenKey(
  878. ParametersHandle,
  879. KEY_READ,
  880. &objectAttributes
  881. );
  882. if (!NT_SUCCESS(status)) {
  883. ZwClose( configHandle );
  884. return status;
  885. }
  886. //
  887. // All keys successfully opened or created.
  888. //
  889. ZwClose( configHandle );
  890. return STATUS_SUCCESS;
  891. } // AfdOpenRegistry
  892. ULONG
  893. AfdReadSingleParameter(
  894. IN HANDLE ParametersHandle,
  895. IN PWCHAR ValueName,
  896. IN LONG DefaultValue
  897. )
  898. /*++
  899. Routine Description:
  900. This routine is called by AFD to read a single parameter
  901. from the registry. If the parameter is found it is stored
  902. in Data.
  903. Arguments:
  904. ParametersHandle - A pointer to the open registry.
  905. ValueName - The name of the value to search for.
  906. DefaultValue - The default value.
  907. Return Value:
  908. The value to use; will be the default if the value is not
  909. found or is not in the correct range.
  910. --*/
  911. {
  912. ULONG informationBuffer[32]; // declare ULONG to get it aligned
  913. PKEY_VALUE_FULL_INFORMATION information =
  914. (PKEY_VALUE_FULL_INFORMATION)informationBuffer;
  915. UNICODE_STRING valueKeyName;
  916. ULONG informationLength;
  917. LONG returnValue;
  918. NTSTATUS status;
  919. PAGED_CODE( );
  920. RtlInitUnicodeString( &valueKeyName, ValueName );
  921. status = ZwQueryValueKey(
  922. ParametersHandle,
  923. &valueKeyName,
  924. KeyValueFullInformation,
  925. (PVOID)information,
  926. sizeof (informationBuffer),
  927. &informationLength
  928. );
  929. if (status == STATUS_SUCCESS &&
  930. information->DataLength == sizeof(ULONG) &&
  931. information->Type==REG_DWORD) {
  932. RtlMoveMemory(
  933. (PVOID)&returnValue,
  934. ((PUCHAR)information) + information->DataOffset,
  935. sizeof(ULONG)
  936. );
  937. if (returnValue < 0) {
  938. returnValue = DefaultValue;
  939. }
  940. else if (returnValue!=DefaultValue) {
  941. DbgPrint ("AFD: Read %ls from the registry, value: 0x%lx (%s: 0x%lx))\n",
  942. ValueName, returnValue,
  943. AfdVolatileConfig ? "previous" : "default",
  944. DefaultValue);
  945. }
  946. } else {
  947. returnValue = DefaultValue;
  948. }
  949. return returnValue;
  950. } // AfdReadSingleParameter
  951. NTSTATUS
  952. AfdBuildDeviceAcl(
  953. OUT PACL *DeviceAcl
  954. )
  955. /*++
  956. Routine Description:
  957. This routine builds an ACL which gives Administrators, LocalSystem,
  958. and NetworkService principals full access. All other principals have no access.
  959. Arguments:
  960. DeviceAcl - Output pointer to the new ACL.
  961. Return Value:
  962. STATUS_SUCCESS or an appropriate error code.
  963. --*/
  964. {
  965. PGENERIC_MAPPING GenericMapping;
  966. ULONG AclLength;
  967. NTSTATUS Status;
  968. ACCESS_MASK AccessMask = GENERIC_ALL;
  969. PACL NewAcl;
  970. //
  971. // Enable access to all the globally defined SIDs
  972. //
  973. GenericMapping = IoGetFileObjectGenericMapping();
  974. RtlMapGenericMask( &AccessMask, GenericMapping );
  975. AclLength = sizeof( ACL ) +
  976. 3 * FIELD_OFFSET (ACCESS_ALLOWED_ACE, SidStart) +
  977. RtlLengthSid( SeExports->SeAliasAdminsSid ) +
  978. RtlLengthSid( SeExports->SeLocalSystemSid ) +
  979. RtlLengthSid( SeExports->SeNetworkServiceSid );
  980. NewAcl = AFD_ALLOCATE_POOL_PRIORITY (
  981. PagedPool,
  982. AclLength,
  983. AFD_SECURITY_POOL_TAG,
  984. HighPoolPriority
  985. );
  986. if (NewAcl == NULL) {
  987. return( STATUS_INSUFFICIENT_RESOURCES );
  988. }
  989. Status = RtlCreateAcl (NewAcl, AclLength, ACL_REVISION );
  990. if (!NT_SUCCESS( Status )) {
  991. AFD_FREE_POOL(
  992. NewAcl,
  993. AFD_SECURITY_POOL_TAG
  994. );
  995. return( Status );
  996. }
  997. Status = RtlAddAccessAllowedAce (
  998. NewAcl,
  999. ACL_REVISION2,
  1000. AccessMask,
  1001. SeExports->SeAliasAdminsSid
  1002. );
  1003. ASSERT( NT_SUCCESS( Status ));
  1004. Status = RtlAddAccessAllowedAce (
  1005. NewAcl,
  1006. ACL_REVISION2,
  1007. AccessMask,
  1008. SeExports->SeLocalSystemSid
  1009. );
  1010. ASSERT( NT_SUCCESS( Status ));
  1011. Status = RtlAddAccessAllowedAce (
  1012. NewAcl,
  1013. ACL_REVISION2,
  1014. AccessMask,
  1015. SeExports->SeNetworkServiceSid
  1016. );
  1017. ASSERT( NT_SUCCESS( Status ));
  1018. *DeviceAcl = NewAcl;
  1019. return( STATUS_SUCCESS );
  1020. } // AfdBuildDeviceAcl
  1021. NTSTATUS
  1022. AfdCreateSecurityDescriptor(
  1023. VOID
  1024. )
  1025. /*++
  1026. Routine Description:
  1027. This routine creates a security descriptor which gives access
  1028. only to certain priviliged accounts. This descriptor is used
  1029. to access check raw endpoint opens and exclisive access to transport
  1030. addresses.
  1031. Arguments:
  1032. None.
  1033. Return Value:
  1034. STATUS_SUCCESS or an appropriate error code.
  1035. --*/
  1036. {
  1037. PACL devAcl = NULL;
  1038. NTSTATUS status;
  1039. BOOLEAN memoryAllocated = FALSE;
  1040. PSECURITY_DESCRIPTOR afdSecurityDescriptor;
  1041. ULONG afdSecurityDescriptorLength;
  1042. CHAR buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
  1043. PSECURITY_DESCRIPTOR localSecurityDescriptor =
  1044. (PSECURITY_DESCRIPTOR)buffer;
  1045. PSECURITY_DESCRIPTOR localAfdAdminSecurityDescriptor;
  1046. SECURITY_INFORMATION securityInformation = DACL_SECURITY_INFORMATION;
  1047. //
  1048. // Get a pointer to the security descriptor from the AFD device object.
  1049. //
  1050. status = ObGetObjectSecurity(
  1051. AfdDeviceObject,
  1052. &afdSecurityDescriptor,
  1053. &memoryAllocated
  1054. );
  1055. if (!NT_SUCCESS(status)) {
  1056. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_ERROR_LEVEL,
  1057. "AFD: Unable to get security descriptor, error: %x\n",
  1058. status
  1059. ));
  1060. ASSERT(memoryAllocated == FALSE);
  1061. return(status);
  1062. }
  1063. //
  1064. // Build a local security descriptor with an ACL giving only
  1065. // certain priviliged accounts.
  1066. //
  1067. status = AfdBuildDeviceAcl(&devAcl);
  1068. if (!NT_SUCCESS(status)) {
  1069. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_ERROR_LEVEL,
  1070. "AFD: Unable to create Raw ACL, error: %x\n", status));
  1071. goto error_exit;
  1072. }
  1073. (VOID) RtlCreateSecurityDescriptor(
  1074. localSecurityDescriptor,
  1075. SECURITY_DESCRIPTOR_REVISION
  1076. );
  1077. (VOID) RtlSetDaclSecurityDescriptor(
  1078. localSecurityDescriptor,
  1079. TRUE,
  1080. devAcl,
  1081. FALSE
  1082. );
  1083. //
  1084. // Make a copy of the AFD descriptor. This copy will be the raw descriptor.
  1085. //
  1086. afdSecurityDescriptorLength = RtlLengthSecurityDescriptor(
  1087. afdSecurityDescriptor
  1088. );
  1089. localAfdAdminSecurityDescriptor = ExAllocatePoolWithTag (
  1090. PagedPool,
  1091. afdSecurityDescriptorLength,
  1092. AFD_SECURITY_POOL_TAG
  1093. );
  1094. if (localAfdAdminSecurityDescriptor == NULL) {
  1095. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_ERROR_LEVEL,
  1096. "AFD: couldn't allocate security descriptor\n"));
  1097. goto error_exit;
  1098. }
  1099. RtlMoveMemory(
  1100. localAfdAdminSecurityDescriptor,
  1101. afdSecurityDescriptor,
  1102. afdSecurityDescriptorLength
  1103. );
  1104. AfdAdminSecurityDescriptor = localAfdAdminSecurityDescriptor;
  1105. //
  1106. // Now apply the local descriptor to the raw descriptor.
  1107. //
  1108. status = SeSetSecurityDescriptorInfo(
  1109. NULL,
  1110. &securityInformation,
  1111. localSecurityDescriptor,
  1112. &AfdAdminSecurityDescriptor,
  1113. PagedPool,
  1114. IoGetFileObjectGenericMapping()
  1115. );
  1116. if (!NT_SUCCESS(status)) {
  1117. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_ERROR_LEVEL,
  1118. "AFD: SeSetSecurity failed, %lx\n",
  1119. status));
  1120. ASSERT (AfdAdminSecurityDescriptor==localAfdAdminSecurityDescriptor);
  1121. ExFreePool (AfdAdminSecurityDescriptor);
  1122. AfdAdminSecurityDescriptor = NULL;
  1123. goto error_exit;
  1124. }
  1125. if (AfdAdminSecurityDescriptor!=localAfdAdminSecurityDescriptor) {
  1126. ExFreePool (localAfdAdminSecurityDescriptor);
  1127. }
  1128. status = STATUS_SUCCESS;
  1129. error_exit:
  1130. ObReleaseObjectSecurity(
  1131. afdSecurityDescriptor,
  1132. memoryAllocated
  1133. );
  1134. if (devAcl!=NULL) {
  1135. AFD_FREE_POOL(
  1136. devAcl,
  1137. AFD_SECURITY_POOL_TAG
  1138. );
  1139. }
  1140. return(status);
  1141. }
  1142. VOID
  1143. AfdReadVolatileParameters (
  1144. PVOID Parameter
  1145. )
  1146. {
  1147. UNREFERENCED_PARAMETER (Parameter);
  1148. PAGED_CODE ();
  1149. ExAcquireResourceExclusiveLite( AfdResource, TRUE );
  1150. if (AfdParametersNotifyHandle!=NULL) {
  1151. ULONG i;
  1152. NTSTATUS status;
  1153. status = ZwNotifyChangeKey (
  1154. AfdParametersNotifyHandle,
  1155. NULL,
  1156. (PIO_APC_ROUTINE)(ULONG_PTR)&AfdParametersNotifyWorker,
  1157. (PVOID)(UINT_PTR)(unsigned int)DelayedWorkQueue,
  1158. &AfdDontCareIoStatus,
  1159. REG_NOTIFY_CHANGE_LAST_SET,
  1160. FALSE,
  1161. NULL, 0,
  1162. TRUE);
  1163. if (NT_SUCCESS (status)) {
  1164. for ( i = 0; i < AFD_VOLATILE_CONFIG_VAR_COUNT; i++ ) {
  1165. *AfdVolatileConfigInfo[i].Variable =
  1166. AfdReadSingleParameter(
  1167. AfdParametersNotifyHandle,
  1168. AfdVolatileConfigInfo[i].RegistryValueName,
  1169. *AfdVolatileConfigInfo[i].Variable
  1170. );
  1171. }
  1172. }
  1173. else {
  1174. DbgPrint (
  1175. "AFD: Failed to start notification for volatile parameter changes, status: %lx\n",
  1176. status);
  1177. ZwClose (AfdParametersNotifyHandle);
  1178. AfdParametersNotifyHandle = NULL;
  1179. }
  1180. }
  1181. else {
  1182. ASSERT (AfdParametersUnloadEvent!=NULL);
  1183. IoQueueWorkItem (AfdWorkQueueItem,
  1184. AfdReleaseRegistryHandleWait,
  1185. DelayedWorkQueue,
  1186. NULL);
  1187. }
  1188. ExReleaseResourceLite( AfdResource );
  1189. }
  1190. VOID
  1191. AfdReleaseRegistryHandleWait (
  1192. IN PDEVICE_OBJECT DeviceObject,
  1193. IN PVOID Context
  1194. )
  1195. {
  1196. UNREFERENCED_PARAMETER (DeviceObject);
  1197. UNREFERENCED_PARAMETER (Context);
  1198. ASSERT (AfdParametersUnloadEvent!=NULL);
  1199. KeSetEvent (AfdParametersUnloadEvent, AfdPriorityBoost, FALSE);
  1200. }