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.

766 lines
22 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation.
  4. //
  5. // File: dfsinit.c
  6. //
  7. // Contents: This module implements the DRIVER_INITIALIZATION routine
  8. // for the Dfs file system driver.
  9. //
  10. // Functions: DfsDriverEntry - Main entry point for driver initialization
  11. // DfsIoTimerRoutine - Main entry point for scavenger thread
  12. // DfsDeleteDevices - Routine to scavenge deleted net uses
  13. //
  14. //-----------------------------------------------------------------------------
  15. #include "align.h"
  16. #include "dfsprocs.h"
  17. #include "fastio.h"
  18. #include "fcbsup.h"
  19. //
  20. // The following are includes for init modules, which will get discarded when
  21. // the driver has finished loading.
  22. //
  23. #include "provider.h"
  24. //
  25. // The debug trace level
  26. //
  27. #define Dbg (DEBUG_TRACE_INIT)
  28. VOID
  29. MupGetDebugFlags(VOID);
  30. VOID
  31. DfsGetEventLogValue(VOID);
  32. VOID
  33. DfsIoTimerRoutine(
  34. IN PDEVICE_OBJECT DeviceObject,
  35. IN PVOID Context
  36. );
  37. VOID
  38. DfsDeleteDevices(
  39. PDFS_TIMER_CONTEXT DfsTimerContext);
  40. NTSTATUS
  41. DfsShutdown (
  42. IN PDEVICE_OBJECT DeviceObject,
  43. IN PIRP Irp
  44. );
  45. BOOL
  46. DfsCheckLUIDDeviceMapsEnabled(
  47. VOID
  48. );
  49. //
  50. // Globals
  51. //
  52. HANDLE DfsDirHandle = NULL;
  53. BOOL DfsLUIDDeviceMapsEnabled = FALSE;
  54. #ifdef ALLOC_PRAGMA
  55. #pragma alloc_text(INIT, DfsDriverEntry)
  56. #pragma alloc_text(PAGE, DfsDeleteDevices)
  57. #pragma alloc_text(PAGE, DfsUnload)
  58. #pragma alloc_text(PAGE, DfsShutdown)
  59. //
  60. // The following routine should not be pageable, because it gets called by
  61. // the NT timer routine frequently. We don't want to thrash.
  62. //
  63. // DfsIoTimerRoutine
  64. //
  65. #endif // ALLOC_PRAGMA
  66. //
  67. // This macro takes a pointer (or ulong) and returns its rounded up quadword
  68. // value
  69. //
  70. #define QuadAlign(Ptr) ( \
  71. ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
  72. )
  73. //+-------------------------------------------------------------------
  74. //
  75. // Function: DfsDriverEntry, main entry point
  76. //
  77. // Synopsis: This is the initialization routine for the Dfs file system
  78. // device driver. This routine creates the device object for
  79. // the FileSystem device and performs all other driver
  80. // initialization.
  81. //
  82. // Arguments: [DriverObject] -- Pointer to driver object created by the
  83. // system.
  84. // [RegistryPath] -- Path to section in registry describing
  85. // this driver's configuration.
  86. //
  87. // Returns: [NTSTATUS] - The function value is the final status from
  88. // the initialization operation.
  89. //
  90. //--------------------------------------------------------------------
  91. NTSTATUS
  92. DfsDriverEntry(
  93. IN PDRIVER_OBJECT DriverObject,
  94. IN PUNICODE_STRING RegistryPath
  95. ) {
  96. NTSTATUS Status;
  97. UNICODE_STRING UnicodeString;
  98. PDEVICE_OBJECT DeviceObject;
  99. OBJECT_ATTRIBUTES ObjectAttributes;
  100. PWSTR p;
  101. int i;
  102. IO_STATUS_BLOCK iosb;
  103. LUID LogonID = SYSTEM_LUID;
  104. #if DBG
  105. //
  106. // If debug, get debug flags
  107. //
  108. MupGetDebugFlags();
  109. #endif
  110. //
  111. // Get the event logging level
  112. //
  113. DfsGetEventLogValue();
  114. //
  115. // See if someone else has already created a File System Device object
  116. // with the name we intend to use. If so, we bail.
  117. //
  118. RtlInitUnicodeString( &UnicodeString, DFS_DRIVER_NAME );
  119. //
  120. // Create the filesystem device object.
  121. //
  122. Status = IoCreateDevice( DriverObject,
  123. 0,
  124. &UnicodeString,
  125. FILE_DEVICE_DFS_FILE_SYSTEM,
  126. FILE_REMOTE_DEVICE | FILE_DEVICE_SECURE_OPEN,
  127. FALSE,
  128. &DeviceObject );
  129. if ( !NT_SUCCESS( Status ) ) {
  130. return Status;
  131. }
  132. //
  133. // Create a permanent object directory in which the logical root
  134. // device objects will reside. Make the directory temporary, so
  135. // we can just close the handle to make it go away.
  136. //
  137. UnicodeString.Buffer = p = LogicalRootDevPath;
  138. UnicodeString.Length = 0;
  139. UnicodeString.MaximumLength = MAX_LOGICAL_ROOT_LEN;
  140. while (*p++ != UNICODE_NULL)
  141. UnicodeString.Length += sizeof (WCHAR);
  142. InitializeObjectAttributes(
  143. &ObjectAttributes,
  144. &UnicodeString,
  145. 0,
  146. NULL,
  147. NULL );
  148. Status = ZwCreateDirectoryObject(
  149. &DfsDirHandle,
  150. DIRECTORY_ALL_ACCESS,
  151. &ObjectAttributes);
  152. if ( !NT_SUCCESS( Status ) ) {
  153. IoDeleteDevice (DeviceObject);
  154. return Status;
  155. }
  156. p[-1] = UNICODE_PATH_SEP;
  157. UnicodeString.Length += sizeof (WCHAR);
  158. //
  159. // Initialize the driver object with this driver's entry points.
  160. // Most are simply passed through to some other device driver.
  161. //
  162. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  163. DriverObject->MajorFunction[i] = DfsVolumePassThrough;
  164. }
  165. DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)DfsFsdCreate;
  166. DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)DfsFsdClose;
  167. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)DfsFsdCleanup;
  168. DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdQueryInformation;
  169. DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdSetInformation;
  170. DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)DfsFsdFileSystemControl;
  171. DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]= (PDRIVER_DISPATCH)DfsFsdQueryVolumeInformation;
  172. DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]= (PDRIVER_DISPATCH)DfsFsdSetVolumeInformation;
  173. DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DfsShutdown;
  174. DriverObject->FastIoDispatch = &FastIoDispatch;
  175. Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject, &FsFilterCallbacks );
  176. if (!NT_SUCCESS( Status )) {
  177. ZwClose (DfsDirHandle);
  178. IoDeleteDevice (DeviceObject);
  179. goto ErrorOut;
  180. }
  181. //
  182. // Initialize the global data structures
  183. //
  184. RtlZeroMemory(&DfsData, sizeof (DFS_DATA));
  185. DfsData.NodeTypeCode = DSFS_NTC_DATA_HEADER;
  186. DfsData.NodeByteSize = sizeof( DFS_DATA );
  187. InitializeListHead( &DfsData.VcbQueue );
  188. InitializeListHead( &DfsData.DeletedVcbQueue );
  189. // Initialize the devless root queue: this holds all the device less
  190. // net uses.
  191. InitializeListHead( &DfsData.DrtQueue );
  192. InitializeListHead( &DfsData.Credentials );
  193. InitializeListHead( &DfsData.DeletedCredentials );
  194. InitializeListHead( &DfsData.OfflineRoots );
  195. DfsData.DriverObject = DriverObject;
  196. DfsData.FileSysDeviceObject = DeviceObject;
  197. DfsData.LogRootDevName = UnicodeString;
  198. ExInitializeResourceLite( &DfsData.Resource );
  199. KeInitializeEvent( &DfsData.PktWritePending, NotificationEvent, TRUE );
  200. KeInitializeSemaphore( &DfsData.PktReferralRequests, 1, 1 );
  201. DfsData.MachineState = DFS_CLIENT;
  202. //
  203. // Allocate Provider structures.
  204. //
  205. DfsData.pProvider = ExAllocatePoolWithTag(
  206. PagedPool,
  207. sizeof ( PROVIDER_DEF ) * MAX_PROVIDERS,
  208. ' puM');
  209. if (DfsData.pProvider == NULL) {
  210. ZwClose (DfsDirHandle);
  211. IoDeleteDevice (DeviceObject);
  212. Status = STATUS_INSUFFICIENT_RESOURCES;
  213. goto ErrorOut;
  214. }
  215. for (i = 0; i < MAX_PROVIDERS; i++) {
  216. DfsData.pProvider[i].NodeTypeCode = DSFS_NTC_PROVIDER;
  217. DfsData.pProvider[i].NodeByteSize = sizeof ( PROVIDER_DEF );
  218. }
  219. DfsData.cProvider = 0;
  220. DfsData.maxProvider = MAX_PROVIDERS;
  221. //
  222. // Initialize the system wide PKT
  223. //
  224. PktInitialize(&DfsData.Pkt);
  225. {
  226. ULONG SystemSizeMultiplier;
  227. switch (MmQuerySystemSize()) {
  228. default:
  229. case MmSmallSystem:
  230. SystemSizeMultiplier = 4;
  231. break;
  232. case MmMediumSystem:
  233. SystemSizeMultiplier = 8;
  234. break;
  235. case MmLargeSystem:
  236. SystemSizeMultiplier = 16;
  237. break;
  238. }
  239. //
  240. // Allocate the DFS_FCB hash table structure. The number of
  241. // hash buckets will depend upon the memory size of the system.
  242. //
  243. Status = DfsInitFcbs(SystemSizeMultiplier * 2);
  244. if (!NT_SUCCESS (Status)) {
  245. PktUninitialize(&DfsData.Pkt);
  246. ExFreePool (DfsData.pProvider);
  247. ZwClose (DfsDirHandle);
  248. IoDeleteDevice (DeviceObject);
  249. goto ErrorOut;
  250. }
  251. //
  252. // Create a lookaside for the IRP contexts
  253. //
  254. ExInitializeNPagedLookasideList (&DfsData.IrpContextLookaside,
  255. NULL,
  256. NULL,
  257. 0,
  258. sizeof(IRP_CONTEXT),
  259. 'IpuM',
  260. 10 // unused
  261. );
  262. }
  263. //
  264. // Set up global pointer to the system process.
  265. //
  266. DfsData.OurProcess = PsGetCurrentProcess();
  267. //
  268. // Set up the global pointers for the EA buffers to be used to differentiate
  269. // CSC agent opens from non CSC agent opens. This is a read only buffer used
  270. // to distinguish the CSC agent requests
  271. //
  272. //
  273. {
  274. UCHAR EaNameCSCAgentSize = (UCHAR) (ROUND_UP_COUNT(
  275. strlen(EA_NAME_CSCAGENT) + sizeof(CHAR),
  276. ALIGN_DWORD
  277. ) - sizeof(CHAR));
  278. DfsData.CSCEaBufferLength = ROUND_UP_COUNT(
  279. FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
  280. EaNameCSCAgentSize + sizeof(CHAR),
  281. ALIGN_DWORD
  282. );
  283. DfsData.CSCEaBuffer = ExAllocatePoolWithTag(
  284. PagedPool,
  285. DfsData.CSCEaBufferLength,
  286. ' puM');
  287. if (DfsData.CSCEaBuffer != NULL) {
  288. // clear the buffer, otherwise so we don't get any spurious
  289. // failure due to IO manager checks
  290. memset(DfsData.CSCEaBuffer, 0, DfsData.CSCEaBufferLength);
  291. RtlCopyMemory(
  292. (LPSTR)DfsData.CSCEaBuffer->EaName,
  293. EA_NAME_CSCAGENT,
  294. EaNameCSCAgentSize);
  295. DfsData.CSCEaBuffer->EaNameLength = EaNameCSCAgentSize;
  296. DfsData.CSCEaBuffer->EaValueLength = 0;
  297. DfsData.CSCEaBuffer->NextEntryOffset = 0;
  298. } else {
  299. ExDeleteNPagedLookasideList (&DfsData.IrpContextLookaside);
  300. DfsUninitFcbs ();
  301. PktUninitialize(&DfsData.Pkt);
  302. ExFreePool (DfsData.pProvider);
  303. ZwClose (DfsDirHandle);
  304. IoDeleteDevice (DeviceObject);
  305. Status = STATUS_INSUFFICIENT_RESOURCES;
  306. DfsDbgTrace(-1, DEBUG_TRACE_ERROR, "Failed to allocate CSC ea buffer %08lx\n", ULongToPtr(Status) );
  307. return Status;
  308. }
  309. }
  310. //
  311. // Register the file system with the I/O system. We don't need to invert this as its never registered.
  312. //
  313. IoRegisterFileSystem( DeviceObject );
  314. Status = IoRegisterShutdownNotification (DeviceObject); // This is automaticaly removed when IoDeleteDevice is called
  315. if (!NT_SUCCESS (Status)) {
  316. ExFreePool (DfsData.CSCEaBuffer);
  317. ExDeleteNPagedLookasideList (&DfsData.IrpContextLookaside);
  318. DfsUninitFcbs ();
  319. PktUninitialize(&DfsData.Pkt);
  320. ExFreePool (DfsData.pProvider);
  321. ZwClose (DfsDirHandle);
  322. IoDeleteDevice (DeviceObject);
  323. return Status;
  324. }
  325. //
  326. // Initialize the provider definitions from the registry.
  327. //
  328. if (!NT_SUCCESS( ProviderInit() )) {
  329. DfsDbgTrace(0,DEBUG_TRACE_ERROR,
  330. "Could not initialize some or all providers!\n", 0);
  331. }
  332. //
  333. // Check if LUID device maps are enabled
  334. //
  335. DfsLUIDDeviceMapsEnabled = DfsCheckLUIDDeviceMapsEnabled();
  336. //
  337. // Initialize the logical roots device objects. These are what form the
  338. // link between the outside world and the Dfs driver.
  339. //
  340. #ifdef TERMSRV
  341. Status = DfsInitializeLogicalRoot( DD_DFS_DEVICE_NAME, NULL, NULL, 0, INVALID_SESSIONID, &LogonID);
  342. #else // TERMSRV
  343. Status = DfsInitializeLogicalRoot( DD_DFS_DEVICE_NAME, NULL, NULL, 0, &LogonID);
  344. #endif // TERMSRV
  345. if (!NT_SUCCESS(Status)) {
  346. DfsDbgTrace(-1, DEBUG_TRACE_ERROR, "Failed creation of root logical root %08lx\n", ULongToPtr(Status) );
  347. ExDeleteNPagedLookasideList (&DfsData.IrpContextLookaside);
  348. DfsUninitFcbs ();
  349. PktUninitialize(&DfsData.Pkt);
  350. ExFreePool (DfsData.pProvider);
  351. ZwClose (DfsDirHandle);
  352. IoDeleteDevice (DeviceObject);
  353. return(Status);
  354. }
  355. //
  356. // Let us start off the Timer Routine.
  357. //
  358. RtlZeroMemory(&DfsTimerContext, sizeof(DFS_TIMER_CONTEXT));
  359. DfsTimerContext.InUse = FALSE;
  360. DfsTimerContext.TickCount = 0;
  361. //
  362. // 375929, io initialize timer, check return status.
  363. //
  364. Status = IoInitializeTimer( DeviceObject,
  365. DfsIoTimerRoutine,
  366. &DfsTimerContext );
  367. if (Status != STATUS_SUCCESS) {
  368. #ifdef TERMSRV
  369. DfsDeleteLogicalRoot (DD_DFS_DEVICE_NAME, FALSE, INVALID_SESSIONID, &LogonID);
  370. #else
  371. DfsDeleteLogicalRoot (DD_DFS_DEVICE_NAME, FALSE, &LogonID);
  372. #endif
  373. ExDeleteNPagedLookasideList (&DfsData.IrpContextLookaside);
  374. DfsUninitFcbs ();
  375. PktUninitialize(&DfsData.Pkt);
  376. ExFreePool (DfsData.pProvider);
  377. ZwClose (DfsDirHandle);
  378. IoDeleteDevice (DeviceObject);
  379. goto ErrorOut;
  380. }
  381. DfsDbgTrace(0, Dbg, "Initialized the Timer routine\n", 0);
  382. //
  383. // Let us start the timer now.
  384. //
  385. IoStartTimer(DeviceObject);
  386. DfsDbgTrace(-1, Dbg, "DfsDriverEntry exit STATUS_SUCCESS\n", 0);
  387. return STATUS_SUCCESS;
  388. ErrorOut:
  389. DfsDbgTrace(-1, DEBUG_TRACE_ERROR, "DfsDriverEntry exit %08lx\n", ULongToPtr(Status) );
  390. return Status;
  391. }
  392. NTSTATUS
  393. DfsShutdown (
  394. IN PDEVICE_OBJECT DeviceObject,
  395. IN PIRP Irp
  396. )
  397. {
  398. //
  399. // Unregister the file system object so we can unload
  400. //
  401. IoUnregisterFileSystem (DeviceObject);
  402. DfsCompleteRequest( NULL, Irp, STATUS_SUCCESS );
  403. return STATUS_SUCCESS;
  404. }
  405. //+----------------------------------------------------------------------------
  406. //
  407. // Function: DfsUnload
  408. //
  409. // Synopsis: Routine called at unload time to free resources
  410. //
  411. // Arguments: [DriverObject] -- Driver object of MUP
  412. //
  413. // Returns: Nothing
  414. //
  415. //-----------------------------------------------------------------------------
  416. VOID
  417. DfsUnload(
  418. IN PDRIVER_OBJECT DriverObject
  419. )
  420. {
  421. LUID LogonID = SYSTEM_LUID;
  422. IoStopTimer(DfsData.FileSysDeviceObject);
  423. #ifdef TERMSRV
  424. DfsDeleteLogicalRoot (DD_DFS_DEVICE_NAME, FALSE, INVALID_SESSIONID, &LogonID);
  425. #else
  426. DfsDeleteLogicalRoot (DD_DFS_DEVICE_NAME, FALSE, &LogonID);
  427. #endif
  428. ExFreePool (DfsData.CSCEaBuffer);
  429. ExDeleteNPagedLookasideList (&DfsData.IrpContextLookaside);
  430. DfsUninitFcbs ();
  431. PktUninitialize(&DfsData.Pkt);
  432. ExFreePool (DfsData.pProvider);
  433. ExDeleteResourceLite( &DfsData.Resource );
  434. ZwClose (DfsDirHandle);
  435. IoDeleteDevice (DfsData.FileSysDeviceObject);
  436. }
  437. //+----------------------------------------------------------------------------
  438. //
  439. // Function: DfsDeleteDevices
  440. //
  441. // Synopsis: Routine to scavenge deleted devices (net uses).
  442. //
  443. // Arguments: [pDfsTimerContext] -- Timer Context
  444. //
  445. // Returns: Nothing - this routine is meant to be queued to a worker
  446. // thread.
  447. //
  448. //-----------------------------------------------------------------------------
  449. VOID
  450. DfsDeleteDevices(
  451. PDFS_TIMER_CONTEXT DfsTimerContext)
  452. {
  453. PLIST_ENTRY plink;
  454. PDFS_VCB Vcb;
  455. PLOGICAL_ROOT_DEVICE_OBJECT DeletedObject;
  456. if (DfsData.DeletedVcbQueue.Flink != &DfsData.DeletedVcbQueue) {
  457. DfsDbgTrace(0, Dbg, "Examining Deleted Vcbs...\n", 0);
  458. ExAcquireResourceExclusiveLite(&DfsData.Resource, TRUE);
  459. for (plink = DfsData.DeletedVcbQueue.Flink;
  460. plink != &DfsData.DeletedVcbQueue;
  461. NOTHING) {
  462. Vcb = CONTAINING_RECORD(
  463. plink,
  464. DFS_VCB,
  465. VcbLinks);
  466. plink = plink->Flink;
  467. DeletedObject = CONTAINING_RECORD(
  468. Vcb,
  469. LOGICAL_ROOT_DEVICE_OBJECT,
  470. Vcb);
  471. if (Vcb->OpenFileCount == 0 &&
  472. Vcb->DirectAccessOpenCount == 0 &&
  473. DeletedObject->DeviceObject.ReferenceCount == 0) {
  474. DfsDbgTrace(0, Dbg, "Deleting Vcb@%08lx\n", Vcb);
  475. if (Vcb->LogRootPrefix.Buffer != NULL)
  476. ExFreePool(Vcb->LogRootPrefix.Buffer);
  477. if (Vcb->LogicalRoot.Buffer != NULL)
  478. ExFreePool(Vcb->LogicalRoot.Buffer);
  479. RemoveEntryList(&Vcb->VcbLinks);
  480. ObDereferenceObject((PVOID) DeletedObject);
  481. IoDeleteDevice( &DeletedObject->DeviceObject );
  482. } else {
  483. DfsDbgTrace(0, Dbg, "Not deleting Vcb@%08lx\n", Vcb);
  484. DfsDbgTrace(0, Dbg,
  485. "OpenFileCount = %d\n", ULongToPtr(Vcb->OpenFileCount) );
  486. DfsDbgTrace(0, Dbg,
  487. "DirectAccessOpens = %d\n", ULongToPtr(Vcb->DirectAccessOpenCount) );
  488. DfsDbgTrace(0, Dbg,
  489. "DeviceObject Reference count = %d\n",
  490. ULongToPtr(DeletedObject->DeviceObject.ReferenceCount) );
  491. }
  492. }
  493. ExReleaseResourceLite(&DfsData.Resource);
  494. }
  495. DfsTimerContext->InUse = FALSE;
  496. }
  497. //+-------------------------------------------------------------------------
  498. //
  499. // Function: DfsIoTimerRoutine
  500. //
  501. // Synopsis: This function gets called by IO Subsystem once every second.
  502. // This can be used for various purposes in the driver. For now,
  503. // it periodically posts a request to a system thread to age Pkt
  504. // Entries.
  505. //
  506. // Arguments: [Context] -- This is the context information. It is actually
  507. // a pointer to a DFS_TIMER_CONTEXT.
  508. // [DeviceObject] -- Pointer to the Device object for DFS. We dont
  509. // really use this here.
  510. //
  511. // Returns: Nothing
  512. //
  513. // Notes: The Context which we get here is assumed to have all the
  514. // required fields setup properly.
  515. //
  516. // History: 04/24/93 SudK Created.
  517. //
  518. //--------------------------------------------------------------------------
  519. VOID
  520. DfsIoTimerRoutine(
  521. IN PDEVICE_OBJECT DeviceObject,
  522. IN PVOID Context
  523. )
  524. {
  525. PDFS_TIMER_CONTEXT pDfsTimerContext = (PDFS_TIMER_CONTEXT) Context;
  526. DfsDbgTrace(+1, Dbg, "DfsIoTimerRoutine: Entered\n", 0);
  527. //
  528. // If the DfsTimerContext is in USE then we just return blindly. Due to
  529. // this action we might actually lose some ticks. But then we really are
  530. // not very particular about this and hence dont care.
  531. //
  532. if (pDfsTimerContext->InUse == TRUE) {
  533. DfsDbgTrace(-1, Dbg, "DfsIoTimerRoutine: TimerContext in use\n", 0);
  534. return;
  535. }
  536. //
  537. // First let us increment the count in the DFS_TIMER_CONTEXT. If it has
  538. // reached a bound value then we have to go ahead and schedule the
  539. // necessary work items.
  540. //
  541. pDfsTimerContext->TickCount++;
  542. if (pDfsTimerContext->TickCount == DFS_MAX_TICKS) {
  543. DfsDbgTrace(0, Dbg, "Queuing Pkt Entry Scavenger\n", 0);
  544. pDfsTimerContext->InUse = TRUE;
  545. ExInitializeWorkItem(
  546. &pDfsTimerContext->WorkQueueItem,
  547. DfsAgePktEntries,
  548. pDfsTimerContext);
  549. ExQueueWorkItem( &pDfsTimerContext->WorkQueueItem, DelayedWorkQueue);
  550. } else if (DfsData.DeletedVcbQueue.Flink != &DfsData.DeletedVcbQueue) {
  551. DfsDbgTrace(0, Dbg, "Queueing Deleted Vcb Scavenger\n", 0);
  552. pDfsTimerContext->InUse = TRUE;
  553. ExInitializeWorkItem(
  554. &pDfsTimerContext->DeleteQueueItem,
  555. DfsDeleteDevices,
  556. pDfsTimerContext);
  557. ExQueueWorkItem(&pDfsTimerContext->DeleteQueueItem, DelayedWorkQueue);
  558. }
  559. DfsDbgTrace(-1, Dbg, "DfsIoTimerRoutine: Exiting\n", 0);
  560. }
  561. //+-------------------------------------------------------------------------
  562. //
  563. // Function: DfsCheckLUIDDeviceMapsEnabled
  564. //
  565. // Synopsis: This function calls ZwQueryInformationProcess to determine if
  566. // LUID device maps are enabled/disabled
  567. //
  568. // Arguments: NONE
  569. //
  570. // Returns:
  571. // TRUE - LUID device maps are enabled
  572. //
  573. // FALSE - LUID device maps are disabled
  574. //
  575. //--------------------------------------------------------------------------
  576. BOOL
  577. DfsCheckLUIDDeviceMapsEnabled(
  578. VOID
  579. )
  580. {
  581. NTSTATUS Status;
  582. ULONG LUIDDeviceMapsEnabled;
  583. BOOL Result;
  584. Status = ZwQueryInformationProcess( NtCurrentProcess(),
  585. ProcessLUIDDeviceMapsEnabled,
  586. &LUIDDeviceMapsEnabled,
  587. sizeof(LUIDDeviceMapsEnabled),
  588. NULL
  589. );
  590. if (!NT_SUCCESS(Status)) {
  591. DfsDbgTrace(
  592. -1,
  593. DEBUG_TRACE_ERROR,
  594. "DfsCheckLUIDDeviceMapsEnabled to failed to check if LUID device maps enabled, status = %08lx\n",
  595. ULongToPtr(Status));
  596. Result = FALSE;
  597. }
  598. else {
  599. Result = (LUIDDeviceMapsEnabled != 0);
  600. }
  601. return( Result );
  602. }