Source code of Windows XP (NT5)
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.

1954 lines
49 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. init.cxx
  5. Abstract:
  6. This module performs initialization for the UL device driver.
  7. Author:
  8. Keith Moore (keithmo) 10-Jun-1998
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. //
  13. // Private constants.
  14. //
  15. #define DEFAULT_THREAD_AFFINITY_MASK ((1ui64 << KeNumberProcessors) - 1)
  16. //
  17. // Private types.
  18. //
  19. typedef struct _SID_MASK_PAIR
  20. {
  21. PSID pSid;
  22. ACCESS_MASK AccessMask;
  23. } SID_MASK_PAIR, *PSID_MASK_PAIR;
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif // __cplusplus
  27. //
  28. // Private prototypes.
  29. //
  30. NTSTATUS
  31. UlpApplySecurityToDeviceObjects(
  32. VOID
  33. );
  34. NTSTATUS
  35. UlpCreateSecurityDescriptor(
  36. OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
  37. IN PSID_MASK_PAIR pSidMaskPairs,
  38. IN ULONG NumSidMaskPairs
  39. );
  40. VOID
  41. UlpCleanupSecurityDescriptor(
  42. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  43. );
  44. NTSTATUS
  45. UlpSetDeviceObjectSecurity(
  46. IN PDEVICE_OBJECT pDeviceObject,
  47. IN SECURITY_INFORMATION SecurityInformation,
  48. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  49. );
  50. VOID
  51. UlpReadRegistry (
  52. IN PUL_CONFIG pConfig
  53. );
  54. VOID
  55. UlpTerminateModules(
  56. VOID
  57. );
  58. #if ALLOW_UNLOAD
  59. VOID
  60. UlpUnload (
  61. IN PDRIVER_OBJECT DriverObject
  62. );
  63. #endif // ALLOW_UNLOAD
  64. #ifdef __cplusplus
  65. }; // extern "C"
  66. #endif // __cplusplus
  67. //
  68. // Private globals.
  69. //
  70. #if DBG
  71. ULONG g_UlpForceInitFailure = 0;
  72. #endif // DBG
  73. #ifdef ALLOC_PRAGMA
  74. #pragma alloc_text( INIT, DriverEntry )
  75. #pragma alloc_text( INIT, UlpApplySecurityToDeviceObjects )
  76. #pragma alloc_text( INIT, UlpCreateSecurityDescriptor )
  77. #pragma alloc_text( INIT, UlpCleanupSecurityDescriptor )
  78. #pragma alloc_text( INIT, UlpSetDeviceObjectSecurity )
  79. #pragma alloc_text( INIT, UlpReadRegistry )
  80. #if ALLOW_UNLOAD
  81. #pragma alloc_text( PAGE, UlpUnload )
  82. #pragma alloc_text( PAGE, UlpTerminateModules )
  83. #endif // ALLOW_UNLOAD
  84. //
  85. // Note that UlpTerminateModules() must be "page" if driver unloading
  86. // is enabled (it's called from UlpUnload), but can be "init" otherwise
  87. // (it's only called after initialization failure).
  88. //
  89. #if ALLOW_UNLOAD
  90. #pragma alloc_text( PAGE, UlpTerminateModules )
  91. #else
  92. #pragma alloc_text( INIT, UlpTerminateModules )
  93. #endif // ALLOW_UNLOAD
  94. #endif // ALLOC_PRAGMA
  95. //
  96. // Public functions.
  97. //
  98. /***************************************************************************++
  99. Routine Description:
  100. This is the initialization routine for the UL device driver.
  101. Arguments:
  102. DriverObject - Supplies a pointer to driver object created by the
  103. system.
  104. RegistryPath - Supplies the name of the driver's configuration
  105. registry tree.
  106. Return Value:
  107. NTSTATUS - Completion status.
  108. --***************************************************************************/
  109. NTSTATUS
  110. DriverEntry(
  111. IN PDRIVER_OBJECT DriverObject,
  112. IN PUNICODE_STRING RegistryPath
  113. )
  114. {
  115. NTSTATUS status;
  116. UNICODE_STRING deviceName;
  117. OBJECT_ATTRIBUTES objectAttributes;
  118. CLONG i;
  119. UL_CONFIG config;
  120. //
  121. // Sanity check.
  122. //
  123. PAGED_CODE();
  124. //
  125. // Grab the number of processors in the system.
  126. //
  127. g_UlNumberOfProcessors = KeNumberProcessors;
  128. g_UlThreadAffinityMask = DEFAULT_THREAD_AFFINITY_MASK;
  129. //
  130. // Grab the largest cache line size in the system
  131. //
  132. g_UlCacheLineSize = KeGetRecommendedSharedDataAlignment();
  133. for (g_UlCacheLineBits = 0;
  134. (1U << g_UlCacheLineBits) < g_UlCacheLineSize;
  135. ++g_UlCacheLineBits)
  136. {}
  137. ASSERT(g_UlCacheLineSize <= (1U << g_UlCacheLineBits));
  138. //
  139. // Snag a pointer to the system process.
  140. //
  141. g_pUlSystemProcess = (PKPROCESS)IoGetCurrentProcess();
  142. //
  143. // Read registry information.
  144. //
  145. UlpReadRegistry( &config );
  146. #if DBG
  147. //
  148. // Give anyone using the kernel debugger a chance to abort
  149. // initialization.
  150. //
  151. if (g_UlpForceInitFailure != 0)
  152. {
  153. status = STATUS_UNSUCCESSFUL;
  154. goto fatal;
  155. }
  156. #endif // DBG
  157. //
  158. // Initialize the global trace logs.
  159. //
  160. UlInitializeOwnerRefTraceLog();
  161. CREATE_REF_TRACE_LOG( g_pMondoGlobalTraceLog, 16384 - REF_TRACE_OVERHEAD, 0 );
  162. CREATE_REF_TRACE_LOG( g_pTdiTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
  163. CREATE_REF_TRACE_LOG( g_pHttpRequestTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  164. CREATE_REF_TRACE_LOG( g_pHttpConnectionTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  165. CREATE_REF_TRACE_LOG( g_pHttpResponseTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  166. CREATE_REF_TRACE_LOG( g_pAppPoolTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  167. CREATE_REF_TRACE_LOG( g_pConfigGroupTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  168. CREATE_REF_TRACE_LOG( g_pThreadTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  169. CREATE_REF_TRACE_LOG( g_pMdlTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  170. CREATE_REF_TRACE_LOG( g_pFilterTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  171. CREATE_IRP_TRACE_LOG( g_pIrpTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
  172. CREATE_TIME_TRACE_LOG( g_pTimeTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
  173. CREATE_REPLENISH_TRACE_LOG( g_pReplenishTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
  174. CREATE_FILTQ_TRACE_LOG( g_pFilterQueueTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  175. CREATE_REF_TRACE_LOG( g_pSiteCounterTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  176. CREATE_REF_TRACE_LOG( g_pConnectionCountTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  177. CREATE_REF_TRACE_LOG( g_pConfigGroupInfoTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  178. CREATE_REF_TRACE_LOG( g_pChunkTrackerTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
  179. CREATE_REF_TRACE_LOG( g_pWorkItemTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
  180. //
  181. // Create an object directory to contain our device objects.
  182. //
  183. RtlInitUnicodeString( &deviceName, HTTP_DIRECTORY_NAME );
  184. InitializeObjectAttributes(
  185. &objectAttributes, // ObjectAttributes
  186. &deviceName, // ObjectName
  187. OBJ_CASE_INSENSITIVE | // Attributes
  188. UL_KERNEL_HANDLE,
  189. NULL, // RootDirectory
  190. NULL // SecurityDescriptor
  191. );
  192. UlAttachToSystemProcess();
  193. status = ZwCreateDirectoryObject(
  194. &g_UlDirectoryObject, // DirectoryHandle
  195. DIRECTORY_ALL_ACCESS, // AccessMask
  196. &objectAttributes // ObjectAttributes
  197. );
  198. UlDetachFromSystemProcess();
  199. if (!NT_SUCCESS(status))
  200. {
  201. goto fatal;
  202. }
  203. //
  204. // Create the control channel device object.
  205. //
  206. RtlInitUnicodeString( &deviceName, HTTP_CONTROL_DEVICE_NAME );
  207. status = IoCreateDevice(
  208. DriverObject, // DriverObject
  209. 0, // DeviceExtension
  210. &deviceName, // DeviceName
  211. FILE_DEVICE_NETWORK, // DeviceType
  212. 0, // DeviceCharacteristics
  213. TRUE, // Exclusive
  214. &g_pUlControlDeviceObject // DeviceObject
  215. );
  216. if (!NT_SUCCESS(status))
  217. {
  218. goto fatal;
  219. }
  220. //
  221. // Create the filter device object.
  222. //
  223. RtlInitUnicodeString( &deviceName, HTTP_FILTER_DEVICE_NAME );
  224. status = IoCreateDevice(
  225. DriverObject, // DriverObject
  226. 0, // DeviceExtension
  227. &deviceName, // DeviceName
  228. FILE_DEVICE_NETWORK, // DeviceType
  229. 0, // DeviceCharacteristics
  230. FALSE, // Exclusive
  231. &g_pUlFilterDeviceObject // DeviceObject
  232. );
  233. if (!NT_SUCCESS(status))
  234. {
  235. goto fatal;
  236. }
  237. g_pUlFilterDeviceObject->StackSize = g_UlIrpStackSize;
  238. //
  239. // Create the app pool device object.
  240. //
  241. RtlInitUnicodeString( &deviceName, HTTP_APP_POOL_DEVICE_NAME );
  242. status = IoCreateDevice(
  243. DriverObject, // DriverObject
  244. 0, // DeviceExtension
  245. &deviceName, // DeviceName
  246. FILE_DEVICE_NETWORK, // DeviceType
  247. 0, // DeviceCharacteristics
  248. FALSE, // Exclusive
  249. &g_pUlAppPoolDeviceObject // DeviceObject
  250. );
  251. if (!NT_SUCCESS(status))
  252. {
  253. goto fatal;
  254. }
  255. g_pUlAppPoolDeviceObject->StackSize = g_UlIrpStackSize;
  256. //
  257. // If so requested, apply security to the device objects.
  258. //
  259. // CODEWORK: REMOVE THIS CONFIGURATION PARAMETER!
  260. //
  261. if (config.EnableSecurity)
  262. {
  263. status = UlpApplySecurityToDeviceObjects();
  264. if (!NT_SUCCESS(status))
  265. {
  266. goto fatal;
  267. }
  268. }
  269. else
  270. {
  271. KdPrint(( "UL: security disabled\n" ));
  272. }
  273. //
  274. // Initialize the driver object with this driver's entrypoints.
  275. //
  276. DriverObject->MajorFunction[IRP_MJ_CREATE] = &UlCreate;
  277. DriverObject->MajorFunction[IRP_MJ_CLOSE] = &UlClose;
  278. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = &UlCleanup;
  279. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &UlDeviceControl;
  280. DriverObject->FastIoDispatch = &UlFastIoDispatch;
  281. DriverObject->DriverUnload = NULL;
  282. #if ALLOW_UNLOAD
  283. if( config.EnableUnload )
  284. {
  285. KdPrint(( "UL: DriverUnload enabled\n" ));
  286. DriverObject->DriverUnload = &UlpUnload;
  287. }
  288. #endif // ALLOW_UNLOAD
  289. //
  290. // Initialize global data.
  291. //
  292. status = UlInitializeData(&config);
  293. if (!NT_SUCCESS(status))
  294. {
  295. goto fatal;
  296. }
  297. //
  298. // Create the thread pool.
  299. //
  300. status = UlInitializeThreadPool(config.ThreadsPerCpu);
  301. if (!NT_SUCCESS(status))
  302. {
  303. goto fatal;
  304. }
  305. //
  306. // Initialize common TDI.
  307. //
  308. status = UxInitializeTdi();
  309. if (!NT_SUCCESS(status))
  310. {
  311. goto fatal;
  312. }
  313. //
  314. // Initialize server connection code.
  315. //
  316. status = UlInitializeTdi();
  317. if (!NT_SUCCESS(status))
  318. {
  319. goto fatal;
  320. }
  321. //
  322. // Initialize temporary test code.
  323. //
  324. // status = UlInitializeTdiTest();
  325. // if (!NT_SUCCESS(status))
  326. // {
  327. // goto fatal;
  328. // }
  329. //
  330. // Initialize George.
  331. //
  332. status = UlLargeMemInitialize(&config);
  333. ASSERT( NT_SUCCESS(status) );
  334. //
  335. // Initialize Keith.
  336. //
  337. status = UlInitializeControlChannel();
  338. ASSERT( NT_SUCCESS(status) );
  339. //
  340. // Initialize Henry.
  341. //
  342. status = InitializeHttpUtil();
  343. ASSERT( NT_SUCCESS(status) );
  344. status = InitializeParser();
  345. ASSERT( NT_SUCCESS(status) );
  346. status = UlInitializeOpaqueIdTable();
  347. ASSERT( NT_SUCCESS(status) );
  348. status = InitializeFileCache();
  349. ASSERT( NT_SUCCESS(status) );
  350. //
  351. // Initialize Michael.
  352. //
  353. status = UlInitializeFilterChannel();
  354. ASSERT( NT_SUCCESS(status) );
  355. //
  356. // Initialize Alex.
  357. //
  358. status = UlInitializeUriCache(&config);
  359. if ( !NT_SUCCESS(status) )
  360. {
  361. goto fatal;
  362. }
  363. status = UlInitializeDateCache();
  364. ASSERT( NT_SUCCESS(status) );
  365. //
  366. // Initialize Paul.
  367. //
  368. status = UlInitializeCG();
  369. ASSERT( NT_SUCCESS(status) );
  370. status = UlInitializeAP();
  371. ASSERT( NT_SUCCESS(status) );
  372. //
  373. // Initialize Ali
  374. //
  375. status = UlInitializeLogs();
  376. ASSERT( NT_SUCCESS(status) );
  377. // TC Init may fail if PSched
  378. // is not installed.
  379. UlTcInitialize();
  380. #if 0
  381. status = UlTcInitialize();
  382. ASSERT( NT_SUCCESS(status));
  383. #endif
  384. status = UlInitGlobalConnectionLimits();
  385. ASSERT( NT_SUCCESS(status) );
  386. //
  387. // Initialize Eric.
  388. //
  389. status = UlInitializeHttpRcv();
  390. ASSERT( NT_SUCCESS(status) );
  391. status = UlInitializeCounters();
  392. ASSERT( NT_SUCCESS(status) );
  393. UlInitializeTimeoutMonitor();
  394. #if DBG
  395. //
  396. // Give anyone using the kernel debugger one final chance to abort
  397. // initialization.
  398. //
  399. if (g_UlpForceInitFailure != 0)
  400. {
  401. status = STATUS_UNSUCCESSFUL;
  402. goto fatal;
  403. }
  404. #endif // DBG
  405. return STATUS_SUCCESS;
  406. //
  407. // Fatal error handlers.
  408. //
  409. fatal:
  410. UlpTerminateModules();
  411. ASSERT( !NT_SUCCESS(status) );
  412. return status;
  413. } // DriverEntry
  414. //
  415. // Private functions.
  416. //
  417. /***************************************************************************++
  418. Routine Description:
  419. Applies the appropriate security descriptors to the global device
  420. objects created at initialization time.
  421. Return Value:
  422. NTSTATUS - Completion status.
  423. --***************************************************************************/
  424. NTSTATUS
  425. UlpApplySecurityToDeviceObjects(
  426. VOID
  427. )
  428. {
  429. NTSTATUS status;
  430. SECURITY_DESCRIPTOR securityDescriptor;
  431. PGENERIC_MAPPING pFileObjectGenericMapping;
  432. ACCESS_MASK fileRead;
  433. ACCESS_MASK fileAll;
  434. HANDLE handle;
  435. SID_MASK_PAIR sidMaskPairs[3];
  436. //
  437. // Sanity check.
  438. //
  439. PAGED_CODE();
  440. ASSERT( IS_VALID_DEVICE_OBJECT( g_pUlControlDeviceObject ) );
  441. ASSERT( IS_VALID_DEVICE_OBJECT( g_pUlFilterDeviceObject ) );
  442. ASSERT( IS_VALID_DEVICE_OBJECT( g_pUlAppPoolDeviceObject ) );
  443. //
  444. // Gain access to the predefined SIDs and other security-related
  445. // goodies exported by the kernel.
  446. //
  447. //SeEnableAccessToExports();
  448. //
  449. // Map a couple of generic file access types to their corresponding
  450. // object-specific rights.
  451. //
  452. pFileObjectGenericMapping = IoGetFileObjectGenericMapping();
  453. ASSERT( pFileObjectGenericMapping != NULL );
  454. fileRead = GENERIC_READ;
  455. RtlMapGenericMask(
  456. &fileRead,
  457. pFileObjectGenericMapping
  458. );
  459. fileAll = GENERIC_ALL;
  460. RtlMapGenericMask(
  461. &fileAll,
  462. pFileObjectGenericMapping
  463. );
  464. //
  465. // Build a restrictive security descriptor for the control device
  466. // object:
  467. //
  468. // Full access for NT AUTHORITY\SYSTEM
  469. // Full access for BUILTIN\Administrators
  470. //
  471. sidMaskPairs[0].pSid = SeExports->SeLocalSystemSid;
  472. sidMaskPairs[0].AccessMask = fileAll;
  473. sidMaskPairs[1].pSid = SeExports->SeAliasAdminsSid;
  474. sidMaskPairs[1].AccessMask = fileAll;
  475. status = UlpCreateSecurityDescriptor(
  476. &securityDescriptor, // pSecurityDescriptor
  477. &sidMaskPairs[0], // pSidMaskPairs
  478. 2 // NumSidMaskPairs
  479. );
  480. if (!NT_SUCCESS(status))
  481. {
  482. goto complete;
  483. }
  484. status = UlpSetDeviceObjectSecurity(
  485. g_pUlControlDeviceObject,
  486. DACL_SECURITY_INFORMATION,
  487. &securityDescriptor
  488. );
  489. UlpCleanupSecurityDescriptor( &securityDescriptor );
  490. if (!NT_SUCCESS(status))
  491. {
  492. goto complete;
  493. }
  494. //
  495. // Build a restrictive security descriptor for the filter device
  496. // object:
  497. //
  498. // Full access for NT AUTHORITY\SYSTEM
  499. // Full access for BUILTIN\Administrators
  500. //
  501. sidMaskPairs[0].pSid = SeExports->SeLocalSystemSid;
  502. sidMaskPairs[0].AccessMask = fileAll;
  503. sidMaskPairs[1].pSid = SeExports->SeAliasAdminsSid;
  504. sidMaskPairs[1].AccessMask = fileAll;
  505. status = UlpCreateSecurityDescriptor(
  506. &securityDescriptor, // pSecurityDescriptor
  507. &sidMaskPairs[0], // pSidMaskPairs
  508. 2 // NumSidMaskPairs
  509. );
  510. if (!NT_SUCCESS(status))
  511. {
  512. goto complete;
  513. }
  514. status = UlpSetDeviceObjectSecurity(
  515. g_pUlFilterDeviceObject,
  516. DACL_SECURITY_INFORMATION,
  517. &securityDescriptor
  518. );
  519. UlpCleanupSecurityDescriptor( &securityDescriptor );
  520. if (!NT_SUCCESS(status))
  521. {
  522. goto complete;
  523. }
  524. //
  525. // Build a slightly less restrictive security descriptor for the
  526. // app pool device object:
  527. //
  528. // Full access for NT AUTHORITY\SYSTEM
  529. // Full access for BUILTIN\Administrators
  530. // Read access for Everyone
  531. //
  532. sidMaskPairs[0].pSid = SeExports->SeLocalSystemSid;
  533. sidMaskPairs[0].AccessMask = fileAll;
  534. sidMaskPairs[1].pSid = SeExports->SeAliasAdminsSid;
  535. sidMaskPairs[1].AccessMask = fileAll;
  536. sidMaskPairs[2].pSid = SeExports->SeWorldSid;
  537. sidMaskPairs[2].AccessMask = fileRead;
  538. status = UlpCreateSecurityDescriptor(
  539. &securityDescriptor, // pSecurityDescriptor
  540. &sidMaskPairs[0], // pSidMaskPairs
  541. 3 // NumSidMaskPairs
  542. );
  543. if (!NT_SUCCESS(status))
  544. {
  545. goto complete;
  546. }
  547. status = UlpSetDeviceObjectSecurity(
  548. g_pUlAppPoolDeviceObject,
  549. DACL_SECURITY_INFORMATION,
  550. &securityDescriptor
  551. );
  552. UlpCleanupSecurityDescriptor( &securityDescriptor );
  553. if (!NT_SUCCESS(status))
  554. {
  555. goto complete;
  556. }
  557. complete:
  558. return status;
  559. } // UlpApplySecurityToDeviceObjects
  560. /***************************************************************************++
  561. Routine Description:
  562. Allocates and initializes a security descriptor with the specified
  563. attributes.
  564. Arguments:
  565. pSecurityDescriptor - Supplies a pointer to the security descriptor
  566. to initialize.
  567. pSidMaskPairs - Supplies an array of SID/ACCESS_MASK pairs.
  568. NumSidMaskPairs - Supplies the number of SID/ACESS_MASK pairs.
  569. Return Value:
  570. NTSTATUS - Completion status.
  571. --***************************************************************************/
  572. NTSTATUS
  573. UlpCreateSecurityDescriptor(
  574. OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
  575. IN PSID_MASK_PAIR pSidMaskPairs,
  576. IN ULONG NumSidMaskPairs
  577. )
  578. {
  579. NTSTATUS status;
  580. PACL pDacl;
  581. ULONG daclLength;
  582. ULONG i;
  583. //
  584. // Sanity check.
  585. //
  586. PAGED_CODE();
  587. ASSERT( pSecurityDescriptor != NULL );
  588. ASSERT( pSidMaskPairs != NULL );
  589. ASSERT( NumSidMaskPairs > 0 );
  590. //
  591. // Setup locals so we know how to cleanup on exit.
  592. //
  593. pDacl = NULL;
  594. //
  595. // Initialize the security descriptor.
  596. //
  597. status = RtlCreateSecurityDescriptor(
  598. pSecurityDescriptor, // SecurityDescriptor
  599. SECURITY_DESCRIPTOR_REVISION // Revision
  600. );
  601. if (!NT_SUCCESS(status))
  602. {
  603. goto cleanup;
  604. }
  605. //
  606. // Calculate the DACL length.
  607. //
  608. daclLength = sizeof(ACL);
  609. for (i = 0 ; i < NumSidMaskPairs ; i++)
  610. {
  611. daclLength += sizeof(ACCESS_ALLOWED_ACE);
  612. daclLength += RtlLengthSid( pSidMaskPairs[i].pSid );
  613. }
  614. //
  615. // Allocate & initialize the DACL.
  616. //
  617. pDacl = (PACL) UL_ALLOCATE_POOL(
  618. PagedPool,
  619. daclLength,
  620. UL_SECURITY_DATA_POOL_TAG
  621. );
  622. if (pDacl == NULL)
  623. {
  624. status = STATUS_INSUFFICIENT_RESOURCES;
  625. goto cleanup;
  626. }
  627. status = RtlCreateAcl(
  628. pDacl, // Acl
  629. daclLength, // AclLength
  630. ACL_REVISION // AclRevision
  631. );
  632. if (!NT_SUCCESS(status))
  633. {
  634. goto cleanup;
  635. }
  636. //
  637. // Add the necessary access-allowed ACEs to the DACL.
  638. //
  639. for (i = 0 ; i < NumSidMaskPairs ; i++)
  640. {
  641. status = RtlAddAccessAllowedAce(
  642. pDacl, // Acl
  643. ACL_REVISION, // AceRevision
  644. pSidMaskPairs[i].AccessMask, // AccessMask
  645. pSidMaskPairs[i].pSid // Sid
  646. );
  647. if (!NT_SUCCESS(status))
  648. {
  649. goto cleanup;
  650. }
  651. }
  652. //
  653. // Attach the DACL to the security descriptor.
  654. //
  655. status = RtlSetDaclSecurityDescriptor(
  656. pSecurityDescriptor, // SecurityDescriptor
  657. TRUE, // DaclPresent
  658. pDacl, // Dacl
  659. FALSE // DaclDefaulted
  660. );
  661. if (!NT_SUCCESS(status))
  662. {
  663. goto cleanup;
  664. }
  665. //
  666. // Success!
  667. //
  668. ASSERT( NT_SUCCESS(status) );
  669. return STATUS_SUCCESS;
  670. cleanup:
  671. ASSERT( !NT_SUCCESS(status) );
  672. if (pDacl != NULL)
  673. {
  674. UL_FREE_POOL(
  675. pDacl,
  676. UL_SECURITY_DATA_POOL_TAG
  677. );
  678. }
  679. return status;
  680. } // UlpCreateSecurityDescriptor
  681. /***************************************************************************++
  682. Routine Description:
  683. Frees any resources associated with the security descriptor created
  684. by UlpCreateSecurityDescriptor().
  685. Arguments:
  686. pSecurityDescriptor - Supplies the security descriptor to cleanup.
  687. --***************************************************************************/
  688. VOID
  689. UlpCleanupSecurityDescriptor(
  690. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  691. )
  692. {
  693. NTSTATUS status;
  694. PACL pDacl;
  695. BOOLEAN daclPresent;
  696. BOOLEAN daclDefaulted;
  697. //
  698. // Sanity check.
  699. //
  700. PAGED_CODE();
  701. ASSERT( RtlValidSecurityDescriptor( pSecurityDescriptor ) );
  702. //
  703. // Try to retrieve the DACL from the security descriptor.
  704. //
  705. status = RtlGetDaclSecurityDescriptor(
  706. pSecurityDescriptor, // SecurityDescriptor
  707. &daclPresent, // DaclPresent
  708. &pDacl, // Dacl
  709. &daclDefaulted // DaclDefaulted
  710. );
  711. if (NT_SUCCESS(status))
  712. {
  713. if (daclPresent && (pDacl != NULL))
  714. {
  715. UL_FREE_POOL(
  716. pDacl,
  717. UL_SECURITY_DATA_POOL_TAG
  718. );
  719. }
  720. }
  721. } // UlpCleanupSecurityDescriptor
  722. /***************************************************************************++
  723. Routine Description:
  724. Applies the specified security descriptor to the specified device
  725. object.
  726. Arguments:
  727. pDeviceObject - Supplies the device object to manipulate.
  728. SecurityInformation - Supplies the level of information to change.
  729. pSecurityDescriptor - Supplies the new security descriptor for the
  730. device object.
  731. Return Value:
  732. NTSTATUS - Completion status.
  733. --***************************************************************************/
  734. NTSTATUS
  735. UlpSetDeviceObjectSecurity(
  736. IN PDEVICE_OBJECT pDeviceObject,
  737. IN SECURITY_INFORMATION SecurityInformation,
  738. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  739. )
  740. {
  741. NTSTATUS status;
  742. HANDLE handle;
  743. //
  744. // Sanity check.
  745. //
  746. PAGED_CODE();
  747. ASSERT( IS_VALID_DEVICE_OBJECT( pDeviceObject ) );
  748. ASSERT( RtlValidSecurityDescriptor( pSecurityDescriptor ) );
  749. //
  750. // Open a handle to the device object.
  751. //
  752. UlAttachToSystemProcess();
  753. status = ObOpenObjectByPointer(
  754. pDeviceObject, // Object
  755. OBJ_CASE_INSENSITIVE | // HandleAttributes
  756. UL_KERNEL_HANDLE,
  757. NULL, // PassedAccessState
  758. MAXIMUM_ALLOWED, // DesiredAccess
  759. NULL, // ObjectType
  760. KernelMode, // AccessMode
  761. &handle // Handle
  762. );
  763. if (NT_SUCCESS(status))
  764. {
  765. status = NtSetSecurityObject(
  766. handle, // Handle
  767. SecurityInformation, // SecurityInformation
  768. pSecurityDescriptor // SecurityDescriptor
  769. );
  770. ZwClose( handle );
  771. }
  772. UlDetachFromSystemProcess();
  773. return status;
  774. } // UlpSetDeviceObjectSecurity
  775. /***************************************************************************++
  776. Routine Description:
  777. Reads the UL section of the registry. Any values contained in the
  778. registry override defaults.
  779. Arguments:
  780. pConfig - Supplies a pointer to a UL_CONFIG structure that receives
  781. init-time configuration parameters. These are basically
  782. parameters that do not need to persist in the driver once
  783. initialization is complete.
  784. --***************************************************************************/
  785. VOID
  786. UlpReadRegistry(
  787. IN PUL_CONFIG pConfig
  788. )
  789. {
  790. HANDLE parametersHandle;
  791. NTSTATUS status;
  792. LONG tmp;
  793. LONGLONG tmp64;
  794. UNICODE_STRING registryPath;
  795. //
  796. // Sanity check.
  797. //
  798. PAGED_CODE();
  799. //
  800. // Establish defaults.
  801. //
  802. pConfig->ThreadsPerCpu = DEFAULT_THREADS_PER_CPU;
  803. pConfig->IrpContextLookasideDepth = DEFAULT_IRP_CONTEXT_LOOKASIDE_DEPTH;
  804. pConfig->ReceiveBufferLookasideDepth = DEFAULT_RCV_BUFFER_LOOKASIDE_DEPTH;
  805. pConfig->ResourceLookasideDepth = DEFAULT_RESOURCE_LOOKASIDE_DEPTH;
  806. pConfig->RequestBufferLookasideDepth = DEFAULT_REQ_BUFFER_LOOKASIDE_DEPTH;
  807. pConfig->InternalRequestLookasideDepth = DEFAULT_INT_REQUEST_LOOKASIDE_DEPTH;
  808. pConfig->ResponseBufferLookasideDepth = DEFAULT_RESP_BUFFER_LOOKASIDE_DEPTH;
  809. pConfig->SendTrackerLookasideDepth = DEFAULT_SEND_TRACKER_LOOKASIDE_DEPTH;
  810. pConfig->LogBufferLookasideDepth = DEFAULT_LOG_BUFFER_LOOKASIDE_DEPTH;
  811. pConfig->EnableUnload = DEFAULT_ENABLE_UNLOAD;
  812. pConfig->EnableSecurity = DEFAULT_ENABLE_SECURITY;
  813. pConfig->UriConfig.EnableCache = DEFAULT_CACHE_ENABLED;
  814. pConfig->UriConfig.MaxCacheUriCount = DEFAULT_MAX_CACHE_URI_COUNT;
  815. pConfig->UriConfig.MaxCacheMegabyteCount = DEFAULT_MAX_CACHE_MEGABYTE_COUNT;
  816. pConfig->UriConfig.MaxUriBytes = DEFAULT_MAX_URI_BYTES;
  817. pConfig->UriConfig.ScavengerPeriod = DEFAULT_CACHE_SCAVENGER_PERIOD;
  818. pConfig->LargeMemMegabytes = DEFAULT_LARGE_MEM_MEGABYTES;
  819. //
  820. // Open the registry.
  821. //
  822. RtlInitUnicodeString( &registryPath, REGISTRY_UL_INFORMATION );
  823. status = UlOpenRegistry( &registryPath, &parametersHandle );
  824. if (status != STATUS_SUCCESS)
  825. {
  826. return;
  827. }
  828. #if DBG
  829. //
  830. // Read the debug flags.
  831. //
  832. g_UlDebug = (ULONG)UlReadLongParameter(
  833. parametersHandle,
  834. REGISTRY_DEBUG_FLAGS,
  835. g_UlDebug
  836. );
  837. //
  838. // Force a breakpoint if so requested.
  839. //
  840. if (UlReadLongParameter(
  841. parametersHandle,
  842. REGISTRY_BREAK_ON_STARTUP,
  843. DEFAULT_BREAK_ON_STARTUP) != 0 )
  844. {
  845. DbgBreakPoint();
  846. }
  847. //
  848. // Read the break-on-error flags.
  849. //
  850. g_UlBreakOnError = (ULONG)UlReadLongParameter(
  851. parametersHandle,
  852. REGISTRY_BREAK_ON_ERROR,
  853. g_UlBreakOnError
  854. );
  855. g_UlVerboseErrors = (ULONG)UlReadLongParameter(
  856. parametersHandle,
  857. REGISTRY_VERBOSE_ERRORS,
  858. g_UlVerboseErrors
  859. );
  860. //
  861. // Break-on-error implies verbose-errors.
  862. //
  863. if (g_UlBreakOnError)
  864. {
  865. g_UlVerboseErrors = TRUE;
  866. }
  867. #endif // DBG
  868. #if ALLOW_UNLOAD
  869. //
  870. // Enable driver unload if requested.
  871. //
  872. pConfig->EnableUnload = UlReadLongParameter(
  873. parametersHandle,
  874. REGISTRY_ENABLE_UNLOAD,
  875. (LONG)pConfig->EnableUnload
  876. ) != 0;
  877. #endif // ALLOW_UNLOAD
  878. //
  879. // Enable driver security if requested.
  880. //
  881. pConfig->EnableSecurity = UlReadLongParameter(
  882. parametersHandle,
  883. REGISTRY_ENABLE_SECURITY,
  884. (LONG)pConfig->EnableSecurity
  885. ) != 0;
  886. //
  887. // Read the stack size and priority boost values from the registry.
  888. //
  889. tmp = UlReadLongParameter(
  890. parametersHandle,
  891. REGISTRY_IRP_STACK_SIZE,
  892. (LONG)g_UlIrpStackSize
  893. );
  894. //
  895. // Enforce reasonable minimum/maximum values for the IRP stack size.
  896. //
  897. if (tmp < 2)
  898. {
  899. tmp = 2;
  900. }
  901. else if (tmp > 64)
  902. {
  903. tmp = 64;
  904. }
  905. g_UlIrpStackSize = (CCHAR)tmp;
  906. tmp = UlReadLongParameter(
  907. parametersHandle,
  908. REGISTRY_PRIORITY_BOOST,
  909. (LONG)g_UlPriorityBoost
  910. );
  911. if (tmp > 16 || tmp <= 0)
  912. {
  913. tmp = DEFAULT_PRIORITY_BOOST;
  914. }
  915. g_UlPriorityBoost = (CCHAR)tmp;
  916. //
  917. // Read the thread pool parameters.
  918. //
  919. tmp = UlReadLongParameter(
  920. parametersHandle,
  921. REGISTRY_THREADS_PER_CPU,
  922. (LONG)pConfig->ThreadsPerCpu
  923. );
  924. if (tmp > 0xFFFF || tmp <= 0)
  925. {
  926. tmp = DEFAULT_THREADS_PER_CPU;
  927. }
  928. pConfig->ThreadsPerCpu = (USHORT)tmp;
  929. //
  930. // Other configuration parameters.
  931. //
  932. tmp = UlReadLongParameter(
  933. parametersHandle,
  934. REGISTRY_MIN_IDLE_CONNECTIONS,
  935. (LONG)g_UlMinIdleConnections
  936. );
  937. if (tmp > 0xFFFF || tmp <= 1)
  938. {
  939. tmp = DEFAULT_MIN_IDLE_CONNECTIONS;
  940. }
  941. g_UlMinIdleConnections = (USHORT)tmp;
  942. tmp = UlReadLongParameter(
  943. parametersHandle,
  944. REGISTRY_MAX_IDLE_CONNECTIONS,
  945. (LONG)g_UlMaxIdleConnections
  946. );
  947. if (tmp > 0xFFFF || tmp <= 0)
  948. {
  949. tmp = DEFAULT_MAX_IDLE_CONNECTIONS;
  950. }
  951. g_UlMaxIdleConnections = (USHORT)tmp;
  952. tmp = UlReadLongParameter(
  953. parametersHandle,
  954. REGISTRY_IRP_CONTEXT_LOOKASIDE_DEPTH,
  955. (LONG)pConfig->IrpContextLookasideDepth
  956. );
  957. if (tmp > 0xFFFF || tmp <= 0)
  958. {
  959. tmp = DEFAULT_IRP_CONTEXT_LOOKASIDE_DEPTH;
  960. }
  961. pConfig->IrpContextLookasideDepth = (USHORT)tmp;
  962. tmp = UlReadLongParameter(
  963. parametersHandle,
  964. REGISTRY_RCV_BUFFER_LOOKASIDE_DEPTH,
  965. (LONG)pConfig->ReceiveBufferLookasideDepth
  966. );
  967. if (tmp > 0xFFFF || tmp <= 0)
  968. {
  969. tmp = DEFAULT_RCV_BUFFER_LOOKASIDE_DEPTH;
  970. }
  971. pConfig->ReceiveBufferLookasideDepth = (USHORT)tmp;
  972. tmp = UlReadLongParameter(
  973. parametersHandle,
  974. REGISTRY_REQ_BUFFER_LOOKASIDE_DEPTH,
  975. (LONG)pConfig->RequestBufferLookasideDepth
  976. );
  977. if (tmp > 0xFFFF || tmp <= 0)
  978. {
  979. tmp = DEFAULT_REQ_BUFFER_LOOKASIDE_DEPTH;
  980. }
  981. pConfig->RequestBufferLookasideDepth = (USHORT)tmp;
  982. tmp = UlReadLongParameter(
  983. parametersHandle,
  984. REGISTRY_INT_REQUEST_LOOKASIDE_DEPTH,
  985. (LONG)pConfig->InternalRequestLookasideDepth
  986. );
  987. if (tmp > 0xFFFF || tmp <= 0)
  988. {
  989. tmp = DEFAULT_INT_REQUEST_LOOKASIDE_DEPTH;
  990. }
  991. pConfig->InternalRequestLookasideDepth = (USHORT)tmp;
  992. tmp = UlReadLongParameter(
  993. parametersHandle,
  994. REGISTRY_RESP_BUFFER_LOOKASIDE_DEPTH,
  995. (LONG)pConfig->ResponseBufferLookasideDepth
  996. );
  997. if (tmp > 0xFFFF || tmp <= 0)
  998. {
  999. tmp = DEFAULT_RESP_BUFFER_LOOKASIDE_DEPTH;
  1000. }
  1001. pConfig->ResponseBufferLookasideDepth = (USHORT)tmp;
  1002. tmp = UlReadLongParameter(
  1003. parametersHandle,
  1004. REGISTRY_SEND_TRACKER_LOOKASIDE_DEPTH,
  1005. (LONG)pConfig->SendTrackerLookasideDepth
  1006. );
  1007. if (tmp > 0xFFFF || tmp <= 0)
  1008. {
  1009. tmp = DEFAULT_SEND_TRACKER_LOOKASIDE_DEPTH;
  1010. }
  1011. pConfig->SendTrackerLookasideDepth = (USHORT)tmp;
  1012. tmp = UlReadLongParameter(
  1013. parametersHandle,
  1014. REGISTRY_LOG_BUFFER_LOOKASIDE_DEPTH,
  1015. (LONG)pConfig->LogBufferLookasideDepth
  1016. );
  1017. if (tmp > 0xFFFF || tmp <= 0)
  1018. {
  1019. tmp = DEFAULT_LOG_BUFFER_LOOKASIDE_DEPTH;
  1020. }
  1021. pConfig->LogBufferLookasideDepth = (USHORT)tmp;
  1022. g_UlEnableConnectionReuse = UlReadLongParameter(
  1023. parametersHandle,
  1024. REGISTRY_ENABLE_CONNECTION_REUSE,
  1025. (LONG)g_UlEnableConnectionReuse
  1026. ) != 0;
  1027. g_UlEnableNagling = UlReadLongParameter(
  1028. parametersHandle,
  1029. REGISTRY_ENABLE_NAGLING,
  1030. (LONG)g_UlEnableNagling
  1031. ) != 0;
  1032. g_UlEnableThreadAffinity = UlReadLongParameter(
  1033. parametersHandle,
  1034. REGISTRY_ENABLE_THREAD_AFFINITY,
  1035. (LONG)g_UlEnableThreadAffinity
  1036. ) != 0;
  1037. tmp64 = UlReadLongLongParameter(
  1038. parametersHandle,
  1039. REGISTRY_THREAD_AFFINITY_MASK,
  1040. g_UlThreadAffinityMask
  1041. );
  1042. if ((ULONGLONG)tmp64 > DEFAULT_THREAD_AFFINITY_MASK
  1043. || (ULONGLONG)tmp64 == 0)
  1044. {
  1045. tmp64 = DEFAULT_THREAD_AFFINITY_MASK;
  1046. }
  1047. g_UlThreadAffinityMask = (ULONGLONG)tmp64;
  1048. tmp = UlReadLongParameter(
  1049. parametersHandle,
  1050. REGISTRY_MAX_WORK_QUEUE_DEPTH,
  1051. (LONG)g_UlMaxWorkQueueDepth
  1052. );
  1053. if (tmp > 0xFFFF || tmp < 0)
  1054. {
  1055. tmp = DEFAULT_MAX_WORK_QUEUE_DEPTH;
  1056. }
  1057. g_UlMaxWorkQueueDepth = (USHORT)tmp;
  1058. tmp = UlReadLongParameter(
  1059. parametersHandle,
  1060. REGISTRY_MIN_WORK_DEQUEUE_DEPTH,
  1061. (LONG)g_UlMinWorkDequeueDepth
  1062. );
  1063. if (tmp > 0xFFFF || tmp < 0)
  1064. {
  1065. tmp = DEFAULT_MIN_WORK_DEQUEUE_DEPTH;
  1066. }
  1067. g_UlMinWorkDequeueDepth = (USHORT)tmp;
  1068. tmp = UlReadLongParameter(
  1069. parametersHandle,
  1070. REGISTRY_OPAQUE_ID_TABLE_SIZE,
  1071. (LONG)g_UlOpaqueIdTableSize
  1072. );
  1073. if (tmp > 0xFFFF || tmp <= 0)
  1074. {
  1075. tmp = DEFAULT_OPAQUE_ID_TABLE_SIZE;
  1076. }
  1077. g_UlOpaqueIdTableSize = tmp;
  1078. //
  1079. // MAX url setting
  1080. //
  1081. tmp = UlReadLongParameter(
  1082. parametersHandle,
  1083. REGISTRY_MAX_URL_LENGTH,
  1084. (LONG)g_UlMaxUrlLength
  1085. );
  1086. if (tmp > 0xFFFF || tmp <= 0)
  1087. {
  1088. tmp = DEFAULT_MAX_URL_LENGTH;
  1089. }
  1090. g_UlMaxUrlLength = (USHORT)tmp;
  1091. //
  1092. // MAX allowed field length in HTTP requests
  1093. //
  1094. tmp = UlReadLongParameter(
  1095. parametersHandle,
  1096. REGISTRY_MAX_FIELD_LENGTH,
  1097. (LONG)g_UlMaxFieldLength
  1098. );
  1099. if (tmp > 0xFFFFFF || tmp <= 0)
  1100. {
  1101. tmp = DEFAULT_MAX_FIELD_LENGTH;
  1102. }
  1103. g_UlMaxFieldLength = tmp;
  1104. //
  1105. // If defined this will overwrite the default
  1106. // log timer cycle period of 1 hour and make
  1107. // the testing of the log recycling easier.
  1108. // The value is interpreted in seconds.
  1109. //
  1110. tmp = UlReadLongParameter(
  1111. parametersHandle,
  1112. REGISTRY_DEBUG_LOGTIMER_CYCLE,
  1113. (LONG)g_UlDebugLogTimerCycle
  1114. );
  1115. if (tmp > 0xFFFF || tmp <= 0)
  1116. {
  1117. tmp = DEFAULT_DEBUG_LOGTIMER_CYCLE;
  1118. }
  1119. g_UlDebugLogTimerCycle = (USHORT)tmp;
  1120. tmp = UlReadLongParameter(
  1121. parametersHandle,
  1122. REGISTRY_DEBUG_LOG_BUFFER_PERIOD,
  1123. (LONG)g_UlDebugLogBufferPeriod
  1124. );
  1125. if (tmp > 0xFFFF || tmp <= 0)
  1126. {
  1127. tmp = DEFAULT_DEBUG_LOG_BUFFER_PERIOD;
  1128. }
  1129. g_UlDebugLogBufferPeriod = (USHORT)tmp;
  1130. tmp = UlReadLongParameter(
  1131. parametersHandle,
  1132. REGISTRY_LOG_BUFFER_SIZE,
  1133. (LONG)g_UlLogBufferSize
  1134. );
  1135. if (tmp > MAXIMUM_ALLOWED_LOG_BUFFER_SIZE
  1136. || tmp < MINIMUM_ALLOWED_LOG_BUFFER_SIZE )
  1137. {
  1138. // Basically this value will be discarted by the logging code
  1139. // instead systems granularity size (64K) will be used.
  1140. tmp = DEFAULT_LOG_BUFFER_SIZE;
  1141. }
  1142. tmp -= tmp % 4096; // Align down to 4k
  1143. g_UlLogBufferSize = (ULONG) tmp;
  1144. //
  1145. // read the resource lookaside config
  1146. //
  1147. tmp = UlReadLongParameter(
  1148. parametersHandle,
  1149. REGISTRY_RESOURCE_LOOKASIDE_DEPTH,
  1150. (LONG)pConfig->ResourceLookasideDepth
  1151. );
  1152. if (tmp > 0xFFFF || tmp <= 0)
  1153. {
  1154. tmp = DEFAULT_RESOURCE_LOOKASIDE_DEPTH;
  1155. }
  1156. pConfig->ResourceLookasideDepth = (USHORT)tmp;
  1157. tmp = UlReadLongParameter(
  1158. parametersHandle,
  1159. REGISTRY_MAX_REQUEST_BYTES,
  1160. g_UlMaxRequestBytes
  1161. );
  1162. if (tmp > 0xFFFFFF || tmp <= 0)
  1163. {
  1164. tmp = DEFAULT_MAX_REQUEST_BYTES;
  1165. }
  1166. g_UlMaxRequestBytes = ALIGN_DOWN( tmp, PVOID );
  1167. tmp = UlReadLongParameter(
  1168. parametersHandle,
  1169. REGISTRY_RCV_BUFFER_SIZE,
  1170. g_UlReceiveBufferSize
  1171. );
  1172. if (tmp > 0xFFFFFF || tmp <= 0)
  1173. {
  1174. tmp = DEFAULT_RCV_BUFFER_SIZE;
  1175. }
  1176. g_UlReceiveBufferSize = ALIGN_DOWN( tmp, PVOID );
  1177. tmp = UlReadLongParameter(
  1178. parametersHandle,
  1179. REGISTRY_RESP_BUFFER_SIZE,
  1180. g_UlResponseBufferSize
  1181. );
  1182. if (tmp > 0xFFFFFF || tmp <= 0)
  1183. {
  1184. tmp = DEFAULT_RESP_BUFFER_SIZE;
  1185. }
  1186. g_UlResponseBufferSize = ALIGN_DOWN( tmp, PVOID );
  1187. //
  1188. // Read URL processing parameters.
  1189. // BUGBUG: read legacy IIS value?
  1190. //
  1191. g_UlEnableNonUTF8 = UlReadLongParameter(
  1192. parametersHandle,
  1193. REGISTRY_ENABLE_NON_UTF8_URL,
  1194. DEFAULT_ENABLE_NON_UTF8_URL
  1195. ) != 0;
  1196. if (g_UlEnableNonUTF8)
  1197. {
  1198. g_UlEnableDBCS = UlReadLongParameter(
  1199. parametersHandle,
  1200. REGISTRY_ENABLE_DBCS_URL,
  1201. DEFAULT_ENABLE_DBCS_URL
  1202. ) != 0;
  1203. }
  1204. else
  1205. {
  1206. //
  1207. // We can't do DBCS if we only accept UTF-8.
  1208. //
  1209. g_UlEnableDBCS = FALSE;
  1210. }
  1211. if (g_UlEnableDBCS)
  1212. {
  1213. g_UlFavorDBCS = UlReadLongParameter(
  1214. parametersHandle,
  1215. REGISTRY_FAVOR_DBCS_URL,
  1216. DEFAULT_FAVOR_DBCS_URL
  1217. ) != 0;
  1218. }
  1219. else
  1220. {
  1221. //
  1222. // We can't favor DBCS if we don't allow DBCS.
  1223. //
  1224. g_UlFavorDBCS = FALSE;
  1225. }
  1226. tmp = UlReadLongParameter(
  1227. parametersHandle,
  1228. REGISTRY_MAX_INTERNAL_URL_LENGTH,
  1229. g_UlMaxInternalUrlLength
  1230. );
  1231. if (tmp > 0xFFFFFF || tmp <= 0)
  1232. {
  1233. tmp = DEFAULT_MAX_INTERNAL_URL_LENGTH;
  1234. }
  1235. g_UlMaxInternalUrlLength = (USHORT)tmp;
  1236. //
  1237. // Read URI Cache parameters
  1238. //
  1239. pConfig->UriConfig.EnableCache = UlReadLongParameter(
  1240. parametersHandle,
  1241. REGISTRY_CACHE_ENABLED,
  1242. DEFAULT_CACHE_ENABLED
  1243. ) != 0;
  1244. pConfig->UriConfig.MaxCacheUriCount = UlReadLongParameter(
  1245. parametersHandle,
  1246. REGISTRY_MAX_CACHE_URI_COUNT,
  1247. DEFAULT_MAX_CACHE_URI_COUNT
  1248. );
  1249. pConfig->UriConfig.MaxCacheMegabyteCount = UlReadLongParameter(
  1250. parametersHandle,
  1251. REGISTRY_MAX_CACHE_MEGABYTE_COUNT,
  1252. DEFAULT_MAX_CACHE_MEGABYTE_COUNT
  1253. );
  1254. pConfig->UriConfig.MaxUriBytes = UlReadLongParameter(
  1255. parametersHandle,
  1256. REGISTRY_MAX_URI_BYTES,
  1257. DEFAULT_MAX_URI_BYTES
  1258. );
  1259. pConfig->UriConfig.ScavengerPeriod = UlReadLongParameter(
  1260. parametersHandle,
  1261. REGISTRY_CACHE_SCAVENGER_PERIOD,
  1262. DEFAULT_CACHE_SCAVENGER_PERIOD
  1263. );
  1264. pConfig->UriConfig.HashTableBits = UlReadLongParameter(
  1265. parametersHandle,
  1266. REGISTRY_HASH_TABLE_BITS,
  1267. DEFAULT_HASH_TABLE_BITS
  1268. );
  1269. pConfig->LargeMemMegabytes = UlReadLongParameter(
  1270. parametersHandle,
  1271. REGISTRY_LARGE_MEM_MEGABYTES,
  1272. DEFAULT_LARGE_MEM_MEGABYTES
  1273. );
  1274. //
  1275. // Make sure we can always buffer enough bytes for an entire request
  1276. // header.
  1277. //
  1278. g_UlMaxBufferedBytes = MAX(g_UlMaxBufferedBytes, g_UlMaxRequestBytes);
  1279. //
  1280. // Dump configuration on checked builds.
  1281. //
  1282. #if DBG
  1283. DbgPrint( "UL Configuration:\n" );
  1284. #if DBG
  1285. DbgPrint( " g_UlDebug = %08lx\n", g_UlDebug );
  1286. DbgPrint( " g_UlBreakOnError = %lu\n", g_UlBreakOnError );
  1287. DbgPrint( " g_UlVerboseErrors = %lu\n", g_UlVerboseErrors );
  1288. #endif // DBG
  1289. DbgPrint( " g_UlIrpStackSize = %lu\n", g_UlIrpStackSize );
  1290. DbgPrint( " g_UlPriorityBoost = %lu\n", g_UlPriorityBoost );
  1291. DbgPrint( " g_UlMinIdleConnections = %lu\n", g_UlMinIdleConnections );
  1292. DbgPrint( " g_UlMaxIdleConnections = %lu\n", g_UlMaxIdleConnections );
  1293. DbgPrint( " g_UlEnableConnectionReuse = %lu\n", g_UlEnableConnectionReuse );
  1294. DbgPrint( " g_UlEnableNagling = %lu\n", g_UlEnableNagling );
  1295. DbgPrint( " g_UlEnableThreadAffinity = %lu\n", g_UlEnableThreadAffinity );
  1296. DbgPrint( " g_UlThreadAffinityMask = %I64x\n", g_UlThreadAffinityMask );
  1297. DbgPrint( " g_UlMaxWorkQueueDepth = %lu\n", g_UlMaxWorkQueueDepth );
  1298. DbgPrint( " g_UlMinWorkDequeueDepth = %lu\n", g_UlMinWorkDequeueDepth );
  1299. DbgPrint( " g_UlOpaqueIdTableSize = %lu\n", g_UlOpaqueIdTableSize );
  1300. DbgPrint( " g_UlMaxRequestBytes = %lu\n", g_UlMaxRequestBytes );
  1301. DbgPrint( " g_UlReceiveBufferSize = %lu\n", g_UlReceiveBufferSize );
  1302. DbgPrint( " g_UlResponseBufferSize = %lu\n", g_UlResponseBufferSize );
  1303. DbgPrint( " g_UlMaxUrlLength = %lu\n", g_UlMaxUrlLength );
  1304. DbgPrint( " g_UlMaxFieldLength = %lu\n", g_UlMaxFieldLength );
  1305. DbgPrint( " g_UlDebugLogTimerCycle = %lu\n", g_UlDebugLogTimerCycle );
  1306. DbgPrint( " g_UlDebugLogBufferPeriod = %lu\n", g_UlDebugLogBufferPeriod );
  1307. DbgPrint( " g_UlLogBufferSize = %lu\n", g_UlLogBufferSize );
  1308. DbgPrint( " g_UlEnableNonUTF8 = %lu\n", g_UlEnableNonUTF8 );
  1309. DbgPrint( " g_UlEnableDBCS = %lu\n", g_UlEnableDBCS );
  1310. DbgPrint( " g_UlFavorDBCS = %lu\n", g_UlFavorDBCS );
  1311. DbgPrint( " g_UlMaxInternalUrlLength = %lu\n", g_UlMaxInternalUrlLength );
  1312. #if ALLOW_UNLOAD
  1313. DbgPrint( " EnableUnload = %lu\n", pConfig->EnableUnload );
  1314. #endif // ALLOW_UNLOAD
  1315. DbgPrint( " EnableSecurity = %lu\n", pConfig->EnableSecurity );
  1316. DbgPrint( " ThreadsPerCpu = %lx\n", pConfig->ThreadsPerCpu );
  1317. DbgPrint( " IrpContextLookasideDepth = %lu\n", pConfig->IrpContextLookasideDepth );
  1318. DbgPrint( " ReceiveBufferLookasideDepth = %lu\n", pConfig->ReceiveBufferLookasideDepth );
  1319. DbgPrint( " ResourceLookasideDepth = %lu\n", pConfig->ResourceLookasideDepth );
  1320. DbgPrint( " RequestBufferLookasideDepth = %lu\n", pConfig->RequestBufferLookasideDepth );
  1321. DbgPrint( " IntlRequestLookasideDepth = %lu\n", pConfig->InternalRequestLookasideDepth );
  1322. DbgPrint( " ResponseBufferLookasideDepth = %lu\n", pConfig->ResponseBufferLookasideDepth );
  1323. DbgPrint( " SendTrackerLookasideDepth = %lu\n", pConfig->SendTrackerLookasideDepth );
  1324. DbgPrint( " LogBufferLookasideDepth = %lu\n", pConfig->LogBufferLookasideDepth );
  1325. DbgPrint( " EnableCache = %lu\n", pConfig->UriConfig.EnableCache );
  1326. DbgPrint( " MaxCacheUriCount = %lu\n", pConfig->UriConfig.MaxCacheUriCount );
  1327. DbgPrint( " MaxCacheMegabyteCount = %lu\n", pConfig->UriConfig.MaxCacheMegabyteCount );
  1328. DbgPrint( " ScavengerPeriod = %lu\n", pConfig->UriConfig.ScavengerPeriod );
  1329. DbgPrint( " HashTableBits = %ld\n", pConfig->UriConfig.HashTableBits);
  1330. DbgPrint( " MaxUriBytes = %lu\n", pConfig->UriConfig.MaxUriBytes );
  1331. DbgPrint( " LargeMemMegabytes = %ld\n", pConfig->LargeMemMegabytes );
  1332. #endif // DBG
  1333. //
  1334. // Cleanup.
  1335. //
  1336. UlCloseSystemHandle( parametersHandle );
  1337. } // UlpReadRegistry
  1338. #if ALLOW_UNLOAD
  1339. /***************************************************************************++
  1340. Routine Description:
  1341. Unload routine called by the IO subsystem when UL is getting
  1342. unloaded.
  1343. --***************************************************************************/
  1344. VOID
  1345. UlpUnload(
  1346. IN PDRIVER_OBJECT DriverObject
  1347. )
  1348. {
  1349. //
  1350. // Sanity check.
  1351. //
  1352. PAGED_CODE();
  1353. UL_ENTER_DRIVER("UlpUnload", NULL);
  1354. #if DBG
  1355. KdPrint(( "UlpUnload called.\n" ));
  1356. #endif // DBG
  1357. //
  1358. // Terminate the UL modules.
  1359. //
  1360. UlpTerminateModules();
  1361. UL_LEAVE_DRIVER("UlpUnload");
  1362. #if DBG
  1363. //
  1364. // Terminate any debug-specific data after UL_LEAVE_DRIVER
  1365. //
  1366. UlDbgTerminateDebugData( );
  1367. #endif // DBG
  1368. } // UlpUnload
  1369. #endif // ALLOW_UNLOAD
  1370. /***************************************************************************++
  1371. Routine Description:
  1372. Terminates the various UL modules in the correct order.
  1373. --***************************************************************************/
  1374. VOID
  1375. UlpTerminateModules(
  1376. VOID
  1377. )
  1378. {
  1379. //
  1380. // Sanity check.
  1381. //
  1382. PAGED_CODE();
  1383. //
  1384. // Wait for endpoints to go away, so we're sure all I/O is done.
  1385. //
  1386. UlWaitForEndpointDrain();
  1387. //
  1388. // Kill Michael.
  1389. //
  1390. UlTerminateDateCache();
  1391. UlTerminateUriCache();
  1392. UlTerminateFilterChannel();
  1393. //
  1394. // Kill Henry.
  1395. //
  1396. TerminateFileCache();
  1397. //
  1398. // Kill Paul.
  1399. //
  1400. UlTerminateCG();
  1401. UlTerminateAP();
  1402. //
  1403. // Kill Keith.
  1404. //
  1405. UlTerminateControlChannel();
  1406. //
  1407. // TerminateLogs Blocks until all Io To Be Complete
  1408. //
  1409. // Note:CG should be terminated before Logs.
  1410. // Otherwise we won't stop issuing the buffer writes.
  1411. // ThreadPool should be terminated after Logs.
  1412. // Otherwise our Completion APCs won't be completed back.
  1413. //
  1414. //
  1415. // Kill Ali
  1416. //
  1417. UlTerminateLogs();
  1418. UlTcTerminate();
  1419. //
  1420. // Kill Eric.
  1421. //
  1422. UlTerminateHttpRcv();
  1423. UlTerminateCounters();
  1424. UlTerminateTimeoutMonitor();
  1425. //
  1426. // Kill George.
  1427. //
  1428. UlLargeMemTerminate();
  1429. //
  1430. // Kill TDI.
  1431. //
  1432. UxTerminateTdi();
  1433. UlTerminateTdi();
  1434. //
  1435. // Kill the thread pool.
  1436. //
  1437. UlTerminateThreadPool();
  1438. //
  1439. // Kill the opaque Ids
  1440. //
  1441. UlTerminateOpaqueIdTable();
  1442. //
  1443. // Kill any global data.
  1444. //
  1445. UlTerminateData();
  1446. //
  1447. // Delete our device objects.
  1448. //
  1449. if (g_pUlAppPoolDeviceObject != NULL)
  1450. {
  1451. IoDeleteDevice( g_pUlAppPoolDeviceObject );
  1452. }
  1453. if (g_pUlFilterDeviceObject != NULL)
  1454. {
  1455. IoDeleteDevice( g_pUlFilterDeviceObject );
  1456. }
  1457. if (g_pUlControlDeviceObject != NULL)
  1458. {
  1459. IoDeleteDevice( g_pUlControlDeviceObject );
  1460. }
  1461. //
  1462. // Delete the directory container.
  1463. //
  1464. if (g_UlDirectoryObject != NULL)
  1465. {
  1466. UlCloseSystemHandle( g_UlDirectoryObject );
  1467. }
  1468. //
  1469. // Delete the global trace logs.
  1470. //
  1471. DESTROY_REF_TRACE_LOG( g_pTdiTraceLog );
  1472. DESTROY_REF_TRACE_LOG( g_pHttpRequestTraceLog );
  1473. DESTROY_REF_TRACE_LOG( g_pHttpConnectionTraceLog );
  1474. DESTROY_REF_TRACE_LOG( g_pHttpResponseTraceLog );
  1475. DESTROY_REF_TRACE_LOG( g_pAppPoolTraceLog );
  1476. DESTROY_REF_TRACE_LOG( g_pConfigGroupTraceLog );
  1477. DESTROY_REF_TRACE_LOG( g_pThreadTraceLog );
  1478. DESTROY_REF_TRACE_LOG( g_pMdlTraceLog );
  1479. DESTROY_REF_TRACE_LOG( g_pFilterTraceLog );
  1480. DESTROY_REF_TRACE_LOG( g_pMondoGlobalTraceLog );
  1481. DESTROY_IRP_TRACE_LOG( g_pIrpTraceLog );
  1482. DESTROY_TIME_TRACE_LOG( g_pTimeTraceLog );
  1483. DESTROY_REPLENISH_TRACE_LOG( g_pReplenishTraceLog );
  1484. DESTROY_FILTQ_TRACE_LOG( g_pFilterQueueTraceLog );
  1485. DESTROY_REF_TRACE_LOG( g_pSiteCounterTraceLog );
  1486. DESTROY_REF_TRACE_LOG( g_pConnectionCountTraceLog );
  1487. DESTROY_REF_TRACE_LOG( g_pConfigGroupInfoTraceLog );
  1488. DESTROY_REF_TRACE_LOG( g_pChunkTrackerTraceLog );
  1489. DESTROY_REF_TRACE_LOG( g_pWorkItemTraceLog );
  1490. UlTerminateOwnerRefTraceLog();
  1491. } // UlpTerminateModules