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.

2203 lines
54 KiB

  1. //--------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: misc.cxx
  6. //
  7. //--------------------------------------------------------------------------
  8. #define UNICODE 1
  9. #include <stdio.h>
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <windows.h>
  14. #include <shellapi.h>
  15. #include <winldap.h>
  16. #include <stdlib.h>
  17. #include <dsgetdc.h>
  18. #include <lm.h>
  19. #include <dfsstr.h>
  20. #include <dfsmrshl.h>
  21. #include <marshal.hxx>
  22. #include <lmdfs.h>
  23. #include <dfspriv.h>
  24. #include <dfsm.hxx>
  25. #include <recon.hxx>
  26. #include <rpc.h>
  27. #include <fsctrl.h>
  28. #include <ntdsapi.h>
  29. #include <dsrole.h>
  30. #include <ntlsa.h>
  31. #include "struct.hxx"
  32. #include "ftsup.hxx"
  33. #include "stdsup.hxx"
  34. #include "rootsup.hxx"
  35. #include "flush.hxx"
  36. #include "info.hxx"
  37. #include "misc.hxx"
  38. #include "messages.h"
  39. #define MAX_BUF_SIZE 10000
  40. WCHAR MsgBuf[MAX_BUF_SIZE];
  41. CHAR AnsiBuf[MAX_BUF_SIZE*3];
  42. WCHAR wszRootShare[MAX_PATH+1] = { 0 };
  43. #define WINLOGON_FOLDER L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"
  44. #define SFCVALUE L"SFCDisable"
  45. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  46. DWORD
  47. DfspDomVerify(
  48. LPWSTR pwszDfsName,
  49. LPWSTR pwszShareName,
  50. LPWSTR pwszDcName,
  51. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  52. LPWSTR pwszHexValue);
  53. DWORD
  54. DfspDomView(
  55. LPWSTR pwszDfsName,
  56. LPWSTR pwszShareName,
  57. LPWSTR pwszDcName,
  58. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  59. LPWSTR pwszHexValue);
  60. DWORD
  61. DfspGetLinkName(
  62. LPWSTR pwszDfsRoot,
  63. LPWSTR *ppwszLinkName);
  64. DWORD
  65. CmdMupFlags(
  66. ULONG dwFsctrl,
  67. LPWSTR pwszHexValue)
  68. {
  69. DWORD dwErr = ERROR_SUCCESS;
  70. NTSTATUS NtStatus;
  71. HANDLE DriverHandle = NULL;
  72. IO_STATUS_BLOCK IoStatusBlock;
  73. OBJECT_ATTRIBUTES objectAttributes;
  74. UNICODE_STRING DfsDriverName;
  75. ULONG Level = 0;
  76. if (fSwDebug == TRUE)
  77. MyPrintf(L"CmdMupFlags(0x%x, %ws)\r\n", dwFsctrl, pwszHexValue);
  78. if (pwszHexValue != NULL) {
  79. Level = AtoHex(pwszHexValue, &dwErr);
  80. if (dwErr != ERROR_SUCCESS) {
  81. MyPrintf(L"Bad Level %ws\r\n", pwszHexValue);
  82. goto Cleanup;
  83. }
  84. }
  85. MyPrintf(L"Setting debug level to 0x%x\r\n", Level);
  86. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  87. InitializeObjectAttributes(
  88. &objectAttributes,
  89. &DfsDriverName,
  90. OBJ_CASE_INSENSITIVE,
  91. NULL,
  92. NULL);
  93. NtStatus = NtCreateFile(
  94. &DriverHandle,
  95. SYNCHRONIZE | FILE_WRITE_DATA,
  96. &objectAttributes,
  97. &IoStatusBlock,
  98. NULL,
  99. FILE_ATTRIBUTE_NORMAL,
  100. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  101. FILE_OPEN_IF,
  102. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  103. NULL,
  104. 0);
  105. if (!NT_SUCCESS(NtStatus)) {
  106. dwErr = RtlNtStatusToDosError(NtStatus);
  107. goto Cleanup;
  108. }
  109. NtStatus = NtFsControlFile(
  110. DriverHandle,
  111. NULL, // Event,
  112. NULL, // ApcRoutine,
  113. NULL, // ApcContext,
  114. &IoStatusBlock,
  115. dwFsctrl,
  116. &Level,
  117. sizeof(ULONG),
  118. NULL,
  119. 0);
  120. dwErr = RtlNtStatusToDosError(NtStatus);
  121. Cleanup:
  122. if (DriverHandle != NULL)
  123. NtClose(DriverHandle);
  124. if (fSwDebug == TRUE)
  125. MyPrintf(L"CmdMupFlags returning %d\r\n", dwErr);
  126. return dwErr;
  127. }
  128. DWORD
  129. CmdMupReadReg(
  130. BOOLEAN fSwDfs)
  131. {
  132. DWORD dwErr = ERROR_SUCCESS;
  133. NTSTATUS NtStatus;
  134. HANDLE DriverHandle = NULL;
  135. IO_STATUS_BLOCK IoStatusBlock;
  136. OBJECT_ATTRIBUTES objectAttributes;
  137. UNICODE_STRING DfsDriverName;
  138. ULONG Level = 0;
  139. if (fSwDebug == TRUE)
  140. MyPrintf(L"MupReadReg()\r\n");
  141. if (fSwDfs == TRUE) {
  142. MyPrintf(L"--dfs.sys--\r\n");
  143. RtlInitUnicodeString(&DfsDriverName, DFS_SERVER_NAME);
  144. } else {
  145. MyPrintf(L"--mup.sys--\r\n");
  146. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  147. }
  148. InitializeObjectAttributes(
  149. &objectAttributes,
  150. &DfsDriverName,
  151. OBJ_CASE_INSENSITIVE,
  152. NULL,
  153. NULL);
  154. NtStatus = NtCreateFile(
  155. &DriverHandle,
  156. SYNCHRONIZE,
  157. &objectAttributes,
  158. &IoStatusBlock,
  159. NULL,
  160. FILE_ATTRIBUTE_NORMAL,
  161. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  162. FILE_OPEN_IF,
  163. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  164. NULL,
  165. 0);
  166. if (!NT_SUCCESS(NtStatus)) {
  167. dwErr = RtlNtStatusToDosError(NtStatus);
  168. goto Cleanup;
  169. }
  170. NtStatus = NtFsControlFile(
  171. DriverHandle,
  172. NULL, // Event,
  173. NULL, // ApcRoutine,
  174. NULL, // ApcContext,
  175. &IoStatusBlock,
  176. FSCTL_DFS_REREAD_REGISTRY,
  177. NULL,
  178. 0,
  179. NULL,
  180. 0);
  181. dwErr = RtlNtStatusToDosError(NtStatus);
  182. Cleanup:
  183. if (DriverHandle != NULL)
  184. NtClose(DriverHandle);
  185. if (fSwDebug == TRUE)
  186. MyPrintf(L"MupReadReg exit\r\n");
  187. return dwErr;
  188. }
  189. DWORD
  190. AtoHex(
  191. LPWSTR pwszHexValue,
  192. PDWORD pdwErr)
  193. {
  194. DWORD dwHexValue = 0;
  195. // if (fSwDebug == TRUE)
  196. // MyPrintf(L"AtoHex(%ws)\r\n", pwszHexValue);
  197. if (pwszHexValue == NULL) {
  198. *pdwErr = ERROR_INVALID_PARAMETER;
  199. goto AllDone;
  200. }
  201. if (pwszHexValue[0] == L'0' && (pwszHexValue[1] == L'x' || pwszHexValue[1] == L'X'))
  202. pwszHexValue = &pwszHexValue[2];
  203. swscanf(pwszHexValue, L"%x", &dwHexValue);
  204. AllDone:
  205. // if (fSwDebug == TRUE)
  206. // MyPrintf(L"AtoHex returning 0x%x (dwErr=0x%x)\r\n", dwHexValue, *pdwErr);
  207. return dwHexValue;
  208. }
  209. DWORD
  210. AtoDec(
  211. LPWSTR pwszDecValue,
  212. PDWORD pdwErr)
  213. {
  214. DWORD dwDecValue = 0;
  215. // if (fSwDebug == TRUE)
  216. // MyPrintf(L"AtoDec(%ws)\r\n", pwszDecValue);
  217. if (pwszDecValue == NULL) {
  218. *pdwErr = ERROR_INVALID_PARAMETER;
  219. goto AllDone;
  220. }
  221. swscanf(pwszDecValue, L"%d", &dwDecValue);
  222. AllDone:
  223. // if (fSwDebug == TRUE)
  224. // MyPrintf(L"AtoDec returning 0x%x (dwErr=0x%x)\r\n", dwDecValue, *pdwErr);
  225. return dwDecValue;
  226. }
  227. CHAR ServerName[0x1000];
  228. DWORD
  229. CmdDfsAlt(
  230. LPWSTR pwszServerName)
  231. {
  232. DWORD dwErr = ERROR_SUCCESS;
  233. NTSTATUS NtStatus;
  234. HANDLE DriverHandle = NULL;
  235. IO_STATUS_BLOCK IoStatusBlock;
  236. OBJECT_ATTRIBUTES objectAttributes;
  237. UNICODE_STRING DfsDriverName;
  238. if (fSwDebug == TRUE)
  239. MyPrintf(L"DfsAlt(%ws)\r\n", pwszServerName);
  240. if (pwszServerName == NULL) {
  241. dwErr = ERROR_INVALID_PARAMETER;
  242. goto Cleanup;
  243. }
  244. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  245. InitializeObjectAttributes(
  246. &objectAttributes,
  247. &DfsDriverName,
  248. OBJ_CASE_INSENSITIVE,
  249. NULL,
  250. NULL
  251. );
  252. NtStatus = NtCreateFile(
  253. &DriverHandle,
  254. SYNCHRONIZE,
  255. &objectAttributes,
  256. &IoStatusBlock,
  257. NULL,
  258. FILE_ATTRIBUTE_NORMAL,
  259. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  260. FILE_OPEN_IF,
  261. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  262. NULL,
  263. 0);
  264. if (!NT_SUCCESS(NtStatus)) {
  265. dwErr = RtlNtStatusToDosError(NtStatus);
  266. goto Cleanup;
  267. }
  268. if (
  269. (wcslen(pwszServerName) < 5) ||
  270. *pwszServerName != L'\\' ||
  271. *(pwszServerName+1) != L'\\'
  272. ) {
  273. dwErr = ERROR_INVALID_PARAMETER;
  274. goto Cleanup;
  275. }
  276. MyPrintf(L"%ws -> ", pwszServerName);
  277. // Resolve to server name
  278. NtStatus = NtFsControlFile(
  279. DriverHandle,
  280. NULL, // Event,
  281. NULL, // ApcRoutine,
  282. NULL, // ApcContext,
  283. &IoStatusBlock,
  284. FSCTL_DFS_GET_SERVER_NAME,
  285. pwszServerName,
  286. wcslen(pwszServerName) * sizeof(WCHAR),
  287. ServerName,
  288. sizeof(ServerName)
  289. );
  290. if (!NT_SUCCESS(NtStatus)) {
  291. dwErr = RtlNtStatusToDosError(NtStatus);
  292. } else if (NT_SUCCESS(IoStatusBlock.Status) && IoStatusBlock.Information > 0) {
  293. MyPrintf(L"%ws\r\n", ServerName);
  294. } else {
  295. dwErr = RtlNtStatusToDosError(IoStatusBlock.Status);
  296. }
  297. Cleanup:
  298. if (DriverHandle == NULL)
  299. NtClose(DriverHandle);
  300. if (fSwDebug == TRUE)
  301. MyPrintf(L"DfsAlt exit %d\r\n", dwErr);
  302. return dwErr;
  303. }
  304. DWORD
  305. CmdSetDc(
  306. LPWSTR pwszDcName)
  307. {
  308. DWORD dwErr = ERROR_SUCCESS;
  309. NTSTATUS NtStatus;
  310. HANDLE DriverHandle = NULL;
  311. IO_STATUS_BLOCK IoStatusBlock;
  312. OBJECT_ATTRIBUTES objectAttributes;
  313. UNICODE_STRING DfsDriverName;
  314. if (fSwDebug == TRUE)
  315. MyPrintf(L"CmdSetDc(%ws)\r\n", pwszDcName);
  316. if (pwszDcName == NULL) {
  317. dwErr = ERROR_INVALID_PARAMETER;
  318. goto Cleanup;
  319. }
  320. pwszDcName += 2;
  321. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  322. InitializeObjectAttributes(
  323. &objectAttributes,
  324. &DfsDriverName,
  325. OBJ_CASE_INSENSITIVE,
  326. NULL,
  327. NULL
  328. );
  329. NtStatus = NtCreateFile(
  330. &DriverHandle,
  331. SYNCHRONIZE | FILE_WRITE_DATA,
  332. &objectAttributes,
  333. &IoStatusBlock,
  334. NULL,
  335. FILE_ATTRIBUTE_NORMAL,
  336. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  337. FILE_OPEN_IF,
  338. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  339. NULL,
  340. 0
  341. );
  342. if (!NT_SUCCESS(NtStatus)) {
  343. dwErr = RtlNtStatusToDosError(NtStatus);
  344. goto Cleanup;
  345. }
  346. NtStatus = NtFsControlFile(
  347. DriverHandle,
  348. NULL, // Event,
  349. NULL, // ApcRoutine,
  350. NULL, // ApcContext,
  351. &IoStatusBlock,
  352. FSCTL_DFS_PKT_SET_DC_NAME,
  353. pwszDcName,
  354. wcslen(pwszDcName) * sizeof(WCHAR) + sizeof(WCHAR),
  355. NULL,
  356. 0);
  357. dwErr = RtlNtStatusToDosError(NtStatus);
  358. Cleanup:
  359. if (DriverHandle != NULL)
  360. NtClose(DriverHandle);
  361. if (fSwDebug == TRUE)
  362. MyPrintf(L"CmdSetDc exit %d\r\n", dwErr);
  363. return dwErr;
  364. }
  365. DWORD
  366. CmdDcList(
  367. LPWSTR pwszDomainName,
  368. LPWSTR pwszDcName,
  369. PSEC_WINNT_AUTH_IDENTITY pAuthIdent)
  370. {
  371. PDS_DOMAIN_CONTROLLER_INFO_1 pDsDomainControllerInfo1 = NULL;
  372. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pPrimaryDomainInfo = NULL;
  373. HANDLE hDs = NULL;
  374. DWORD dwErr;
  375. DWORD Count;
  376. ULONG i;
  377. if (fSwDebug == TRUE)
  378. MyPrintf(L"CmdDcList(%ws,%ws)\r\n", pwszDomainName, pwszDcName);
  379. if (pwszDcName != NULL) {
  380. dwErr = DsBind(pwszDcName, NULL, &hDs);
  381. } else if (pwszDomainName != NULL) {
  382. dwErr = DsBind(NULL, pwszDomainName, &hDs);
  383. } else {
  384. dwErr = DsRoleGetPrimaryDomainInformation(
  385. NULL,
  386. DsRolePrimaryDomainInfoBasic,
  387. (PBYTE *)&pPrimaryDomainInfo);
  388. if (dwErr != ERROR_SUCCESS)
  389. goto Cleanup;
  390. pwszDomainName = pPrimaryDomainInfo->DomainNameDns;
  391. dwErr = DsBind(NULL, pwszDomainName, &hDs);
  392. }
  393. if (fSwDebug == TRUE)
  394. MyPrintf(L"Bind returned %d\r\n", dwErr);
  395. if (dwErr != ERROR_SUCCESS)
  396. goto Cleanup;
  397. dwErr = DsGetDomainControllerInfo(
  398. hDs,
  399. pwszDomainName,
  400. 1,
  401. &Count,
  402. (PVOID *)&pDsDomainControllerInfo1);
  403. if (dwErr != ERROR_SUCCESS) {
  404. if (fSwDebug == TRUE)
  405. MyPrintf(L"DsGetDomainControllerInfo() returned %d\r\n", dwErr);
  406. goto Cleanup;
  407. }
  408. for (i = 0; i < Count; i++) {
  409. MyPrintf(L"%d:\r\n", i+1);
  410. MyPrintf(L"\tNetbiosName=%ws\r\n", pDsDomainControllerInfo1[i].NetbiosName);
  411. MyPrintf(L"\tDnsHostName=%ws\r\n", pDsDomainControllerInfo1[i].DnsHostName);
  412. MyPrintf(L"\tSiteName=%ws\r\n", pDsDomainControllerInfo1[i].SiteName);
  413. if (fSwDebug == TRUE) {
  414. MyPrintf(L"\tComputerObjectName=%ws\r\n", pDsDomainControllerInfo1[i].ComputerObjectName);
  415. MyPrintf(L"\tServerObjectName=%ws\r\n", pDsDomainControllerInfo1[i].ServerObjectName);
  416. }
  417. MyPrintf(L"\tfIsPdc=%d\r\n", pDsDomainControllerInfo1[i].fIsPdc);
  418. MyPrintf(L"\tfDsEnabled=%d\r\n", pDsDomainControllerInfo1[i].fDsEnabled);
  419. }
  420. Cleanup:
  421. if (pDsDomainControllerInfo1 != NULL) {
  422. DsFreeDomainControllerInfo(
  423. 1,
  424. Count,
  425. pDsDomainControllerInfo1);
  426. }
  427. if (pPrimaryDomainInfo != NULL)
  428. DsRoleFreeMemory(pPrimaryDomainInfo);
  429. if (hDs != NULL)
  430. DsUnBind(&hDs);
  431. if (fSwDebug == TRUE)
  432. MyPrintf(L"CmdDcList returning %d\r\n", dwErr);
  433. return dwErr;
  434. }
  435. DWORD
  436. CmdDomList(
  437. LPWSTR pwszDcName,
  438. LPWSTR pwszDomainName,
  439. PSEC_WINNT_AUTH_IDENTITY pAuthIdent)
  440. {
  441. DWORD dwErr = ERROR_SUCCESS;
  442. LPWSTR *DomDfsList = NULL;
  443. ULONG i;
  444. MyPrintf(L"Getting DomDfs's in %ws\r\n", pwszDomainName);
  445. dwErr = NetDfsRootEnum(
  446. pwszDcName,
  447. pwszDomainName,
  448. pAuthIdent,
  449. &DomDfsList);
  450. if (dwErr != ERROR_SUCCESS)
  451. return dwErr;
  452. if (DomDfsList != NULL) {
  453. for (i = 0; DomDfsList[i]; i++)
  454. /* NOTHING */;
  455. MyPrintf(L"Found %d DomDfs's\r\n", i);
  456. for (i = 0; DomDfsList[i]; i++)
  457. MyPrintf(L"%ws\r\n", DomDfsList[i]);
  458. NetApiBufferFree(DomDfsList);
  459. }
  460. return dwErr;
  461. }
  462. DWORD
  463. CmdStdList(
  464. LPWSTR pwszDomainName)
  465. {
  466. DWORD dwErr = ERROR_SUCCESS;
  467. PSERVER_INFO_101 pInfo101 = NULL;
  468. ULONG dwEntriesRead;
  469. ULONG dwTotalEntries;
  470. ULONG i;
  471. MyPrintf(L"Getting Dfs's in %ws\r\n", pwszDomainName);
  472. dwErr = NetServerEnum(
  473. NULL,
  474. 101,
  475. (PUCHAR *)&pInfo101,
  476. -1,
  477. &dwEntriesRead,
  478. &dwTotalEntries,
  479. SV_TYPE_DFS,
  480. pwszDomainName,
  481. NULL);
  482. if (dwErr != ERROR_SUCCESS)
  483. return dwErr;
  484. if (pInfo101 != NULL) {
  485. MyPrintf(L"Found %d Dfs's\r\n", dwEntriesRead);
  486. for (i = 0; i < dwEntriesRead; i++) {
  487. MyPrintf(L"%ws (%d.%d)\r\n",
  488. pInfo101[i].sv101_name,
  489. pInfo101[i].sv101_version_major,
  490. pInfo101[i].sv101_version_minor);
  491. }
  492. NetApiBufferFree(pInfo101);
  493. }
  494. return dwErr;
  495. }
  496. DWORD
  497. CmdVerify(
  498. LPWSTR pwszDfsRoot,
  499. LPWSTR pwszDcName,
  500. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  501. LPWSTR pwszHexValue)
  502. {
  503. DWORD dwErr = ERROR_SUCCESS;
  504. LPWSTR pwszDfsName = NULL;
  505. LPWSTR pwszShareName = NULL;
  506. BOOLEAN IsDomainName = FALSE;
  507. if (fSwDebug == TRUE)
  508. MyPrintf(L"CmdVerify(%ws,%ws)\r\n", pwszDfsRoot, pwszDcName);
  509. if (pwszDfsRoot == NULL) {
  510. dwErr = ERROR_INVALID_PARAMETER;
  511. goto Cleanup;
  512. }
  513. dwErr = DfspParseName(
  514. pwszDfsRoot,
  515. &pwszDfsName,
  516. &pwszShareName);
  517. if (dwErr != ERROR_SUCCESS)
  518. goto Cleanup;
  519. dwErr = DfspIsDomainName(
  520. pwszDfsName,
  521. pwszDcName,
  522. &IsDomainName);
  523. if (dwErr != ERROR_SUCCESS)
  524. goto Cleanup;
  525. if (IsDomainName == TRUE) {
  526. dwErr = DfspDomVerify(
  527. pwszDfsName,
  528. pwszShareName,
  529. pwszDcName,
  530. pAuthIdent,
  531. pwszHexValue);
  532. } else {
  533. fArgVerify = TRUE;
  534. dwErr = CmdViewOrVerify(
  535. pwszDfsName,
  536. pwszDcName,
  537. NULL,
  538. pAuthIdent,
  539. pwszHexValue);
  540. }
  541. Cleanup:
  542. if (pwszDfsName != NULL)
  543. free(pwszDfsName);
  544. if (pwszShareName != NULL)
  545. free(pwszShareName);
  546. if (fSwDebug == TRUE)
  547. MyPrintf(L"CmdVerify returning %d\r\n", dwErr);
  548. return dwErr;
  549. }
  550. DWORD
  551. DfspDomVerify(
  552. LPWSTR pwszDfsName,
  553. LPWSTR pwszShareName,
  554. LPWSTR pwszDcName,
  555. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  556. LPWSTR pwszHexValue)
  557. {
  558. ULONG i;
  559. DWORD dwErr = ERROR_SUCCESS;
  560. WCHAR wszTempName[MAX_PATH+1];
  561. DFS_VOLUME_LIST DfsVolList = { 0 };
  562. BOOLEAN IsFtRoot = FALSE;
  563. WCHAR wszDfsName[MAX_PATH+1];
  564. DWORD cbName;
  565. DWORD dwType;
  566. DWORD Level = 0;
  567. HKEY hKey = NULL;
  568. HKEY rKey = NULL;
  569. if (fSwDebug == TRUE)
  570. MyPrintf(L"DfspDomVerify(%ws,%ws,%ws)\r\n", pwszDfsName, pwszShareName, pwszHexValue);
  571. if (pwszHexValue != NULL) {
  572. Level = AtoHex(pwszHexValue, &dwErr);
  573. if (dwErr != ERROR_SUCCESS) {
  574. MyPrintf(L"Bad Level %ws\r\n", pwszHexValue);
  575. goto Cleanup;
  576. }
  577. }
  578. MyPrintf(L"\\\\%ws\\%ws is a DomDfs\r\n", pwszDfsName, pwszShareName);
  579. dwErr = DfsGetFtVol(
  580. &DfsVolList,
  581. pwszShareName,
  582. pwszDcName,
  583. pwszDfsName,
  584. pAuthIdent);
  585. if (dwErr != ERROR_SUCCESS)
  586. goto Cleanup;
  587. for (i = 0; i < DfsVolList.Volumes[0]->ReplCount; i++) {
  588. wcscpy(wszTempName, L"\\\\");
  589. wcscat(wszTempName, DfsVolList.Volumes[0]->ReplicaInfo[i].pwszServerName);
  590. IsFtRoot = FALSE;
  591. if (rKey != NULL) {
  592. RegCloseKey(rKey);
  593. rKey = NULL;
  594. }
  595. if (hKey != NULL) {
  596. RegCloseKey(hKey);
  597. hKey = NULL;
  598. }
  599. MyPrintf(L"Checking root %ws\r\n", wszTempName);
  600. dwErr = RegConnectRegistry(
  601. wszTempName,
  602. HKEY_LOCAL_MACHINE,
  603. &rKey);
  604. if (dwErr != ERROR_SUCCESS) {
  605. ErrorMessage(MSG_CAN_NOT_OPEN_REGISTRY, wszTempName, dwErr);
  606. continue;
  607. }
  608. dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey);
  609. if (dwErr != ERROR_SUCCESS) {
  610. MyPrintf(L"Can not open %ws of %ws (error %d)\r\n",
  611. VOLUMES_DIR,
  612. wszTempName,
  613. dwErr);
  614. continue;
  615. }
  616. if (dwErr == ERROR_SUCCESS) {
  617. cbName = MAX_PATH;
  618. dwErr = RegQueryValueEx(
  619. hKey,
  620. FTDFS_VALUE_NAME,
  621. NULL,
  622. &dwType,
  623. (PBYTE) wszDfsName,
  624. &cbName);
  625. if (dwErr == ERROR_MORE_DATA)
  626. dwErr = ERROR_SUCCESS;
  627. if (dwErr == ERROR_SUCCESS && dwType == REG_SZ)
  628. IsFtRoot = TRUE;
  629. }
  630. if (IsFtRoot == FALSE) {
  631. MyPrintf(L"%ws is not a DomDfs root (%d)\r\n",
  632. wszTempName,
  633. dwErr);
  634. continue;
  635. }
  636. cbName = MAX_PATH;
  637. dwErr = RegQueryValueEx(
  638. hKey,
  639. ROOT_SHARE_VALUE_NAME,
  640. NULL,
  641. &dwType,
  642. (PBYTE) wszRootShare,
  643. &cbName);
  644. if (dwErr == ERROR_MORE_DATA)
  645. dwErr = ERROR_SUCCESS;
  646. if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) {
  647. MyPrintf(L"Registry value \"RootShare\" is missing or corrupt.\r\n");
  648. continue;
  649. }
  650. dwErr = GetExitPtInfo(
  651. rKey,
  652. &DfsVolList.pRootLocalVol,
  653. &DfsVolList.cRootLocalVol);
  654. if (dwErr != ERROR_SUCCESS) {
  655. MyPrintf(L"Could not get registry/exit pt info for %ws\r\n", wszTempName);
  656. continue;
  657. }
  658. if (fArgVerify)
  659. DfsCheckVolList(&DfsVolList, Level);
  660. DfsFreeRootLocalVol(
  661. DfsVolList.pRootLocalVol,
  662. DfsVolList.cRootLocalVol);
  663. DfsVolList.pRootLocalVol = NULL;
  664. DfsVolList.cRootLocalVol = 0;
  665. }
  666. Cleanup:
  667. //
  668. // Free volume info
  669. //
  670. DfsFreeVolList(&DfsVolList);
  671. //
  672. // Free exit pt info
  673. //
  674. DfsFreeRootLocalVol(
  675. DfsVolList.pRootLocalVol,
  676. DfsVolList.cRootLocalVol);
  677. if (hKey != NULL)
  678. RegCloseKey(hKey);
  679. if (rKey != NULL)
  680. RegCloseKey(rKey);
  681. if (fSwDebug == TRUE)
  682. MyPrintf(L"DfspDomVerify returning %d\r\n", dwErr);
  683. return dwErr;
  684. }
  685. DWORD
  686. CmdView(
  687. LPWSTR pwszDfsRoot,
  688. LPWSTR pwszDcName,
  689. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  690. LPWSTR pwszHexValue)
  691. {
  692. DWORD dwErr = ERROR_SUCCESS;
  693. LPWSTR pwszDfsName = NULL;
  694. LPWSTR pwszShareName = NULL;
  695. BOOLEAN IsDomainName = FALSE;
  696. if (fSwDebug == TRUE)
  697. MyPrintf(L"CmdView(%ws,%ws,%ws)\r\n", pwszDfsRoot, pwszDcName, pwszHexValue);
  698. if (pwszDfsRoot == NULL) {
  699. dwErr = ERROR_INVALID_PARAMETER;
  700. goto Cleanup;
  701. }
  702. dwErr = DfspParseName(
  703. pwszDfsRoot,
  704. &pwszDfsName,
  705. &pwszShareName);
  706. if (dwErr != ERROR_SUCCESS)
  707. goto Cleanup;
  708. dwErr = DfspIsDomainName(
  709. pwszDfsName,
  710. pwszDcName,
  711. &IsDomainName);
  712. if (dwErr != ERROR_SUCCESS)
  713. goto Cleanup;
  714. if (IsDomainName == TRUE) {
  715. dwErr = DfspDomView(
  716. pwszDfsName,
  717. pwszShareName,
  718. pwszDcName,
  719. pAuthIdent,
  720. pwszHexValue);
  721. } else {
  722. fArgView = TRUE;
  723. dwErr = CmdViewOrVerify(
  724. pwszDfsName,
  725. pwszDcName,
  726. NULL,
  727. pAuthIdent,
  728. pwszHexValue);
  729. }
  730. Cleanup:
  731. if (pwszDfsName != NULL)
  732. free(pwszDfsName);
  733. if (pwszShareName != NULL)
  734. free(pwszShareName);
  735. if (fSwDebug == TRUE)
  736. MyPrintf(L"CmdView returning %d\r\n", dwErr);
  737. return dwErr;
  738. }
  739. DWORD
  740. DfspDomView(
  741. LPWSTR pwszDfsName,
  742. LPWSTR pwszShareName,
  743. LPWSTR pwszDcName,
  744. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  745. LPWSTR pwszHexValue)
  746. {
  747. DWORD dwErr = ERROR_SUCCESS;
  748. DFS_VOLUME_LIST DfsVolList = { 0 };
  749. ULONG Level = 0;
  750. if (fSwDebug == TRUE)
  751. MyPrintf(L"DfspDomView(%ws,%ws,%ws)\r\n", pwszDfsName, pwszShareName, pwszHexValue);
  752. if (pwszHexValue != NULL) {
  753. Level = AtoHex(pwszHexValue, &dwErr);
  754. if (dwErr != ERROR_SUCCESS) {
  755. MyPrintf(L"Bad Level %ws\r\n", pwszHexValue);
  756. goto Cleanup;
  757. }
  758. }
  759. MyPrintf(L"\\\\%ws\\%ws is a DomDfs\r\n", pwszDfsName, pwszShareName);
  760. dwErr = DfsGetFtVol(
  761. &DfsVolList,
  762. pwszShareName,
  763. pwszDcName,
  764. pwszDfsName,
  765. pAuthIdent);
  766. if (dwErr != ERROR_SUCCESS)
  767. goto Cleanup;
  768. if (fSwDebug == TRUE)
  769. DfsDumpVolList(&DfsVolList);
  770. DfsViewVolList(&DfsVolList, Level);
  771. Cleanup:
  772. //
  773. // Free volume info
  774. //
  775. DfsFreeVolList(&DfsVolList);
  776. //
  777. // Free exit pt info
  778. //
  779. DfsFreeRootLocalVol(
  780. DfsVolList.pRootLocalVol,
  781. DfsVolList.cRootLocalVol);
  782. return dwErr;
  783. }
  784. DWORD
  785. CmdWhatIs(
  786. LPWSTR pwszServerName)
  787. {
  788. DWORD dwErr = ERROR_SUCCESS;
  789. WCHAR wszDomDfsName[MAX_PATH+1];
  790. BOOLEAN IsFtRoot = FALSE;
  791. DWORD cbName;
  792. DWORD dwType;
  793. HKEY hKey = NULL;
  794. HKEY rKey = NULL;
  795. ULONG Len;
  796. if (fSwDebug == TRUE)
  797. MyPrintf(L"CmdWhatIs(%ws)\n", pwszServerName);
  798. if (pwszServerName != NULL) {
  799. Len = wcslen(pwszServerName);
  800. while (pwszServerName[0] == UNICODE_PATH_SEP &&
  801. pwszServerName[1] == UNICODE_PATH_SEP &&
  802. pwszServerName[2] == UNICODE_PATH_SEP &&
  803. Len > 3) {
  804. pwszServerName++;
  805. Len--;
  806. }
  807. }
  808. //
  809. // See if this is a Fault-Tolerant Dfs vs Server-Based Dfs
  810. //
  811. dwErr = RegConnectRegistry(
  812. pwszServerName,
  813. HKEY_LOCAL_MACHINE,
  814. &rKey);
  815. if (dwErr != ERROR_SUCCESS) {
  816. ErrorMessage(MSG_CAN_NOT_CONNECT, pwszServerName);
  817. goto Cleanup;
  818. }
  819. dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey);
  820. if (dwErr == ERROR_SUCCESS) {
  821. cbName = MAX_PATH;
  822. dwErr = RegQueryValueEx(
  823. hKey,
  824. FTDFS_VALUE_NAME,
  825. NULL,
  826. &dwType,
  827. (PBYTE) wszDomDfsName,
  828. &cbName);
  829. if (dwErr == ERROR_MORE_DATA)
  830. dwErr = ERROR_SUCCESS;
  831. if (dwErr == ERROR_SUCCESS && dwType == REG_SZ)
  832. IsFtRoot = TRUE;
  833. } else {
  834. MyPrintf(L"Not a Dfs root\r\n");
  835. goto Cleanup;
  836. }
  837. cbName = MAX_PATH;
  838. dwErr = RegQueryValueEx(
  839. hKey,
  840. ROOT_SHARE_VALUE_NAME,
  841. NULL,
  842. &dwType,
  843. (PBYTE) wszRootShare,
  844. &cbName);
  845. if (dwErr == ERROR_MORE_DATA)
  846. dwErr = ERROR_SUCCESS;
  847. if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) {
  848. MyPrintf(L"Registry value \"RootShare\" is missing or corrupt.\r\n");
  849. goto Cleanup;
  850. }
  851. if (IsFtRoot == TRUE) {
  852. MyPrintf(L"Is DomDfs \"%ws\", root share is \"%ws\"\r\n", wszDomDfsName, wszRootShare);
  853. } else {
  854. MyPrintf(L"Is StdDfs, root share is \"%ws\"\r\n", wszRootShare);
  855. }
  856. Cleanup:
  857. if (hKey != NULL)
  858. RegCloseKey(hKey);
  859. if (rKey != NULL)
  860. RegCloseKey(rKey);
  861. if (fSwDebug == TRUE)
  862. MyPrintf(L"CmdWhatIs returning %d\r\n", dwErr);
  863. return dwErr;
  864. }
  865. DWORD
  866. CmdCscOnLine(
  867. LPWSTR pwszServerName)
  868. {
  869. DWORD dwErr = STATUS_SUCCESS;
  870. NTSTATUS NtStatus;
  871. HANDLE DriverHandle = NULL;
  872. IO_STATUS_BLOCK IoStatusBlock;
  873. OBJECT_ATTRIBUTES objectAttributes;
  874. UNICODE_STRING DfsDriverName;
  875. ULONG Type = 0;
  876. if (fSwDebug)
  877. MyPrintf(L"CmdCscOnLine(%ws)\r\n", pwszServerName);
  878. if (pwszServerName == NULL)
  879. pwszServerName = L"";
  880. MyPrintf(L"ServerName=[%ws]\r\n", pwszServerName);
  881. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  882. InitializeObjectAttributes(
  883. &objectAttributes,
  884. &DfsDriverName,
  885. OBJ_CASE_INSENSITIVE,
  886. NULL,
  887. NULL);
  888. NtStatus = NtCreateFile(
  889. &DriverHandle,
  890. SYNCHRONIZE | FILE_WRITE_DATA,
  891. &objectAttributes,
  892. &IoStatusBlock,
  893. NULL,
  894. FILE_ATTRIBUTE_NORMAL,
  895. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  896. FILE_OPEN_IF,
  897. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  898. NULL,
  899. 0);
  900. if (!NT_SUCCESS(NtStatus)) {
  901. dwErr = RtlNtStatusToDosError(NtStatus);
  902. if (fSwDebug)
  903. MyPrintf(L"NtCreateFile returned 0x%x\r\n", NtStatus);
  904. goto Cleanup;
  905. }
  906. NtStatus = NtFsControlFile(
  907. DriverHandle,
  908. NULL, // Event,
  909. NULL, // ApcRoutine,
  910. NULL, // ApcContext,
  911. &IoStatusBlock,
  912. FSCTL_DFS_CSC_SERVER_ONLINE,
  913. pwszServerName,
  914. wcslen(pwszServerName) * sizeof(WCHAR),
  915. NULL,
  916. 0);
  917. NtClose(DriverHandle);
  918. if (!NT_SUCCESS(NtStatus)) {
  919. if (fSwDebug)
  920. MyPrintf(L"NtFsControlFile returned 0x%x\r\n", NtStatus);
  921. }
  922. dwErr = RtlNtStatusToDosError(NtStatus);
  923. Cleanup:
  924. if (fSwDebug && dwErr != ERROR_SUCCESS)
  925. MyPrintf(L"CmdCscOnLine exit %d\r\n", dwErr);
  926. return(dwErr);
  927. }
  928. DWORD
  929. CmdCscOffLine(
  930. LPWSTR pwszServerName)
  931. {
  932. DWORD dwErr = STATUS_SUCCESS;
  933. NTSTATUS NtStatus;
  934. HANDLE DriverHandle = NULL;
  935. IO_STATUS_BLOCK IoStatusBlock;
  936. OBJECT_ATTRIBUTES objectAttributes;
  937. UNICODE_STRING DfsDriverName;
  938. ULONG Type = 0;
  939. if (fSwDebug)
  940. MyPrintf(L"CmdCscOffLine(%ws)\r\n", pwszServerName);
  941. if (pwszServerName == NULL)
  942. pwszServerName = L"";
  943. MyPrintf(L"ServerName=[%ws]\r\n", pwszServerName);
  944. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  945. InitializeObjectAttributes(
  946. &objectAttributes,
  947. &DfsDriverName,
  948. OBJ_CASE_INSENSITIVE,
  949. NULL,
  950. NULL);
  951. NtStatus = NtCreateFile(
  952. &DriverHandle,
  953. SYNCHRONIZE | FILE_WRITE_DATA,
  954. &objectAttributes,
  955. &IoStatusBlock,
  956. NULL,
  957. FILE_ATTRIBUTE_NORMAL,
  958. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  959. FILE_OPEN_IF,
  960. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  961. NULL,
  962. 0);
  963. if (!NT_SUCCESS(NtStatus)) {
  964. dwErr = RtlNtStatusToDosError(NtStatus);
  965. if (fSwDebug)
  966. MyPrintf(L"NtCreateFile returned 0x%x\r\n", NtStatus);
  967. goto Cleanup;
  968. }
  969. NtStatus = NtFsControlFile(
  970. DriverHandle,
  971. NULL, // Event,
  972. NULL, // ApcRoutine,
  973. NULL, // ApcContext,
  974. &IoStatusBlock,
  975. FSCTL_DFS_CSC_SERVER_OFFLINE,
  976. pwszServerName,
  977. wcslen(pwszServerName) * sizeof(WCHAR),
  978. NULL,
  979. 0);
  980. NtClose(DriverHandle);
  981. if (!NT_SUCCESS(NtStatus)) {
  982. if (fSwDebug)
  983. MyPrintf(L"NtFsControlFile returned 0x%x\r\n", NtStatus);
  984. }
  985. dwErr = RtlNtStatusToDosError(NtStatus);
  986. Cleanup:
  987. if (fSwDebug && dwErr != ERROR_SUCCESS)
  988. MyPrintf(L"CmdCscOffLine exit %d\r\n", dwErr);
  989. return(dwErr);
  990. }
  991. DWORD
  992. CmdDfsFsctlDfs(
  993. LPWSTR DriverName,
  994. DWORD FsctlCmd)
  995. {
  996. DWORD dwErr = STATUS_SUCCESS;
  997. NTSTATUS NtStatus;
  998. HANDLE DriverHandle = NULL;
  999. IO_STATUS_BLOCK IoStatusBlock;
  1000. OBJECT_ATTRIBUTES objectAttributes;
  1001. UNICODE_STRING DfsDriverName;
  1002. ULONG Type = 0;
  1003. if (fSwDebug)
  1004. MyPrintf(L"CmdDfsFsctlDfs(0x%x)\r\n", FsctlCmd);
  1005. RtlInitUnicodeString(&DfsDriverName, DriverName);
  1006. InitializeObjectAttributes(
  1007. &objectAttributes,
  1008. &DfsDriverName,
  1009. OBJ_CASE_INSENSITIVE,
  1010. NULL,
  1011. NULL);
  1012. NtStatus = NtCreateFile(
  1013. &DriverHandle,
  1014. SYNCHRONIZE | FILE_WRITE_DATA,
  1015. &objectAttributes,
  1016. &IoStatusBlock,
  1017. NULL,
  1018. FILE_ATTRIBUTE_NORMAL,
  1019. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  1020. FILE_OPEN_IF,
  1021. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  1022. NULL,
  1023. 0);
  1024. if (!NT_SUCCESS(NtStatus)) {
  1025. dwErr = RtlNtStatusToDosError(NtStatus);
  1026. if (fSwDebug)
  1027. MyPrintf(L"NtCreateFile returned 0x%x\r\n", NtStatus);
  1028. goto Cleanup;
  1029. }
  1030. NtStatus = NtFsControlFile(
  1031. DriverHandle,
  1032. NULL, // Event,
  1033. NULL, // ApcRoutine,
  1034. NULL, // ApcContext,
  1035. &IoStatusBlock,
  1036. FsctlCmd,
  1037. NULL,
  1038. 0,
  1039. NULL,
  1040. 0);
  1041. NtClose(DriverHandle);
  1042. if (!NT_SUCCESS(NtStatus)) {
  1043. if (fSwDebug)
  1044. MyPrintf(L"NtFsControlFile returned 0x%x\r\n", NtStatus);
  1045. }
  1046. dwErr = RtlNtStatusToDosError(NtStatus);
  1047. Cleanup:
  1048. if (fSwDebug && dwErr != ERROR_SUCCESS)
  1049. MyPrintf(L"CmdDfsFsctlDfs exit %d\r\n", dwErr);
  1050. return(dwErr);
  1051. }
  1052. DWORD
  1053. CmdSetOnSite(
  1054. LPWSTR pwszDfsRoot,
  1055. LPWSTR pwszDcName,
  1056. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  1057. ULONG set)
  1058. {
  1059. DWORD dwErr = ERROR_SUCCESS;
  1060. LPWSTR pwszDfsName = NULL;
  1061. LPWSTR pwszShareName = NULL;
  1062. LPWSTR pwszLinkName = NULL;
  1063. WCHAR wszDomDfsName[MAX_PATH+1];
  1064. BOOLEAN IsFtRoot = FALSE;
  1065. DWORD cbName;
  1066. DWORD dwType;
  1067. HKEY hKey = NULL;
  1068. HKEY rKey = NULL;
  1069. BOOLEAN IsDomainName = FALSE;
  1070. dwErr = DfspParseName(pwszDfsRoot, &pwszDfsName, &pwszShareName);
  1071. if (dwErr != ERROR_SUCCESS)
  1072. goto Cleanup;
  1073. dwErr = DfspGetLinkName(pwszDfsRoot, &pwszLinkName);
  1074. if (dwErr != ERROR_SUCCESS)
  1075. goto Cleanup;
  1076. dwErr = DfspIsDomainName(
  1077. pwszDfsName,
  1078. pwszDcName,
  1079. &IsDomainName);
  1080. if (dwErr != ERROR_SUCCESS)
  1081. goto Cleanup;
  1082. if (IsDomainName == TRUE) {
  1083. dwErr = DfsSetFtOnSite(pwszDfsName, pwszShareName, pwszLinkName, pwszDcName, pAuthIdent, set);
  1084. }
  1085. else {
  1086. dwErr = RegConnectRegistry( pwszDfsName, HKEY_LOCAL_MACHINE, &rKey);
  1087. if (dwErr != ERROR_SUCCESS) {
  1088. ErrorMessage(MSG_CAN_NOT_CONNECT, pwszDfsName);
  1089. goto Cleanup;
  1090. }
  1091. dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey);
  1092. if (dwErr == ERROR_SUCCESS) {
  1093. cbName = MAX_PATH;
  1094. dwErr = RegQueryValueEx(
  1095. hKey,
  1096. FTDFS_VALUE_NAME,
  1097. NULL,
  1098. &dwType,
  1099. (PBYTE) wszDomDfsName,
  1100. &cbName);
  1101. if (dwErr == ERROR_MORE_DATA)
  1102. dwErr = ERROR_SUCCESS;
  1103. if (dwErr == ERROR_SUCCESS && dwType == REG_SZ)
  1104. IsFtRoot = TRUE;
  1105. } else {
  1106. MyPrintf(L"Not a Dfs root\r\n");
  1107. goto Cleanup;
  1108. }
  1109. if (IsFtRoot == TRUE) {
  1110. MyPrintf(L"Not a Std Dfs root\r\n");
  1111. goto Cleanup;
  1112. }
  1113. dwErr = DfsSetOnSite(rKey, pwszLinkName, set);
  1114. }
  1115. Cleanup:
  1116. if (pwszDfsName != NULL)
  1117. free(pwszDfsName);
  1118. if (pwszShareName != NULL)
  1119. free(pwszShareName);
  1120. if (pwszLinkName != NULL)
  1121. free(pwszLinkName);
  1122. if (rKey != NULL)
  1123. RegCloseKey(rKey);
  1124. if (hKey != NULL)
  1125. RegCloseKey(hKey);
  1126. return dwErr;
  1127. }
  1128. DWORD
  1129. CmdViewOrVerify(
  1130. LPWSTR pwszServerName,
  1131. LPWSTR pwszDcName,
  1132. LPWSTR pwszDomainName,
  1133. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  1134. LPWSTR pwszHexValue)
  1135. {
  1136. ULONG i;
  1137. DWORD dwErr = ERROR_SUCCESS;
  1138. DFS_VOLUME_LIST DfsVolList = { 0 };
  1139. BOOLEAN IsFtRoot = FALSE;
  1140. WCHAR wszDomDfsName[MAX_PATH+1];
  1141. LPWSTR pwszDomDfsName = NULL;
  1142. DWORD cbName;
  1143. DWORD dwType;
  1144. HKEY hKey = NULL;
  1145. HKEY rKey = NULL;
  1146. ULONG Level = 0;
  1147. ErrorMessage(MSG_CONNECTING, pwszServerName);
  1148. if (pwszHexValue != NULL) {
  1149. Level = AtoHex(pwszHexValue, &dwErr);
  1150. if (dwErr != ERROR_SUCCESS) {
  1151. MyPrintf(L"Bad Level %ws\r\n", pwszHexValue);
  1152. goto Cleanup;
  1153. }
  1154. }
  1155. //
  1156. // See if this is a Fault-Tolerant Dfs vs Server-Based Dfs
  1157. //
  1158. dwErr = RegConnectRegistry(
  1159. pwszServerName,
  1160. HKEY_LOCAL_MACHINE,
  1161. &rKey);
  1162. if (dwErr != ERROR_SUCCESS) {
  1163. ErrorMessage(MSG_CAN_NOT_CONNECT, pwszServerName);
  1164. goto Cleanup;
  1165. }
  1166. dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey);
  1167. if (dwErr == ERROR_SUCCESS) {
  1168. cbName = MAX_PATH;
  1169. dwErr = RegQueryValueEx(
  1170. hKey,
  1171. FTDFS_VALUE_NAME,
  1172. NULL,
  1173. &dwType,
  1174. (PBYTE) wszDomDfsName,
  1175. &cbName);
  1176. if (dwErr == ERROR_MORE_DATA)
  1177. dwErr = ERROR_SUCCESS;
  1178. if (dwErr == ERROR_SUCCESS && dwType == REG_SZ)
  1179. IsFtRoot = TRUE;
  1180. } else {
  1181. MyPrintf(L"Not a Dfs root\r\n");
  1182. goto Cleanup;
  1183. }
  1184. cbName = MAX_PATH;
  1185. dwErr = RegQueryValueEx(
  1186. hKey,
  1187. ROOT_SHARE_VALUE_NAME,
  1188. NULL,
  1189. &dwType,
  1190. (PBYTE) wszRootShare,
  1191. &cbName);
  1192. if (dwErr == ERROR_MORE_DATA)
  1193. dwErr = ERROR_SUCCESS;
  1194. if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) {
  1195. MyPrintf(L"Registry value \"RootShare\" is missing or corrupt.\r\n");
  1196. goto Cleanup;
  1197. }
  1198. if (IsFtRoot == TRUE) {
  1199. if (fSwDebug == TRUE)
  1200. MyPrintf(L"Registry says is DomDfs (%ws)...\r\n", wszDomDfsName);
  1201. if (pwszDomDfsName == NULL) {
  1202. pwszDomDfsName = wszDomDfsName;
  1203. } else {
  1204. if (fSwDebug == TRUE)
  1205. MyPrintf(L"You specified to check against %ws\r\n", pwszDomDfsName);
  1206. }
  1207. dwErr = DfsGetFtVol(
  1208. &DfsVolList,
  1209. pwszDomDfsName,
  1210. pwszDcName,
  1211. pwszDomainName,
  1212. pAuthIdent);
  1213. if (dwErr != ERROR_SUCCESS)
  1214. goto Cleanup;
  1215. dwErr = GetExitPtInfo(
  1216. rKey,
  1217. &DfsVolList.pRootLocalVol,
  1218. &DfsVolList.cRootLocalVol);
  1219. if (dwErr != ERROR_SUCCESS)
  1220. goto Cleanup;
  1221. } else {
  1222. if (fSwDebug == TRUE)
  1223. MyPrintf(L"Is StdDfs...\r\n");
  1224. dwErr = DfsGetStdVol(
  1225. rKey,
  1226. &DfsVolList);
  1227. if (dwErr != ERROR_SUCCESS)
  1228. goto Cleanup;
  1229. dwErr = GetExitPtInfo(
  1230. rKey,
  1231. &DfsVolList.pRootLocalVol,
  1232. &DfsVolList.cRootLocalVol);
  1233. if (dwErr != ERROR_SUCCESS)
  1234. goto Cleanup;
  1235. }
  1236. //
  1237. // Print it all
  1238. //
  1239. if (fSwDebug == TRUE) {
  1240. DfsDumpVolList(&DfsVolList);
  1241. DfsDumpExitPtList(
  1242. DfsVolList.pRootLocalVol,
  1243. DfsVolList.cRootLocalVol);
  1244. }
  1245. if (fArgView == TRUE)
  1246. DfsViewVolList(&DfsVolList, Level);
  1247. //
  1248. // Compare volume info and LocalVolume exitpoint cache
  1249. //
  1250. if (fArgVerify == TRUE)
  1251. DfsCheckVolList(&DfsVolList, Level);
  1252. Cleanup:
  1253. //
  1254. // Free volume info
  1255. //
  1256. DfsFreeVolList(&DfsVolList);
  1257. //
  1258. // Free exit pt info
  1259. //
  1260. DfsFreeRootLocalVol(
  1261. DfsVolList.pRootLocalVol,
  1262. DfsVolList.cRootLocalVol);
  1263. if (hKey != NULL)
  1264. RegCloseKey(hKey);
  1265. if (rKey != NULL)
  1266. RegCloseKey(rKey);
  1267. return dwErr;
  1268. }
  1269. DWORD
  1270. CmdSfp(
  1271. LPWSTR pwszServerName,
  1272. BOOLEAN fSwOn,
  1273. BOOLEAN fSwOff)
  1274. {
  1275. DWORD dwErr = ERROR_SUCCESS;
  1276. HKEY rKey = NULL;
  1277. HKEY hKey = NULL;
  1278. ULONG cbSize;
  1279. DWORD dwSFCDisable = 0;
  1280. if (fSwDebug == TRUE)
  1281. MyPrintf(L"CmdSfp(%ws,ON=%d,OFF=%d)\r\n",
  1282. pwszServerName,
  1283. fSwOn,
  1284. fSwOff);
  1285. if (fSwOn == TRUE && fSwOff == TRUE) {
  1286. MyPrintf(L" ON and OFF at the same time? Forget it!\r\n");
  1287. dwErr = ERROR_INVALID_PARAMETER;
  1288. goto Cleanup;
  1289. }
  1290. dwErr = RegConnectRegistry(
  1291. pwszServerName,
  1292. HKEY_LOCAL_MACHINE,
  1293. &rKey);
  1294. if (dwErr != ERROR_SUCCESS) {
  1295. ErrorMessage(MSG_CAN_NOT_CONNECT, pwszServerName);
  1296. goto Cleanup;
  1297. }
  1298. dwErr = RegOpenKey(rKey,
  1299. WINLOGON_FOLDER,
  1300. &hKey);
  1301. if (dwErr != ERROR_SUCCESS) {
  1302. ErrorMessage(MSG_CAN_NOT_ACCESS_FOLDER, WINLOGON_FOLDER);
  1303. goto Cleanup;
  1304. }
  1305. if (fSwOn == TRUE || fSwOff == TRUE) {
  1306. dwSFCDisable = fSwOn == TRUE ? 0 : 1;
  1307. dwErr = RegSetValueEx(
  1308. hKey,
  1309. L"SFCDisable",
  1310. NULL,
  1311. REG_DWORD,
  1312. (LPBYTE) &dwSFCDisable,
  1313. sizeof(DWORD));
  1314. }
  1315. cbSize = sizeof(ULONG);
  1316. dwErr = DfsmQueryValue(
  1317. hKey,
  1318. SFCVALUE,
  1319. REG_DWORD,
  1320. sizeof(DWORD),
  1321. (LPBYTE) &dwSFCDisable,
  1322. &cbSize);
  1323. if (dwErr == ERROR_MORE_DATA)
  1324. dwErr = ERROR_SUCCESS;
  1325. if (dwErr != ERROR_SUCCESS) {
  1326. MyPrintf(L"Cannot access the registry value %ws\r\n", SFCVALUE);
  1327. goto Cleanup;
  1328. }
  1329. MyPrintf(L"SFP = 0x%x (%ws)\r\n",
  1330. dwSFCDisable,
  1331. dwSFCDisable == 0 ? L"ON" : L"OFF");
  1332. Cleanup:
  1333. if (hKey != NULL)
  1334. RegCloseKey(hKey);
  1335. if (rKey != NULL)
  1336. RegCloseKey(rKey);
  1337. if (fSwDebug == TRUE)
  1338. MyPrintf(L"CmdSfp returning %d\r\n", dwErr);
  1339. return dwErr;
  1340. }
  1341. DWORD
  1342. CmdRegistry(
  1343. LPWSTR pwszServerName,
  1344. LPWSTR pwszFolderName,
  1345. LPWSTR pwszValueName,
  1346. LPWSTR pwszHexValue)
  1347. {
  1348. DWORD dwErr = ERROR_SUCCESS;
  1349. HKEY rKey = NULL;
  1350. HKEY hKey = NULL;
  1351. ULONG cbSize;
  1352. DWORD dwValue = 0;
  1353. if (fSwDebug == TRUE)
  1354. MyPrintf(L"CmdRegistry(%ws,%ws)\r\n",
  1355. pwszServerName,
  1356. pwszHexValue);
  1357. dwErr = RegConnectRegistry(
  1358. pwszServerName,
  1359. HKEY_LOCAL_MACHINE,
  1360. &rKey);
  1361. if (dwErr != ERROR_SUCCESS) {
  1362. ErrorMessage(MSG_CAN_NOT_CONNECT, pwszServerName);
  1363. goto Cleanup;
  1364. }
  1365. dwErr = RegOpenKey(
  1366. rKey,
  1367. pwszFolderName,
  1368. &hKey);
  1369. if (dwErr != ERROR_SUCCESS) {
  1370. ErrorMessage(MSG_CAN_NOT_ACCESS_FOLDER, pwszFolderName);
  1371. goto Cleanup;
  1372. }
  1373. if (pwszHexValue != NULL) {
  1374. if (pwszHexValue[0] == L'0' && (pwszHexValue[1] == L'x' || pwszHexValue[1] == L'X'))
  1375. dwValue = AtoHex(pwszHexValue, &dwErr);
  1376. else
  1377. dwValue = AtoDec(pwszHexValue, &dwErr);
  1378. if (dwErr != ERROR_SUCCESS) {
  1379. MyPrintf(L"bad value %ws\r\n", pwszHexValue);
  1380. goto Cleanup;
  1381. }
  1382. dwErr = RegSetValueEx(
  1383. hKey,
  1384. pwszValueName,
  1385. NULL,
  1386. REG_DWORD,
  1387. (LPBYTE) &dwValue,
  1388. sizeof(DWORD));
  1389. }
  1390. cbSize = sizeof(ULONG);
  1391. dwErr = DfsmQueryValue(
  1392. hKey,
  1393. pwszValueName,
  1394. REG_DWORD,
  1395. sizeof(DWORD),
  1396. (LPBYTE) &dwValue,
  1397. &cbSize);
  1398. if (dwErr == ERROR_MORE_DATA)
  1399. dwErr = ERROR_SUCCESS;
  1400. if (dwErr != ERROR_SUCCESS) {
  1401. MyPrintf(L"Cannot access registry value %ws\r\n", pwszValueName);
  1402. goto Cleanup;
  1403. }
  1404. MyPrintf(L"%ws = 0x%x (%d)\r\n",
  1405. pwszValueName,
  1406. dwValue,
  1407. dwValue);
  1408. Cleanup:
  1409. if (hKey != NULL)
  1410. RegCloseKey(hKey);
  1411. if (rKey != NULL)
  1412. RegCloseKey(rKey);
  1413. if (fSwDebug == TRUE)
  1414. MyPrintf(L"CmdRegistry returning %d\r\n", dwErr);
  1415. return dwErr;
  1416. }
  1417. DWORD
  1418. CmdTrusts(
  1419. LPWSTR pwszDomainName,
  1420. LPWSTR pwszDcName,
  1421. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  1422. BOOLEAN fListAll)
  1423. {
  1424. PDS_DOMAIN_TRUSTS pDsDomainTrusts = NULL;
  1425. PDOMAIN_CONTROLLER_INFO pDcInfo = NULL;
  1426. ULONG DsDomainCount = 0;
  1427. DWORD dwErr = ERROR_SUCCESS;
  1428. ULONG Count = 1;
  1429. ULONG i;
  1430. if (fSwDebug == TRUE)
  1431. MyPrintf(L"CmdTrusts(%ws,%ws)\r\n", pwszDomainName, pwszDcName);
  1432. if (pwszDcName == NULL) {
  1433. dwErr = DsGetDcName(
  1434. NULL, // Computer to remote to
  1435. pwszDomainName, // Domain
  1436. NULL, // Domain Guid
  1437. NULL, // Site Guid
  1438. DS_FORCE_REDISCOVERY,
  1439. &pDcInfo);
  1440. if (dwErr != ERROR_SUCCESS) {
  1441. if (fSwDebug == TRUE)
  1442. MyPrintf(L"DsGetDcName() returned %d\r\n", dwErr);
  1443. goto Cleanup;
  1444. }
  1445. pwszDcName = &pDcInfo->DomainControllerName[2];
  1446. ErrorMessage(MSG_CONNECTING, pwszDcName);
  1447. }
  1448. dwErr = DsEnumerateDomainTrusts(
  1449. pwszDcName,
  1450. DS_DOMAIN_VALID_FLAGS,
  1451. &pDsDomainTrusts,
  1452. &DsDomainCount);
  1453. if (dwErr != ERROR_SUCCESS) {
  1454. if (fSwDebug == TRUE)
  1455. MyPrintf(L"DsEnumerateDomainTrusts() returned %d\r\n", dwErr);
  1456. goto Cleanup;
  1457. }
  1458. for (i = 0; i < DsDomainCount; i++) {
  1459. if (pDsDomainTrusts[i].TrustType == TRUST_TYPE_UPLEVEL || fListAll == TRUE) {
  1460. MyPrintf(L"%d:\r\n", Count++);
  1461. MyPrintf(L" NetbiosDomainName %ws\r\n", pDsDomainTrusts[i].NetbiosDomainName);
  1462. MyPrintf(L" DnsDomainName %ws\r\n", pDsDomainTrusts[i].DnsDomainName);
  1463. MyPrintf(L" Flags 0x%x\r\n", pDsDomainTrusts[i].Flags);
  1464. MyPrintf(L" ParentIndex %d\r\n", pDsDomainTrusts[i].ParentIndex);
  1465. MyPrintf(L" TrustType 0x%x\r\n", pDsDomainTrusts[i].TrustType);
  1466. MyPrintf(L" TrustAttributes 0x%x\r\n", pDsDomainTrusts[i].TrustAttributes);
  1467. }
  1468. }
  1469. Cleanup:
  1470. if (pDsDomainTrusts != NULL)
  1471. NetApiBufferFree(pDsDomainTrusts);
  1472. if (pDcInfo != NULL)
  1473. NetApiBufferFree(pDcInfo);
  1474. if (fSwDebug == TRUE)
  1475. MyPrintf(L"CmdTrusts returning %d\r\n", dwErr);
  1476. return dwErr;
  1477. }
  1478. DWORD
  1479. CmdSiteInfo(
  1480. LPWSTR pwszMachineName)
  1481. {
  1482. DWORD dwErr = ERROR_SUCCESS;
  1483. LPDFS_SITELIST_INFO pSiteInfo = NULL;
  1484. ULONG i;
  1485. if (fSwDebug == TRUE)
  1486. MyPrintf(L"CmdSiteInfo(%ws)\r\n", pwszMachineName);
  1487. if (pwszMachineName == NULL) {
  1488. dwErr = ERROR_INVALID_PARAMETER;
  1489. goto Cleanup;
  1490. }
  1491. dwErr = I_NetDfsManagerReportSiteInfo(
  1492. pwszMachineName,
  1493. &pSiteInfo);
  1494. if (dwErr != ERROR_SUCCESS || pSiteInfo == NULL)
  1495. goto Cleanup;
  1496. MyPrintf(L"%ws:\r\n", &pwszMachineName[2]);
  1497. for (i = 0; i < pSiteInfo->cSites; i++) {
  1498. MyPrintf(L" %ws\r\n",
  1499. pSiteInfo->Site[i].SiteName);
  1500. }
  1501. Cleanup:
  1502. if (pSiteInfo != NULL)
  1503. NetApiBufferFree(pSiteInfo);
  1504. if (fSwDebug == TRUE)
  1505. MyPrintf(L"CmdSiteInfo returning %d\r\n", dwErr);
  1506. return dwErr;
  1507. }
  1508. DWORD
  1509. CmdAddRoot(
  1510. LPWSTR pwszDomDfsName,
  1511. LPWSTR pwszServerName,
  1512. LPWSTR pwszShareName,
  1513. LPWSTR pwszComment)
  1514. {
  1515. DWORD dwErr = ERROR_SUCCESS;
  1516. if (fSwDebug == TRUE)
  1517. MyPrintf(L"CmdAddRoot(%ws,%ws,%ws,%ws)\r\n",
  1518. pwszDomDfsName,
  1519. pwszServerName,
  1520. pwszShareName,
  1521. pwszComment);
  1522. if (pwszDomDfsName != NULL)
  1523. while (*pwszDomDfsName == UNICODE_PATH_SEP)
  1524. pwszDomDfsName++;
  1525. if (pwszDomDfsName == NULL || wcslen(pwszDomDfsName) == 0) {
  1526. dwErr = NetDfsAddStdRoot(
  1527. pwszServerName,
  1528. pwszShareName,
  1529. pwszComment,
  1530. 0);
  1531. } else {
  1532. dwErr = NetDfsAddFtRoot(
  1533. pwszServerName,
  1534. pwszShareName,
  1535. pwszDomDfsName,
  1536. pwszComment,
  1537. 0);
  1538. }
  1539. if (fSwDebug == TRUE)
  1540. MyPrintf(L"CmdAddRoot returning %d\r\n", dwErr);
  1541. return dwErr;
  1542. }
  1543. DWORD
  1544. CmdRemRoot(
  1545. LPWSTR pwszDomDfsName,
  1546. LPWSTR pwszServerName,
  1547. LPWSTR pwszShareName)
  1548. {
  1549. DWORD dwErr = ERROR_SUCCESS;
  1550. if (fSwDebug == TRUE)
  1551. MyPrintf(L"CmdRemRoot(%ws,%ws,%ws)\r\n",
  1552. pwszDomDfsName,
  1553. pwszServerName,
  1554. pwszShareName);
  1555. if (pwszDomDfsName != NULL)
  1556. while (*pwszDomDfsName == UNICODE_PATH_SEP)
  1557. pwszDomDfsName++;
  1558. if (pwszDomDfsName == NULL || wcslen(pwszDomDfsName) == 0) {
  1559. dwErr = NetDfsRemoveStdRoot(
  1560. pwszServerName,
  1561. pwszShareName,
  1562. 0);
  1563. } else {
  1564. dwErr = NetDfsRemoveFtRoot(
  1565. pwszServerName,
  1566. pwszShareName,
  1567. pwszDomDfsName,
  1568. 0);
  1569. }
  1570. if (fSwDebug == TRUE)
  1571. MyPrintf(L"CmdRemRoot returning %d\r\n", dwErr);
  1572. return dwErr;
  1573. }
  1574. DWORD
  1575. DfspIsDomainName(
  1576. LPWSTR pwszDomainName,
  1577. LPWSTR pwszDcName,
  1578. PBOOLEAN pIsDomainName)
  1579. {
  1580. PDS_DOMAIN_TRUSTS pDsDomainTrusts = NULL;
  1581. PDOMAIN_CONTROLLER_INFO pDcInfo = NULL;
  1582. ULONG DsDomainCount = 0;
  1583. DWORD dwErr = ERROR_SUCCESS;
  1584. ULONG i;
  1585. if (fSwDebug == TRUE)
  1586. MyPrintf(L"DfspIsDomainName(%ws,%ws)\r\n", pwszDomainName, pwszDcName);
  1587. if (pwszDcName == NULL) {
  1588. dwErr = DsGetDcName(
  1589. NULL, // Computer to remote to
  1590. NULL, // Domain
  1591. NULL, // Domain Guid
  1592. NULL, // Site Guid
  1593. DS_FORCE_REDISCOVERY,
  1594. &pDcInfo);
  1595. if (dwErr != ERROR_SUCCESS) {
  1596. if (fSwDebug == TRUE)
  1597. MyPrintf(L"DsGetDcName() returned %d\r\n", dwErr);
  1598. goto Cleanup;
  1599. }
  1600. pwszDcName = &pDcInfo->DomainControllerName[2];
  1601. }
  1602. dwErr = DsEnumerateDomainTrusts(
  1603. pwszDcName,
  1604. DS_DOMAIN_VALID_FLAGS,
  1605. &pDsDomainTrusts,
  1606. &DsDomainCount);
  1607. if (dwErr != ERROR_SUCCESS) {
  1608. if (fSwDebug == TRUE)
  1609. MyPrintf(L"DsEnumerateDomainTrusts() returned %d\r\n", dwErr);
  1610. goto Cleanup;
  1611. }
  1612. *pIsDomainName = FALSE;
  1613. for (i = 0; i < DsDomainCount; i++) {
  1614. if (
  1615. (pDsDomainTrusts[i].NetbiosDomainName != NULL &&
  1616. _wcsicmp(pwszDomainName, pDsDomainTrusts[i].NetbiosDomainName) == 0)
  1617. ||
  1618. (pDsDomainTrusts[i].DnsDomainName != NULL &&
  1619. _wcsicmp(pwszDomainName, pDsDomainTrusts[i].DnsDomainName) == 0)
  1620. ) {
  1621. *pIsDomainName = TRUE;
  1622. goto Cleanup;
  1623. }
  1624. }
  1625. Cleanup:
  1626. if (pDsDomainTrusts != NULL)
  1627. NetApiBufferFree(pDsDomainTrusts);
  1628. if (pDcInfo != NULL)
  1629. NetApiBufferFree(pDcInfo);
  1630. if (fSwDebug == TRUE)
  1631. MyPrintf(
  1632. L"DfspIsDomainName returning %d (%s)\r\n",
  1633. dwErr, *pIsDomainName == TRUE ? "T" : "F");
  1634. if (dwErr == ERROR_NO_SUCH_DOMAIN)
  1635. {
  1636. *pIsDomainName = FALSE;
  1637. dwErr = ERROR_SUCCESS;
  1638. }
  1639. return dwErr;
  1640. }
  1641. DWORD
  1642. DfspParseName(
  1643. LPWSTR pwszDfsRoot,
  1644. LPWSTR *ppwszDfsName,
  1645. LPWSTR *ppwszShareName)
  1646. {
  1647. DWORD dwErr = ERROR_SUCCESS;
  1648. LPWSTR pwszDfsName = NULL;
  1649. LPWSTR pwszShareName = NULL;
  1650. WCHAR *wCp1 = NULL;
  1651. WCHAR *wCp2 = NULL;
  1652. ULONG Len = 0;
  1653. if (fSwDebug == TRUE)
  1654. MyPrintf(L"DfspParseName(%ws)\r\n", pwszDfsRoot);
  1655. wCp1 = pwszDfsRoot;
  1656. while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
  1657. wCp1++;
  1658. if (*wCp1 == UNICODE_NULL) {
  1659. dwErr = ERROR_INVALID_PARAMETER;
  1660. goto Cleanup;
  1661. }
  1662. wCp2 = wCp1;
  1663. while (*wCp2 != UNICODE_PATH_SEP && *wCp2 != UNICODE_NULL)
  1664. wCp2++;
  1665. if (*wCp2 == UNICODE_NULL) {
  1666. dwErr = ERROR_INVALID_PARAMETER;
  1667. goto Cleanup;
  1668. }
  1669. Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR));
  1670. pwszDfsName = (LPWSTR)malloc(Len + sizeof(WCHAR));
  1671. if (pwszDfsName == NULL) {
  1672. dwErr = ERROR_OUTOFMEMORY;
  1673. goto Cleanup;
  1674. }
  1675. RtlZeroMemory(pwszDfsName,Len+sizeof(WCHAR));
  1676. RtlCopyMemory(pwszDfsName, wCp1, Len);
  1677. wCp1 = wCp2;
  1678. while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
  1679. wCp1++;
  1680. if (*wCp1 == UNICODE_NULL) {
  1681. dwErr = ERROR_INVALID_PARAMETER;
  1682. goto Cleanup;
  1683. }
  1684. wCp2 = wCp1;
  1685. while (*wCp2 != UNICODE_PATH_SEP && *wCp2 != UNICODE_NULL)
  1686. wCp2++;
  1687. Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR));
  1688. pwszShareName = (LPWSTR)malloc(Len + sizeof(WCHAR));
  1689. if (pwszShareName == NULL) {
  1690. dwErr = ERROR_OUTOFMEMORY;
  1691. goto Cleanup;
  1692. }
  1693. RtlZeroMemory(pwszShareName,Len+sizeof(WCHAR));
  1694. RtlCopyMemory(pwszShareName, wCp1, Len);
  1695. *ppwszDfsName = pwszDfsName;
  1696. *ppwszShareName = pwszShareName;
  1697. Cleanup:
  1698. if (dwErr != ERROR_SUCCESS) {
  1699. if (pwszDfsName != NULL)
  1700. free(pwszDfsName);
  1701. if (pwszShareName != NULL)
  1702. free(pwszShareName);
  1703. }
  1704. if (fSwDebug == TRUE)
  1705. MyPrintf(L"DfspParseName returning %d\r\n", dwErr);
  1706. return dwErr;
  1707. }
  1708. DWORD
  1709. DfspGetLinkName(
  1710. LPWSTR pwszDfsRoot,
  1711. LPWSTR *ppwszLinkName)
  1712. {
  1713. WCHAR *wCp1 = NULL;
  1714. WCHAR *wCp2 = NULL;
  1715. ULONG Len = 0;
  1716. DWORD dwErr = ERROR_SUCCESS;
  1717. wCp1 = pwszDfsRoot;
  1718. while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
  1719. wCp1++;
  1720. if (*wCp1 == UNICODE_NULL) {
  1721. dwErr = ERROR_INVALID_PARAMETER;
  1722. goto Cleanup;
  1723. }
  1724. while (*wCp1 != UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
  1725. wCp1++;
  1726. if (*wCp1 == UNICODE_NULL) {
  1727. dwErr = ERROR_INVALID_PARAMETER;
  1728. goto Cleanup;
  1729. }
  1730. *ppwszLinkName = ++wCp1;
  1731. Cleanup:
  1732. return dwErr;
  1733. }
  1734. VOID
  1735. MyFormatMessageText(
  1736. HRESULT dwMsgId,
  1737. PWSTR pszBuffer,
  1738. DWORD dwBufferSize,
  1739. va_list *parglist)
  1740. {
  1741. DWORD dwReturn = FormatMessage(
  1742. (dwMsgId >= MSG_FIRST_MESSAGE)
  1743. ? FORMAT_MESSAGE_FROM_HMODULE
  1744. : FORMAT_MESSAGE_FROM_SYSTEM,
  1745. NULL,
  1746. dwMsgId,
  1747. LANG_USER_DEFAULT,
  1748. pszBuffer,
  1749. dwBufferSize,
  1750. parglist);
  1751. if (dwReturn == 0)
  1752. MyPrintf(L"Formatmessage failed 0x%x\r\n", GetLastError());
  1753. }
  1754. VOID
  1755. ErrorMessage(
  1756. IN HRESULT hr,
  1757. ...)
  1758. {
  1759. ULONG cch;
  1760. va_list arglist;
  1761. va_start(arglist, hr);
  1762. MyFormatMessageText(hr, MsgBuf, ARRAYLEN(MsgBuf), &arglist);
  1763. cch = WideCharToMultiByte(CP_OEMCP, 0,
  1764. MsgBuf, wcslen(MsgBuf),
  1765. AnsiBuf, MAX_BUF_SIZE*3,
  1766. NULL, NULL);
  1767. WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), AnsiBuf, cch, &cch, NULL);
  1768. va_end(arglist);
  1769. }
  1770. VOID
  1771. MyPrintf(
  1772. PWCHAR format,
  1773. ...)
  1774. {
  1775. ULONG cch;
  1776. va_list va;
  1777. va_start(va, format);
  1778. wvsprintf(MsgBuf, format, va);
  1779. cch = WideCharToMultiByte(CP_OEMCP, 0,
  1780. MsgBuf, wcslen(MsgBuf),
  1781. AnsiBuf, MAX_BUF_SIZE*3,
  1782. NULL, NULL);
  1783. WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), AnsiBuf, cch, &cch, NULL);
  1784. va_end(va);
  1785. return;
  1786. }
  1787. VOID
  1788. MyFPrintf(
  1789. HANDLE hHandle,
  1790. PWCHAR format,
  1791. ...)
  1792. {
  1793. ULONG cch;
  1794. va_list va;
  1795. va_start(va, format);
  1796. wvsprintf(MsgBuf, format, va);
  1797. cch = WideCharToMultiByte(CP_OEMCP, 0,
  1798. MsgBuf, wcslen(MsgBuf),
  1799. AnsiBuf, MAX_BUF_SIZE*3,
  1800. NULL, NULL);
  1801. WriteFile(hHandle, AnsiBuf, cch, &cch, NULL);
  1802. va_end(va);
  1803. return;
  1804. }