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.

769 lines
20 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. Init.c
  5. Abstract:
  6. This module implements the DRIVER_INITIALIZATION routine for
  7. the null mini rdr.
  8. --*/
  9. #include "precomp.h"
  10. #pragma hdrstop
  11. //
  12. // The local debug trace level
  13. //
  14. #define Dbg (DEBUG_TRACE_INIT)
  15. #include "ntverp.h"
  16. #include "nulmrx.h"
  17. //
  18. // Global data declarations.
  19. //
  20. NULMRX_STATE NulMRxState = NULMRX_STARTABLE;
  21. //
  22. // Mini Redirector global variables.
  23. //
  24. //
  25. // LogRate
  26. //
  27. ULONG LogRate = 0;
  28. //
  29. // NULMRX version
  30. //
  31. ULONG NulMRxVersion = VER_PRODUCTBUILD;
  32. //
  33. // This is the minirdr dispatch table. It is initialized by
  34. // NulMRxInitializeTables. This table will be used by the wrapper to call
  35. // into this minirdr
  36. //
  37. struct _MINIRDR_DISPATCH NulMRxDispatch;
  38. //
  39. // Pointer to the device Object for this minirdr. Since the device object is
  40. // created by the wrapper when this minirdr registers, this pointer is
  41. // initialized in the DriverEntry routine below (see RxRegisterMinirdr)
  42. //
  43. PRDBSS_DEVICE_OBJECT NulMRxDeviceObject;
  44. //
  45. // declare the shadow debugtrace controlpoints
  46. //
  47. RXDT_DefineCategory(CREATE);
  48. RXDT_DefineCategory(CLEANUP);
  49. RXDT_DefineCategory(CLOSE);
  50. RXDT_DefineCategory(READ);
  51. RXDT_DefineCategory(WRITE);
  52. RXDT_DefineCategory(LOCKCTRL);
  53. RXDT_DefineCategory(FLUSH);
  54. RXDT_DefineCategory(PREFIX);
  55. RXDT_DefineCategory(FCBSTRUCTS);
  56. RXDT_DefineCategory(DISPATCH);
  57. RXDT_DefineCategory(EA);
  58. RXDT_DefineCategory(DEVFCB);
  59. RXDT_DefineCategory(INIT);
  60. //
  61. // The following enumerated values signify the current state of the minirdr
  62. // initialization. With the aid of this state information, it is possible
  63. // to determine which resources to deallocate, whether deallocation comes
  64. // as a result of a normal stop/unload, or as the result of an exception
  65. //
  66. typedef enum _NULMRX_INIT_STATES {
  67. NULMRXINIT_ALL_INITIALIZATION_COMPLETED,
  68. NULMRXINIT_MINIRDR_REGISTERED,
  69. NULMRXINIT_START
  70. } NULMRX_INIT_STATES;
  71. //
  72. // function prototypes
  73. //
  74. NTSTATUS
  75. NulMRxInitializeTables(
  76. void
  77. );
  78. VOID
  79. NulMRxUnload(
  80. IN PDRIVER_OBJECT DriverObject
  81. );
  82. VOID
  83. NulMRxInitUnwind(
  84. IN PDRIVER_OBJECT DriverObject,
  85. IN NULMRX_INIT_STATES NulMRxInitState
  86. );
  87. NTSTATUS
  88. NulMRxFsdDispatch (
  89. IN PDEVICE_OBJECT DeviceObject,
  90. IN PIRP Irp
  91. );
  92. VOID
  93. NulMRxReadRegistryParameters();
  94. NTSTATUS
  95. DriverEntry(
  96. IN PDRIVER_OBJECT DriverObject,
  97. IN PUNICODE_STRING RegistryPath
  98. )
  99. /*++
  100. Routine Description:
  101. This is the initialization routine for the mini redirector
  102. Arguments:
  103. DriverObject - Pointer to driver object created by the system.
  104. Return Value:
  105. RXSTATUS - The function value is the final status from the initialization
  106. operation.
  107. --*/
  108. {
  109. NTSTATUS Status;
  110. PRX_CONTEXT RxContext = NULL;
  111. ULONG Controls = 0;
  112. NULMRX_INIT_STATES NulMRxInitState = 0;
  113. UNICODE_STRING NulMRxName;
  114. UNICODE_STRING UserModeDeviceName;
  115. PNULMRX_DEVICE_EXTENSION pDeviceExtension;
  116. ULONG i;
  117. DbgPrint("+++ NULMRX Driver %08lx Loaded +++\n", DriverObject);
  118. Status = RxDriverEntry(DriverObject, RegistryPath);
  119. if (Status != STATUS_SUCCESS) {
  120. DbgPrint("Wrapper failed to initialize. Status = %08lx\n",Status);
  121. return(Status);
  122. }
  123. try {
  124. NulMRxInitState = NULMRXINIT_START;
  125. //
  126. // Register this minirdr with the connection engine. Registration makes the connection
  127. // engine aware of the device name, driver object, and other characteristics.
  128. // If registration is successful, a new device object is returned
  129. //
  130. //
  131. RtlInitUnicodeString(&NulMRxName, DD_NULMRX_FS_DEVICE_NAME_U);
  132. SetFlag(Controls,RX_REGISTERMINI_FLAG_DONT_PROVIDE_UNCS);
  133. SetFlag(Controls,RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS);
  134. Status = RxRegisterMinirdr(
  135. &NulMRxDeviceObject, // where the new device object goes
  136. DriverObject, // the Driver Object to register
  137. &NulMRxDispatch, // the dispatch table for this driver
  138. Controls, // dont register with unc and for mailslots
  139. &NulMRxName, // the device name for this minirdr
  140. sizeof(NULMRX_DEVICE_EXTENSION), // IN ULONG DeviceExtensionSize,
  141. FILE_DEVICE_NETWORK_FILE_SYSTEM, // IN ULONG DeviceType - disk ?
  142. FILE_REMOTE_DEVICE // IN ULONG DeviceCharacteristics
  143. );
  144. if (Status!=STATUS_SUCCESS) {
  145. DbgPrint("NulMRxDriverEntry failed: %08lx\n", Status );
  146. try_return(Status);
  147. }
  148. //
  149. // Init the device extension data
  150. // NOTE: the device extension actually points to fields
  151. // in the RDBSS_DEVICE_OBJECT. Our space is past the end
  152. // of this struct !!
  153. //
  154. pDeviceExtension = (PNULMRX_DEVICE_EXTENSION)
  155. ((PBYTE)(NulMRxDeviceObject) + sizeof(RDBSS_DEVICE_OBJECT));
  156. RxDefineNode(pDeviceExtension,NULMRX_DEVICE_EXTENSION);
  157. pDeviceExtension->DeviceObject = NulMRxDeviceObject;
  158. // initialize local connection list
  159. for (i = 0; i < 26; i++)
  160. {
  161. pDeviceExtension->LocalConnections[i] = FALSE;
  162. }
  163. // Mutex for synchronizining our connection list
  164. ExInitializeFastMutex( &pDeviceExtension->LCMutex );
  165. // The device object has been created. Need to setup a symbolic
  166. // link so that the device may be accessed from a Win32 user mode
  167. // application.
  168. RtlInitUnicodeString(&UserModeDeviceName, DD_NULMRX_USERMODE_SHADOW_DEV_NAME_U);
  169. Status = IoCreateSymbolicLink( &UserModeDeviceName, &NulMRxName);
  170. if (Status!=STATUS_SUCCESS) {
  171. DbgPrint("NulMRxDriverEntry failed: %08lx\n", Status );
  172. try_return(Status);
  173. }
  174. NulMRxInitState = NULMRXINIT_MINIRDR_REGISTERED;
  175. //
  176. // Build the dispatch tables for the minirdr
  177. //
  178. Status = NulMRxInitializeTables();
  179. if (!NT_SUCCESS( Status )) {
  180. try_return(Status);
  181. }
  182. //
  183. // Get information from the registry
  184. //
  185. NulMRxReadRegistryParameters();
  186. try_exit: NOTHING;
  187. } finally {
  188. if (Status != STATUS_SUCCESS) {
  189. NulMRxInitUnwind(DriverObject,NulMRxInitState);
  190. }
  191. }
  192. if (Status != STATUS_SUCCESS) {
  193. DbgPrint("NulMRx failed to start with %08lx %08lx\n",Status,NulMRxInitState);
  194. return(Status);
  195. }
  196. //
  197. // Setup Unload Routine
  198. //
  199. DriverObject->DriverUnload = NulMRxUnload;
  200. //
  201. //setup the driver dispatch for people who come in here directly....like the browser
  202. //
  203. for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
  204. {
  205. DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)NulMRxFsdDispatch;
  206. }
  207. //
  208. // Start the mini-rdr (used to be a START IOCTL)
  209. //
  210. RxContext = RxCreateRxContext(
  211. NULL,
  212. NulMRxDeviceObject,
  213. RX_CONTEXT_FLAG_IN_FSP);
  214. if (RxContext != NULL) {
  215. Status = RxStartMinirdr(
  216. RxContext,
  217. &RxContext->PostRequest);
  218. if (Status == STATUS_SUCCESS) {
  219. NULMRX_STATE State;
  220. State = (NULMRX_STATE)InterlockedCompareExchange(
  221. (LONG *)&NulMRxState,
  222. NULMRX_STARTED,
  223. NULMRX_STARTABLE);
  224. if (State != NULMRX_STARTABLE) {
  225. Status = STATUS_REDIRECTOR_STARTED;
  226. DbgPrint("Status is STATUS_REDIR_STARTED\n");
  227. }
  228. //
  229. // Chance to get resources in context
  230. // of system process.....!!!
  231. //
  232. } else if(Status == STATUS_PENDING ) {
  233. }
  234. RxDereferenceAndDeleteRxContext(RxContext);
  235. } else {
  236. Status = STATUS_INSUFFICIENT_RESOURCES;
  237. }
  238. return STATUS_SUCCESS;
  239. }
  240. VOID
  241. NulMRxInitUnwind(
  242. IN PDRIVER_OBJECT DriverObject,
  243. IN NULMRX_INIT_STATES NulMRxInitState
  244. )
  245. /*++
  246. Routine Description:
  247. This routine does the common uninit work for unwinding from a bad driver entry or for unloading.
  248. Arguments:
  249. NulMRxInitState - tells how far we got into the intialization
  250. Return Value:
  251. None
  252. --*/
  253. {
  254. PAGED_CODE();
  255. switch (NulMRxInitState) {
  256. case NULMRXINIT_ALL_INITIALIZATION_COMPLETED:
  257. //Nothing extra to do...this is just so that the constant in RxUnload doesn't change.......
  258. //lack of break intentional
  259. case NULMRXINIT_MINIRDR_REGISTERED:
  260. RxUnregisterMinirdr(NulMRxDeviceObject);
  261. //lack of break intentional
  262. case NULMRXINIT_START:
  263. break;
  264. }
  265. }
  266. VOID
  267. NulMRxUnload(
  268. IN PDRIVER_OBJECT DriverObject
  269. )
  270. /*++
  271. Routine Description:
  272. This is the unload routine for the Exchange mini redirector.
  273. Arguments:
  274. DriverObject - pointer to the driver object for the NulMRx
  275. Return Value:
  276. None
  277. --*/
  278. {
  279. PRX_CONTEXT RxContext;
  280. NTSTATUS Status;
  281. UNICODE_STRING UserModeDeviceName;
  282. PAGED_CODE();
  283. NulMRxInitUnwind(DriverObject,NULMRXINIT_ALL_INITIALIZATION_COMPLETED);
  284. RxContext = RxCreateRxContext(
  285. NULL,
  286. NulMRxDeviceObject,
  287. RX_CONTEXT_FLAG_IN_FSP);
  288. if (RxContext != NULL) {
  289. Status = RxStopMinirdr(
  290. RxContext,
  291. &RxContext->PostRequest);
  292. if (Status == STATUS_SUCCESS) {
  293. NULMRX_STATE State;
  294. State = (NULMRX_STATE)InterlockedCompareExchange(
  295. (LONG *)&NulMRxState,
  296. NULMRX_STARTABLE,
  297. NULMRX_STARTED);
  298. if (State != NULMRX_STARTABLE) {
  299. Status = STATUS_REDIRECTOR_STARTED;
  300. }
  301. }
  302. RxDereferenceAndDeleteRxContext(RxContext);
  303. } else {
  304. Status = STATUS_INSUFFICIENT_RESOURCES;
  305. }
  306. RtlInitUnicodeString(&UserModeDeviceName, DD_NULMRX_USERMODE_SHADOW_DEV_NAME_U);
  307. Status = IoDeleteSymbolicLink( &UserModeDeviceName);
  308. if (Status!=STATUS_SUCCESS) {
  309. DbgPrint("NulMRx: Could not delete Symbolic Link\n");
  310. }
  311. RxUnload(DriverObject);
  312. DbgPrint("+++ NULMRX Driver %08lx Unoaded +++\n", DriverObject);
  313. }
  314. NTSTATUS
  315. NulMRxInitializeTables(
  316. void
  317. )
  318. /*++
  319. Routine Description:
  320. This routine sets up the mini redirector dispatch vector and also calls
  321. to initialize any other tables needed.
  322. Return Value:
  323. RXSTATUS - The return status for the operation
  324. --*/
  325. {
  326. //
  327. // Ensure that the Exchange mini redirector context satisfies the size constraints
  328. //
  329. //ASSERT(sizeof(NULMRX_RX_CONTEXT) <= MRX_CONTEXT_SIZE);
  330. //
  331. // Build the local minirdr dispatch table and initialize
  332. //
  333. ZeroAndInitializeNodeType( &NulMRxDispatch, RDBSS_NTC_MINIRDR_DISPATCH, sizeof(MINIRDR_DISPATCH));
  334. //
  335. // null mini redirector extension sizes and allocation policies.
  336. //
  337. NulMRxDispatch.MRxFlags = (RDBSS_MANAGE_NET_ROOT_EXTENSION |
  338. RDBSS_MANAGE_FCB_EXTENSION);
  339. NulMRxDispatch.MRxSrvCallSize = 0; // srvcall extension is not handled in rdbss
  340. NulMRxDispatch.MRxNetRootSize = sizeof(NULMRX_NETROOT_EXTENSION);
  341. NulMRxDispatch.MRxVNetRootSize = 0;
  342. NulMRxDispatch.MRxFcbSize = sizeof(NULMRX_FCB_EXTENSION);
  343. NulMRxDispatch.MRxSrvOpenSize = 0;
  344. NulMRxDispatch.MRxFobxSize = 0;
  345. // Mini redirector cancel routine ..
  346. NulMRxDispatch.MRxCancel = NULL;
  347. //
  348. // Mini redirector Start/Stop. Each mini-rdr can be started or stopped
  349. // while the others continue to operate.
  350. //
  351. NulMRxDispatch.MRxStart = NulMRxStart;
  352. NulMRxDispatch.MRxStop = NulMRxStop;
  353. NulMRxDispatch.MRxDevFcbXXXControlFile = NulMRxDevFcbXXXControlFile;
  354. //
  355. // Mini redirector name resolution.
  356. //
  357. NulMRxDispatch.MRxCreateSrvCall = NulMRxCreateSrvCall;
  358. NulMRxDispatch.MRxSrvCallWinnerNotify = NulMRxSrvCallWinnerNotify;
  359. NulMRxDispatch.MRxCreateVNetRoot = NulMRxCreateVNetRoot;
  360. NulMRxDispatch.MRxUpdateNetRootState = NulMRxUpdateNetRootState;
  361. NulMRxDispatch.MRxExtractNetRootName = NulMRxExtractNetRootName;
  362. NulMRxDispatch.MRxFinalizeSrvCall = NulMRxFinalizeSrvCall;
  363. NulMRxDispatch.MRxFinalizeNetRoot = NulMRxFinalizeNetRoot;
  364. NulMRxDispatch.MRxFinalizeVNetRoot = NulMRxFinalizeVNetRoot;
  365. //
  366. // File System Object Creation/Deletion.
  367. //
  368. NulMRxDispatch.MRxCreate = NulMRxCreate;
  369. NulMRxDispatch.MRxCollapseOpen = NulMRxCollapseOpen;
  370. NulMRxDispatch.MRxShouldTryToCollapseThisOpen = NulMRxShouldTryToCollapseThisOpen;
  371. NulMRxDispatch.MRxExtendForCache = NulMRxExtendFile;
  372. NulMRxDispatch.MRxExtendForNonCache = NulMRxExtendFile;
  373. NulMRxDispatch.MRxTruncate = NulMRxTruncate;
  374. NulMRxDispatch.MRxCleanupFobx = NulMRxCleanupFobx;
  375. NulMRxDispatch.MRxCloseSrvOpen = NulMRxCloseSrvOpen;
  376. NulMRxDispatch.MRxFlush = NulMRxFlush;
  377. NulMRxDispatch.MRxForceClosed = NulMRxForcedClose;
  378. NulMRxDispatch.MRxDeallocateForFcb = NulMRxDeallocateForFcb;
  379. NulMRxDispatch.MRxDeallocateForFobx = NulMRxDeallocateForFobx;
  380. //
  381. // File System Objects query/Set
  382. //
  383. NulMRxDispatch.MRxQueryDirectory = NulMRxQueryDirectory;
  384. NulMRxDispatch.MRxQueryVolumeInfo = NulMRxQueryVolumeInformation;
  385. NulMRxDispatch.MRxQueryEaInfo = NulMRxQueryEaInformation;
  386. NulMRxDispatch.MRxSetEaInfo = NulMRxSetEaInformation;
  387. NulMRxDispatch.MRxQuerySdInfo = NulMRxQuerySecurityInformation;
  388. NulMRxDispatch.MRxSetSdInfo = NulMRxSetSecurityInformation;
  389. NulMRxDispatch.MRxQueryFileInfo = NulMRxQueryFileInformation;
  390. NulMRxDispatch.MRxSetFileInfo = NulMRxSetFileInformation;
  391. NulMRxDispatch.MRxSetFileInfoAtCleanup = NulMRxSetFileInformationAtCleanup;
  392. //
  393. // Buffering state change
  394. //
  395. NulMRxDispatch.MRxComputeNewBufferingState = NulMRxComputeNewBufferingState;
  396. //
  397. // File System Object I/O
  398. //
  399. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_READ] = NulMRxRead;
  400. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_WRITE] = NulMRxWrite;
  401. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = NulMRxLocks;
  402. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_EXCLUSIVELOCK] = NulMRxLocks;
  403. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK] = NulMRxLocks;
  404. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK_MULTIPLE] = NulMRxLocks;
  405. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_FSCTL] = NulMRxFsCtl;
  406. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_IOCTL] = NulMRxIoCtl;
  407. NulMRxDispatch.MRxLowIOSubmit[LOWIO_OP_NOTIFY_CHANGE_DIRECTORY] = NulMRxNotifyChangeDirectory;
  408. //
  409. // Miscellanous
  410. //
  411. NulMRxDispatch.MRxCompleteBufferingStateChangeRequest = NulMRxCompleteBufferingStateChangeRequest;
  412. return(STATUS_SUCCESS);
  413. }
  414. NTSTATUS
  415. NulMRxStart(
  416. PRX_CONTEXT RxContext,
  417. IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
  418. )
  419. /*++
  420. Routine Description:
  421. This routine completes the initialization of the mini redirector fromn the
  422. RDBSS perspective. Note that this is different from the initialization done
  423. in DriverEntry. Any initialization that depends on RDBSS should be done as
  424. part of this routine while the initialization that is independent of RDBSS
  425. should be done in the DriverEntry routine.
  426. Arguments:
  427. RxContext - Supplies the Irp that was used to startup the rdbss
  428. Return Value:
  429. RXSTATUS - The return status for the operation
  430. --*/
  431. {
  432. NTSTATUS Status = STATUS_SUCCESS;
  433. return Status;
  434. }
  435. NTSTATUS
  436. NulMRxStop(
  437. PRX_CONTEXT RxContext,
  438. IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
  439. )
  440. /*++
  441. Routine Description:
  442. This routine is used to activate the mini redirector from the RDBSS perspective
  443. Arguments:
  444. RxContext - the context that was used to start the mini redirector
  445. pContext - the null mini rdr context passed in at registration time.
  446. Return Value:
  447. RXSTATUS - The return status for the operation
  448. --*/
  449. {
  450. NTSTATUS Status;
  451. //DbgPrint("Entering NulMRxStop \n");
  452. return(STATUS_SUCCESS);
  453. }
  454. NTSTATUS
  455. NulMRxFsdDispatch (
  456. IN PDEVICE_OBJECT DeviceObject,
  457. IN PIRP Irp
  458. )
  459. /*++
  460. Routine Description:
  461. This routine implements the FSD dispatch for the mini DRIVER object.
  462. Arguments:
  463. DeviceObject - Supplies the device object for the packet being processed.
  464. Irp - Supplies the Irp being processed
  465. Return Value:
  466. RXSTATUS - The Fsd status for the Irp
  467. --*/
  468. {
  469. NTSTATUS Status = STATUS_SUCCESS;
  470. ASSERT(DeviceObject==(PDEVICE_OBJECT)NulMRxDeviceObject);
  471. if (DeviceObject!=(PDEVICE_OBJECT)NulMRxDeviceObject) {
  472. Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  473. Irp->IoStatus.Information = 0;
  474. IoCompleteRequest(Irp, IO_NO_INCREMENT );
  475. return (STATUS_INVALID_DEVICE_REQUEST);
  476. }
  477. Status = RxFsdDispatch((PRDBSS_DEVICE_OBJECT)NulMRxDeviceObject,Irp);
  478. return Status;
  479. }
  480. NTSTATUS
  481. NulMRxGetUlongRegistryParameter(
  482. HANDLE ParametersHandle,
  483. PWCHAR ParameterName,
  484. PULONG ParamUlong,
  485. BOOLEAN LogFailure
  486. )
  487. /*++
  488. Routine Description:
  489. This routine is called to read a ULONG param from t he registry.
  490. Arguments:
  491. ParametersHandle - the handle of the containing registry "folder"
  492. ParameterName - name of the parameter to be read
  493. ParamUlong - where to store the value, if successful
  494. LogFailure - if TRUE and the registry stuff fails, log an error
  495. Return Value:
  496. RXSTATUS - STATUS_SUCCESS
  497. --*/
  498. {
  499. ULONG Storage[16];
  500. PKEY_VALUE_PARTIAL_INFORMATION Value;
  501. ULONG ValueSize;
  502. UNICODE_STRING UnicodeString;
  503. NTSTATUS Status;
  504. ULONG BytesRead;
  505. PAGED_CODE(); //INIT
  506. Value = (PKEY_VALUE_PARTIAL_INFORMATION)Storage;
  507. ValueSize = sizeof(Storage);
  508. RtlInitUnicodeString(&UnicodeString, ParameterName);
  509. Status = ZwQueryValueKey(ParametersHandle,
  510. &UnicodeString,
  511. KeyValuePartialInformation,
  512. Value,
  513. ValueSize,
  514. &BytesRead);
  515. if (NT_SUCCESS(Status)) {
  516. if (Value->Type == REG_DWORD) {
  517. PULONG ConfigValue = (PULONG)&Value->Data[0];
  518. *ParamUlong = *((PULONG)ConfigValue);
  519. DbgPrint("readRegistryvalue %wZ = %08lx\n",&UnicodeString,*ParamUlong);
  520. return(STATUS_SUCCESS);
  521. } else {
  522. Status = STATUS_INVALID_PARAMETER;
  523. }
  524. }
  525. if (LogFailure)
  526. {
  527. // log the failure...
  528. }
  529. return Status;
  530. }
  531. VOID
  532. NulMRxReadRegistryParameters()
  533. {
  534. NTSTATUS Status;
  535. OBJECT_ATTRIBUTES ObjectAttributes;
  536. UNICODE_STRING ParametersRegistryKeyName;
  537. HANDLE ParametersHandle;
  538. ULONG Temp = 0;
  539. RtlInitUnicodeString(&ParametersRegistryKeyName, NULL_MINIRDR_PARAMETERS);
  540. InitializeObjectAttributes(
  541. &ObjectAttributes,
  542. &ParametersRegistryKeyName,
  543. OBJ_CASE_INSENSITIVE,
  544. NULL,
  545. NULL
  546. );
  547. Status = ZwOpenKey (&ParametersHandle, KEY_READ, &ObjectAttributes);
  548. if (NT_SUCCESS(Status)) {
  549. Status = NulMRxGetUlongRegistryParameter(ParametersHandle,
  550. L"LogRate",
  551. (PULONG)&Temp,
  552. FALSE
  553. );
  554. }
  555. if (NT_SUCCESS(Status)) {
  556. LogRate = Temp;
  557. // Check for bogus parameters.
  558. if(LogRate > 10) {
  559. LogRate = 10;
  560. }
  561. }
  562. ZwClose(ParametersHandle);
  563. }