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.

2404 lines
60 KiB

  1. //--------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: stdsup.cxx
  6. //
  7. //--------------------------------------------------------------------------
  8. #define UNICODE
  9. #include <stdio.h>
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <windows.h>
  14. #include <winldap.h>
  15. #include <stdlib.h>
  16. #include <dsgetdc.h>
  17. #include <lm.h>
  18. #include <dfsstr.h>
  19. #include <dfsmrshl.h>
  20. #include <marshal.hxx>
  21. #include <lmdfs.h>
  22. #include <dfspriv.h>
  23. #include <csites.hxx>
  24. #include <dfsm.hxx>
  25. #include <recon.hxx>
  26. #include <rpc.h>
  27. #include "struct.hxx"
  28. #include "rootsup.hxx"
  29. #include "dfsacl.hxx"
  30. #include "misc.hxx"
  31. #include "messages.h"
  32. #include "struct.hxx"
  33. #include "ftsup.hxx"
  34. #include "stdsup.hxx"
  35. DWORD
  36. PutSiteTable(
  37. HKEY hKey,
  38. PDFS_VOLUME_LIST pDfsVolList);
  39. DWORD
  40. DfsRecoverVolList(
  41. PDFS_VOLUME_LIST pDfsVolList);
  42. DWORD
  43. DfsRegDeleteKeyAndChildren(
  44. HKEY hkey,
  45. LPWSTR s);
  46. DWORD
  47. DfsGetStdVol(
  48. HKEY rKey,
  49. PDFS_VOLUME_LIST pDfsVolList)
  50. {
  51. HKEY hKey = NULL;
  52. DWORD dwErr;
  53. LPWSTR *pNames = NULL;
  54. ULONG cKeys = 0;
  55. ULONG i;
  56. WCHAR VolumesDir[MAX_PATH+1];
  57. wcscpy(VolumesDir, VOLUMES_DIR);
  58. wcscat(VolumesDir, L"domainroot");
  59. dwErr = RegOpenKey(
  60. rKey,
  61. VolumesDir,
  62. &hKey);
  63. if (dwErr != ERROR_SUCCESS) {
  64. MyPrintf(L"Not a StdDfs root!\r\n");
  65. goto Cleanup;
  66. }
  67. dwErr = EnumKeys(
  68. hKey,
  69. &cKeys,
  70. &pNames);
  71. if (dwErr != ERROR_SUCCESS) {
  72. MyPrintf(L"No exit points...\r\n");
  73. goto SiteInfo;
  74. }
  75. pDfsVolList->Version = 3;
  76. pDfsVolList->VolCount = cKeys+1;
  77. pDfsVolList->Volumes = (PDFS_VOLUME *)malloc((cKeys+1) * sizeof(PDFS_VOLUME));
  78. if (pDfsVolList->Volumes == NULL) {
  79. dwErr = ERROR_OUTOFMEMORY;
  80. goto Cleanup;
  81. }
  82. pDfsVolList->AllocatedVolCount = cKeys + 1;
  83. RtlZeroMemory(pDfsVolList->Volumes, pDfsVolList->AllocatedVolCount * sizeof(PDFS_VOLUME));
  84. pDfsVolList->Volumes[0] = (PDFS_VOLUME) malloc(sizeof(DFS_VOLUME));
  85. if (pDfsVolList->Volumes[0] == NULL) {
  86. dwErr = ERROR_OUTOFMEMORY;
  87. goto Cleanup;
  88. }
  89. RtlZeroMemory(pDfsVolList->Volumes[0], sizeof(DFS_VOLUME));
  90. dwErr = GetDfsKey(
  91. rKey,
  92. L"domainroot",
  93. pDfsVolList->Volumes[0]);
  94. for (i = 0; i < cKeys; i++) {
  95. wcscpy(VolumesDir, L"domainroot\\");
  96. wcscat(VolumesDir, pNames[i]);
  97. pDfsVolList->Volumes[i+1] = (PDFS_VOLUME) malloc(sizeof(DFS_VOLUME));
  98. if (pDfsVolList->Volumes[i+1] == NULL) {
  99. dwErr = ERROR_OUTOFMEMORY;
  100. goto Cleanup;
  101. }
  102. RtlZeroMemory(pDfsVolList->Volumes[i+1], sizeof(DFS_VOLUME));
  103. dwErr = GetDfsKey(
  104. rKey,
  105. VolumesDir,
  106. pDfsVolList->Volumes[i+1]);
  107. }
  108. //
  109. // Do any recovery needed
  110. //
  111. dwErr = DfsRecoverVolList(pDfsVolList);
  112. RegCloseKey(hKey);
  113. hKey = NULL;
  114. pDfsVolList->DfsType = STDDFS;
  115. SiteInfo:
  116. //
  117. // Site information
  118. //
  119. wcscpy(VolumesDir, VOLUMES_DIR);
  120. wcscat(VolumesDir, L"siteroot");
  121. dwErr = RegOpenKey(
  122. rKey,
  123. VolumesDir,
  124. &hKey);
  125. if (dwErr != ERROR_SUCCESS) {
  126. dwErr = ERROR_SUCCESS;
  127. goto Cleanup;
  128. }
  129. dwErr = GetSiteTable(
  130. hKey,
  131. pDfsVolList);
  132. if (dwErr != ERROR_SUCCESS) {
  133. MyPrintf(L"Missing siteroot key (non-fatal error)\r\n");
  134. dwErr = ERROR_SUCCESS;
  135. }
  136. Cleanup:
  137. FreeNameList(
  138. pNames,
  139. cKeys);
  140. pNames = NULL;
  141. if (hKey != NULL)
  142. RegCloseKey(hKey);
  143. return dwErr;
  144. }
  145. DWORD
  146. GetDfsKey(
  147. HKEY rKey,
  148. LPWSTR wszKeyName,
  149. PDFS_VOLUME pVolume)
  150. {
  151. DWORD dwErr = 0;
  152. HKEY hKey = NULL;
  153. ULONG cRepl;
  154. WCHAR VolumesDir[MAX_PATH+1];
  155. wcscpy(VolumesDir, VOLUMES_DIR);
  156. wcscat(VolumesDir, wszKeyName);
  157. if (fSwDebug == TRUE)
  158. MyPrintf(L"GetDfsKey(%ws)\r\n", VolumesDir);
  159. dwErr = RegOpenKey(
  160. rKey,
  161. VolumesDir,
  162. &hKey);
  163. if (dwErr != ERROR_SUCCESS) {
  164. if (fSwDebug == TRUE)
  165. MyPrintf(L"RegOpenKey(%ws) returned %d\r\n", VolumesDir, dwErr);
  166. goto Cleanup;
  167. }
  168. //
  169. // Id (Prefix, Type, state, etc)
  170. //
  171. wcscpy(VolumesDir, L"\\");
  172. wcscat(VolumesDir, wszKeyName);
  173. GIP_DUPLICATE_STRING(dwErr, VolumesDir, &pVolume->wszObjectName);
  174. if (dwErr != ERROR_SUCCESS) {
  175. if (fSwDebug == TRUE)
  176. MyPrintf(L"DUP_STRING(%ws) returned %d\r\n", VolumesDir, dwErr);
  177. goto Cleanup;
  178. }
  179. dwErr = GetIdProps(
  180. hKey,
  181. &pVolume->dwType,
  182. &pVolume->dwState,
  183. &pVolume->wszPrefix,
  184. &pVolume->wszShortPrefix,
  185. &pVolume->idVolume,
  186. &pVolume->wszComment,
  187. &pVolume->dwTimeout,
  188. &pVolume->ftPrefix,
  189. &pVolume->ftState,
  190. &pVolume->ftComment);
  191. if (dwErr != ERROR_SUCCESS) {
  192. if (fSwDebug == TRUE)
  193. MyPrintf(L"GetIdProps() returned %d\r\n", dwErr);
  194. goto Cleanup;
  195. }
  196. //
  197. // Services (replicas)
  198. //
  199. dwErr = GetSvcProps(
  200. hKey,
  201. pVolume);
  202. if (dwErr != ERROR_SUCCESS) {
  203. if (fSwDebug == TRUE)
  204. MyPrintf(L"GetSvcProps() returned %d\r\n", dwErr);
  205. goto Cleanup;
  206. }
  207. dwErr = GetVersionProps(
  208. hKey,
  209. VERSION_PROPS,
  210. &pVolume->dwVersion);
  211. if (dwErr != ERROR_SUCCESS) {
  212. if (fSwDebug == TRUE)
  213. MyPrintf(L"GetVersionProps() returned %d\r\n", dwErr);
  214. goto Cleanup;
  215. }
  216. dwErr = GetRecoveryProps(
  217. hKey,
  218. RECOVERY_PROPS,
  219. &pVolume->cbRecovery,
  220. &pVolume->pRecovery);
  221. if (dwErr != ERROR_SUCCESS) {
  222. if (fSwDebug == TRUE)
  223. MyPrintf(L"GetRecoveryProps() returned %d\r\n", dwErr);
  224. goto Cleanup;
  225. }
  226. Cleanup:
  227. if (hKey != NULL)
  228. RegCloseKey(hKey);
  229. if (fSwDebug == TRUE)
  230. MyPrintf(L"GetDfsKey exit %d\r\n", dwErr);
  231. return( dwErr );
  232. }
  233. DWORD
  234. ReadSiteTable(PBYTE pBuffer, ULONG cbBuffer)
  235. {
  236. DWORD dwErr;
  237. ULONG cObjects = 0;
  238. ULONG cbThisObj;
  239. ULONG i;
  240. ULONG j;
  241. PLIST_ENTRY pListHead, pLink;
  242. PDFSM_SITE_ENTRY pSiteInfo;
  243. MARSHAL_BUFFER marshalBuffer;
  244. GUID guid;
  245. ULONG Size;
  246. dwErr = ERROR_SUCCESS;
  247. if (dwErr == ERROR_SUCCESS && cbBuffer >= sizeof(ULONG)) {
  248. //
  249. // Unmarshall all the objects (NET_DFS_SITENAME_INFO's) in the buffer
  250. //
  251. MarshalBufferInitialize(
  252. &marshalBuffer,
  253. cbBuffer,
  254. pBuffer);
  255. DfsRtlGetGuid(&marshalBuffer, &guid);
  256. DfsRtlGetUlong(&marshalBuffer, &cObjects);
  257. for (j = 0; j < cObjects; j++) {
  258. pSiteInfo = (PDFSM_SITE_ENTRY) new BYTE [cbBuffer-sizeof(ULONG)];
  259. if (pSiteInfo == NULL) {
  260. dwErr = ERROR_OUTOFMEMORY;
  261. goto Cleanup;
  262. }
  263. dwErr = DfsRtlGet(&marshalBuffer,&MiDfsmSiteEntry, pSiteInfo);
  264. Size = (ULONG)((PCHAR)&pSiteInfo->Info.Site[pSiteInfo->Info.cSites] - (PCHAR)pSiteInfo);
  265. }
  266. }
  267. Cleanup:
  268. return dwErr;
  269. }
  270. //+----------------------------------------------------------------------------
  271. //
  272. // Function: GetIdProps
  273. //
  274. // Synopsis: Retrieves the Id Properties of a Dfs Manager volume object.
  275. //
  276. // Arguments:
  277. //
  278. // Returns: [S_OK] -- Successfully retrieved the properties.
  279. //
  280. // [DFS_E_VOLUME_OBJECT_CORRUPT] -- The stored properties could
  281. // not be parsed properly.
  282. //
  283. // [DFS_E_INCONSISTENT] -- Another volume object seems to have
  284. // the same prefix!
  285. //
  286. // [ERROR_OUTOFMEMORY] -- Unable to allocate memory for properties
  287. // or other uses.
  288. //
  289. // DWORD from DfsmQueryValue
  290. //
  291. //-----------------------------------------------------------------------------
  292. DWORD
  293. GetIdProps(
  294. HKEY hKey,
  295. PULONG pdwType,
  296. PULONG pdwState,
  297. LPWSTR *ppwszPrefix,
  298. LPWSTR *ppwszShortPath,
  299. GUID *pidVolume,
  300. LPWSTR *ppwszComment,
  301. PULONG pdwTimeout,
  302. FILETIME *pftPrefix,
  303. FILETIME *pftState,
  304. FILETIME *pftComment)
  305. {
  306. DWORD dwErr;
  307. NTSTATUS status;
  308. DWORD dwType;
  309. DWORD cbBuffer;
  310. ULONG dwTimeout;
  311. PBYTE pBuffer = NULL;
  312. MARSHAL_BUFFER marshalBuffer;
  313. DFS_ID_PROPS idProps;
  314. if (fSwDebug == TRUE)
  315. MyPrintf(L"GetIdProps()\r\n");
  316. *ppwszPrefix = NULL;
  317. *ppwszComment = NULL;
  318. dwErr = GetBlobByValue(
  319. hKey,
  320. ID_PROPS,
  321. &pBuffer,
  322. &cbBuffer);
  323. if (dwErr != ERROR_SUCCESS)
  324. goto Cleanup;
  325. MarshalBufferInitialize(&marshalBuffer, cbBuffer, pBuffer);
  326. status = DfsRtlGet(&marshalBuffer, &MiDfsIdProps, &idProps);
  327. if (NT_SUCCESS(status)) {
  328. GIP_DUPLICATE_PREFIX( dwErr, idProps.wszPrefix, ppwszPrefix );
  329. if (dwErr == ERROR_SUCCESS) {
  330. GIP_DUPLICATE_PREFIX(
  331. dwErr,
  332. idProps.wszShortPath,
  333. ppwszShortPath );
  334. }
  335. if (dwErr == ERROR_SUCCESS) {
  336. GIP_DUPLICATE_STRING(
  337. dwErr,
  338. idProps.wszComment,
  339. ppwszComment);
  340. }
  341. //
  342. // There are two possible versions of the blob. One has the timeout
  343. // after all the other stuff, the other doesn't.
  344. // So, if there are sizeof(ULONG) bytes left in the blob,
  345. // assume it is the timeout. Otherwise this is an old
  346. // version of the blob, and the timeout isn't here, so we set it to
  347. // the global value.
  348. idProps.dwTimeout = GTimeout;
  349. if (
  350. (marshalBuffer.Current < marshalBuffer.Last)
  351. &&
  352. (marshalBuffer.Last - marshalBuffer.Current) == sizeof(ULONG)
  353. ) {
  354. DfsRtlGetUlong(&marshalBuffer, &idProps.dwTimeout);
  355. }
  356. if (dwErr == ERROR_SUCCESS) {
  357. *pdwType = idProps.dwType;
  358. *pdwState = idProps.dwState;
  359. *pidVolume = idProps.idVolume;
  360. *pdwTimeout = idProps.dwTimeout;
  361. *pftPrefix = idProps.ftEntryPath;
  362. *pftState = idProps.ftState;
  363. *pftComment = idProps.ftComment;
  364. }
  365. if (dwErr != ERROR_SUCCESS) {
  366. if (*ppwszPrefix != NULL) {
  367. delete [] *ppwszPrefix;
  368. *ppwszPrefix = NULL;
  369. }
  370. if (*ppwszShortPath != NULL) {
  371. delete [] *ppwszShortPath;
  372. *ppwszShortPath = NULL;
  373. }
  374. if (*ppwszComment != NULL) {
  375. delete [] *ppwszComment;
  376. *ppwszComment = NULL;
  377. }
  378. }
  379. if (idProps.wszPrefix != NULL)
  380. MarshalBufferFree(idProps.wszPrefix);
  381. if (idProps.wszShortPath != NULL)
  382. MarshalBufferFree(idProps.wszShortPath);
  383. if (idProps.wszComment != NULL)
  384. MarshalBufferFree(idProps.wszComment);
  385. } else {
  386. if (status == STATUS_INSUFFICIENT_RESOURCES) {
  387. dwErr = ERROR_OUTOFMEMORY;
  388. } else {
  389. dwErr = NERR_DfsInternalCorruption;
  390. }
  391. }
  392. Cleanup:
  393. if (pBuffer != NULL)
  394. delete [] pBuffer;
  395. if (fSwDebug == TRUE)
  396. MyPrintf(L"GetIdProps exit %d\r\n", dwErr);
  397. return( dwErr );
  398. }
  399. DWORD
  400. DfsSetStdVol(
  401. HKEY rKey,
  402. PDFS_VOLUME_LIST pDfsVolList)
  403. {
  404. HKEY hKey = NULL;
  405. DWORD dwErr = ERROR_SUCCESS;
  406. DWORD dwErr2 = ERROR_SUCCESS;
  407. ULONG i;
  408. PDFS_VOLUME pVol;
  409. PWCHAR wCp;
  410. WCHAR FolderDir[MAX_PATH+1];
  411. if (fSwDebug == TRUE)
  412. MyPrintf(L"DfsSetStdVol()\r\n");
  413. wcscpy(FolderDir, VOLUMES_DIR);
  414. wcscat(FolderDir, L"domainroot");
  415. dwErr = RegOpenKey(
  416. rKey,
  417. FolderDir,
  418. &hKey);
  419. if (dwErr != ERROR_SUCCESS) {
  420. MyPrintf(L"Not a StdDfs root!\r\n");
  421. goto Cleanup;
  422. }
  423. //
  424. // Loop through all the dfs links and if the modify bit is set,
  425. // create an entry in the registry. If the delete bit is set,
  426. // delete the entry.
  427. //
  428. // On error we continue, but capture the error which will
  429. // later be returned.
  430. //
  431. for (i = 1; i < pDfsVolList->VolCount; i++) {
  432. pVol = pDfsVolList->Volumes[i];
  433. if ((pVol->vFlags & VFLAGS_DELETE) != 0) {
  434. for (wCp = &pVol->wszObjectName[1]; *wCp != NULL && *wCp != UNICODE_PATH_SEP; wCp++)
  435. NOTHING;
  436. wCp++;
  437. dwErr = RegDeleteKey(hKey, wCp);
  438. } else if ((pVol->vFlags & VFLAGS_MODIFY) != 0) {
  439. dwErr = SetDfsKey(hKey, pVol->wszObjectName, pVol);
  440. } else {
  441. dwErr = ERROR_SUCCESS;
  442. }
  443. if (dwErr != ERROR_SUCCESS)
  444. dwErr2 = dwErr;
  445. }
  446. RegCloseKey(hKey);
  447. hKey = NULL;
  448. //
  449. // Write site table only if it has changed
  450. //
  451. if ((pDfsVolList->sFlags & VFLAGS_MODIFY) != 0 || pDfsVolList->SiteCount > 0) {
  452. wcscpy(FolderDir, VOLUMES_DIR);
  453. wcscat(FolderDir, L"siteroot");
  454. dwErr = RegOpenKey(
  455. rKey,
  456. FolderDir,
  457. &hKey);
  458. if (dwErr != ERROR_SUCCESS) {
  459. MyPrintf(L"Can not open siteroot\r\n");
  460. goto Cleanup;
  461. }
  462. dwErr2 = PutSiteTable(hKey, pDfsVolList);
  463. }
  464. Cleanup:
  465. if (hKey != NULL)
  466. RegCloseKey(hKey);
  467. if (fSwDebug == TRUE)
  468. MyPrintf(L"DfsSetStdVol() exit %d\r\n", dwErr2);
  469. return dwErr2;
  470. }
  471. DWORD
  472. SetDfsKey(
  473. HKEY rKey,
  474. LPWSTR wszKeyName,
  475. PDFS_VOLUME pVolume)
  476. {
  477. DWORD dwErr = ERROR_SUCCESS;
  478. HKEY hKey = NULL;
  479. PWCHAR wCp;
  480. if (fSwDebug == TRUE)
  481. MyPrintf(L"SetDfsKey(%ws)\r\n", wszKeyName);
  482. for (wCp = &wszKeyName[1]; *wCp != NULL && *wCp != UNICODE_PATH_SEP; wCp++)
  483. NOTHING;
  484. if (*wCp != UNICODE_PATH_SEP) {
  485. dwErr = ERROR_INVALID_PARAMETER;
  486. goto Cleanup;
  487. }
  488. wCp++;
  489. dwErr = RegCreateKey(
  490. rKey,
  491. wCp,
  492. &hKey);
  493. if (dwErr != ERROR_SUCCESS) {
  494. if (fSwDebug == TRUE)
  495. MyPrintf(L"RegCreateKey(%ws) returned %d\r\n", wCp, dwErr);
  496. goto Cleanup;
  497. }
  498. dwErr = SetIdProps(
  499. hKey,
  500. pVolume->dwType,
  501. pVolume->dwState,
  502. pVolume->wszPrefix,
  503. pVolume->wszShortPrefix,
  504. pVolume->idVolume,
  505. pVolume->wszComment,
  506. pVolume->dwTimeout,
  507. pVolume->ftPrefix,
  508. pVolume->ftState,
  509. pVolume->ftComment);
  510. if (dwErr != ERROR_SUCCESS) {
  511. if (fSwDebug == TRUE)
  512. MyPrintf(L"SetIdProps() returned %d\r\n", dwErr);
  513. goto Cleanup;
  514. }
  515. //
  516. // Services (replicas)
  517. //
  518. dwErr = SetSvcProps(
  519. hKey,
  520. pVolume);
  521. if (dwErr != ERROR_SUCCESS) {
  522. if (fSwDebug == TRUE)
  523. MyPrintf(L"SetSvcProps() returned %d\r\n", dwErr);
  524. goto Cleanup;
  525. }
  526. dwErr = SetVersionProps(
  527. hKey,
  528. pVolume);
  529. if (dwErr != ERROR_SUCCESS) {
  530. if (fSwDebug == TRUE)
  531. MyPrintf(L"SetVersionProps() returned %d\r\n", dwErr);
  532. goto Cleanup;
  533. }
  534. dwErr = SetRecoveryProps(
  535. hKey,
  536. pVolume);
  537. if (dwErr != ERROR_SUCCESS) {
  538. if (fSwDebug == TRUE)
  539. MyPrintf(L"SetRecoveryProps() returned %d\r\n", dwErr);
  540. goto Cleanup;
  541. }
  542. Cleanup:
  543. if (hKey != NULL)
  544. RegCloseKey(hKey);
  545. if (fSwDebug == TRUE)
  546. MyPrintf(L"SetDfsKey exit %d\r\n", dwErr);
  547. return( dwErr );
  548. }
  549. //+----------------------------------------------------------------------------
  550. //
  551. // Function: SetIdProps
  552. //
  553. // Synopsis: Sets the Id Properties of a Dfs Manager volume object.
  554. //
  555. // Arguments:
  556. //
  557. // Returns: [S_OK] -- Successfully retrieved the properties.
  558. //
  559. // [ERROR_OUTOFMEMORY] -- Unable to allocate memory for properties
  560. // or other uses.
  561. //
  562. //-----------------------------------------------------------------------------
  563. DWORD
  564. SetIdProps(
  565. HKEY hKey,
  566. ULONG dwType,
  567. ULONG dwState,
  568. LPWSTR pwszPrefix,
  569. LPWSTR pwszShortPath,
  570. GUID idVolume,
  571. LPWSTR pwszComment,
  572. ULONG dwTimeout,
  573. FILETIME ftPrefix,
  574. FILETIME ftState,
  575. FILETIME ftComment)
  576. {
  577. // prefix bug 447510; initialize dwerr
  578. DWORD dwErr = ERROR_SUCCESS;
  579. NTSTATUS status;
  580. DWORD cbBuffer;
  581. PBYTE pBuffer = NULL;
  582. MARSHAL_BUFFER marshalBuffer;
  583. DFS_ID_PROPS idProps;
  584. idProps.wszPrefix = wcschr( &pwszPrefix[1], UNICODE_PATH_SEP );
  585. idProps.wszShortPath = wcschr( &pwszShortPath[1], UNICODE_PATH_SEP );
  586. idProps.idVolume = idVolume;
  587. idProps.dwState = dwState;
  588. idProps.dwType = dwType;
  589. idProps.wszComment = pwszComment;
  590. idProps.dwTimeout = dwTimeout;
  591. idProps.ftEntryPath = ftPrefix;
  592. idProps.ftState = ftState;
  593. idProps.ftComment = ftComment;
  594. cbBuffer = 0;
  595. status = DfsRtlSize( &MiDfsIdProps, &idProps, &cbBuffer );
  596. if (NT_SUCCESS(status)) {
  597. //
  598. // Add extra bytes for the timeout, which will go at the end
  599. //
  600. cbBuffer += sizeof(ULONG);
  601. pBuffer = new BYTE [cbBuffer];
  602. if (pBuffer != NULL) {
  603. MarshalBufferInitialize( &marshalBuffer, cbBuffer, pBuffer);
  604. status = DfsRtlPut( &marshalBuffer, &MiDfsIdProps, &idProps );
  605. DfsRtlPutUlong(&marshalBuffer, &dwTimeout);
  606. if (NT_SUCCESS(status)) {
  607. dwErr = SetBlobByValue(
  608. hKey,
  609. ID_PROPS,
  610. pBuffer,
  611. cbBuffer);
  612. }
  613. }
  614. }
  615. if (pBuffer != NULL)
  616. delete [] pBuffer;
  617. return( dwErr );
  618. }
  619. DWORD
  620. SetSvcProps(
  621. HKEY hKey,
  622. PDFS_VOLUME pVol)
  623. {
  624. DWORD cbBuffer;
  625. DWORD dwErr = ERROR_SUCCESS;
  626. PBYTE Buffer = NULL;
  627. PBYTE pBuf = NULL;
  628. ULONG *Size = NULL;
  629. ULONG *pSize = NULL;
  630. ULONG TotalSize = 0;
  631. ULONG i;
  632. if (fSwDebug == TRUE)
  633. MyPrintf(L"SetSvcProps(%ws)\r\n", pVol->wszObjectName);
  634. pSize = Size = (PULONG) malloc(sizeof(ULONG) * (pVol->ReplCount + pVol->DelReplCount));
  635. if (Size == NULL) {
  636. dwErr = ERROR_OUTOFMEMORY;
  637. goto Cleanup;
  638. }
  639. //
  640. // Need all the size values now and later for marshalling stuff.
  641. // So we collect them here into an array.
  642. //
  643. TotalSize = 0;
  644. for (i = 0; i < pVol->ReplCount; i++) {
  645. *pSize = GetReplicaMarshalSize(&pVol->ReplicaInfo[i], &pVol->FtModification[i]);
  646. TotalSize += *pSize;
  647. pSize++;
  648. }
  649. for (i = 0; i < pVol->DelReplCount; i++) {
  650. *pSize = GetReplicaMarshalSize(&pVol->DelReplicaInfo[i], &pVol->DelFtModification[i]);
  651. TotalSize += *pSize;
  652. pSize++;
  653. }
  654. //
  655. // Allocate the byte Buffer we need
  656. //
  657. // TotalSize is the size required marshal all the replicas and
  658. // their last-modification-timestamps.
  659. //
  660. // In addition, we need:
  661. //
  662. // 1 ULONG for storing the count of replicas
  663. // ReplCount ULONGs for storing the marshal size of each replica.
  664. //
  665. TotalSize += sizeof(ULONG) * (1 + pVol->ReplCount + 1 + pVol->DelReplCount);
  666. Buffer = pBuf = (PBYTE) malloc(TotalSize);
  667. if (Buffer == NULL) {
  668. dwErr = ERROR_OUTOFMEMORY;
  669. goto Cleanup;
  670. }
  671. //
  672. // Set the number of entries to follow in the Buffer at the start.
  673. //
  674. _PutULong(pBuf, pVol->ReplCount);
  675. pBuf += sizeof(ULONG);
  676. pSize = Size;
  677. for (i = 0; i < pVol->ReplCount; i++) {
  678. //
  679. // Marshall each replica Entry into the Buffer.
  680. // Remember we first need to put the size of the marshalled
  681. // replica entry to follow, then the FILETIME for the replica,
  682. // and finally, the marshalled replica entry structure.
  683. //
  684. _PutULong(pBuf, *pSize);
  685. pBuf += sizeof(ULONG);
  686. dwErr = SerializeReplica(
  687. &pVol->ReplicaInfo[i],
  688. pVol->FtModification ? &pVol->FtModification[i] : NULL,
  689. pBuf,
  690. *pSize);
  691. if (dwErr != ERROR_SUCCESS)
  692. goto Cleanup;
  693. pBuf += *pSize;
  694. pSize++;
  695. }
  696. //
  697. // Now the deleted replicas
  698. //
  699. _PutULong(pBuf, pVol->DelReplCount);
  700. pBuf += sizeof(ULONG);
  701. for (i = 0; i < pVol->DelReplCount; i++) {
  702. _PutULong(pBuf, *pSize);
  703. pBuf += sizeof(ULONG);
  704. dwErr = SerializeReplica(
  705. &pVol->DelReplicaInfo[i],
  706. pVol->DelFtModification ? &pVol->DelFtModification[i] : NULL,
  707. pBuf,
  708. *pSize);
  709. if (dwErr != ERROR_SUCCESS)
  710. goto Cleanup;
  711. pBuf += *pSize;
  712. pSize++;
  713. }
  714. dwErr = SetBlobByValue(
  715. hKey,
  716. SVC_PROPS,
  717. Buffer,
  718. TotalSize);
  719. Cleanup:
  720. if (Buffer != NULL)
  721. delete [] Buffer;
  722. if (Size != NULL)
  723. delete [] Size;
  724. if (fSwDebug == TRUE)
  725. MyPrintf(L"SetSvcProps exit %d\n", dwErr);
  726. return dwErr;
  727. }
  728. DWORD
  729. SetVersionProps(
  730. HKEY hKey,
  731. PDFS_VOLUME pVol)
  732. {
  733. DWORD dwErr = ERROR_SUCCESS;
  734. if (fSwDebug == TRUE)
  735. MyPrintf(L"SetVersionProps(%ws)\r\n", pVol->wszObjectName);
  736. dwErr = RegSetValueEx(
  737. hKey,
  738. VERSION_PROPS,
  739. NULL,
  740. REG_DWORD,
  741. (LPBYTE) &pVol->dwVersion,
  742. sizeof(DWORD));
  743. if (fSwDebug == TRUE)
  744. MyPrintf(L"SetVersionProps exit %d\n", dwErr);
  745. return dwErr;
  746. }
  747. DWORD
  748. SetRecoveryProps(
  749. HKEY hKey,
  750. PDFS_VOLUME pVol)
  751. {
  752. DWORD dwErr = ERROR_SUCCESS;
  753. DWORD dwRecovery = 0;
  754. if (fSwDebug == TRUE)
  755. MyPrintf(L"SetRecoveryProps(%ws)\r\n", pVol->wszObjectName);
  756. dwErr = RegSetValueEx(
  757. hKey,
  758. RECOVERY_PROPS,
  759. NULL,
  760. REG_BINARY,
  761. (LPBYTE) &dwRecovery,
  762. sizeof(DWORD));
  763. if (fSwDebug == TRUE)
  764. MyPrintf(L"SetRecoveryProps exit %d\n", dwErr);
  765. return dwErr;
  766. }
  767. DWORD
  768. PutSiteTable(
  769. HKEY hKey,
  770. PDFS_VOLUME_LIST pDfsVolList)
  771. {
  772. DWORD dwErr;
  773. DWORD cbBuffer;
  774. PBYTE pBuffer = NULL;
  775. ULONG cObjects;
  776. ULONG i;
  777. PLIST_ENTRY pListHead, pLink;
  778. PDFSM_SITE_ENTRY pSiteInfo;
  779. MARSHAL_BUFFER marshalBuffer;
  780. GUID SiteTableGuid = {0};
  781. if (fSwDebug == TRUE)
  782. MyPrintf(L"PutSiteTable()\n");
  783. //
  784. // Create a new Guid
  785. //
  786. dwErr = UuidCreate(&SiteTableGuid);
  787. if(dwErr != RPC_S_OK){
  788. // couldn't create a valid uuid
  789. goto Cleanup;
  790. }
  791. //
  792. // The cObjects count
  793. //
  794. cbBuffer = sizeof(ULONG) + sizeof(GUID);
  795. //
  796. // Add up the number of entries we need to store, and the total size of all
  797. // of them.
  798. //
  799. cObjects = 0;
  800. pListHead = &pDfsVolList->SiteList;
  801. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  802. pSiteInfo = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  803. DfsRtlSize(&MiDfsmSiteEntry, pSiteInfo, &cbBuffer);
  804. cObjects++;
  805. }
  806. //
  807. // Get a buffer big enough
  808. //
  809. pBuffer = (PBYTE) malloc(cbBuffer);
  810. if (pBuffer == NULL) {
  811. dwErr = ERROR_OUTOFMEMORY;
  812. goto Cleanup;
  813. }
  814. //
  815. // Put the guid, then the object count in the beginning of the buffer
  816. //
  817. MarshalBufferInitialize(
  818. &marshalBuffer,
  819. cbBuffer,
  820. pBuffer);
  821. DfsRtlPutGuid(&marshalBuffer, &SiteTableGuid);
  822. DfsRtlPutUlong(&marshalBuffer, &cObjects);
  823. //
  824. // Walk the linked list of objects, marshalling them into the buffer.
  825. //
  826. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  827. pSiteInfo = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  828. DfsRtlPut(&marshalBuffer,&MiDfsmSiteEntry, pSiteInfo);
  829. }
  830. //
  831. // Write the site table binary blob
  832. //
  833. dwErr = RegSetValueEx(
  834. hKey,
  835. SITE_VALUE_NAME,
  836. NULL,
  837. REG_BINARY,
  838. pBuffer,
  839. cbBuffer);
  840. Cleanup:
  841. if (pBuffer)
  842. free(pBuffer);
  843. if (fSwDebug == TRUE)
  844. MyPrintf(L"PutSiteTable exit %d\n", dwErr);
  845. return dwErr;
  846. }
  847. //+----------------------------------------------------------------------------
  848. //
  849. // Function: DfsmQueryValue
  850. //
  851. // Synopsis: Helper function that calls RegQueryValueEx and verifies that
  852. // the returned type is equal to the expected type.
  853. //
  854. // Arguments: [hkey] -- Handle to key
  855. // [wszValueName] -- Name of value to read
  856. // [dwExpectedType] -- Expected type of value
  857. // [dwExpectedSize] -- Expected size of read in value. If
  858. // this is nonzero, this routine will return an error
  859. // if the read-in size is not equal to expected size.
  860. // If this is 0, no checking is performed.
  861. // [pBuffer] -- To receive the value data
  862. // [pcbBuffer] -- On call, size of pBuffer. On successful return,
  863. // the size of data read in
  864. //
  865. // Returns: [ERROR_SUCCESS] -- Successfully read the value data.
  866. //
  867. // [DFS_E_VOLUME_OBJECT_CORRUPT] -- If read-in type did not
  868. // match dwExpectedType, or if dwExpectedSize was
  869. // nonzero and the read-in size did not match it.
  870. //
  871. // DWORD_FROM_WIN32 of RegQueryValueEx return code.
  872. //
  873. //-----------------------------------------------------------------------------
  874. DWORD
  875. DfsmQueryValue(
  876. HKEY hkey,
  877. LPWSTR wszValueName,
  878. DWORD dwExpectedType,
  879. DWORD dwExpectedSize,
  880. PBYTE pBuffer,
  881. LPDWORD pcbBuffer)
  882. {
  883. DWORD dwErr;
  884. DWORD dwType;
  885. dwErr = RegQueryValueEx(
  886. hkey,
  887. wszValueName,
  888. NULL,
  889. &dwType,
  890. pBuffer,
  891. pcbBuffer);
  892. if (dwErr == ERROR_SUCCESS) {
  893. if (dwExpectedType != dwType) {
  894. dwErr = NERR_DfsInternalCorruption;
  895. } else if (dwExpectedSize != 0 && dwExpectedSize != *pcbBuffer) {
  896. dwErr = NERR_DfsInternalCorruption;
  897. } else {
  898. dwErr = ERROR_SUCCESS;
  899. }
  900. }
  901. return( dwErr );
  902. }
  903. //+----------------------------------------------------------------------------
  904. //
  905. // Function: GetBlobByValue
  906. //
  907. // Synopsis: Retrieves a property of type Binary from the value wszProperty
  908. //
  909. // Arguments:
  910. //
  911. // Returns:
  912. //
  913. //-----------------------------------------------------------------------------
  914. DWORD
  915. GetBlobByValue(
  916. HKEY hKey,
  917. LPWSTR wszProperty,
  918. PBYTE *ppBuffer,
  919. PULONG pcbBuffer)
  920. {
  921. DWORD dwErr;
  922. DWORD dwUnused;
  923. dwErr = RegQueryInfoKey(
  924. hKey, // Key
  925. NULL, // Class string
  926. NULL, // Size of class string
  927. NULL, // Reserved
  928. &dwUnused, // # of subkeys
  929. &dwUnused, // max size of subkey name
  930. &dwUnused, // max size of class name
  931. &dwUnused, // # of values
  932. &dwUnused, // max size of value name
  933. pcbBuffer, // max size of value data,
  934. NULL, // security descriptor
  935. NULL); // Last write time
  936. if (dwErr == ERROR_SUCCESS) {
  937. *ppBuffer = new BYTE [*pcbBuffer];
  938. if (*ppBuffer != NULL) {
  939. dwErr = DfsmQueryValue(
  940. hKey,
  941. wszProperty,
  942. REG_BINARY,
  943. 0,
  944. *ppBuffer,
  945. pcbBuffer);
  946. if (dwErr) {
  947. delete [] *ppBuffer;
  948. *ppBuffer = NULL;
  949. *pcbBuffer = 0;
  950. }
  951. } else {
  952. dwErr = ERROR_OUTOFMEMORY;
  953. }
  954. }
  955. return( dwErr );
  956. }
  957. //+----------------------------------------------------------------------------
  958. //
  959. // Function: SetBlobByValue
  960. //
  961. // Synopsis: Saves a property of type Binary for the value wszProperty
  962. //
  963. // Arguments:
  964. //
  965. // Returns:
  966. //
  967. //-----------------------------------------------------------------------------
  968. DWORD
  969. SetBlobByValue(
  970. HKEY hKey,
  971. LPWSTR wszProperty,
  972. PBYTE pBuffer,
  973. ULONG cbBuffer)
  974. {
  975. DWORD dwErr;
  976. DWORD dwUnused;
  977. DWORD unused;
  978. dwErr = RegQueryInfoKey(
  979. hKey, // Key
  980. NULL, // Class string
  981. NULL, // Size of class string
  982. NULL, // Reserved
  983. &dwUnused, // # of subkeys
  984. &dwUnused, // max size of subkey name
  985. &dwUnused, // max size of class name
  986. &dwUnused, // # of values
  987. &dwUnused, // max size of value name
  988. &unused, // max size of value data,
  989. NULL, // security descriptor
  990. NULL); // Last write time
  991. if (dwErr == ERROR_SUCCESS) {
  992. dwErr = RegSetValueEx(
  993. hKey,
  994. wszProperty,
  995. NULL,
  996. REG_BINARY,
  997. pBuffer,
  998. cbBuffer);
  999. } else {
  1000. dwErr = ERROR_OUTOFMEMORY;
  1001. }
  1002. return( dwErr );
  1003. }
  1004. DWORD
  1005. GetSvcProps(
  1006. HKEY hKey,
  1007. PDFS_VOLUME pVol)
  1008. {
  1009. DWORD cbBuffer;
  1010. DWORD dwErr;
  1011. PBYTE Buffer = NULL;
  1012. PBYTE pBuf = NULL;
  1013. if (fSwDebug == TRUE)
  1014. MyPrintf(L"GetSvcProps(%ws)\r\n", pVol->wszObjectName);
  1015. dwErr = GetBlobByValue(
  1016. hKey,
  1017. SVC_PROPS,
  1018. &Buffer,
  1019. &cbBuffer);
  1020. if (dwErr != ERROR_SUCCESS)
  1021. goto Cleanup;
  1022. pBuf = Buffer;
  1023. dwErr = UnSerializeReplicaList(
  1024. &pVol->ReplCount,
  1025. &pVol->AllocatedReplCount,
  1026. &pVol->ReplicaInfo,
  1027. &pVol->FtModification,
  1028. &pBuf);
  1029. if (dwErr != ERROR_SUCCESS)
  1030. goto Cleanup;
  1031. //
  1032. // Get deleted replicas
  1033. //
  1034. if (pBuf < (pBuf + cbBuffer)) {
  1035. dwErr = UnSerializeReplicaList(
  1036. &pVol->DelReplCount,
  1037. &pVol->AllocatedDelReplCount,
  1038. &pVol->DelReplicaInfo,
  1039. &pVol->DelFtModification,
  1040. &pBuf);
  1041. }
  1042. Cleanup:
  1043. if (Buffer != NULL)
  1044. delete [] Buffer;
  1045. if (fSwDebug == TRUE)
  1046. MyPrintf(L"GetSvcProps exit %d\n", dwErr);
  1047. return dwErr;
  1048. }
  1049. //+----------------------------------------------------------------------------
  1050. //
  1051. // Function: GetVersionProps
  1052. //
  1053. // Synopsis: Retrieves the version property set of a Dfs Manager volume
  1054. // object.
  1055. //
  1056. // Returns: [S_OK] -- If successful.
  1057. //
  1058. // DWORD from DfsmQueryValue
  1059. //
  1060. //-----------------------------------------------------------------------------
  1061. DWORD
  1062. GetVersionProps(
  1063. HKEY hKey,
  1064. LPWSTR wszProperty,
  1065. PULONG pVersion)
  1066. {
  1067. DWORD dwErr;
  1068. DWORD cbSize;
  1069. cbSize = sizeof(ULONG);
  1070. dwErr = DfsmQueryValue(
  1071. hKey,
  1072. wszProperty,
  1073. REG_DWORD,
  1074. sizeof(DWORD),
  1075. (LPBYTE) pVersion,
  1076. &cbSize);
  1077. return dwErr;
  1078. }
  1079. //+----------------------------------------------------------------------------
  1080. //
  1081. // Function: GetRecoveryProps
  1082. //
  1083. // Synopsis: Retrieves the recovery properties of a Dfs Manager volume
  1084. // object.
  1085. //
  1086. // Arguments: [ppRecovery] -- On successful return, points to a buffer
  1087. // allocated to hold the recovery property.
  1088. // [pcbRecovery] -- On successful return, size in bytes of
  1089. // recovery buffer.
  1090. //
  1091. // Returns:
  1092. //
  1093. //-----------------------------------------------------------------------------
  1094. DWORD
  1095. GetRecoveryProps(
  1096. HKEY hKey,
  1097. LPWSTR wszProperty,
  1098. PULONG pcbRecovery,
  1099. PBYTE *ppRecovery)
  1100. {
  1101. DWORD dwErr;
  1102. dwErr = GetBlobByValue(
  1103. hKey,
  1104. wszProperty,
  1105. ppRecovery,
  1106. pcbRecovery);
  1107. return dwErr;
  1108. }
  1109. DWORD
  1110. EnumKeys(
  1111. HKEY hKey,
  1112. PULONG pcKeys,
  1113. LPWSTR **ppNames)
  1114. {
  1115. // figure out how many keys are currently stored in this key
  1116. // and allocate a buffer to hold the return results.
  1117. LPWSTR *pNames = NULL;
  1118. WCHAR wszClass[MAX_PATH+1];
  1119. ULONG cbClass = sizeof(wszClass);
  1120. ULONG cSubKeys, cbMaxSubKeyLen, cbMaxClassLen;
  1121. ULONG cValues, cbMaxValueIDLen, cbMaxValueLen;
  1122. SECURITY_DESCRIPTOR SecDescriptor;
  1123. FILETIME ft;
  1124. DWORD dwErr = ERROR_SUCCESS;
  1125. DWORD dwIndex=0;
  1126. dwErr = RegQueryInfoKey(
  1127. hKey,
  1128. wszClass,
  1129. &cbClass,
  1130. NULL,
  1131. &cSubKeys,
  1132. &cbMaxSubKeyLen,
  1133. &cbMaxClassLen,
  1134. &cValues,
  1135. &cbMaxValueIDLen,
  1136. &cbMaxValueLen,
  1137. (DWORD *)&SecDescriptor,
  1138. &ft);
  1139. if (dwErr != ERROR_SUCCESS)
  1140. goto Cleanup;
  1141. pNames = new LPWSTR [cSubKeys];
  1142. if (pNames == NULL) {
  1143. dwErr = ERROR_OUTOFMEMORY;
  1144. goto Cleanup;
  1145. }
  1146. RtlZeroMemory(pNames, cSubKeys * sizeof(LPWSTR));
  1147. // loop enumerating and adding names
  1148. for (dwIndex = 0; dwIndex < cSubKeys && dwErr == ERROR_SUCCESS; dwIndex++) {
  1149. WCHAR wszKeyName[MAX_PATH];
  1150. ULONG cbKeyName = sizeof(wszKeyName)/sizeof(WCHAR);
  1151. WCHAR wszClass[MAX_PATH];
  1152. ULONG cbClass = sizeof(wszClass)/sizeof(WCHAR);
  1153. FILETIME ft;
  1154. dwErr = RegEnumKeyEx(
  1155. hKey, // handle
  1156. dwIndex, // index
  1157. wszKeyName, // key name
  1158. &cbKeyName, // length of key name
  1159. NULL, // title index
  1160. wszClass, // class
  1161. &cbClass, // length of class
  1162. &ft); // last write time
  1163. if (dwErr == ERROR_SUCCESS) {
  1164. GIP_DUPLICATE_STRING(
  1165. dwErr,
  1166. wszKeyName,
  1167. &pNames[dwIndex]);
  1168. }
  1169. };
  1170. // finished the enumeration, check the results
  1171. if (dwErr == ERROR_NO_MORE_ITEMS || dwErr == ERROR_SUCCESS) {
  1172. *pcKeys = dwIndex;
  1173. *ppNames = pNames;
  1174. } else {
  1175. // Cleanup and return an error
  1176. while (dwIndex) {
  1177. delete pNames[--dwIndex];
  1178. }
  1179. delete [] pNames;
  1180. }
  1181. Cleanup:
  1182. return(dwErr);
  1183. }
  1184. DWORD
  1185. GetSiteTable(
  1186. HKEY hKey,
  1187. PDFS_VOLUME_LIST pDfsVolList)
  1188. {
  1189. DWORD dwErr = ERROR_SUCCESS;
  1190. NTSTATUS NtStatus;
  1191. ULONG cSite;
  1192. PDFSM_SITE_ENTRY pSiteEntry;
  1193. PDFSM_SITE_ENTRY pTmpSiteEntry;
  1194. MARSHAL_BUFFER marshalBuffer;
  1195. ULONG Size;
  1196. PLIST_ENTRY pListHead;
  1197. PLIST_ENTRY pLink;
  1198. PBYTE pObjectData = NULL;
  1199. ULONG cbObjectData;
  1200. PBYTE pBuffer = NULL;
  1201. ULONG cbBuffer;
  1202. ULONG i;
  1203. if (fSwDebug == TRUE)
  1204. MyPrintf(L"GetSiteTable()\r\n");
  1205. dwErr = GetBlobByValue(
  1206. hKey,
  1207. L"SiteTable",
  1208. &pObjectData,
  1209. &cbObjectData);
  1210. if (dwErr != ERROR_SUCCESS)
  1211. goto Cleanup;
  1212. //
  1213. // Unserialize the buffer
  1214. //
  1215. InitializeListHead(&pDfsVolList->SiteList);
  1216. MarshalBufferInitialize(
  1217. &marshalBuffer,
  1218. cbObjectData,
  1219. pObjectData);
  1220. NtStatus = DfsRtlGetGuid(&marshalBuffer, &pDfsVolList->SiteGuid);
  1221. if (!NT_SUCCESS(NtStatus)) {
  1222. dwErr = RtlNtStatusToDosError(NtStatus);
  1223. goto Cleanup;
  1224. }
  1225. NtStatus = DfsRtlGetUlong(&marshalBuffer, &pDfsVolList->SiteCount);
  1226. if (!NT_SUCCESS(NtStatus)) {
  1227. dwErr = RtlNtStatusToDosError(NtStatus);
  1228. goto Cleanup;
  1229. }
  1230. pBuffer = (BYTE *)malloc(cbObjectData);
  1231. if (pBuffer == NULL) {
  1232. dwErr = ERROR_OUTOFMEMORY;
  1233. goto Cleanup;
  1234. }
  1235. pTmpSiteEntry = (PDFSM_SITE_ENTRY)pBuffer;
  1236. for (cSite = 0; cSite < pDfsVolList->SiteCount; cSite++) {
  1237. RtlZeroMemory(pBuffer, cbObjectData);
  1238. NtStatus = DfsRtlGet(
  1239. &marshalBuffer,
  1240. &MiDfsmSiteEntry,
  1241. pBuffer);
  1242. if (!NT_SUCCESS(NtStatus)) {
  1243. dwErr = RtlNtStatusToDosError(NtStatus);
  1244. goto Cleanup;
  1245. }
  1246. Size = sizeof(DFSM_SITE_ENTRY) + (pTmpSiteEntry->Info.cSites * sizeof(DFS_SITENAME_INFO));
  1247. pSiteEntry = (PDFSM_SITE_ENTRY) malloc(Size);
  1248. if (pSiteEntry == NULL) {
  1249. dwErr = ERROR_OUTOFMEMORY;
  1250. goto Cleanup;
  1251. }
  1252. RtlCopyMemory(pSiteEntry, pBuffer, Size);
  1253. InsertHeadList(&pDfsVolList->SiteList, &pSiteEntry->Link);
  1254. }
  1255. Cleanup:
  1256. if (pBuffer != NULL)
  1257. delete [] pBuffer;
  1258. return dwErr;
  1259. }
  1260. //+------------------------------------------------------------------------
  1261. //
  1262. // Function: DfsCheckVolList
  1263. //
  1264. // Synopsis: Prints the volume information represented by the volume
  1265. // list passed in.
  1266. //
  1267. // Returns: [ERROR_SUCCESS] -- If all went well.
  1268. //
  1269. // History: 11/19/98 JHarper Created
  1270. //
  1271. //-------------------------------------------------------------------------
  1272. VOID
  1273. DfsCheckVolList(
  1274. PDFS_VOLUME_LIST pDfsVolList,
  1275. ULONG Level)
  1276. {
  1277. ULONG cVol;
  1278. ULONG cRepl;
  1279. ULONG cExit;
  1280. PLIST_ENTRY pListHead;
  1281. PLIST_ENTRY pLink;
  1282. PDFSM_SITE_ENTRY pSiteEntry;
  1283. PDFS_ROOTLOCALVOL pRootLocalVol = pDfsVolList->pRootLocalVol;
  1284. BOOLEAN SvcOk = FALSE;
  1285. BOOLEAN IdOk = FALSE;
  1286. BOOLEAN VerOk = FALSE;
  1287. BOOLEAN RecOk = FALSE;
  1288. BOOLEAN Ok1 = FALSE;
  1289. BOOLEAN Ok2 = FALSE;
  1290. MyPrintf(L"(metadata)..\r\n");
  1291. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  1292. IdOk = SvcOk = VerOk = RecOk = TRUE;
  1293. if (
  1294. pDfsVolList->Volumes[cVol]->wszPrefix == NULL
  1295. ||
  1296. pDfsVolList->Volumes[cVol]->wszShortPrefix == NULL
  1297. ||
  1298. pDfsVolList->Volumes[cVol]->dwTimeout <= 0
  1299. ||
  1300. pDfsVolList->Volumes[cVol]->dwState == 0
  1301. ) {
  1302. IdOk = FALSE;
  1303. }
  1304. if (pDfsVolList->Volumes[cVol]->ReplCount == 0)
  1305. SvcOk = FALSE;
  1306. if (pDfsVolList->Volumes[cVol]->dwVersion == 0)
  1307. VerOk = FALSE;
  1308. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->ReplCount; cRepl++) {
  1309. if (
  1310. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszServerName == NULL
  1311. ||
  1312. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszShareName == NULL
  1313. ) {
  1314. SvcOk = FALSE;
  1315. }
  1316. }
  1317. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->DelReplCount; cRepl++) {
  1318. if (
  1319. pDfsVolList->Volumes[cVol]->DelReplicaInfo[cRepl].pwszServerName == NULL
  1320. ||
  1321. pDfsVolList->Volumes[cVol]->DelReplicaInfo[cRepl].pwszShareName == NULL
  1322. ) {
  1323. SvcOk = FALSE;
  1324. }
  1325. }
  1326. if (IdOk != TRUE || SvcOk != TRUE) {
  1327. MyPrintf(L"%ws: Bad or Missing values: %ws %ws %ws %ws\r\n",
  1328. pDfsVolList->Volumes[cVol]->wszObjectName,
  1329. IdOk == TRUE ? L"" : L"ID",
  1330. SvcOk == TRUE ? L"" : L"Svc",
  1331. VerOk == TRUE ? L"" : L"Version",
  1332. RecOk == TRUE ? L"" : L"Recovery");
  1333. }
  1334. }
  1335. if (Level > 0) {
  1336. //
  1337. // Verify that all the vols have exit points
  1338. //
  1339. MyPrintf(L"(volumes have exit points)..\r\n");
  1340. Ok1 = Ok2 = FALSE;
  1341. for (cVol = 1; cVol < pDfsVolList->VolCount; cVol++) {
  1342. Ok1 = FALSE;
  1343. if (fSwDebug == TRUE) {
  1344. MyPrintf(L"++++ [%ws]\r\n", pDfsVolList->Volumes[cVol]->wszObjectName);
  1345. MyPrintf(L" %d ExitPts:", pRootLocalVol[0].cLocalVolCount);
  1346. }
  1347. for (cExit = 0; cExit < pRootLocalVol[0].cLocalVolCount; cExit++) {
  1348. if (fSwDebug == TRUE)
  1349. MyPrintf(L"%d ", cExit);
  1350. if (
  1351. (pDfsVolList->Volumes[cVol]->wszObjectName != NULL &&
  1352. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName != NULL)
  1353. &&
  1354. (pDfsVolList->Volumes[cVol]->wszObjectName[12] ==
  1355. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName[0])
  1356. &&
  1357. wcscmp(
  1358. &pDfsVolList->Volumes[cVol]->wszObjectName[12],
  1359. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName) == 0
  1360. ) {
  1361. Ok1 = TRUE;
  1362. break;
  1363. }
  1364. }
  1365. if (fSwDebug == TRUE)
  1366. MyPrintf(L"\r\n", cExit);
  1367. if (Ok1 != TRUE && wcslen(&pDfsVolList->Volumes[cVol]->wszObjectName[12]) > 0) {
  1368. MyPrintf(L"Missing [%ws] in LocalVolumes\r\n",
  1369. &pDfsVolList->Volumes[cVol]->wszObjectName[12]);
  1370. }
  1371. }
  1372. //
  1373. // Verify that all the exit points have vols
  1374. //
  1375. MyPrintf(L"(exit points have volumes)..\r\n");
  1376. Ok1 = Ok2 = FALSE;
  1377. for (cExit = 0; cExit < pRootLocalVol[0].cLocalVolCount; cExit++) {
  1378. Ok1 = FALSE;
  1379. if (fSwDebug == TRUE) {
  1380. MyPrintf(L"---- [%ws]\r\n", pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName);
  1381. MyPrintf(L" %d Vols:", pDfsVolList->VolCount);
  1382. }
  1383. for (cVol = 1; cVol < pDfsVolList->VolCount; cVol++) {
  1384. if (fSwDebug == TRUE)
  1385. MyPrintf(L"%d ", cVol);
  1386. if (
  1387. (pDfsVolList->Volumes[cVol]->wszObjectName != NULL &&
  1388. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName != NULL)
  1389. &&
  1390. (pDfsVolList->Volumes[cVol]->wszObjectName[12] ==
  1391. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName[0])
  1392. &&
  1393. wcscmp(
  1394. &pDfsVolList->Volumes[cVol]->wszObjectName[12],
  1395. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName) == 0
  1396. ) {
  1397. Ok1 = TRUE;
  1398. break;
  1399. }
  1400. }
  1401. if (fSwDebug == TRUE)
  1402. MyPrintf(L"\r\n", cVol);
  1403. if (Ok1 != TRUE) {
  1404. MyPrintf(L"Extra ExitPt [%ws] in LocalVolumes\r\n",
  1405. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName);
  1406. }
  1407. }
  1408. }
  1409. MyPrintf(L"(exit point internal consistency)...\r\n");
  1410. Ok1 = Ok2 = FALSE;
  1411. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  1412. Ok1 = FALSE;
  1413. for (cExit = 0; cExit < pRootLocalVol[0].cLocalVolCount; cExit++) {
  1414. if (
  1415. (pDfsVolList->Volumes[cVol]->wszObjectName != NULL &&
  1416. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName != NULL)
  1417. &&
  1418. (pDfsVolList->Volumes[cVol]->wszObjectName[12] ==
  1419. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName[0])
  1420. &&
  1421. wcscmp(
  1422. &pDfsVolList->Volumes[cVol]->wszObjectName[12],
  1423. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName) == 0
  1424. ) {
  1425. Ok1 = TRUE;
  1426. break;
  1427. }
  1428. }
  1429. if (Ok1 == TRUE && wcslen(&pDfsVolList->Volumes[cVol]->wszObjectName[12]) > 0) {
  1430. PWCHAR wCp1 = &pDfsVolList->Volumes[cVol]->wszPrefix[1];
  1431. PWCHAR wCp2 = &pRootLocalVol[0].pDfsLocalVol[cExit].wszEntryPath[1];
  1432. while (*wCp1 != L'\\')
  1433. wCp1++;
  1434. while (*wCp2 != L'\\')
  1435. wCp2++;
  1436. if (_wcsicmp(wCp1,wCp2) != 0) {
  1437. MyPrintf(L"Mismatch in ExitPt in [%ws]\r\n",
  1438. pRootLocalVol[0].pDfsLocalVol[cExit].wszObjectName);
  1439. MyPrintf(L" [%ws] vs [%ws]\r\n",
  1440. pDfsVolList->Volumes[cVol]->wszPrefix,
  1441. pRootLocalVol[0].pDfsLocalVol[cExit].wszEntryPath);
  1442. }
  1443. }
  1444. }
  1445. }
  1446. DWORD
  1447. GetExitPtInfo(
  1448. HKEY rKey,
  1449. PDFS_ROOTLOCALVOL *ppRootLocalVol,
  1450. PULONG pcVolCount)
  1451. {
  1452. HKEY hKey = NULL;
  1453. HKEY hKeyExPt = NULL;
  1454. LPWSTR *pNames = NULL;
  1455. ULONG dwErr;
  1456. ULONG cKeys;
  1457. ULONG i;
  1458. PDFS_ROOTLOCALVOL pRootLocalVol;
  1459. DWORD cbBuffer;
  1460. DWORD cbSize;
  1461. DWORD dwType;
  1462. WCHAR wszBuffer[MAX_PATH+1];
  1463. if (fSwDebug == TRUE)
  1464. MyPrintf(L"GetExitPtInfo()\r\n");
  1465. dwErr = RegOpenKey(
  1466. rKey,
  1467. REG_KEY_LOCAL_VOLUMES,
  1468. &hKey);
  1469. if (dwErr != ERROR_SUCCESS)
  1470. goto Cleanup;
  1471. dwErr = EnumKeys(
  1472. hKey,
  1473. &cKeys,
  1474. &pNames);
  1475. if (dwErr != ERROR_SUCCESS)
  1476. goto Cleanup;
  1477. pRootLocalVol = (PDFS_ROOTLOCALVOL)malloc(sizeof(DFS_ROOTLOCALVOL) * cKeys);
  1478. if (pRootLocalVol == NULL) {
  1479. dwErr = ERROR_OUTOFMEMORY;
  1480. goto Cleanup;
  1481. }
  1482. RtlZeroMemory(pRootLocalVol, sizeof(DFS_ROOTLOCALVOL) * cKeys);
  1483. for (i = 0; i < cKeys; i++) {
  1484. if (fSwDebug == TRUE)
  1485. MyPrintf(L"RegOpenKey(%ws)\r\n", pNames[i]);
  1486. dwErr = RegOpenKey(
  1487. hKey,
  1488. pNames[i],
  1489. &hKeyExPt);
  1490. if (dwErr != ERROR_SUCCESS)
  1491. continue;
  1492. GIP_DUPLICATE_STRING(dwErr, pNames[i], &pRootLocalVol[i].wszObjectName);
  1493. cbSize = sizeof(ULONG);
  1494. dwErr = DfsmQueryValue(
  1495. hKeyExPt,
  1496. REG_VALUE_ENTRY_TYPE,
  1497. REG_DWORD,
  1498. sizeof(DWORD),
  1499. (LPBYTE) &pRootLocalVol[i].dwEntryType,
  1500. &cbSize);
  1501. cbBuffer = sizeof(wszBuffer);
  1502. dwErr = RegQueryValueEx(
  1503. hKeyExPt,
  1504. REG_VALUE_ENTRY_PATH, // "EntryPath"
  1505. NULL,
  1506. &dwType,
  1507. (LPBYTE) wszBuffer,
  1508. &cbBuffer);
  1509. if (dwErr == ERROR_MORE_DATA)
  1510. dwErr = ERROR_SUCCESS;
  1511. if (dwErr == ERROR_SUCCESS)
  1512. GIP_DUPLICATE_STRING(dwErr, wszBuffer, &pRootLocalVol[i].wszEntryPath);
  1513. cbBuffer = sizeof(wszBuffer);
  1514. dwErr = RegQueryValueEx(
  1515. hKeyExPt,
  1516. REG_VALUE_SHARE_NAME, // "ShareName"
  1517. NULL,
  1518. &dwType,
  1519. (LPBYTE) wszBuffer,
  1520. &cbBuffer);
  1521. if (dwErr == ERROR_MORE_DATA)
  1522. dwErr = ERROR_SUCCESS;
  1523. if (dwErr == ERROR_SUCCESS)
  1524. GIP_DUPLICATE_STRING(dwErr, wszBuffer, &pRootLocalVol[i].wszShareName);
  1525. cbBuffer = sizeof(wszBuffer);
  1526. dwErr = RegQueryValueEx(
  1527. hKeyExPt,
  1528. REG_VALUE_SHORT_PATH, // "ShortEntryPath"
  1529. NULL,
  1530. &dwType,
  1531. (LPBYTE) wszBuffer,
  1532. &cbBuffer);
  1533. if (dwErr == ERROR_SUCCESS)
  1534. GIP_DUPLICATE_STRING(dwErr, wszBuffer, &pRootLocalVol[i].wszShortEntryPath);
  1535. cbBuffer = sizeof(wszBuffer);
  1536. dwErr = RegQueryValueEx(
  1537. hKeyExPt,
  1538. REG_VALUE_STORAGE_ID, // "StorageId"
  1539. NULL,
  1540. &dwType,
  1541. (LPBYTE) wszBuffer,
  1542. &cbBuffer);
  1543. if (dwErr == ERROR_MORE_DATA)
  1544. dwErr = ERROR_SUCCESS;
  1545. if (dwErr == ERROR_SUCCESS)
  1546. GIP_DUPLICATE_STRING(dwErr, wszBuffer, &pRootLocalVol[i].wszStorageId);
  1547. dwErr = GetExitPts(
  1548. hKeyExPt,
  1549. &pRootLocalVol[i]);
  1550. RegCloseKey(hKeyExPt);
  1551. }
  1552. FreeNameList(
  1553. pNames,
  1554. cKeys);
  1555. pNames = NULL;
  1556. *ppRootLocalVol = pRootLocalVol;
  1557. *pcVolCount = cKeys;
  1558. Cleanup:
  1559. FreeNameList(
  1560. pNames,
  1561. cKeys);
  1562. if (hKey != NULL)
  1563. RegCloseKey(hKey);
  1564. if (fSwDebug == TRUE)
  1565. MyPrintf(L"GetExitPtInfo returning %d\r\n", dwErr);
  1566. return dwErr;
  1567. }
  1568. VOID
  1569. FreeNameList(
  1570. LPWSTR *pNames,
  1571. ULONG cNames)
  1572. {
  1573. ULONG i;
  1574. if (pNames != NULL) {
  1575. for (i = 0; i < cNames; i++) {
  1576. if (pNames[i] != NULL)
  1577. delete [] pNames[i];
  1578. }
  1579. delete [] pNames;
  1580. }
  1581. }
  1582. DWORD
  1583. GetExitPts(
  1584. HKEY hKey,
  1585. PDFS_ROOTLOCALVOL pRootLocalVol)
  1586. {
  1587. ULONG cNames = 0;
  1588. LPWSTR *pNames = NULL;
  1589. ULONG cKeys = 0;
  1590. ULONG dwErr = ERROR_SUCCESS;
  1591. ULONG i;
  1592. DWORD dwType = 0;
  1593. DWORD cbBuffer = 0;
  1594. DWORD cbSize = 0;
  1595. HKEY hKeyExPt = NULL;
  1596. WCHAR wszBuffer[MAX_PATH+1];
  1597. dwErr = EnumKeys(
  1598. hKey,
  1599. &cKeys,
  1600. &pNames);
  1601. if (dwErr != ERROR_SUCCESS)
  1602. goto Cleanup;
  1603. pRootLocalVol->pDfsLocalVol = (PDFS_LOCALVOLUME)malloc(sizeof(DFS_LOCALVOLUME) * cKeys);
  1604. if (pRootLocalVol->pDfsLocalVol == NULL) {
  1605. dwErr = ERROR_OUTOFMEMORY;
  1606. goto Cleanup;
  1607. }
  1608. RtlZeroMemory(pRootLocalVol->pDfsLocalVol, sizeof(DFS_LOCALVOLUME) * cKeys);
  1609. pRootLocalVol->cLocalVolCount = cKeys;
  1610. for (i = 0; i < cKeys; i++) {
  1611. if (fSwDebug == TRUE)
  1612. MyPrintf(L" GetExitPts(%ws)\r\n", pNames[i]);
  1613. //
  1614. // Get EntryPath
  1615. //
  1616. dwErr = RegOpenKey(
  1617. hKey,
  1618. pNames[i],
  1619. &hKeyExPt);
  1620. if (dwErr != ERROR_SUCCESS) {
  1621. if (fSwDebug == TRUE)
  1622. MyPrintf(L"RegOpenKey returned %d\r\n", dwErr);
  1623. continue;
  1624. }
  1625. GIP_DUPLICATE_STRING(dwErr, pNames[i], &pRootLocalVol->pDfsLocalVol[i].wszObjectName);
  1626. cbBuffer = sizeof(wszBuffer);
  1627. dwErr = RegQueryValueEx(
  1628. hKeyExPt,
  1629. REG_VALUE_ENTRY_PATH, // "EntryPath"
  1630. NULL,
  1631. &dwType,
  1632. (LPBYTE) wszBuffer,
  1633. &cbBuffer);
  1634. if (dwErr == ERROR_MORE_DATA)
  1635. dwErr = ERROR_SUCCESS;
  1636. if (dwErr != ERROR_SUCCESS && fSwDebug == TRUE)
  1637. MyPrintf(L"RegQueryValueEx returned %d\r\n", dwErr);
  1638. if (dwErr == ERROR_SUCCESS)
  1639. GIP_DUPLICATE_STRING(dwErr, wszBuffer, &pRootLocalVol->pDfsLocalVol[i].wszEntryPath);
  1640. RegCloseKey(hKeyExPt);
  1641. }
  1642. Cleanup:
  1643. FreeNameList(
  1644. pNames,
  1645. cKeys);
  1646. return dwErr;
  1647. }
  1648. DWORD
  1649. DfsSetOnSite(
  1650. HKEY rKey,
  1651. LPWSTR wszKeyName,
  1652. ULONG set)
  1653. {
  1654. HKEY hKey = NULL;
  1655. DWORD dwErr;
  1656. LPWSTR *pNames = NULL;
  1657. ULONG cKeys = 0;
  1658. ULONG i;
  1659. WCHAR VolumesDir[MAX_PATH+1];
  1660. wcscpy(VolumesDir, VOLUMES_DIR);
  1661. wcscat(VolumesDir, L"domainroot");
  1662. dwErr = RegOpenKey(
  1663. rKey,
  1664. VolumesDir,
  1665. &hKey);
  1666. if (dwErr != ERROR_SUCCESS) {
  1667. MyPrintf(L"Not a StdDfs root!\r\n");
  1668. goto Cleanup;
  1669. }
  1670. dwErr = EnumKeys(
  1671. hKey,
  1672. &cKeys,
  1673. &pNames);
  1674. if (dwErr != ERROR_SUCCESS) {
  1675. MyPrintf(L"No exit points...\r\n");
  1676. goto Cleanup;
  1677. }
  1678. dwErr = SetSiteInfoOnKey(
  1679. rKey,
  1680. L"domainroot",
  1681. wszKeyName,
  1682. set);
  1683. for (i = 0; i < cKeys && dwErr != ERROR_SUCCESS && dwErr != ERROR_REQUEST_ABORTED && dwErr != ERROR_PATH_NOT_FOUND; i++) {
  1684. wcscpy(VolumesDir, L"domainroot\\");
  1685. wcscat(VolumesDir, pNames[i]);
  1686. dwErr = SetSiteInfoOnKey(
  1687. rKey,
  1688. VolumesDir, wszKeyName, set);
  1689. }
  1690. if (dwErr == ERROR_PATH_NOT_FOUND)
  1691. ErrorMessage(MSG_LINK_NOT_FOUND, wszKeyName);
  1692. Cleanup:
  1693. if (pNames != NULL)
  1694. FreeNameList(
  1695. pNames,
  1696. cKeys);
  1697. if (hKey != NULL)
  1698. RegCloseKey(hKey);
  1699. return dwErr;
  1700. }
  1701. DWORD
  1702. SetSiteInfoOnKey(
  1703. HKEY rKey,
  1704. LPWSTR wszKeyName,
  1705. LPWSTR wszPrefixMatch,
  1706. ULONG Set)
  1707. {
  1708. DWORD dwErr = 0;
  1709. HKEY hKey = NULL;
  1710. ULONG cRepl;
  1711. WCHAR VolumesDir[MAX_PATH+1];
  1712. DFS_VOLUME Volume;
  1713. PDFS_VOLUME pVolume = &Volume;
  1714. wcscpy(VolumesDir, VOLUMES_DIR);
  1715. wcscat(VolumesDir, wszKeyName);
  1716. LPWSTR usePrefix;
  1717. if (fSwDebug == TRUE)
  1718. MyPrintf(L"SetSiteInfoOnKey(%ws)\r\n", VolumesDir);
  1719. dwErr = RegOpenKey(
  1720. rKey,
  1721. VolumesDir,
  1722. &hKey);
  1723. if (dwErr != ERROR_SUCCESS) {
  1724. if (fSwDebug == TRUE)
  1725. MyPrintf(L"RegOpenKey(%ws) returned %d\r\n", VolumesDir, dwErr);
  1726. goto Cleanup;
  1727. }
  1728. //
  1729. // Id (Prefix, Type, state, etc)
  1730. //
  1731. dwErr = GetIdProps(
  1732. hKey,
  1733. &pVolume->dwType,
  1734. &pVolume->dwState,
  1735. &pVolume->wszPrefix,
  1736. &pVolume->wszShortPrefix,
  1737. &pVolume->idVolume,
  1738. &pVolume->wszComment,
  1739. &pVolume->dwTimeout,
  1740. &pVolume->ftPrefix,
  1741. &pVolume->ftState,
  1742. &pVolume->ftComment);
  1743. if (dwErr != ERROR_SUCCESS) {
  1744. if (fSwDebug == TRUE)
  1745. MyPrintf(L"GetIdProps() returned %d\r\n", dwErr);
  1746. goto Cleanup;
  1747. }
  1748. usePrefix = pVolume->wszPrefix;
  1749. DfspGetLinkName(usePrefix, &usePrefix);
  1750. if (fSwDebug) {
  1751. MyPrintf(L"prefix (%ws, %ws), keyname (%ws)\r\n",
  1752. usePrefix,
  1753. pVolume->wszShortPrefix,
  1754. wszPrefixMatch);
  1755. }
  1756. if (_wcsicmp(usePrefix, wszPrefixMatch) == 0) {
  1757. dwErr = ERROR_SUCCESS;
  1758. if (fSwDebug) {
  1759. MyPrintf(L"Match found prefix (%ws, %ws), keyname (%ws)\r\n",
  1760. usePrefix,
  1761. pVolume->wszShortPrefix,
  1762. wszPrefixMatch);
  1763. }
  1764. if (Set) {
  1765. if (pVolume->dwType & PKT_ENTRY_TYPE_INSITE_ONLY) {
  1766. ErrorMessage(MSG_SITE_INFO_ALREADY_SET,
  1767. pVolume->wszPrefix);
  1768. dwErr = ERROR_REQUEST_ABORTED;
  1769. }
  1770. else {
  1771. ErrorMessage(MSG_SITE_INFO_NOW_SET,
  1772. pVolume->wszPrefix);
  1773. pVolume->dwType |= PKT_ENTRY_TYPE_INSITE_ONLY;
  1774. }
  1775. }
  1776. else {
  1777. if (pVolume->dwType & PKT_ENTRY_TYPE_INSITE_ONLY) {
  1778. ErrorMessage(MSG_SITE_INFO_NOW_SET,
  1779. pVolume->wszPrefix);
  1780. pVolume->dwType &= ~PKT_ENTRY_TYPE_INSITE_ONLY;
  1781. }
  1782. else {
  1783. ErrorMessage(MSG_SITE_INFO_ALREADY_SET,
  1784. pVolume->wszPrefix);
  1785. dwErr = ERROR_REQUEST_ABORTED;
  1786. }
  1787. }
  1788. if (dwErr == ERROR_SUCCESS) {
  1789. dwErr = SetIdProps(
  1790. hKey,
  1791. pVolume->dwType,
  1792. pVolume->dwState,
  1793. pVolume->wszPrefix,
  1794. pVolume->wszShortPrefix,
  1795. pVolume->idVolume,
  1796. pVolume->wszComment,
  1797. pVolume->dwTimeout,
  1798. pVolume->ftPrefix,
  1799. pVolume->ftState,
  1800. pVolume->ftComment);
  1801. if (dwErr != ERROR_SUCCESS) {
  1802. if (fSwDebug == TRUE)
  1803. MyPrintf(L"SetIdProps() returned %d\r\n", dwErr);
  1804. goto Cleanup;
  1805. }
  1806. }
  1807. }
  1808. else {
  1809. dwErr = ERROR_PATH_NOT_FOUND;
  1810. }
  1811. Cleanup:
  1812. if (hKey != NULL)
  1813. RegCloseKey(hKey);
  1814. if (fSwDebug == TRUE)
  1815. MyPrintf(L"SetSiteInfoOnKey exit %d\r\n", dwErr);
  1816. return( dwErr );
  1817. }
  1818. DWORD
  1819. CmdStdUnmap(
  1820. LPWSTR pwszServerName)
  1821. {
  1822. DWORD dwErr = ERROR_SUCCESS;
  1823. HKEY rKey = NULL;
  1824. HKEY hKey = NULL;
  1825. if (fSwDebug != 0)
  1826. MyPrintf(L"CmdStdUnmap(%ws)\r\n", pwszServerName);
  1827. dwErr = RegConnectRegistry(
  1828. pwszServerName,
  1829. HKEY_LOCAL_MACHINE,
  1830. &rKey);
  1831. if (dwErr != ERROR_SUCCESS) {
  1832. MyPrintf(L"Can not open registry of %ws (error %d)\r\n", pwszServerName, dwErr);
  1833. goto Cleanup;
  1834. }
  1835. //
  1836. // Remove VOLUMES_DIR and children
  1837. //
  1838. dwErr = DfsRegDeleteKeyAndChildren(rKey, DFSHOST_DIR);
  1839. if (dwErr != ERROR_SUCCESS)
  1840. goto Cleanup;
  1841. //
  1842. // New remove all local vol information
  1843. //
  1844. dwErr = DfsRegDeleteKeyAndChildren(rKey, REG_KEY_LOCAL_VOLUMES);
  1845. if (dwErr != ERROR_SUCCESS)
  1846. goto Cleanup;
  1847. Cleanup:
  1848. RegCreateKey(rKey, REG_KEY_LOCAL_VOLUMES, &hKey);
  1849. RegCreateKey(rKey, DFSHOST_DIR, &hKey);
  1850. if (rKey != NULL)
  1851. RegCloseKey(rKey);
  1852. if (hKey != NULL)
  1853. RegCloseKey(hKey);
  1854. if (fSwDebug != 0)
  1855. MyPrintf(L"CmdStdUnmap exit %d\r\n", dwErr);
  1856. return dwErr;
  1857. }
  1858. DWORD
  1859. CmdClean(
  1860. LPWSTR pwszServerName)
  1861. {
  1862. DWORD dwErr = ERROR_SUCCESS;
  1863. HKEY rKey = NULL;
  1864. HKEY hKey = NULL;
  1865. if (fSwDebug != 0)
  1866. MyPrintf(L"CmdClean(%ws)\r\n", pwszServerName);
  1867. dwErr = RegConnectRegistry(
  1868. pwszServerName,
  1869. HKEY_LOCAL_MACHINE,
  1870. &rKey);
  1871. if (dwErr != ERROR_SUCCESS) {
  1872. MyPrintf(L"Can not open registry of %ws (error %d)\r\n", pwszServerName, dwErr);
  1873. goto Cleanup;
  1874. }
  1875. //
  1876. // Remove VOLUMES_DIR and children
  1877. //
  1878. dwErr = DfsRegDeleteKeyAndChildren(rKey, DFSHOST_DIR);
  1879. if (dwErr != ERROR_SUCCESS)
  1880. goto Cleanup;
  1881. //
  1882. // New remove all local vol information
  1883. //
  1884. dwErr = DfsRegDeleteKeyAndChildren(rKey, REG_KEY_LOCAL_VOLUMES);
  1885. if (dwErr != ERROR_SUCCESS)
  1886. goto Cleanup;
  1887. Cleanup:
  1888. RegCreateKey(rKey, REG_KEY_LOCAL_VOLUMES, &hKey);
  1889. RegCreateKey(rKey, DFSHOST_DIR, &hKey);
  1890. if (rKey != NULL)
  1891. RegCloseKey(rKey);
  1892. if (hKey != NULL)
  1893. RegCloseKey(hKey);
  1894. if (fSwDebug != 0)
  1895. MyPrintf(L"CmdClean exit %d\r\n", dwErr);
  1896. return dwErr;
  1897. }
  1898. DWORD
  1899. DfsDeleteChildKeys(
  1900. HKEY hKey,
  1901. LPWSTR s)
  1902. {
  1903. WCHAR *wcp, *wcp1;
  1904. HKEY nKey;
  1905. DWORD dwErr;
  1906. DWORD hErr;
  1907. if (fSwDebug != 0)
  1908. MyPrintf(L"DfsDeleteChildKeys(%ws)\r\n", s);
  1909. for (wcp = s; *wcp; wcp++)
  1910. ;
  1911. hErr = dwErr = RegOpenKey(hKey, s, &nKey);
  1912. while (RegEnumKey(nKey, 0, wcp, 50 * sizeof(WCHAR)) == ERROR_SUCCESS) {
  1913. for (wcp1 = wcp; *wcp1; wcp1++)
  1914. ;
  1915. *wcp1++ = L'\\';
  1916. *wcp1 = L'\0';
  1917. dwErr = DfsDeleteChildKeys(hKey, s);
  1918. if (dwErr == ERROR_SUCCESS) {
  1919. dwErr = RegDeleteKey(hKey, s);
  1920. }
  1921. }
  1922. *wcp = L'\0';
  1923. if (hErr == ERROR_SUCCESS) {
  1924. RegCloseKey(nKey);
  1925. }
  1926. if (fSwDebug != 0)
  1927. MyPrintf(L"DfsDeleteChildKeys exit %d\r\n", dwErr);
  1928. return dwErr;
  1929. }
  1930. DWORD
  1931. DfsRegDeleteKeyAndChildren(
  1932. HKEY hkey,
  1933. LPWSTR s)
  1934. {
  1935. DWORD dwErr;
  1936. LONG l;
  1937. LPWSTR wCp;
  1938. if (fSwDebug != 0)
  1939. MyPrintf(L"DfsRegDeleteKeyAndChildren(%ws)\r\n", s);
  1940. wCp = (LPWSTR)malloc(4096);
  1941. if (wCp == NULL) {
  1942. return ERROR_NOT_ENOUGH_MEMORY;
  1943. }
  1944. wcscpy(wCp, s);
  1945. l = wcslen(s);
  1946. if (l > 0 && wCp[l-1] != L'\\') {
  1947. wcscat(wCp, L"\\");
  1948. }
  1949. dwErr = DfsDeleteChildKeys(hkey, wCp);
  1950. if (dwErr == ERROR_SUCCESS) {
  1951. dwErr = RegDeleteKey(hkey, wCp);
  1952. }
  1953. free(wCp);
  1954. if (fSwDebug != 0)
  1955. MyPrintf(L"DfsRegDeleteKeyAndChildren exit %d\r\n", dwErr);
  1956. return dwErr;
  1957. }