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.

1718 lines
40 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1995, Microsoft Corporation
  4. //
  5. // File: dfsminit.cxx
  6. //
  7. // Contents: Initialization code for Dfs Manager service.
  8. //
  9. // Classes:
  10. //
  11. // Functions: DfsManager --
  12. // DfsInitGlobals --
  13. // InitializeDfsManager --
  14. // InitializeVolumeObject --
  15. // DfsHandleKnowledgeInconsistency --
  16. //
  17. //-----------------------------------------------------------------------------
  18. //#include <ntos.h>
  19. //#include <ntrtl.h>
  20. //#include <nturtl.h>
  21. //#include <dfsfsctl.h>
  22. //#include <windows.h>
  23. #include <headers.hxx>
  24. #pragma hdrstop
  25. #include <dfsfsctl.h> // For EA_NAME_OPENIFJP
  26. #include <dfsmsrv.h> // For public function
  27. #include <clusapi.h>
  28. #include <resapi.h>
  29. #include <winldap.h>
  30. #include "cdfsvol.hxx" // prototypes
  31. #include "localvol.hxx"
  32. #include "security.hxx"
  33. #include "dsgetdc.h"
  34. #include "setup.hxx"
  35. #include "dfsmwml.h"
  36. extern "C"
  37. DWORD
  38. DfsGetFtServersFromDs(
  39. PLDAP pLDAP,
  40. LPWSTR wszDomainName,
  41. LPWSTR wszDfsName,
  42. LPWSTR **List);
  43. DWORD
  44. DfspGetPdc(void);
  45. //
  46. // Debug variables
  47. //
  48. //WMILIB_REG_STRUCT DfsRtlWmiReg;
  49. ///GUID DfsmRtlTraceGuid = { // 08fbc600-67ac-4ae4-9f22-c51a4f82f6c9
  50. // 0x08fbc600, 0x67ac, 0x4ae4,
  51. // {
  52. // 0x9f, 0x22, 0xc5, 0x1a, 0x4f, 0x82, 0xf6, 0xc9
  53. // }
  54. //};
  55. //WML_DATA wml;
  56. DECLARE_INFOLEVEL(IDfsVol)
  57. //
  58. // Global variables.
  59. //
  60. CRITICAL_SECTION globalCritSec;
  61. ULONG ulDfsManagerType;
  62. WCHAR wszComputerName[MAX_PATH];
  63. LPWSTR pwszComputerName = NULL;
  64. WCHAR wszDomainName[MAX_PATH];
  65. LPWSTR pwszDomainName = NULL;
  66. WCHAR wszDfsRootName[MAX_PATH];
  67. LPWSTR pwszDfsRootName = NULL;
  68. WCHAR wszDSMachineName[MAX_PATH];
  69. LPWSTR pwszDSMachineName = NULL;
  70. //
  71. // Contains the name of the FtDfs, if we are an FtDfs root
  72. //
  73. WCHAR wszFtDfsName[MAX_PATH];
  74. LPWSTR pwszFtDfsName = NULL;
  75. //
  76. // If an FtDfs, this is the ldap connection we're using
  77. //
  78. PLDAP pLdapConnection = NULL;
  79. ULONG GTimeout = 0;
  80. extern "C" {
  81. ULONG DfsSvcVerbose = 0;
  82. ULONG DfsSvcLdap = 0;
  83. ULONG DfsEventLog = 0;
  84. ULONG DfsDnsConfig = 0;
  85. }
  86. BOOLEAN NetDfsInitDone = FALSE;
  87. HANDLE hSyncThread = NULL;
  88. HANDLE hSyncEvent = NULL;
  89. HANDLE hFrsSyncEvent = NULL;
  90. DWORD dwFrsSyncIntervalInMs = 1000 * 60; // 1 minute by default
  91. DWORD dwSyncIntervalInMs = 1000 * 60 * 60; // 1 hour by default
  92. DWORD dwSyncThreadId;
  93. ULONG DcLockIntervalInMs = 1000 * 60 * 60 * 2; // 2 hours by default
  94. CStorageDirectory *pDfsmStorageDirectory = NULL;
  95. CSites *pDfsmSites = NULL;
  96. #if (DBG == 1) || (_CT_TEST_HOOK == 1)
  97. RECOVERY_BREAK_POINT gRecoveryBkptInfo;
  98. #endif
  99. //
  100. // The name of the Dfs configuration container
  101. //
  102. WCHAR DfsConfigContainer[] = L"CN=Dfs-Configuration,CN=System";
  103. LPWSTR gConfigurationDN = NULL;
  104. //
  105. // Useful EA Buffer for opening Junction Points
  106. //
  107. CHAR EaBuffer[ sizeof(FILE_FULL_EA_INFORMATION) + sizeof(EA_NAME_OPENIFJP) ];
  108. PFILE_FULL_EA_INFORMATION pOpenIfJPEa = (PFILE_FULL_EA_INFORMATION) EaBuffer;
  109. ULONG cbOpenIfJPEa = sizeof(EaBuffer);
  110. DWORD
  111. InitializeVolumeObject(
  112. PWSTR pwszVolName,
  113. BOOLEAN bInitVol,
  114. BOOLEAN SyncRemoteServerName=FALSE);
  115. DWORD
  116. InitializeDfsManager(void);
  117. DWORD
  118. InitializeNetDfsInterface(void);
  119. DWORD
  120. DfsManagerStartDSSync();
  121. DWORD
  122. DfsManagerDSSyncThread(
  123. PVOID Context);
  124. DWORD
  125. GetSyncInterval();
  126. ULONG
  127. GetDcLockInterval();
  128. DWORD
  129. GetEntryTimeout();
  130. VOID
  131. GetDebugSwitches();
  132. VOID
  133. GetEventLogSwitches();
  134. VOID
  135. GetConfigSwitches();
  136. DWORD
  137. DfspGetFtDfsName();
  138. //+----------------------------------------------------------------------------
  139. //
  140. // Function: DfsManager
  141. //
  142. // Synopsis: Entry procedure for the main Dfs Manager service thread.
  143. // Initializes the Dfs Manager structures, creates the RPC
  144. // threads that will wait around listening for admin operation
  145. // calls, and lastly, creates a thread to monitor Knowledge
  146. // Sync calls from the driver.
  147. //
  148. // Arguments: [wszRootName] -- Name of dfs root for which this Dfs Manager
  149. // is being instantiated.
  150. // [dwType] -- Type of Dfs Manager being instantiated -
  151. // DFS_MANAGER_SERVER or DFS_MANAGER_FTDFS
  152. //
  153. // Returns: [ERROR_SUCCESS] -- If Dfs Manager started correctly.
  154. //
  155. // [ERROR_OUTOFMEMORY] -- If globals could not be allocated.
  156. //
  157. // Error from reading the Dfs Volume Objects.
  158. //
  159. // Win32 error from registering the RPC interface.
  160. //
  161. // Win32 error from creating the knowledge sync thread.
  162. //
  163. //-----------------------------------------------------------------------------
  164. DWORD
  165. DfsManager(
  166. LPWSTR wszRootName,
  167. DWORD dwType)
  168. {
  169. HANDLE hthreadSync;
  170. DWORD idThread;
  171. DWORD dwErr = ERROR_SUCCESS;
  172. HKEY hkey;
  173. DFS_NAME_CONVENTION NameType;
  174. //
  175. // Initialize the global data structures of Dfs Manager...
  176. //
  177. IDfsVolInlineDebOut((DEB_TRACE, "DfsManager(%ws,0x%x)\n", wszRootName, dwType));
  178. if (dwType == DFS_MANAGER_FTDFS) {
  179. dwErr = DfsInitGlobals(wszRootName, dwType);
  180. } else {
  181. NameType = DFS_NAMETYPE_EITHER;
  182. dwErr = GetDomAndComputerName(NULL, wszComputerName, &NameType);
  183. dwErr = DfsInitGlobals(wszComputerName, dwType);
  184. }
  185. if (dwErr != ERROR_SUCCESS) {
  186. IDfsVolInlineDebOut((DEB_ERROR, "DfsInitGlobals failed %08lx\n", dwErr));
  187. return(dwErr);
  188. }
  189. //
  190. // Initialize the NetDfs RPC interface...
  191. //
  192. dwErr = InitializeNetDfsInterface();
  193. if (dwErr != ERROR_SUCCESS) {
  194. IDfsVolInlineDebOut((DEB_ERROR, "InitializeNetDfsInterface failed %08lx\n", dwErr));
  195. return dwErr;
  196. }
  197. //
  198. // Read in all the Dfs volume objects and initialize them
  199. //
  200. ENTER_DFSM_OPERATION;
  201. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
  202. if (dwErr == ERROR_SUCCESS) {
  203. RegCloseKey( hkey );
  204. DfsmStopDfs();
  205. DfsmResetPkt();
  206. DfsmInitLocalPartitions();
  207. DfsmMarkStalePktEntries();
  208. InitializeVolumeObject( DOMAIN_ROOT_VOL, TRUE, (ulDfsManagerType == DFS_MANAGER_FTDFS)?TRUE:FALSE );
  209. DfsmFlushStalePktEntries();
  210. }
  211. DfsmStartDfs();
  212. DfsmPktFlushCache();
  213. EXIT_DFSM_OPERATION;
  214. if (dwErr != ERROR_SUCCESS)
  215. {
  216. IDfsVolInlineDebOut((DEB_ERROR, "InitializeDfsManager failed %08lx\n", dwErr));
  217. return dwErr;
  218. }
  219. if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
  220. //
  221. // Start the thread that does the DS sync
  222. //
  223. dwErr = DfsManagerStartDSSync();
  224. if (dwErr != ERROR_SUCCESS) {
  225. IDfsVolInlineDebOut((DEB_ERROR, "DfsManagerStartDSSync failed %08lx\n", dwErr));
  226. return(dwErr);
  227. }
  228. }
  229. IDfsVolInlineDebOut((DEB_TRACE, "DfsManager exit\n"));
  230. return ERROR_SUCCESS;
  231. } // DfsManager
  232. DWORD
  233. ClusCallBackFunction(
  234. HRESOURCE hSelf,
  235. HRESOURCE hResource,
  236. LPVOID lpNull)
  237. {
  238. DWORD Value = 0;
  239. DWORD dwStatus = ERROR_INVALID_HANDLE;
  240. HKEY hKey = NULL;
  241. HKEY hParamKey = NULL;
  242. WCHAR wszClusterName[MAX_PATH];
  243. ULONG cSize = MAX_PATH;
  244. hKey = GetClusterResourceKey(hResource, KEY_READ);
  245. if (hKey != NULL) {
  246. dwStatus = ClusterRegOpenKey( hKey, L"Parameters", KEY_READ, &hParamKey );
  247. DFSM_TRACE_ERROR_HIGH(dwStatus, ALL_ERROR, ClusCallBackFunction_Error_ClusterRegOpenKey,
  248. LOGSTATUS(dwStatus));
  249. }
  250. if (dwStatus != ERROR_SUCCESS)
  251. goto ExitWithStatus;
  252. ResUtilGetDwordValue(hParamKey, L"IsDfsRoot", &Value, 0);
  253. if (Value == 1
  254. &&
  255. GetClusterResourceNetworkName(hResource, wszClusterName, &cSize) == TRUE
  256. ) {
  257. #if DBG
  258. if (DfsSvcVerbose)
  259. DbgPrint("ClusCallBackFunction: ClusterName = [%ws]\n", wszClusterName);
  260. #endif
  261. wcscpy(wszDfsRootName, wszClusterName);
  262. wcscpy(wszComputerName, wszClusterName);
  263. } else {
  264. #if DBG
  265. if (DfsSvcVerbose)
  266. DbgPrint("ClusCallBackFunction: Not a root on a cluster.\n");
  267. #endif
  268. }
  269. ExitWithStatus:
  270. if (hKey != NULL)
  271. ClusterRegCloseKey(hKey);
  272. if (hParamKey != NULL)
  273. ClusterRegCloseKey(hParamKey);
  274. return dwStatus;
  275. }
  276. //+----------------------------------------------------------------------------
  277. //
  278. // Function: DfsInitGlobals
  279. //
  280. // Synopsis: Initialize the Dfs Manager globals.
  281. //
  282. // Arguments:
  283. //
  284. // Returns:
  285. //
  286. //-----------------------------------------------------------------------------
  287. extern "C" DWORD
  288. DfsInitGlobals(
  289. LPWSTR pwszRootName,
  290. DWORD dwType)
  291. {
  292. static BOOLEAN fInitDone = FALSE;
  293. DWORD dwErr = ERROR_SUCCESS;
  294. ULONG ulSize = MAX_PATH*sizeof(WCHAR);
  295. DFS_NAME_CONVENTION NameType;
  296. IDfsVolInlineDebOut((DEB_TRACE, "DfsInitGlobals(%ws, %x)\n", pwszRootName, dwType));
  297. //
  298. // Only do init once.
  299. //
  300. if ( !fInitDone ) {
  301. DebugInitialize();
  302. #if DBG
  303. GetDebugSwitches();
  304. if (DfsSvcVerbose)
  305. DbgPrint("DfsInitGlobals(%ws,%d)\n", pwszRootName, dwType);
  306. #endif
  307. GetEventLogSwitches();
  308. GetConfigSwitches();
  309. pwszDSMachineName = NULL;
  310. GTimeout = GetEntryTimeout();
  311. DcLockIntervalInMs = GetDcLockInterval();
  312. ulDfsManagerType = dwType;
  313. pOpenIfJPEa->NextEntryOffset = 0;
  314. pOpenIfJPEa->Flags = 0;
  315. pOpenIfJPEa->EaNameLength = strlen(EA_NAME_OPENIFJP);
  316. pOpenIfJPEa->EaValueLength = 0;
  317. strcpy(pOpenIfJPEa->EaName, EA_NAME_OPENIFJP);
  318. //
  319. // Must enforce exclusivity before the service starts.
  320. //
  321. InitializeCriticalSection(&globalCritSec);
  322. #if (DBG == 1) || (_CT_TEST_HOOK == 1)
  323. gRecoveryBkptInfo.BreakPt = 0xFFFFFFFF;
  324. gRecoveryBkptInfo.pwszApiBreak = NULL;
  325. #endif
  326. wcscpy(wszDfsRootName, pwszRootName);
  327. pwszDfsRootName = wszDfsRootName;
  328. //
  329. // Get computer and domain names
  330. //
  331. NameType = (ulDfsManagerType == DFS_MANAGER_FTDFS) ? DFS_NAMETYPE_DNS : DFS_NAMETYPE_EITHER;
  332. dwErr = GetDomAndComputerName(wszDomainName, wszComputerName, &NameType);
  333. if (dwErr == NERR_Success) {
  334. pwszDomainName = wszDomainName;
  335. pwszComputerName = wszComputerName;
  336. } else {
  337. pwszDomainName = NULL;
  338. pwszComputerName = NULL;
  339. }
  340. //
  341. // Figure out the root of the namespace.
  342. // The root name is the cluster name on clusters, if
  343. // this is a machine-based Dfs.
  344. //
  345. if (dwErr == NERR_Success && ulDfsManagerType == DFS_MANAGER_SERVER) {
  346. #if DBG
  347. if (DfsSvcVerbose)
  348. DbgPrint("DfsInitGlobals: calling ResUtilEnumResources()\n");
  349. #endif
  350. ResUtilEnumResources(NULL,
  351. L"File Share",
  352. ClusCallBackFunction,
  353. NULL);
  354. }
  355. //
  356. // Initialize the ACLs and other global security datastructures needed
  357. // for Access Validation
  358. //
  359. if (dwErr == ERROR_SUCCESS) {
  360. if (DfsInitializeSecurity())
  361. dwErr = ERROR_SUCCESS;
  362. else
  363. dwErr = ERROR_UNEXP_NET_ERR;
  364. }
  365. //
  366. // Initialize the LDAP storage
  367. //
  368. if (dwErr == ERROR_SUCCESS && ulDfsManagerType == DFS_MANAGER_FTDFS) {
  369. dwErr = InitializeLdapStorage(
  370. wszDfsRootName);
  371. }
  372. //
  373. // Initialize the CSites class/storage
  374. //
  375. if (dwErr == ERROR_SUCCESS) {
  376. if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
  377. pDfsmSites = new CSites(LDAP_VOLUMES_DIR SITE_ROOT, &dwErr);
  378. } else {
  379. pDfsmSites = new CSites(VOLUMES_DIR SITE_ROOT, &dwErr);
  380. }
  381. if (pDfsmSites != NULL) {
  382. if (dwErr != ERROR_SUCCESS) {
  383. delete pDfsmSites;
  384. pDfsmSites = NULL;
  385. dwErr = ERROR_OUTOFMEMORY;
  386. }
  387. } else {
  388. dwErr = ERROR_OUTOFMEMORY;
  389. }
  390. }
  391. //
  392. // Initialize the Dfs Manager Storage Directory
  393. //
  394. if (dwErr == ERROR_SUCCESS ) {
  395. pDfsmStorageDirectory = new CStorageDirectory( &dwErr );
  396. if (pDfsmStorageDirectory != NULL) {
  397. if (dwErr == ERROR_SUCCESS) {
  398. fInitDone = TRUE;
  399. } else {
  400. delete pDfsmStorageDirectory;
  401. pDfsmStorageDirectory = NULL;
  402. delete pDfsmSites;
  403. pDfsmSites = NULL;
  404. fInitDone = FALSE;
  405. }
  406. } else {
  407. delete pDfsmSites;
  408. pDfsmSites = NULL;
  409. fInitDone = FALSE;
  410. dwErr = ERROR_OUTOFMEMORY;
  411. }
  412. }
  413. }
  414. IDfsVolInlineDebOut((DEB_TRACE, "DfsInitGlobals() exit\n"));
  415. return dwErr;
  416. } // DfsInitGlobals
  417. //+----------------------------------------------------------------------------
  418. //
  419. // Function: DfsReinitGlobals
  420. //
  421. // Synopsis: ReInitialize the Dfs Manager globals.
  422. //
  423. // Arguments:
  424. //
  425. // Returns:
  426. //
  427. //-----------------------------------------------------------------------------
  428. DWORD
  429. DfsReInitGlobals(
  430. LPWSTR pwszRootName,
  431. DWORD dwType)
  432. {
  433. DWORD dwErr = ERROR_SUCCESS;
  434. ULONG ulSize = MAX_PATH*sizeof(WCHAR);
  435. DFS_NAME_CONVENTION NameType;
  436. IDfsVolInlineDebOut((DEB_TRACE, "DfsReInitGlobals(%ws, %x)\n", pwszRootName, dwType));
  437. #if DBG
  438. GetDebugSwitches();
  439. if (DfsSvcVerbose)
  440. DbgPrint("DfsReInitGlobals(%ws, %d)\n", pwszRootName, dwType);
  441. #endif
  442. GetEventLogSwitches();
  443. GetConfigSwitches();
  444. //
  445. // Get rid of Dfs Manager storage & site info
  446. //
  447. if (pDfsmStorageDirectory != NULL) {
  448. delete pDfsmStorageDirectory;
  449. pDfsmStorageDirectory = NULL;
  450. }
  451. if (pDfsmSites != NULL) {
  452. delete pDfsmSites;
  453. pDfsmSites = NULL;
  454. }
  455. //
  456. // Get rid of Ldap storage
  457. //
  458. UnInitializeLdapStorage();
  459. ulDfsManagerType = dwType;
  460. wcscpy(wszDfsRootName, pwszRootName);
  461. pwszDfsRootName = wszDfsRootName;
  462. //
  463. // Get computer and domain names
  464. //
  465. NameType = (ulDfsManagerType == DFS_MANAGER_FTDFS) ? DFS_NAMETYPE_DNS : DFS_NAMETYPE_EITHER;
  466. dwErr = GetDomAndComputerName(wszDomainName, wszComputerName, &NameType);
  467. if (dwErr == NERR_Success) {
  468. pwszDomainName = wszDomainName;
  469. pwszComputerName = wszComputerName;
  470. } else {
  471. pwszDomainName = NULL;
  472. pwszComputerName = NULL;
  473. }
  474. //
  475. // Figure out the root of the namespace.
  476. // The root name is the cluster name on clusters, if
  477. // this is a machine-based Dfs.
  478. //
  479. if (dwErr == NERR_Success && ulDfsManagerType == DFS_MANAGER_SERVER) {
  480. #if DBG
  481. if (DfsSvcVerbose)
  482. DbgPrint("DfsReInitGlobals: calling ResUtilEnumResources()\n");
  483. #endif
  484. ResUtilEnumResources(NULL,
  485. L"File Share",
  486. ClusCallBackFunction,
  487. NULL);
  488. }
  489. //
  490. // Initialize the LDAP storage
  491. //
  492. if (dwErr == ERROR_SUCCESS && ulDfsManagerType == DFS_MANAGER_FTDFS) {
  493. dwErr = InitializeLdapStorage(
  494. wszDfsRootName);
  495. }
  496. //
  497. // Initialize the CSites class/storage
  498. //
  499. if (dwErr == ERROR_SUCCESS) {
  500. if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
  501. pDfsmSites = new CSites(LDAP_VOLUMES_DIR SITE_ROOT, &dwErr);
  502. } else {
  503. pDfsmSites = new CSites(VOLUMES_DIR SITE_ROOT, &dwErr);
  504. }
  505. if (pDfsmSites != NULL) {
  506. if (dwErr != ERROR_SUCCESS) {
  507. delete pDfsmSites;
  508. pDfsmSites = NULL;
  509. dwErr = ERROR_OUTOFMEMORY;
  510. }
  511. } else {
  512. dwErr = ERROR_OUTOFMEMORY;
  513. }
  514. }
  515. //
  516. // Initialize the Dfs Manager Storage Directory
  517. //
  518. if (dwErr == ERROR_SUCCESS ) {
  519. pDfsmStorageDirectory = new CStorageDirectory( &dwErr );
  520. if (pDfsmStorageDirectory != NULL) {
  521. if (dwErr != ERROR_SUCCESS) {
  522. delete pDfsmStorageDirectory;
  523. pDfsmStorageDirectory = NULL;
  524. delete pDfsmSites;
  525. pDfsmSites = NULL;
  526. }
  527. } else {
  528. delete pDfsmSites;
  529. pDfsmSites = NULL;
  530. dwErr = ERROR_OUTOFMEMORY;
  531. }
  532. }
  533. if (dwType == DFS_MANAGER_FTDFS && hSyncThread == NULL) {
  534. //
  535. // Start the thread that does the DS sync
  536. //
  537. dwErr = DfsManagerStartDSSync();
  538. if (dwErr != ERROR_SUCCESS) {
  539. IDfsVolInlineDebOut((DEB_ERROR, "DfsManagerStartDSSync failed %08lx\n", dwErr));
  540. return(dwErr);
  541. }
  542. }
  543. IDfsVolInlineDebOut((DEB_TRACE, "DfsReInitGlobals() exit\n"));
  544. return dwErr;
  545. } // DfsReInitGlobals
  546. //+------------------------------------------------------------------------
  547. //
  548. // Function: InitializeDfsManager
  549. //
  550. // Synopsis: This method initializes the PKT with the volume objects
  551. //
  552. // Arguments: None
  553. //
  554. // Returns:
  555. //
  556. // Notes:
  557. //
  558. //-------------------------------------------------------------------------
  559. DWORD
  560. InitializeDfsManager(void)
  561. {
  562. DWORD dwErr;
  563. HKEY hkey;
  564. GetEventLogSwitches();
  565. GetConfigSwitches();
  566. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
  567. if (dwErr == ERROR_SUCCESS) {
  568. RegCloseKey( hkey );
  569. dwErr = InitializeVolumeObject( DOMAIN_ROOT_VOL, TRUE );
  570. } else {
  571. dwErr = ERROR_SUCCESS;
  572. }
  573. return(dwErr);
  574. }
  575. //+-----------------------------------------------------------------------
  576. //
  577. // Function: InitializeVolumeObject
  578. //
  579. // Synopsis: This function initializes a volume object and hence all
  580. // objects underneath that one.
  581. //
  582. // Arguments: [pwszVolName] -- Volume Object's Name.
  583. // [bInitVol] -- If TRUE call UpdatePktEntry on this object also.
  584. //
  585. //------------------------------------------------------------------------
  586. DWORD
  587. InitializeVolumeObject(
  588. PWSTR pwszVolName,
  589. BOOLEAN bInitVol,
  590. BOOLEAN SyncRemoteServerName)
  591. {
  592. ULONG count = 0;
  593. DWORD dwErr;
  594. CDfsVolume *tempCDfs;
  595. WCHAR wszVolObjName[MAX_PATH];
  596. HANDLE PktHandle = NULL;
  597. NTSTATUS status;
  598. IDfsVolInlineDebOut(
  599. (DEB_TRACE,
  600. "InitializeVolumeObject(%ws,%d)\n",
  601. pwszVolName, bInitVol));
  602. #if DBG
  603. if (DfsSvcVerbose)
  604. DbgPrint("InitializeVolumeObject(%ws,%s)\n",
  605. pwszVolName,
  606. bInitVol == TRUE ? "TRUE" : "FALSE");
  607. #endif
  608. if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
  609. wcscpy(wszVolObjName, LDAP_VOLUMES_DIR);
  610. } else {
  611. wcscpy(wszVolObjName, VOLUMES_DIR);
  612. }
  613. wcscat(wszVolObjName, pwszVolName);
  614. IDfsVolInlineDebOut(
  615. (DEB_TRACE,
  616. "wszVolObjName=%ws\n",
  617. wszVolObjName));
  618. tempCDfs = new CDfsVolume();
  619. if (tempCDfs == NULL) {
  620. dwErr = ERROR_OUTOFMEMORY;
  621. IDfsVolInlineDebOut((DEB_TRACE, "InitializeVolumeObject Exit\n"));
  622. #if DBG
  623. if (DfsSvcVerbose)
  624. DbgPrint("InitializeVolumeObject exit %d\n", dwErr);
  625. #endif
  626. return dwErr;
  627. }
  628. dwErr = tempCDfs->LoadNoRegister(wszVolObjName, 0);
  629. if (dwErr == ERROR_SUCCESS) {
  630. //
  631. // We'll be sync'ing the site table, so be sure it's ready
  632. //
  633. pDfsmSites->AddRef();
  634. pDfsmSites->MarkEntriesForMerge();
  635. //
  636. // We have to update the PKT entry first since InitializePkt
  637. // will not bother about that part.
  638. //
  639. if (bInitVol) {
  640. status = PktOpen(&PktHandle, 0, 0, NULL);
  641. if (!NT_SUCCESS(status))
  642. PktHandle = NULL;
  643. dwErr = tempCDfs->UpdatePktEntry(PktHandle);
  644. }
  645. if (dwErr != ERROR_SUCCESS) {
  646. //
  647. // We log an EVENT here since this needs admin intervention
  648. // but we go on however.
  649. //
  650. IDfsVolInlineDebOut((DEB_ERROR, "Could not UpdatePkt on %ws %08lx\n",
  651. pwszVolName, dwErr));
  652. } else
  653. #if DBG
  654. if (DfsSvcVerbose)
  655. DbgPrint("InitializevolumeObject:Calling InitializePkt\n");
  656. #endif
  657. if (PktHandle == NULL) {
  658. status = PktOpen(&PktHandle, 0, 0, NULL);
  659. if (!NT_SUCCESS(status))
  660. PktHandle = NULL;
  661. }
  662. dwErr = tempCDfs->InitializePkt(PktHandle);
  663. if (PktHandle != NULL)
  664. PktClose(PktHandle);
  665. #if DBG
  666. if (DfsSvcVerbose)
  667. DbgPrint("InitializevolumeObject:InitializePkt returned %d\n", dwErr);
  668. #endif
  669. //
  670. // The site table should now be in sync
  671. //
  672. pDfsmSites->SyncPktSiteTable();
  673. pDfsmSites->Release();
  674. } else {
  675. IDfsVolInlineDebOut((DEB_ERROR, "Unable to get to %ws %08lx\n",
  676. pwszVolName, dwErr));
  677. }
  678. tempCDfs->Release();
  679. IDfsVolInlineDebOut((DEB_TRACE, "InitializeVolumeObject Exit\n"));
  680. #if DBG
  681. if (DfsSvcVerbose)
  682. DbgPrint("InitializeVolumeObject exit %d\n", dwErr);
  683. #endif
  684. return( dwErr );
  685. }
  686. //+----------------------------------------------------------------------------
  687. //
  688. // Function: InitializeNetDfsInterface
  689. //
  690. // Synopsis: Initializes the NetDfs RPC interface, so this Dfs Manager can
  691. // start servicing the NetDfsXXX APIs.
  692. //
  693. // Arguments: None
  694. //
  695. // Returns: DWORD_FROM_WIN32 of the RPC status from registering the
  696. // RPC interface.
  697. //
  698. //-----------------------------------------------------------------------------
  699. DWORD
  700. InitializeNetDfsInterface()
  701. {
  702. RPC_STATUS status;
  703. LPWSTR wszProtocolSeq = L"ncacn_np";
  704. LPWSTR wszEndPoint = L"\\pipe\\netdfs";
  705. if (NetDfsInitDone == TRUE)
  706. return ERROR_SUCCESS;
  707. status = RpcServerUseProtseqEpW(
  708. (USHORT *)wszProtocolSeq, // Named Pipe protocol
  709. 20, // Max # of calls
  710. (USHORT *)wszEndPoint, // Name of named pipe
  711. NULL); // Security Descriptor
  712. DFSM_TRACE_ERROR_HIGH(status, ALL_ERROR, InitializeNetDfsInterface_Error_RpcServerUseProtseqEpW,
  713. LOGSTATUS(status));
  714. if (status) {
  715. IDfsVolInlineDebOut((DEB_ERROR, "RpcServerUseProtseqEpW failed %08lx\n", status));
  716. return(status);
  717. }
  718. //
  719. // Register the DfsAdministration interface with the RPC runtime library
  720. //
  721. status = RpcServerRegisterIf(netdfs_ServerIfHandle, 0, 0);
  722. DFSM_TRACE_ERROR_HIGH(status, ALL_ERROR, InitializeNetDfsInterface_Error_RpcServerRegisterIf,
  723. LOGSTATUS(status));
  724. if (status) {
  725. IDfsVolInlineDebOut((DEB_ERROR, "RpcServerRegisterIf failed %08lx\n", status));
  726. return(status);
  727. }
  728. //
  729. // Wait for client calls...
  730. //
  731. status = RpcServerListen(
  732. 1, // Minimum # of calls
  733. RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Max calls
  734. 1); // Don't wait...
  735. DFSM_TRACE_ERROR_HIGH(status, ALL_ERROR, InitializeNetDfsInterface_Error_RpcServerListen,
  736. LOGSTATUS(status));
  737. if (status) {
  738. IDfsVolInlineDebOut((DEB_ERROR, "RpcServerListen failed %08lx\n", status));
  739. }
  740. if (status == ERROR_SUCCESS) {
  741. NetDfsInitDone = TRUE;
  742. }
  743. return( status );
  744. }
  745. //+----------------------------------------------------------------------------
  746. //
  747. // Function: DfsManagerHandleKnowledgeInconsistency
  748. //
  749. // Synopsis: Routine to handle knowledge inconsistencies being reported by
  750. // Dfs clients.
  751. //
  752. // Arguments: [Buffer] -- Pointer to marshalled Volume Verify Arg
  753. // [cbMessage] -- size in bytes of pBuffer
  754. //
  755. // Returns: [STATUS_SUCCESS] -- Knowledge inconsistency fixed.
  756. //
  757. // [STATUS_UNSUCCESSFUL] -- Unable to fix Knowledge inconsistency.
  758. // Problem has been logged to event log.
  759. //
  760. //-----------------------------------------------------------------------------
  761. extern "C" NTSTATUS
  762. DfsManagerHandleKnowledgeInconsistency(
  763. PBYTE Buffer,
  764. ULONG cbMessage)
  765. {
  766. DWORD dwErr = ERROR_SUCCESS;
  767. NTSTATUS Status;
  768. MARSHAL_BUFFER MarshalBuffer;
  769. DFS_VOLUME_VERIFY_ARG arg;
  770. PWSTR pwszVolName;
  771. CDfsVolume *pcdfsvol;
  772. pcdfsvol = new CDfsVolume();
  773. if (pcdfsvol != NULL) {
  774. MarshalBufferInitialize(&MarshalBuffer, cbMessage, Buffer);
  775. Status = DfsRtlGet(&MarshalBuffer, &MiVolumeVerifyArg, &arg);
  776. if (NT_SUCCESS(Status)) {
  777. IDfsVolInlineDebOut((DEB_TRACE, "GotParameters: %ws\n", arg.ServiceName.Buffer));
  778. dwErr = GetVolObjForPath(arg.Id.Prefix.Buffer, TRUE, &pwszVolName);
  779. if (dwErr == ERROR_SUCCESS) {
  780. IDfsVolInlineDebOut((DEB_TRACE, "GotVolObjName: %ws\n", pwszVolName));
  781. dwErr = pcdfsvol->LoadNoRegister(pwszVolName, 0);
  782. if (dwErr == ERROR_SUCCESS) {
  783. //
  784. // Remember that the ID actually has the serviceName.
  785. //
  786. dwErr = pcdfsvol->FixServiceKnowledge(arg.ServiceName.Buffer);
  787. } else {
  788. IDfsVolInlineDebOut((
  789. DEB_TRACE, "Could not bind to Vol object\n"));
  790. }
  791. delete [] pwszVolName;
  792. } else {
  793. IDfsVolInlineDebOut((
  794. DEB_TRACE, "Could not get volume objectName\n"));
  795. }
  796. if (arg.Id.Prefix.Buffer != NULL) {
  797. MarshalBufferFree(arg.Id.Prefix.Buffer);
  798. }
  799. if (arg.ServiceName.Buffer != NULL) {
  800. MarshalBufferFree(arg.ServiceName.Buffer);
  801. }
  802. if (dwErr != ERROR_SUCCESS)
  803. Status = STATUS_UNSUCCESSFUL;
  804. } else {
  805. IDfsVolInlineDebOut((
  806. DEB_TRACE,
  807. "Error (NTSTATUS) unmarshalling Knowledge Sync Params %08lx\n",
  808. Status));
  809. }
  810. pcdfsvol->Release();
  811. } else {
  812. Status = STATUS_UNSUCCESSFUL;
  813. }
  814. return(Status);
  815. }
  816. //+----------------------------------------------------------------------------
  817. //
  818. // Function: DfsManagerStartDSSync
  819. //
  820. // Synopsis: Starts a thread that will periodically sync up with the PKT
  821. // in the DS. Used on FT-Dfs root servers.
  822. //
  823. // Arguments: None
  824. //
  825. // Returns: Win32 error from result of allocating necessary resources to
  826. // do DS sync
  827. //
  828. //-----------------------------------------------------------------------------
  829. DWORD
  830. DfsManagerStartDSSync()
  831. {
  832. DWORD dwErr = ERROR_SUCCESS;
  833. NTSTATUS Status;
  834. OBJECT_ATTRIBUTES obja;
  835. ASSERT( ulDfsManagerType == DFS_MANAGER_FTDFS );
  836. InitializeObjectAttributes(&obja, NULL, OBJ_OPENIF, NULL, NULL);
  837. Status = NtCreateEvent(
  838. &hSyncEvent,
  839. SYNCHRONIZE | EVENT_QUERY_STATE | EVENT_MODIFY_STATE,
  840. &obja,
  841. SynchronizationEvent,
  842. FALSE);
  843. if (Status == STATUS_SUCCESS) {
  844. Status = NtCreateEvent(
  845. &hFrsSyncEvent,
  846. SYNCHRONIZE | EVENT_QUERY_STATE | EVENT_MODIFY_STATE,
  847. &obja,
  848. SynchronizationEvent,
  849. FALSE);
  850. }
  851. DFSM_TRACE_ERROR_HIGH(Status, ALL_ERROR, DfsManagerStartDSSync_Error_NtCreateEvent,
  852. LOGSTATUS(Status));
  853. if (Status == STATUS_SUCCESS) {
  854. hSyncThread = CreateThread(
  855. NULL,
  856. 0,
  857. DfsManagerDSSyncThread,
  858. NULL,
  859. 0,
  860. &dwSyncThreadId);
  861. if (hSyncThread == NULL)
  862. dwErr = GetLastError();
  863. } else {
  864. dwErr = GetLastError();
  865. hSyncEvent = NULL;
  866. }
  867. return( dwErr );
  868. }
  869. //+----------------------------------------------------------------------------
  870. //
  871. // Function: DfsManagerDSSyncThread
  872. //
  873. // Synopsis: Periodically syncs the local metadata with the DS
  874. //
  875. // Arguments: [Context] -- Ignored
  876. //
  877. // Returns: Nothing
  878. //
  879. //-----------------------------------------------------------------------------
  880. #if _MSC_FULL_VER >= 13008827
  881. #pragma warning(push)
  882. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  883. #endif
  884. DWORD
  885. DfsManagerDSSyncThread(
  886. PVOID Context)
  887. {
  888. DWORD dwErr;
  889. HKEY hkey;
  890. while (1) {
  891. #if DBG
  892. if (DfsSvcVerbose)
  893. DbgPrint("DfsManagerDSSyncThread()\n");
  894. #endif
  895. dwSyncIntervalInMs = GetSyncInterval();
  896. dwErr = WaitForSingleObject(hSyncEvent, dwSyncIntervalInMs);
  897. if (dwErr != WAIT_TIMEOUT) {
  898. WaitForSingleObject(hFrsSyncEvent, dwFrsSyncIntervalInMs);
  899. }
  900. IDfsVolInlineDebOut((DEB_TRACE, "DfsManagerDSSyncThread()\n"));
  901. if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
  902. ENTER_DFSM_OPERATION;
  903. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
  904. if (dwErr == ERROR_SUCCESS) {
  905. RegCloseKey( hkey );
  906. LdapIncrementBlob(TRUE);
  907. dwErr = LdapDecrementBlob();
  908. }
  909. EXIT_DFSM_OPERATION;
  910. }
  911. }
  912. return( 0 );
  913. }
  914. #if _MSC_FULL_VER >= 13008827
  915. #pragma warning(pop)
  916. #endif
  917. //+----------------------------------------------------------------------------
  918. //
  919. // Function: DfspGetPdc
  920. //
  921. // Synopsis: Sets the global pwszDSMachineName to the PDC
  922. //
  923. // Arguments: None
  924. //
  925. // Returns: ERROR_SUCCESS or failure
  926. //
  927. //-----------------------------------------------------------------------------
  928. DWORD
  929. DfspGetPdc(void)
  930. {
  931. DWORD dwErr;
  932. PDOMAIN_CONTROLLER_INFO pDCInfo;
  933. #if DBG
  934. if (DfsSvcVerbose)
  935. DbgPrint("DfspGetPdc()\n");
  936. #endif
  937. dwErr = DsGetDcName(
  938. NULL, // Computer to remote to
  939. NULL, // Domain - use local domain
  940. NULL, // Domain Guid
  941. NULL, // Site Guid
  942. DS_PDC_REQUIRED | DS_FORCE_REDISCOVERY,
  943. &pDCInfo);
  944. DFSM_TRACE_ERROR_HIGH(dwErr, ALL_ERROR, DfspGetPdc_Error_DsGetDcName,
  945. LOGULONG(dwErr)
  946. );
  947. if (dwErr == ERROR_SUCCESS) {
  948. if (pwszDSMachineName == NULL)
  949. pwszDSMachineName = wszDSMachineName;
  950. wcscpy(pwszDSMachineName, &pDCInfo->DomainControllerName[2]);
  951. NetApiBufferFree( pDCInfo );
  952. }
  953. #if DBG
  954. if (DfsSvcVerbose)
  955. DbgPrint("DfspGetPdc() returning %d\n", dwErr);
  956. #endif
  957. return( dwErr );
  958. }
  959. //+----------------------------------------------------------------------------
  960. //
  961. // Function: GetSyncInterval
  962. //
  963. // Synopsis: Returns the interval at which to sync with the DS
  964. //
  965. // Arguments: None
  966. //
  967. // Returns: Returns the interval at which to sync with the DS
  968. //
  969. //-----------------------------------------------------------------------------
  970. DWORD
  971. GetSyncInterval()
  972. {
  973. DWORD dwErr;
  974. DWORD dwType;
  975. DWORD dwIntervalInSeconds = 60 * 60;
  976. DWORD cbData;
  977. HKEY hkey;
  978. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
  979. if (dwErr == ERROR_SUCCESS) {
  980. cbData = sizeof(dwIntervalInSeconds);
  981. dwErr = RegQueryValueEx(
  982. hkey,
  983. SYNC_INTERVAL_NAME,
  984. NULL,
  985. &dwType,
  986. (PBYTE) &dwIntervalInSeconds,
  987. &cbData);
  988. if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
  989. dwIntervalInSeconds = 60 * 60;
  990. }
  991. RegCloseKey(hkey);
  992. }
  993. return( dwIntervalInSeconds * 1000 );
  994. }
  995. //+----------------------------------------------------------------------------
  996. //
  997. // Function: GetDcLockInterval
  998. //
  999. // Synopsis: Returns the interval to lock onto a DC
  1000. //
  1001. // Arguments: None
  1002. //
  1003. // Returns: Returns the interval to lock onto a DC
  1004. //
  1005. //-----------------------------------------------------------------------------
  1006. ULONG
  1007. GetDcLockInterval()
  1008. {
  1009. DWORD dwErr;
  1010. DWORD dwType;
  1011. DWORD dwIntervalInSeconds = 60 * 60 * 2;
  1012. DWORD cbData;
  1013. HKEY hkey;
  1014. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
  1015. if (dwErr == ERROR_SUCCESS) {
  1016. cbData = sizeof(dwIntervalInSeconds);
  1017. dwErr = RegQueryValueEx(
  1018. hkey,
  1019. DCLOCK_INTERVAL_NAME,
  1020. NULL,
  1021. &dwType,
  1022. (PBYTE) &dwIntervalInSeconds,
  1023. &cbData);
  1024. if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
  1025. dwIntervalInSeconds = 60 * 60 * 2;
  1026. }
  1027. RegCloseKey(hkey);
  1028. }
  1029. return( dwIntervalInSeconds * 1000 );
  1030. }
  1031. //+----------------------------------------------------------------------------
  1032. //
  1033. // Function: GetEntryTimeout
  1034. //
  1035. // Synopsis: Returns the timeout (in seconds) for jp's
  1036. //
  1037. // Arguments: None
  1038. //
  1039. //-----------------------------------------------------------------------------
  1040. DWORD
  1041. GetEntryTimeout()
  1042. {
  1043. DWORD dwErr;
  1044. DWORD dwType;
  1045. DWORD dwTimeoutInSeconds = DEFAULT_PKT_ENTRY_TIMEOUT;
  1046. DWORD cbData;
  1047. HKEY hkey;
  1048. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
  1049. if (dwErr == ERROR_SUCCESS) {
  1050. cbData = sizeof(dwTimeoutInSeconds);
  1051. dwErr = RegQueryValueEx(
  1052. hkey,
  1053. REG_VALUE_TIMETOLIVE,
  1054. NULL,
  1055. &dwType,
  1056. (PBYTE) &dwTimeoutInSeconds,
  1057. &cbData);
  1058. if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
  1059. dwTimeoutInSeconds = DEFAULT_PKT_ENTRY_TIMEOUT;
  1060. }
  1061. RegCloseKey(hkey);
  1062. }
  1063. return( dwTimeoutInSeconds );
  1064. }
  1065. //+----------------------------------------------------------------------------
  1066. //
  1067. // Function: DfspGetFtDfsName
  1068. //
  1069. // Synopsis: Gets the FtDfs name from the registry
  1070. //
  1071. // Arguments: None
  1072. //
  1073. //-----------------------------------------------------------------------------
  1074. DWORD
  1075. DfspGetFtDfsName()
  1076. {
  1077. DWORD dwErr;
  1078. DWORD dwType;
  1079. DWORD cbName;
  1080. HKEY hkey;
  1081. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
  1082. if (dwErr == ERROR_SUCCESS) {
  1083. cbName = sizeof(wszFtDfsName);
  1084. dwErr = RegQueryValueEx(
  1085. hkey,
  1086. FTDFS_VALUE_NAME,
  1087. NULL,
  1088. &dwType,
  1089. (PBYTE) wszFtDfsName,
  1090. &cbName);
  1091. if (dwErr == ERROR_SUCCESS && dwType != REG_SZ) {
  1092. dwErr = ERROR_FILE_NOT_FOUND;
  1093. }
  1094. RegCloseKey( hkey );
  1095. if (dwErr == ERROR_SUCCESS) {
  1096. pwszFtDfsName = wszFtDfsName;
  1097. } else {
  1098. pwszFtDfsName = NULL;
  1099. }
  1100. }
  1101. return dwErr;
  1102. }
  1103. //+----------------------------------------------------------------------------
  1104. //
  1105. // Function: GetConfigSwitches
  1106. //
  1107. // Synopsis: Get configuration switches from the registry
  1108. //
  1109. // Arguments: None
  1110. //
  1111. //-----------------------------------------------------------------------------
  1112. VOID
  1113. GetConfigSwitches()
  1114. {
  1115. DWORD dwErr;
  1116. DWORD dwType;
  1117. DWORD cbData;
  1118. HKEY hkey;
  1119. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
  1120. if (dwErr == ERROR_SUCCESS) {
  1121. cbData = sizeof(DfsDnsConfig);
  1122. dwErr = RegQueryValueEx(
  1123. hkey,
  1124. REG_VALUE_DFSDNSCONFIG,
  1125. NULL,
  1126. &dwType,
  1127. (PBYTE) &DfsDnsConfig,
  1128. &cbData);
  1129. if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD))
  1130. DfsDnsConfig = 0;
  1131. cbData = sizeof(DfsSvcLdap);
  1132. dwErr = RegQueryValueEx(
  1133. hkey,
  1134. REG_VALUE_LDAP,
  1135. NULL,
  1136. &dwType,
  1137. (PBYTE) &DfsSvcLdap,
  1138. &cbData);
  1139. if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD))
  1140. DfsSvcLdap = 0;
  1141. RegCloseKey(hkey);
  1142. }
  1143. }
  1144. //+----------------------------------------------------------------------------
  1145. //
  1146. // Function: GetEventLogSwitches
  1147. //
  1148. // Synopsis: Gets the event log switch values
  1149. //
  1150. // Arguments: None
  1151. //
  1152. //-----------------------------------------------------------------------------
  1153. VOID
  1154. GetEventLogSwitches()
  1155. {
  1156. DWORD dwErr;
  1157. DWORD dwType;
  1158. DWORD cbData;
  1159. HKEY hkey = NULL;
  1160. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_EVENTLOG, &hkey );
  1161. if (dwErr == ERROR_SUCCESS) {
  1162. cbData = sizeof(DfsEventLog);
  1163. dwErr = RegQueryValueEx(
  1164. hkey,
  1165. REG_VALUE_EVENTLOG_GLOBAL,
  1166. NULL,
  1167. &dwType,
  1168. (PBYTE) &DfsEventLog,
  1169. &cbData);
  1170. if (dwErr == ERROR_SUCCESS && dwType == REG_DWORD)
  1171. goto Cleanup;
  1172. DfsEventLog = 0;
  1173. cbData = sizeof(DfsEventLog);
  1174. dwErr = RegQueryValueEx(
  1175. hkey,
  1176. REG_VALUE_EVENTLOG_DFS,
  1177. NULL,
  1178. &dwType,
  1179. (PBYTE) &DfsEventLog,
  1180. &cbData);
  1181. if (dwErr == ERROR_SUCCESS && dwType == REG_DWORD)
  1182. goto Cleanup;
  1183. //
  1184. // Could not find either the global nor the dfs event log setting
  1185. //
  1186. DfsEventLog = 0;
  1187. }
  1188. #if DBG
  1189. if (DfsSvcVerbose)
  1190. DbgPrint("Dfssvc:DfsEventLog = 0x%x\n", DfsEventLog);
  1191. #endif
  1192. Cleanup:
  1193. if (hkey != NULL)
  1194. RegCloseKey(hkey);
  1195. }
  1196. #if DBG
  1197. //+----------------------------------------------------------------------------
  1198. //
  1199. // Function: GetDebugSwitches
  1200. //
  1201. // Synopsis: Gets the debug switch values
  1202. //
  1203. // Arguments: None
  1204. //
  1205. //-----------------------------------------------------------------------------
  1206. VOID
  1207. GetDebugSwitches()
  1208. {
  1209. DWORD dwErr;
  1210. DWORD dwType;
  1211. DWORD cbData;
  1212. HKEY hkey;
  1213. dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
  1214. if (dwErr == ERROR_SUCCESS) {
  1215. cbData = sizeof(DfsSvcVerbose);
  1216. dwErr = RegQueryValueEx(
  1217. hkey,
  1218. REG_VALUE_VERBOSE,
  1219. NULL,
  1220. &dwType,
  1221. (PBYTE) &DfsSvcVerbose,
  1222. &cbData);
  1223. if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
  1224. DfsSvcVerbose = 0;
  1225. }
  1226. cbData = sizeof(IDfsVolInfoLevel);
  1227. dwErr = RegQueryValueEx(
  1228. hkey,
  1229. REG_VALUE_IDFSVOL,
  1230. NULL,
  1231. &dwType,
  1232. (PBYTE) &IDfsVolInfoLevel,
  1233. &cbData);
  1234. if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
  1235. IDfsVolInfoLevel = DEF_INFOLEVEL;
  1236. }
  1237. RegCloseKey(hkey);
  1238. }
  1239. }
  1240. #endif
  1241. //+------------------------------------------------------------------------
  1242. //
  1243. // Function: LogMessage()
  1244. //
  1245. // Synopsis: This method takes an error code and a list of strings and
  1246. // displays the right message for now. Later on this will have
  1247. // to raise an event and do the appropriate stuff actually.
  1248. //
  1249. // Arguments: [ErrNum] -- Error Number (SCODE). This identifies message to
  1250. // pick up.
  1251. // [pwcstrs] -- The strings that are to be displayed.
  1252. // [count] -- Number of strings in above array.
  1253. // [Severity] -- The severity of the error so that we can turn
  1254. // off debuggin selectively.
  1255. //
  1256. // Returns: Nothing.
  1257. //
  1258. // Notes:
  1259. //
  1260. // History: 10-Feb-1993 SudK Created.
  1261. //
  1262. //-------------------------------------------------------------------------
  1263. VOID
  1264. LogMessageFull(
  1265. DWORD Severity,
  1266. PWCHAR pwcstrs[],
  1267. DWORD count,
  1268. DWORD ErrNum)
  1269. {
  1270. IDfsVolInlineDebOut(( Severity, " [%ws] \n", DfsErrString[ErrNum] ));
  1271. for (ULONG _i=0; _i<count; _i++) {
  1272. IDfsVolInlineDebOut(( Severity, "Str%d : [%ws] \n", _i, pwcstrs[_i] ));
  1273. }
  1274. IDfsVolInlineDebOut((Severity, "***%s @ %d *****\n", __FILE__, __LINE__));
  1275. }