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.

664 lines
16 KiB

  1. //+----------------------------------------------------------------------------//+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996, Microsoft Corporation
  4. //
  5. // File: dfsinit.c
  6. //
  7. // Contents: Driver initialization routine for the Dfs server.
  8. //
  9. // Classes: None
  10. //
  11. // Functions: DriverEntry -- Entry point for driver
  12. // DfsCreateMachineName -- Routine to query this computers name
  13. //
  14. //-----------------------------------------------------------------------------
  15. #include "dfsprocs.h"
  16. #include "attach.h"
  17. #include "fastio.h"
  18. #include "registry.h"
  19. #include "regkeys.h"
  20. //
  21. // The following are includes for init modules, which will get discarded when
  22. // the driver has finished loading.
  23. //
  24. #include "provider.h"
  25. #include "localvol.h"
  26. #include "lvolinit.h"
  27. #include "sitesup.h"
  28. #include "ipsup.h"
  29. #include "spcsup.h"
  30. #include "dfswml.h"
  31. //
  32. // The debug trace level
  33. //
  34. #define Dbg (DEBUG_TRACE_INIT)
  35. NTSTATUS
  36. DriverEntry(
  37. IN PDRIVER_OBJECT DriverObject,
  38. IN PUNICODE_STRING RegistryPath
  39. );
  40. VOID
  41. DfsUnload(
  42. IN PDRIVER_OBJECT DriverObject);
  43. NTSTATUS
  44. DfsCreateMachineName(void);
  45. VOID
  46. DfsDeleteMachineName (
  47. VOID);
  48. #if DBG
  49. VOID
  50. DfsGetDebugFlags(void);
  51. #endif
  52. VOID
  53. DfsGetEventLogValue(VOID);
  54. #ifdef ALLOC_PRAGMA
  55. #pragma alloc_text( INIT, DfsCreateMachineName)
  56. #pragma alloc_text( INIT, DriverEntry)
  57. #pragma alloc_text( PAGE, DfsDeleteMachineName)
  58. #pragma alloc_text( PAGE, DfsGetEventLogValue )
  59. #pragma alloc_text( PAGE, DfsUnload)
  60. #if DBG
  61. #pragma alloc_text( PAGE, DfsGetDebugFlags )
  62. #endif
  63. #endif // ALLOC_PRAGMA
  64. //
  65. // This macro takes a pointer (or ulong) and returns its rounded up quadword
  66. // value
  67. //
  68. #define QuadAlign(Ptr) ( \
  69. ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
  70. )
  71. NTSTATUS DfsDrvWmiDispatch(PDEVICE_OBJECT p, PIRP i);
  72. //+-------------------------------------------------------------------
  73. //
  74. // Function: DriverEntry, main entry point
  75. //
  76. // Synopsis: This is the initialization routine for the DFS file system
  77. // device driver. This routine creates the device object for
  78. // the FileSystem device and performs all other driver
  79. // initialization.
  80. //
  81. // Arguments: [DriverObject] -- Pointer to driver object created by the
  82. // system.
  83. //
  84. // Returns: [NTSTATUS] - The function value is the final status from
  85. // the initialization operation.
  86. //
  87. //--------------------------------------------------------------------
  88. NTSTATUS
  89. DriverEntry(
  90. IN PDRIVER_OBJECT DriverObject,
  91. IN PUNICODE_STRING RegistryPath
  92. ) {
  93. NTSTATUS Status;
  94. UNICODE_STRING UnicodeString;
  95. PDEVICE_OBJECT DeviceObject;
  96. OBJECT_ATTRIBUTES ObjectAttributes;
  97. PWSTR p;
  98. int i;
  99. HANDLE hTemp;
  100. HANDLE DirHandle;
  101. PBYTE pData;
  102. DebugTrace(0, Dbg, "***********Dfs DriverEntry()\n", 0);
  103. DfsData.OperationalState = DFS_STATE_UNINITIALIZED;
  104. DfsData.LvState = LV_UNINITIALIZED;
  105. //
  106. // Create the filesystem device object.
  107. //
  108. RtlInitUnicodeString( &UnicodeString, DFS_SERVER_NAME );
  109. Status = IoCreateDevice( DriverObject,
  110. 0,
  111. &UnicodeString,
  112. FILE_DEVICE_DFS_FILE_SYSTEM,
  113. FILE_REMOTE_DEVICE | FILE_DEVICE_SECURE_OPEN,
  114. FALSE,
  115. &DeviceObject );
  116. if ( !NT_SUCCESS( Status ) ) {
  117. return Status;
  118. }
  119. DriverObject->DriverUnload = DfsUnload;
  120. //
  121. // Initialize the driver object with this driver's entry points.
  122. // Most are simply passed through to some other device driver.
  123. //
  124. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  125. DriverObject->MajorFunction[i] = DfsVolumePassThrough;
  126. }
  127. DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)DfsFsdCreate;
  128. DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)DfsFsdClose;
  129. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)DfsFsdCleanup;
  130. DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdSetInformation;
  131. DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)DfsFsdFileSystemControl;
  132. DriverObject->FastIoDispatch = &FastIoDispatch;
  133. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
  134. (PDRIVER_DISPATCH) DfsDrvWmiDispatch;
  135. Status = IoWMIRegistrationControl (DeviceObject, WMIREG_ACTION_REGISTER);
  136. //
  137. // Initialize the global data structures
  138. //
  139. RtlZeroMemory(&DfsData, sizeof (DFS_DATA));
  140. DfsData.NodeTypeCode = DFS_NTC_DATA_HEADER;
  141. DfsData.NodeByteSize = sizeof( DFS_DATA );
  142. InitializeListHead( &DfsData.AVdoQueue );
  143. InitializeListHead( &DfsData.AFsoQueue );
  144. //
  145. // Init assorted hash tables
  146. //
  147. Status = DfsInitFcbs( 0 );
  148. if (!NT_SUCCESS(Status)) {
  149. IoDeleteDevice (DeviceObject);
  150. return Status;
  151. }
  152. Status = DfsInitSites( 0 );
  153. if (!NT_SUCCESS(Status)) {
  154. DfsUninitFcbs ();
  155. IoDeleteDevice (DeviceObject);
  156. return Status;
  157. }
  158. Status = DfsInitSpcHashTable( &DfsData.SpcHashTable, 0 );
  159. if (!NT_SUCCESS(Status)) {
  160. DfsUninitSites ();
  161. DfsUninitFcbs ();
  162. IoDeleteDevice (DeviceObject);
  163. return Status;
  164. }
  165. Status = DfsInitSpcHashTable( &DfsData.FtDfsHashTable, 0 );
  166. if (!NT_SUCCESS(Status)) {
  167. DfsUninitSpcHashTable (DfsData.SpcHashTable);
  168. DfsUninitSites ();
  169. DfsUninitFcbs ();
  170. IoDeleteDevice (DeviceObject);
  171. return Status;
  172. }
  173. Status = DfsInitIp( 0, 0 );
  174. if (!NT_SUCCESS(Status)) {
  175. DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
  176. DfsUninitSpcHashTable (DfsData.SpcHashTable);
  177. DfsUninitSites ();
  178. DfsUninitFcbs ();
  179. IoDeleteDevice (DeviceObject);
  180. return Status;
  181. }
  182. DfsData.DriverObject = DriverObject;
  183. DfsData.FileSysDeviceObject = DeviceObject;
  184. ExInitializeResourceLite( &DfsData.Resource );
  185. DfsData.MachineState = DFS_UNKNOWN;
  186. DfsData.IsDC = FALSE;
  187. DfsCreateMachineName();
  188. DfsData.Pkt.DefaultTimeToLive = DEFAULT_PKT_ENTRY_TIMEOUT;
  189. //
  190. // Override special name table timeout with registry entry
  191. //
  192. Status = KRegSetRoot(wszRegDfsDriver);
  193. if (NT_SUCCESS(Status)) {
  194. Status = KRegGetValue(
  195. L"",
  196. wszDefaultTimeToLive,
  197. (PVOID ) &pData);
  198. KRegCloseRoot();
  199. if (NT_SUCCESS(Status)) {
  200. DfsData.Pkt.DefaultTimeToLive = *((ULONG*)pData);
  201. ExFreePool(pData);
  202. }
  203. }
  204. //
  205. // Initialize Lpc struct
  206. //
  207. RtlInitUnicodeString(&DfsData.DfsLpcInfo.LpcPortName, NULL);
  208. DfsData.DfsLpcInfo.LpcPortState = LPC_STATE_UNINITIALIZED;
  209. ExInitializeFastMutex(&DfsData.DfsLpcInfo.LpcPortMutex);
  210. DfsData.DfsLpcInfo.LpcPortHandle = NULL;
  211. ExInitializeResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
  212. //
  213. // Initialize the system wide PKT
  214. //
  215. Status = PktInitialize(&DfsData.Pkt);
  216. if (!NT_SUCCESS(Status)) {
  217. ExDeleteResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
  218. DfsDeleteMachineName();
  219. ExDeleteResourceLite( &DfsData.Resource );
  220. DfsUninitIp ();
  221. DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
  222. DfsUninitSpcHashTable (DfsData.SpcHashTable);
  223. DfsUninitSites ();
  224. DfsUninitFcbs ();
  225. IoDeleteDevice (DfsData.FileSysDeviceObject);
  226. return Status;
  227. }
  228. //
  229. // Set up global pointer to the system process.
  230. //
  231. DfsData.OurProcess = PsGetCurrentProcess();
  232. //
  233. // Register for callbacks when other file systems are loaded
  234. //
  235. Status = IoRegisterFsRegistrationChange( DriverObject, DfsFsNotification );
  236. if (!NT_SUCCESS (Status)) {
  237. PktUninitialize(&DfsData.Pkt);
  238. ExDeleteResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
  239. DfsDeleteMachineName();
  240. ExDeleteResourceLite( &DfsData.Resource );
  241. DfsUninitIp ();
  242. DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
  243. DfsUninitSpcHashTable (DfsData.SpcHashTable);
  244. DfsUninitSites ();
  245. DfsUninitFcbs ();
  246. IoDeleteDevice (DfsData.FileSysDeviceObject);
  247. return Status;
  248. }
  249. //
  250. // Finally, mark our state to being INITIALIZED
  251. //
  252. DfsData.OperationalState = DFS_STATE_INITIALIZED;
  253. return STATUS_SUCCESS;
  254. }
  255. //+---------------------------------------------------------------------
  256. //
  257. // Function: DfsUnload()
  258. //
  259. // Synopsis: Driver unload routine
  260. //
  261. // Arguments: [DriverObject] -- The driver object created by the system
  262. //
  263. // Returns: Nothing
  264. //
  265. //----------------------------------------------------------------------
  266. VOID
  267. DfsUnload(
  268. IN PDRIVER_OBJECT DriverObject)
  269. {
  270. IoUnregisterFsRegistrationChange(DriverObject, DfsFsNotification);
  271. DfsDetachAllFileSystems ();
  272. PktUninitialize(&DfsData.Pkt);
  273. ExDeleteResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
  274. DfsDeleteMachineName();
  275. ExDeleteResourceLite( &DfsData.Resource );
  276. DfsUninitIp ();
  277. DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
  278. DfsUninitSpcHashTable (DfsData.SpcHashTable);
  279. DfsUninitSites ();
  280. DfsUninitFcbs ();
  281. IoDeleteDevice (DfsData.FileSysDeviceObject);
  282. }
  283. //+---------------------------------------------------------------------
  284. //
  285. // Function: DfsCreateMachineName()
  286. //
  287. // Synopsis: Gets the principal name of this machine by looking at
  288. // Registry.
  289. //
  290. // Arguments: [pustrName] -- The Service Name is to be filled in here.
  291. //
  292. // Returns: STATUS_SUCCESS -- If all went well.
  293. //
  294. //
  295. // History: 30 Mar 1993 SudK Created.
  296. //
  297. //----------------------------------------------------------------------
  298. NTSTATUS
  299. DfsCreateMachineName(void)
  300. {
  301. NTSTATUS status;
  302. UNICODE_STRING PName;
  303. PWCHAR pwszNetBIOSName;
  304. PWCHAR pwszComputerName;
  305. PWCHAR pwszDomainRoot;
  306. PWCHAR pwszOU;
  307. ULONG lOUNameLength;
  308. //
  309. // Now we have to go and get the computer name from the registry.
  310. //
  311. status = KRegSetRoot(wszRegComputerNameRt);
  312. if (NT_SUCCESS(status)) {
  313. status = KRegGetValue(
  314. wszRegComputerNameSubKey,
  315. wszRegComputerNameValue,
  316. (PVOID ) &pwszComputerName);
  317. KRegCloseRoot();
  318. if (NT_SUCCESS(status)) {
  319. RtlInitUnicodeString(
  320. &DfsData.NetBIOSName,
  321. pwszComputerName);
  322. RtlInitUnicodeString(
  323. &DfsData.PrincipalName,
  324. pwszComputerName);
  325. }
  326. }
  327. return(status);
  328. }
  329. VOID
  330. DfsDeleteMachineName (
  331. VOID)
  332. {
  333. ExFreePool (DfsData.NetBIOSName.Buffer);
  334. }
  335. VOID
  336. DfsGetEventLogValue(VOID)
  337. /*++
  338. Routine Description:
  339. This routine checks registry keys to set the event logging level
  340. Arguments:
  341. None
  342. Return Value:
  343. None
  344. --*/
  345. {
  346. NTSTATUS status;
  347. HANDLE DfsRegHandle;
  348. OBJECT_ATTRIBUTES ObjAttr;
  349. ULONG ValueSize;
  350. UNICODE_STRING DfsRegKey;
  351. UNICODE_STRING DfsValueName;
  352. struct {
  353. KEY_VALUE_PARTIAL_INFORMATION Info;
  354. ULONG Buffer;
  355. } DfsValue;
  356. PAGED_CODE();
  357. DebugTrace(0, Dbg, "DfsGetEventLogValue()\n", 0);
  358. RtlInitUnicodeString(
  359. &DfsRegKey,
  360. L"\\Registry\\Machine\\SOFTWARE\\MicroSoft\\Windows NT\\CurrentVersion\\Diagnostics");
  361. InitializeObjectAttributes(
  362. &ObjAttr,
  363. &DfsRegKey,
  364. OBJ_CASE_INSENSITIVE,
  365. 0,
  366. NULL);
  367. status = ZwOpenKey(
  368. &DfsRegHandle,
  369. KEY_QUERY_VALUE,
  370. &ObjAttr);
  371. if (!NT_SUCCESS(status))
  372. return;
  373. RtlInitUnicodeString(&DfsValueName, L"RunDiagnosticLoggingGlobal");
  374. status = ZwQueryValueKey(
  375. DfsRegHandle,
  376. &DfsValueName,
  377. KeyValuePartialInformation,
  378. (PVOID) &DfsValue,
  379. sizeof(DfsValue),
  380. &ValueSize);
  381. if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD) {
  382. DfsEventLog = *((PULONG) DfsValue.Info.Data);
  383. goto Cleanup;
  384. }
  385. RtlInitUnicodeString(&DfsValueName, L"RunDiagnosticLoggingDfs");
  386. status = ZwQueryValueKey(
  387. DfsRegHandle,
  388. &DfsValueName,
  389. KeyValuePartialInformation,
  390. (PVOID) &DfsValue,
  391. sizeof(DfsValue),
  392. &ValueSize);
  393. if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD)
  394. DfsEventLog = *((PULONG) DfsValue.Info.Data);
  395. Cleanup:
  396. ZwClose( DfsRegHandle );
  397. DebugTrace( 0, Dbg, "DfsGetEventLog exit DfsEventLog = 0x%x\n", ULongToPtr( DfsEventLog ));
  398. }
  399. //
  400. // DfspGetMaxReferrals: read from registry the maximum number of referrals
  401. // that we pass back to the client, and store this in the dfsdata.pkt
  402. //
  403. VOID
  404. DfspGetMaxReferrals(
  405. VOID)
  406. {
  407. NTSTATUS status;
  408. HANDLE DfsRegHandle;
  409. OBJECT_ATTRIBUTES ObjAttr;
  410. ULONG ValueSize;
  411. UNICODE_STRING DfsRegKey;
  412. UNICODE_STRING DfsValueName;
  413. struct {
  414. KEY_VALUE_PARTIAL_INFORMATION Info;
  415. ULONG Buffer;
  416. } DfsValue;
  417. RtlInitUnicodeString(
  418. &DfsRegKey,
  419. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\DfsDriver");
  420. InitializeObjectAttributes(
  421. &ObjAttr,
  422. &DfsRegKey,
  423. OBJ_CASE_INSENSITIVE,
  424. 0,
  425. NULL);
  426. status = ZwOpenKey(
  427. &DfsRegHandle,
  428. KEY_QUERY_VALUE,
  429. &ObjAttr);
  430. if (!NT_SUCCESS(status))
  431. return;
  432. RtlInitUnicodeString(&DfsValueName, wszMaxReferrals);
  433. status = ZwQueryValueKey(
  434. DfsRegHandle,
  435. &DfsValueName,
  436. KeyValuePartialInformation,
  437. (PVOID) &DfsValue,
  438. sizeof(DfsValue),
  439. &ValueSize);
  440. if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD) {
  441. DfsData.Pkt.MaxReferrals = *((PULONG) DfsValue.Info.Data);
  442. // DbgPrint("Set MaxReferrals to %d\n", DfsData.Pkt.MaxReferrals);
  443. }
  444. ZwClose( DfsRegHandle );
  445. }
  446. #if DBG
  447. VOID
  448. DfsGetDebugFlags(
  449. VOID
  450. )
  451. /*++
  452. Routine Description:
  453. This routine reads Dfs debug flag settings from the registry
  454. Arguments:
  455. None.
  456. Return Value:
  457. None.
  458. --*/
  459. {
  460. HANDLE handle;
  461. NTSTATUS status;
  462. UNICODE_STRING valueName;
  463. UNICODE_STRING keyName;
  464. OBJECT_ATTRIBUTES objectAttributes;
  465. PWCH providerName;
  466. ULONG lengthRequired;
  467. ULONG Flags = 0;
  468. union {
  469. KEY_VALUE_FULL_INFORMATION;
  470. UCHAR buffer[ sizeof( KEY_VALUE_FULL_INFORMATION ) + 100 ];
  471. } keyValueInformation;
  472. PAGED_CODE();
  473. RtlInitUnicodeString(
  474. &keyName,
  475. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Dfs");
  476. InitializeObjectAttributes(
  477. &objectAttributes,
  478. &keyName,
  479. OBJ_CASE_INSENSITIVE,
  480. 0,
  481. NULL);
  482. status = ZwOpenKey(
  483. &handle,
  484. KEY_QUERY_VALUE,
  485. &objectAttributes);
  486. if (!NT_SUCCESS(status))
  487. return;
  488. RtlInitUnicodeString( &valueName, L"DfsDebugTraceLevelServer" );
  489. status = ZwQueryValueKey(
  490. handle,
  491. &valueName,
  492. KeyValueFullInformation,
  493. &keyValueInformation,
  494. sizeof(keyValueInformation),
  495. &lengthRequired
  496. );
  497. if (
  498. NT_SUCCESS(status) &&
  499. keyValueInformation.Type == REG_DWORD &&
  500. keyValueInformation.DataLength != 0
  501. ) {
  502. Flags = *(PULONG)(((PUCHAR)(&keyValueInformation)) + keyValueInformation.DataOffset);
  503. DfsDebugTraceLevel = Flags;
  504. }
  505. ZwClose( handle );
  506. return;
  507. }
  508. #endif // DBG