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.

2470 lines
64 KiB

  1. //--------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: infile.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 <csites.hxx>
  25. #include <dfsm.hxx>
  26. #include <recon.hxx>
  27. #include <rpc.h>
  28. #include "struct.hxx"
  29. #include "ftsup.hxx"
  30. #include "stdsup.hxx"
  31. #include "rootsup.hxx"
  32. #include "misc.hxx"
  33. #include "messages.h"
  34. #include "fileio.hxx"
  35. //
  36. // These are extensions for perf/scalability
  37. // Undoc'd for now, only apply when scripting
  38. //
  39. FMAKEARG(AddRoot);
  40. FMAKEARG(RemRoot);
  41. FMAKEARG(Share);
  42. FMAKEARG(Server);
  43. FMAKEARG(Link);
  44. FMAKEARG(Site);
  45. FMAKEARG(ShortPrefix);
  46. FMAKEARG(Add);
  47. FMAKEARG(State);
  48. FMAKEARG(Type);
  49. FMAKEARG(Guid);
  50. FMAKEARG(Timeout);
  51. FMAKEARG(Comment)
  52. FMAKEARG(Load);
  53. FMAKEARG(Save);
  54. FMAKEARG(DcName);
  55. FSWITCH(Map);
  56. FSWITCH(UnMap);
  57. FSWITCH(Mod);
  58. LPWSTR pgDfsName = NULL;
  59. LPWSTR pgDcName = NULL;
  60. LPWSTR pgLink = NULL;
  61. LPWSTR pgSite = NULL;
  62. LPWSTR pgShortLink = NULL;
  63. LPWSTR pgTimeout = NULL;
  64. LPWSTR pgState = NULL;
  65. LPWSTR pgType = NULL;
  66. LPWSTR pgGuid = NULL;
  67. LPWSTR pgComment = NULL;
  68. LPWSTR pgAddArg = NULL;
  69. LPWSTR pgDomDfsName = NULL;
  70. LPWSTR pgServerName = NULL;
  71. LPWSTR pgShareName = NULL;
  72. #define UNICODE_COMMENT_CHAR L'/'
  73. //
  74. // Protos
  75. //
  76. DWORD
  77. CmdLoad(
  78. PDFS_VOLUME_LIST pDfsVolList,
  79. LPWSTR pDfsName,
  80. LPWSTR pDcName);
  81. DWORD
  82. CmdSave(
  83. PDFS_VOLUME_LIST pDfsVolList,
  84. LPWSTR pDfsName,
  85. LPWSTR pDcName);
  86. DWORD
  87. CmdLinkMap(
  88. PDFS_VOLUME_LIST pDfsVolList,
  89. LPWSTR pLink,
  90. LPWSTR pShortLink,
  91. LPWSTR pComment,
  92. LPWSTR pTimeout,
  93. LPWSTR pState,
  94. LPWSTR pType,
  95. LPWSTR pGUID,
  96. ULONG LineNum);
  97. DWORD
  98. CmdLink(
  99. PDFS_VOLUME_LIST pDfsVolList,
  100. LPWSTR pLink,
  101. ULONG LineNum);
  102. DWORD
  103. CmdLinkMod(
  104. PDFS_VOLUME_LIST pDfsVolList,
  105. LPWSTR pLink,
  106. LPWSTR pgShortLink,
  107. LPWSTR pComment,
  108. LPWSTR pTimeout,
  109. LPWSTR pState,
  110. LPWSTR pType,
  111. LPWSTR pGUID,
  112. ULONG LineNum);
  113. DWORD
  114. CmdLinkUnmap(
  115. PDFS_VOLUME_LIST pDfsVolList,
  116. LPWSTR pLink,
  117. ULONG LineNum);
  118. DWORD
  119. CmdAdd(
  120. PDFS_VOLUME_LIST pDfsVolList,
  121. LPWSTR pLink,
  122. LPWSTR pAltName,
  123. LPWSTR pState,
  124. LPWSTR Type,
  125. ULONG LineNum);
  126. BOOLEAN
  127. CmdProcessInfileArg(
  128. LPWSTR Arg);
  129. DWORD
  130. DfspBreakName(
  131. LPWSTR pPath,
  132. LPWSTR *ppServerName,
  133. LPWSTR *ppShareName);
  134. DWORD
  135. DfspDomLoad(
  136. PDFS_VOLUME_LIST pDfsVolList,
  137. LPWSTR pDomName,
  138. LPWSTR pDfsName,
  139. LPWSTR pDcName);
  140. DWORD
  141. DfspStdLoad(
  142. PDFS_VOLUME_LIST pDfsVolList,
  143. LPWSTR pServerName,
  144. LPWSTR pShareName,
  145. LPWSTR pDcName);
  146. DWORD
  147. DfspDomSave(
  148. PDFS_VOLUME_LIST pDfsVolList,
  149. LPWSTR pDomName,
  150. LPWSTR pDfsName,
  151. LPWSTR pDcName);
  152. DWORD
  153. DfspStdSave(
  154. PDFS_VOLUME_LIST pDfsVolList,
  155. LPWSTR pServerName,
  156. LPWSTR pShareName);
  157. DWORD
  158. CmdSite(
  159. PDFS_VOLUME_LIST pDfsVolList,
  160. LPWSTR pServer,
  161. ULONG LineNum);
  162. DWORD
  163. CmdSiteMap(
  164. PDFS_VOLUME_LIST pDfsVolList,
  165. LPWSTR pServer,
  166. ULONG LineNum);
  167. DWORD
  168. CmdAddSiteToServer(
  169. PDFS_VOLUME_LIST pDfsVolList,
  170. LPWSTR pServer,
  171. LPWSTR pSite,
  172. ULONG LineNum);
  173. DWORD
  174. CmdSiteUnmap(
  175. PDFS_VOLUME_LIST pDfsVolList,
  176. LPWSTR pServer,
  177. ULONG LineNum);
  178. VOID
  179. DfspExportFile(
  180. HANDLE pHandle,
  181. PDFS_VOLUME_LIST pDfsVolList);
  182. #define INIT_LINK_COUNT 8
  183. #define INIT_ALT_COUNT 2
  184. //
  185. // The one that gets it all going - use a file
  186. //
  187. DWORD
  188. CmdImport(
  189. LPWSTR pInfile)
  190. {
  191. DWORD dwErr = ERROR_SUCCESS;
  192. DFS_VOLUME_LIST DfsVolList = { 0 };
  193. PDFS_VOLUME_LIST pDfsVolList = &DfsVolList;
  194. LONG i;
  195. FILE *fp;
  196. WCHAR InBuf[1026];
  197. LPWSTR *argvw;
  198. PWCHAR wCp;
  199. ULONG LineNum = 1;
  200. int argcw;
  201. int argx;
  202. if (fSwDebug == TRUE)
  203. MyPrintf(L"CmdImport(%ws)\r\n", pInfile);
  204. fp = _wfopen(pInfile, L"r");
  205. if (fp == NULL) {
  206. if (fSwDebug == TRUE)
  207. MyPrintf(L"Can not open %ws for read.\r\n", pInfile);
  208. dwErr = ERROR_FILE_NOT_FOUND;
  209. goto Cleanup;
  210. }
  211. while (fgetws(InBuf, sizeof(InBuf)/sizeof(WCHAR), fp) != NULL) {
  212. // Remove trailing CR/LF
  213. for (wCp = InBuf; *wCp != L'\0'; wCp++) {
  214. if (*wCp == L'\r' || *wCp == L'\n')
  215. *wCp = L'\0';
  216. }
  217. // Strip off comments (indicated by a // )
  218. for (wCp = InBuf; *wCp != L'\0'; wCp++)
  219. if (wCp > InBuf && *wCp == UNICODE_COMMENT_CHAR && *(wCp-1) == UNICODE_COMMENT_CHAR) {
  220. *(wCp-1) = L'\0';
  221. break;
  222. }
  223. // Remove trailing spaces and tabs
  224. while (wCp != InBuf && (*wCp == L' ' || *wCp == L'\t'))
  225. *wCp-- = L'\0';
  226. // Remove leading spaces and tabs
  227. for (wCp = InBuf; *wCp != L'\0' && (*wCp == L' ' || *wCp == L'\t'); wCp++)
  228. NOTHING;
  229. if (fSwDebug == TRUE)
  230. MyPrintf(L"%d:[%ws]\r\n", LineNum, wCp);
  231. if (wcslen(wCp) == 0) {
  232. LineNum++;
  233. continue;
  234. }
  235. argvw = CommandLineToArgvW(wCp, &argcw);
  236. fArgAddRoot = FALSE;
  237. fArgRemRoot = FALSE;
  238. fArgLoad = FALSE;
  239. fArgLink = FALSE;
  240. fArgSite = FALSE;
  241. fArgAdd = FALSE;
  242. fSwMap = FALSE;
  243. fSwUnMap = FALSE;
  244. fSwMod = FALSE;
  245. pgShortLink = NULL;
  246. pgTimeout = NULL;
  247. pgState = NULL;
  248. pgType = NULL;
  249. pgGuid = NULL;
  250. pgComment = NULL;
  251. pgAddArg = NULL;
  252. pgDomDfsName = NULL;
  253. pgServerName = NULL;
  254. for (argx = 0; argx < argcw; argx++) {
  255. if (fSwDebug == TRUE)
  256. MyPrintf(L"%d: [%ws]\r\n", argx, argvw[argx]);
  257. if (CmdProcessInfileArg(argvw[argx]) != TRUE) {
  258. dwErr = ERROR_INVALID_PARAMETER;
  259. MyPrintf(L"Unrecognized parameter in line %d\r\n", LineNum);
  260. }
  261. }
  262. if (fSwDebug == TRUE) {
  263. MyPrintf(L"DfsName=%ws\r\n", pgDfsName);
  264. MyPrintf(L"DcName=%ws\r\n", pgDcName);
  265. MyPrintf(L"Link=%ws\r\n", pgLink);
  266. MyPrintf(L"ShortLink=%ws\r\n", pgShortLink);
  267. MyPrintf(L"Site=%ws\r\n", pgSite);
  268. MyPrintf(L"Timeout=%ws\r\n", pgTimeout);
  269. MyPrintf(L"State=%ws\r\n", pgState);
  270. MyPrintf(L"Type=%ws\r\n", pgType);
  271. MyPrintf(L"Guid=%ws\r\n", pgGuid);
  272. MyPrintf(L"Comment=%ws\r\n", pgComment);
  273. MyPrintf(L"AddArg=%ws\r\n", pgAddArg);
  274. }
  275. //
  276. // Do the work
  277. //
  278. if (fArgLoad == TRUE) {
  279. dwErr = CmdLoad(
  280. pDfsVolList,
  281. pgDfsName,
  282. pgDcName);
  283. } else if (fArgLink == TRUE) {
  284. if (fSwMap == TRUE) {
  285. dwErr = CmdLinkMap(
  286. pDfsVolList,
  287. pgLink,
  288. pgShortLink,
  289. pgComment,
  290. pgTimeout,
  291. pgState,
  292. pgType,
  293. pgGuid,
  294. LineNum);
  295. } else if (fSwMod == TRUE) {
  296. dwErr = CmdLinkMod(
  297. pDfsVolList,
  298. pgLink,
  299. pgShortLink,
  300. pgComment,
  301. pgTimeout,
  302. pgState,
  303. pgType,
  304. pgGuid,
  305. LineNum);
  306. } else if (fSwUnMap == TRUE) {
  307. dwErr = CmdLinkUnmap(
  308. pDfsVolList,
  309. pgLink,
  310. LineNum);
  311. } else {
  312. dwErr = CmdLink(
  313. pDfsVolList,
  314. pgLink,
  315. LineNum);
  316. }
  317. } else if (fArgSite == TRUE) {
  318. if (fSwMap == TRUE) {
  319. dwErr = CmdSiteMap(
  320. pDfsVolList,
  321. pgSite,
  322. LineNum);
  323. } else if (fSwUnMap == TRUE) {
  324. dwErr = CmdSiteUnmap(
  325. pDfsVolList,
  326. pgSite,
  327. LineNum);
  328. } else {
  329. dwErr = CmdSite(
  330. pDfsVolList,
  331. pgSite,
  332. LineNum);
  333. }
  334. } else if (fArgAdd == TRUE) {
  335. if (pgLink != NULL) {
  336. dwErr = CmdAdd(
  337. pDfsVolList,
  338. pgLink,
  339. pgAddArg,
  340. pgState,
  341. pgType,
  342. LineNum);
  343. } else if (pgSite != NULL) {
  344. dwErr = CmdAddSiteToServer(
  345. pDfsVolList,
  346. pgSite,
  347. pgAddArg,
  348. LineNum);
  349. }
  350. } else if (fArgSave == TRUE) {
  351. dwErr = CmdSave(
  352. pDfsVolList,
  353. pgDfsName,
  354. pgDcName);
  355. } else if (fArgAddRoot == TRUE) {
  356. dwErr = CmdAddRoot(
  357. pgDomDfsName,
  358. pgServerName,
  359. pgShareName,
  360. pgComment);
  361. } else if (fArgRemRoot == TRUE) {
  362. dwErr = CmdRemRoot(
  363. pgDomDfsName,
  364. pgServerName,
  365. pgShareName);
  366. } else {
  367. MyPrintf(L"Missing command in line %d\r\n", LineNum);
  368. }
  369. if(dwErr != ERROR_SUCCESS) {
  370. MyPrintf(L"Import: Error %d processing line %d.\r\n", dwErr, LineNum);
  371. goto Cleanup;
  372. }
  373. LineNum++;
  374. }
  375. Cleanup:
  376. // DfsViewVolList(pDfsVolList, 1);
  377. if (fSwDebug == TRUE)
  378. DfsDumpVolList(pDfsVolList);
  379. //
  380. // Free our vol list
  381. //
  382. DfsFreeVolList(pDfsVolList);
  383. if (fSwDebug == TRUE)
  384. MyPrintf(L"CmdImport exit %d\r\n", dwErr);
  385. return dwErr;
  386. }
  387. DWORD
  388. CmdLoad(
  389. PDFS_VOLUME_LIST pDfsVolList,
  390. LPWSTR pDfsName,
  391. LPWSTR pDcName)
  392. {
  393. DWORD dwErr = ERROR_SUCCESS;
  394. LPWSTR pServerName = NULL;
  395. LPWSTR pShareName = NULL;
  396. BOOLEAN IsDomainName = FALSE;
  397. if (fSwDebug == TRUE)
  398. MyPrintf(L"CmdLoad(%ws,%ws)\r\n", pDfsName, pDcName);
  399. if (pDfsName == NULL) {
  400. dwErr = ERROR_INVALID_PARAMETER;
  401. goto Cleanup;
  402. }
  403. dwErr = DfspParseName(
  404. pDfsName,
  405. &pServerName,
  406. &pShareName);
  407. if (dwErr != ERROR_SUCCESS)
  408. goto Cleanup;
  409. dwErr = DfspIsDomainName(
  410. pServerName,
  411. pDcName,
  412. &IsDomainName);
  413. if (dwErr != ERROR_SUCCESS)
  414. goto Cleanup;
  415. if (IsDomainName == TRUE) {
  416. dwErr = DfspDomLoad(
  417. pDfsVolList,
  418. pServerName,
  419. pShareName,
  420. pDcName);
  421. } else {
  422. dwErr = DfspStdLoad(
  423. pDfsVolList,
  424. pServerName,
  425. pShareName,
  426. pDcName);
  427. }
  428. if (dwErr != ERROR_SUCCESS)
  429. goto Cleanup;
  430. //
  431. // The link list may not be sorted - do so now.
  432. //
  433. DfspSortVolList(pDfsVolList);
  434. Cleanup:
  435. if (pServerName != NULL)
  436. free(pServerName);
  437. if (pShareName != NULL)
  438. free(pShareName);
  439. if (fSwDebug == TRUE)
  440. MyPrintf(L"CmdLoad returning %d\r\n", dwErr);
  441. return dwErr;
  442. }
  443. DWORD
  444. DfspDomLoad(
  445. PDFS_VOLUME_LIST pDfsVolList,
  446. LPWSTR pDomName,
  447. LPWSTR pDfsName,
  448. LPWSTR pDcName)
  449. {
  450. DWORD dwErr = ERROR_SUCCESS;
  451. if (fSwDebug == TRUE)
  452. MyPrintf(L"CmdDomLoad(%ws,%ws,%ws)\r\n", pDomName, pDfsName, pDcName);
  453. MyPrintf(L"\\\\%ws\\%ws is a DomDfs\r\n", pDomName, pDfsName);
  454. dwErr = DfsGetFtVol(
  455. pDfsVolList,
  456. pDfsName,
  457. pDcName,
  458. pDomName,
  459. NULL);
  460. if (dwErr != ERROR_SUCCESS)
  461. goto Cleanup;
  462. if (fSwDebug == TRUE)
  463. DfsDumpVolList(pDfsVolList);
  464. Cleanup:
  465. if (fSwDebug == TRUE)
  466. MyPrintf(L"CmdDomLoad returning %d\r\n", dwErr);
  467. return dwErr;
  468. }
  469. DWORD
  470. DfspStdLoad(
  471. PDFS_VOLUME_LIST pDfsVolList,
  472. LPWSTR pServerName,
  473. LPWSTR pShareName,
  474. LPWSTR pDcName)
  475. {
  476. ULONG i;
  477. DWORD dwErr = ERROR_SUCCESS;
  478. BOOLEAN IsFtRoot = FALSE;
  479. WCHAR RootShare[MAX_PATH+1];
  480. WCHAR DomDfsName[MAX_PATH+1];
  481. LPWSTR pDomDfsName = NULL;
  482. DWORD cbName = sizeof(DomDfsName);
  483. DWORD dwType;
  484. HKEY hKey = NULL;
  485. HKEY rKey = NULL;
  486. if (fSwDebug == TRUE)
  487. MyPrintf(L"CmdStdLoad(%ws,%ws,%ws)\r\n", pServerName, pShareName, pDcName);
  488. ErrorMessage(MSG_CONNECTING, pServerName);
  489. //
  490. // See if this is a Fault-Tolerant Dfs vs Server-Based Dfs
  491. //
  492. dwErr = RegConnectRegistry(
  493. pServerName,
  494. HKEY_LOCAL_MACHINE,
  495. &rKey);
  496. if (dwErr != ERROR_SUCCESS) {
  497. ErrorMessage(MSG_CAN_NOT_CONNECT, pServerName);
  498. goto Cleanup;
  499. }
  500. dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey);
  501. if (dwErr == ERROR_SUCCESS) {
  502. dwErr = RegQueryValueEx(
  503. hKey,
  504. FTDFS_VALUE_NAME,
  505. NULL,
  506. &dwType,
  507. (PBYTE) DomDfsName,
  508. &cbName);
  509. if (dwErr == ERROR_MORE_DATA)
  510. dwErr = ERROR_SUCCESS;
  511. if (dwErr == ERROR_SUCCESS && dwType == REG_SZ)
  512. IsFtRoot = TRUE;
  513. } else {
  514. MyPrintf(L"Not a Dfs root\r\n");
  515. goto Cleanup;
  516. }
  517. dwErr = RegQueryValueEx(
  518. hKey,
  519. ROOT_SHARE_VALUE_NAME,
  520. NULL,
  521. &dwType,
  522. (PBYTE) RootShare,
  523. &cbName);
  524. if (dwErr == ERROR_MORE_DATA)
  525. dwErr = ERROR_SUCCESS;
  526. if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) {
  527. MyPrintf(L"Registry value \"RootShare\" is missing or corrupt.\r\n");
  528. goto Cleanup;
  529. }
  530. if (IsFtRoot == TRUE) {
  531. if (fSwDebug == TRUE)
  532. MyPrintf(L"Registry says is DomDfs (%ws)...\r\n", DomDfsName);
  533. if (pDomDfsName == NULL) {
  534. pDomDfsName = DomDfsName;
  535. } else {
  536. if (fSwDebug == TRUE)
  537. MyPrintf(L"You specified to check against %ws\r\n", pDomDfsName);
  538. }
  539. dwErr = DfsGetFtVol(
  540. pDfsVolList,
  541. pDomDfsName,
  542. pDcName,
  543. NULL,
  544. NULL);
  545. if (dwErr != ERROR_SUCCESS)
  546. goto Cleanup;
  547. dwErr = GetExitPtInfo(
  548. rKey,
  549. &pDfsVolList->pRootLocalVol,
  550. &pDfsVolList->cRootLocalVol);
  551. if (dwErr != ERROR_SUCCESS)
  552. goto Cleanup;
  553. } else {
  554. if (fSwDebug == TRUE)
  555. MyPrintf(L"Is StdDfs...\r\n");
  556. dwErr = DfsGetStdVol(
  557. rKey,
  558. pDfsVolList);
  559. if (dwErr != ERROR_SUCCESS)
  560. goto Cleanup;
  561. dwErr = GetExitPtInfo(
  562. rKey,
  563. &pDfsVolList->pRootLocalVol,
  564. &pDfsVolList->cRootLocalVol);
  565. if (dwErr != ERROR_SUCCESS)
  566. goto Cleanup;
  567. }
  568. if (fSwDebug == TRUE)
  569. DfsDumpVolList(pDfsVolList);
  570. Cleanup:
  571. if (hKey != NULL)
  572. RegCloseKey(hKey);
  573. if (rKey != NULL)
  574. RegCloseKey(rKey);
  575. if (fSwDebug == TRUE)
  576. MyPrintf(L"CmdStdLoad returning %d\r\n", dwErr);
  577. return dwErr;
  578. }
  579. DWORD
  580. CmdSave(
  581. PDFS_VOLUME_LIST pDfsVolList,
  582. LPWSTR pDfsName,
  583. LPWSTR pDcName)
  584. {
  585. DWORD dwErr = ERROR_SUCCESS;
  586. LPWSTR pServerName = NULL;
  587. LPWSTR pShareName = NULL;
  588. BOOLEAN IsDomainName = FALSE;
  589. if (fSwDebug == TRUE)
  590. MyPrintf(L"CmdSave(%ws,%ws)\r\n", pDfsName, pDcName);
  591. if (pDfsName == NULL) {
  592. dwErr = ERROR_INVALID_PARAMETER;
  593. goto Cleanup;
  594. }
  595. dwErr = DfspParseName(
  596. pDfsName,
  597. &pServerName,
  598. &pShareName);
  599. if (dwErr != ERROR_SUCCESS)
  600. goto Cleanup;
  601. dwErr = DfspIsDomainName(
  602. pServerName,
  603. pDcName,
  604. &IsDomainName);
  605. if (dwErr != ERROR_SUCCESS)
  606. goto Cleanup;
  607. if (IsDomainName == TRUE) {
  608. dwErr = DfspDomSave(
  609. pDfsVolList,
  610. pServerName,
  611. pShareName,
  612. pDcName);
  613. } else {
  614. dwErr = DfspStdSave(
  615. pDfsVolList,
  616. pServerName,
  617. pShareName);
  618. }
  619. if (dwErr != ERROR_SUCCESS)
  620. goto Cleanup;
  621. Cleanup:
  622. if (pServerName != NULL)
  623. free(pServerName);
  624. if (pShareName != NULL)
  625. free(pShareName);
  626. if (fSwDebug == TRUE)
  627. MyPrintf(L"CmdSave returning %d\r\n", dwErr);
  628. return dwErr;
  629. }
  630. DWORD
  631. DfspDomSave(
  632. PDFS_VOLUME_LIST pDfsVolList,
  633. LPWSTR pDomName,
  634. LPWSTR pDfsName,
  635. LPWSTR pDcName)
  636. {
  637. DWORD dwErr = ERROR_SUCCESS;
  638. ULONG cbBlob = 0;
  639. BYTE *pBlob = NULL;
  640. WCHAR wszDcName[MAX_PATH+1];
  641. if (fSwDebug == TRUE)
  642. MyPrintf(L"CmdDomSave(%ws,%ws,%ws)\r\n", pDomName, pDfsName, pDcName);
  643. MyPrintf(L"CmdDomSave(%ws,%ws,%ws)\r\n", pDomName, pDfsName, pDcName);
  644. MyPrintf(L"\\\\%ws\\%ws is a DomDfs\r\n", pDomName, pDfsName);
  645. if (pDcName == NULL)
  646. dwErr = DfspGetPdc(wszDcName, pDomName);
  647. else
  648. wcscpy(wszDcName, pDcName);
  649. if (dwErr != ERROR_SUCCESS)
  650. goto Cleanup;
  651. ErrorMessage(MSG_CONNECTING, wszDcName);
  652. //
  653. // Serialize
  654. //
  655. dwErr = DfsPutVolList(
  656. &cbBlob,
  657. &pBlob,
  658. pDfsVolList);
  659. if (dwErr != ERROR_SUCCESS)
  660. goto Cleanup;
  661. //
  662. // Update the DS
  663. //
  664. dwErr = DfsPutDsBlob(
  665. pDfsName,
  666. DfsConfigContainer,
  667. wszDcName,
  668. NULL,
  669. cbBlob,
  670. pBlob,
  671. pDfsVolList->RootServers);
  672. if (dwErr != ERROR_SUCCESS)
  673. goto Cleanup;
  674. MyPrintf(L"you need to reinit the dfs service on all roots of %ws\r\n", pDfsName);
  675. #if 0
  676. dwErr = NetDfsManagerInitialize(pServerName, 0);
  677. #endif
  678. Cleanup:
  679. if (pBlob != NULL)
  680. free(pBlob);
  681. if (fSwDebug == TRUE)
  682. MyPrintf(L"CmdDomSave returning %d\r\n", dwErr);
  683. return dwErr;
  684. }
  685. DWORD
  686. DfspStdSave(
  687. PDFS_VOLUME_LIST pDfsVolList,
  688. LPWSTR pServerName,
  689. LPWSTR pShareName)
  690. {
  691. ULONG i;
  692. DWORD dwErr = ERROR_SUCCESS;
  693. BOOLEAN IsFtRoot = FALSE;
  694. WCHAR RootShare[MAX_PATH+1];
  695. WCHAR DomDfsName[MAX_PATH+1];
  696. LPWSTR pDomDfsName = NULL;
  697. DWORD cbName = sizeof(DomDfsName);
  698. DWORD dwType;
  699. HKEY hKey = NULL;
  700. HKEY rKey = NULL;
  701. if (fSwDebug == TRUE)
  702. MyPrintf(L"CmdStdSave(%ws,%ws)\r\n", pServerName, pShareName);
  703. MyPrintf(L"Writing metadata to %ws\n", pServerName);
  704. //
  705. // Verify that this is a Server-based Dfs
  706. //
  707. dwErr = RegConnectRegistry(
  708. pServerName,
  709. HKEY_LOCAL_MACHINE,
  710. &rKey);
  711. if (dwErr != ERROR_SUCCESS) {
  712. ErrorMessage(MSG_CAN_NOT_CONNECT, pServerName);
  713. goto Cleanup;
  714. }
  715. dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey);
  716. if (dwErr != ERROR_SUCCESS) {
  717. MyPrintf(L"Not a Dfs root\r\n");
  718. goto Cleanup;
  719. }
  720. dwErr = RegQueryValueEx(
  721. hKey,
  722. FTDFS_VALUE_NAME,
  723. NULL,
  724. &dwType,
  725. (PBYTE) DomDfsName,
  726. &cbName);
  727. if (dwErr == ERROR_MORE_DATA)
  728. dwErr = ERROR_SUCCESS;
  729. if (dwErr == ERROR_SUCCESS && dwType == REG_SZ)
  730. IsFtRoot = TRUE;
  731. dwErr = RegQueryValueEx(
  732. hKey,
  733. ROOT_SHARE_VALUE_NAME,
  734. NULL,
  735. &dwType,
  736. (PBYTE) RootShare,
  737. &cbName);
  738. if (dwErr == ERROR_MORE_DATA)
  739. dwErr = ERROR_SUCCESS;
  740. if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) {
  741. MyPrintf(L"Registry value \"RootShare\" is missing or corrupt.\r\n");
  742. goto Cleanup;
  743. }
  744. if (IsFtRoot == TRUE) {
  745. if (fSwDebug == TRUE)
  746. MyPrintf(L"Internal error: Registry says is DomDfs (%ws)...\r\n", DomDfsName);
  747. dwErr = ERROR_INTERNAL_ERROR;
  748. goto Cleanup;
  749. }
  750. dwErr = DfsSetStdVol(
  751. rKey,
  752. pDfsVolList);
  753. if (dwErr != ERROR_SUCCESS)
  754. goto Cleanup;
  755. MyPrintf(L"Reinitializing dfs service on %ws\n", pServerName);
  756. dwErr = NetDfsManagerInitialize(pServerName, 0);
  757. Cleanup:
  758. if (hKey != NULL)
  759. RegCloseKey(hKey);
  760. if (rKey != NULL)
  761. RegCloseKey(rKey);
  762. if (fSwDebug == TRUE)
  763. MyPrintf(L"CmdStdSave returning %d\r\n", dwErr);
  764. return dwErr;
  765. }
  766. DWORD
  767. CmdLinkMap(
  768. PDFS_VOLUME_LIST pDfsVolList,
  769. LPWSTR pLink,
  770. LPWSTR pShortLink,
  771. LPWSTR pComment,
  772. LPWSTR pTimeout,
  773. LPWSTR pState,
  774. LPWSTR pType,
  775. LPWSTR pGUID,
  776. ULONG LineNum)
  777. {
  778. DWORD dwErr = ERROR_SUCCESS;
  779. LONG Min;
  780. LONG Max;
  781. LONG Res;
  782. PDFS_VOLUME pVol = NULL;
  783. PVOID pVoid = NULL;
  784. LONG Cur = -1;
  785. LONG i;
  786. ULONG Size;
  787. LPWSTR pPrefix = NULL;
  788. LPWSTR pShortPrefix = NULL;
  789. if (fSwDebug == TRUE)
  790. MyPrintf(L"CmdLinkMap(%ws,%ws,%ws,%ws,%ws,%ws,%ws,%d)\r\n",
  791. pLink,
  792. pShortLink,
  793. pComment,
  794. pTimeout,
  795. pState,
  796. pType,
  797. pGUID,
  798. LineNum);
  799. //
  800. // Trim leading \'s
  801. //
  802. while (*pLink == UNICODE_PATH_SEP)
  803. pLink++;
  804. //
  805. // If no short prefix is given, use the long prefix
  806. //
  807. if (pShortLink == NULL)
  808. pShortLink = pLink;
  809. if(pDfsVolList == NULL){
  810. dwErr = ERROR_INVALID_PARAMETER;
  811. goto Cleanup;
  812. }
  813. if(pDfsVolList->Volumes == NULL){
  814. dwErr = ERROR_INVALID_PARAMETER;
  815. goto Cleanup;
  816. }
  817. //
  818. // Build full prefix and shortprefix names
  819. //
  820. Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) +
  821. sizeof(WCHAR) +
  822. wcslen(pLink) * sizeof(WCHAR) +
  823. sizeof(WCHAR);
  824. pPrefix = (LPWSTR) malloc(Size);
  825. if (pPrefix == NULL) {
  826. dwErr = ERROR_OUTOFMEMORY;
  827. goto Cleanup;
  828. }
  829. Size = wcslen(pDfsVolList->Volumes[0]->wszShortPrefix) * sizeof(WCHAR) +
  830. sizeof(WCHAR) +
  831. wcslen(pShortLink) * sizeof(WCHAR) +
  832. sizeof(WCHAR);
  833. pShortPrefix = (LPWSTR) malloc(Size);
  834. if (pShortPrefix == NULL) {
  835. dwErr = ERROR_OUTOFMEMORY;
  836. goto Cleanup;
  837. }
  838. wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix);
  839. wcscat(pPrefix, UNICODE_PATH_SEP_STR);
  840. wcscat(pPrefix, pLink);
  841. wcscpy(pShortPrefix, pDfsVolList->Volumes[0]->wszShortPrefix);
  842. wcscat(pShortPrefix, UNICODE_PATH_SEP_STR);
  843. wcscat(pShortPrefix, pShortLink);
  844. //
  845. // See if this link is already there. Binary Search.
  846. //
  847. if (pDfsVolList->VolCount > 0) {
  848. Min = 0;
  849. Max = pDfsVolList->VolCount-1;
  850. while (Min <= Max) {
  851. Cur = (Min + Max) / 2;
  852. Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix);
  853. if (Res == 0) {
  854. // we skip it, it is ok.
  855. //dwErr = ERROR_DUP_NAME;
  856. MyPrintf(L"MAP line %d: duplicate link %ws (skipped)\r\n", LineNum, pPrefix);
  857. goto Cleanup;
  858. } else if (Res < 0) {
  859. Min = Cur + 1;
  860. } else {
  861. Max = Cur - 1;
  862. }
  863. }
  864. }
  865. //
  866. // Expand the list if necessary
  867. //
  868. if (pDfsVolList->VolCount >= pDfsVolList->AllocatedVolCount) {
  869. pVoid = realloc(
  870. pDfsVolList->Volumes,
  871. (pDfsVolList->AllocatedVolCount + INIT_LINK_COUNT) * sizeof(PDFS_VOLUME));
  872. if (pVoid == NULL) {
  873. dwErr = ERROR_OUTOFMEMORY;
  874. goto Cleanup;
  875. }
  876. pDfsVolList->Volumes = (PDFS_VOLUME *) pVoid;
  877. RtlZeroMemory(
  878. &pDfsVolList->Volumes[pDfsVolList->AllocatedVolCount],
  879. INIT_LINK_COUNT * sizeof(PDFS_VOLUME));
  880. pDfsVolList->AllocatedVolCount += INIT_LINK_COUNT;
  881. if (fSwDebug == TRUE)
  882. MyPrintf(L"CmdLinkMap:realloced to %d\r\n", pDfsVolList->AllocatedVolCount);
  883. }
  884. if ((pDfsVolList->VolCount % 1000) == 0)
  885. MyPrintf(L"%d\r\n", pDfsVolList->VolCount);
  886. if (Cur == -1)
  887. Cur = 0;
  888. else if (Res < 0)
  889. Cur++;
  890. if (Cur < (LONG)pDfsVolList->VolCount) {
  891. RtlMoveMemory(
  892. &pDfsVolList->Volumes[Cur+1],
  893. &pDfsVolList->Volumes[Cur],
  894. sizeof(PDFS_VOLUME) * (pDfsVolList->VolCount-(ULONG)Cur));
  895. }
  896. //
  897. // Add the new
  898. //
  899. pDfsVolList->Volumes[Cur] = (PDFS_VOLUME) malloc(sizeof(DFS_VOLUME));
  900. if (pDfsVolList->Volumes[Cur] == NULL) {
  901. dwErr = ERROR_OUTOFMEMORY;
  902. goto Cleanup;
  903. }
  904. RtlZeroMemory(pDfsVolList->Volumes[Cur], sizeof(DFS_VOLUME));
  905. pVol = pDfsVolList->Volumes[Cur];
  906. pVol->wszPrefix = pPrefix;
  907. pPrefix = NULL;
  908. pVol->wszShortPrefix = pShortPrefix;
  909. pVol->vFlags |= VFLAGS_MODIFY;
  910. pShortPrefix = NULL;
  911. if (pComment != NULL) {
  912. pVol->wszComment = (PWCHAR)malloc((wcslen(pComment)+1) * sizeof(WCHAR));
  913. if (pVol->wszComment == NULL) {
  914. dwErr = ERROR_OUTOFMEMORY;
  915. goto Cleanup;
  916. }
  917. wcscpy(pVol->wszComment, pComment);
  918. }
  919. if (pGUID != NULL && wcslen(pGUID) == (sizeof(GUID) * 2))
  920. StringToGuid(pGUID, &pVol->idVolume);
  921. else {
  922. dwErr = UuidCreate(&pVol->idVolume);
  923. if(dwErr != RPC_S_OK) {
  924. goto Cleanup;
  925. }
  926. }
  927. pVol->wszObjectName = (PWCHAR)malloc(92);
  928. if (pVol->wszObjectName == NULL) {
  929. dwErr = ERROR_OUTOFMEMORY;
  930. goto Cleanup;
  931. }
  932. RtlZeroMemory(pVol->wszObjectName, 92);
  933. wcscpy(pVol->wszObjectName, L"\\domainroot\\");
  934. GuidToStringEx(&pVol->idVolume, &pVol->wszObjectName[12]);
  935. if (pType != NULL) {
  936. if (pType[0] == L'0' && (pType[1] == L'x' || pType[1] == L'X'))
  937. pVol->dwType = AtoHex(pType, &dwErr);
  938. else
  939. pVol->dwType = AtoDec(pType, &dwErr);
  940. if (dwErr != ERROR_SUCCESS) {
  941. MyPrintf(L"bad value %ws\r\n", pType);
  942. goto Cleanup;
  943. }
  944. } else {
  945. pVol->dwType = 0x1;
  946. }
  947. if (pState != NULL) {
  948. if (pState[0] == L'0' && (pState[1] == L'x' || pState[1] == L'X'))
  949. pVol->dwState = AtoHex(pState, &dwErr);
  950. else
  951. pVol->dwState = AtoDec(pState, &dwErr);
  952. if (dwErr != ERROR_SUCCESS) {
  953. MyPrintf(L"bad value %ws\r\n", pState);
  954. goto Cleanup;
  955. }
  956. } else {
  957. pVol->dwState = 0x1;
  958. }
  959. if (pTimeout != NULL) {
  960. if (pTimeout[0] == L'0' && (pTimeout[1] == L'x' || pTimeout[1] == L'X'))
  961. pVol->dwTimeout = AtoHex(pTimeout, &dwErr);
  962. else
  963. pVol->dwTimeout = AtoDec(pTimeout, &dwErr);
  964. if (dwErr != ERROR_SUCCESS) {
  965. MyPrintf(L"bad value %ws\r\n", pTimeout);
  966. goto Cleanup;
  967. }
  968. } else {
  969. pVol->dwTimeout = 300;
  970. }
  971. pVol->dwVersion = 3;
  972. pVol->ReplCount = 0;
  973. pVol->AllocatedReplCount = 0;
  974. pVol->vFlags |= VFLAGS_MODIFY;
  975. pDfsVolList->VolCount++;
  976. if (fSwDebug == TRUE)
  977. MyPrintf(L"CmdLinkMap exit %d\r\n", dwErr);
  978. return dwErr;
  979. Cleanup:
  980. //
  981. // We had a problem. Clean up and return the error
  982. //
  983. if (pVol != NULL) {
  984. if (pVol->wszObjectName != NULL)
  985. free(pVol->wszObjectName);
  986. if (pVol->wszPrefix != NULL)
  987. free(pVol->wszPrefix);
  988. if (pVol->wszShortPrefix != NULL)
  989. free(pVol->wszShortPrefix);
  990. if (pVol->wszComment != NULL)
  991. free(pVol->wszComment);
  992. RtlZeroMemory(pVol, sizeof(DFS_VOLUME));
  993. }
  994. if (pPrefix != NULL)
  995. free(pPrefix);
  996. if (pShortPrefix != NULL)
  997. free(pShortPrefix);
  998. free(pgLink);
  999. pgLink = NULL;
  1000. if (fSwDebug == TRUE)
  1001. MyPrintf(L"CmdLinkMap exit %d\r\n", dwErr);
  1002. return dwErr;
  1003. }
  1004. DWORD
  1005. CmdLink(
  1006. PDFS_VOLUME_LIST pDfsVolList,
  1007. LPWSTR pLink,
  1008. ULONG LineNum)
  1009. {
  1010. DWORD dwErr = ERROR_NOT_FOUND;
  1011. LONG Min;
  1012. LONG Max;
  1013. LONG Res;
  1014. LONG Cur = -1;
  1015. LONG i;
  1016. ULONG Size;
  1017. LPWSTR pPrefix = NULL;
  1018. if (fSwDebug == TRUE)
  1019. MyPrintf(L"CmdLink(%ws,%d)\r\n",
  1020. pLink,
  1021. LineNum);
  1022. //
  1023. // Trim leading \'s
  1024. //
  1025. while (*pLink == UNICODE_PATH_SEP)
  1026. pLink++;
  1027. //
  1028. // Build full prefix and shortprefix names
  1029. //
  1030. Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) +
  1031. sizeof(WCHAR) +
  1032. wcslen(pLink) * sizeof(WCHAR) +
  1033. sizeof(WCHAR);
  1034. pPrefix = (LPWSTR) malloc(Size);
  1035. if (pPrefix == NULL) {
  1036. dwErr = ERROR_OUTOFMEMORY;
  1037. goto AllDone;
  1038. }
  1039. wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix);
  1040. wcscat(pPrefix, UNICODE_PATH_SEP_STR);
  1041. wcscat(pPrefix, pLink);
  1042. //
  1043. // See if this link is there. Binary Search.
  1044. //
  1045. if (pDfsVolList->VolCount > 0) {
  1046. Min = 0;
  1047. Max = pDfsVolList->VolCount-1;
  1048. while (Min <= Max) {
  1049. Cur = (Min + Max) / 2;
  1050. Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix);
  1051. if (Res == 0) {
  1052. dwErr = ERROR_SUCCESS;
  1053. goto AllDone;
  1054. } else if (Res < 0) {
  1055. Min = Cur + 1;
  1056. } else {
  1057. Max = Cur - 1;
  1058. }
  1059. }
  1060. }
  1061. if (dwErr == ERROR_NOT_FOUND)
  1062. MyPrintf(L"LINK line %d: link %ws not found (skipped)\r\n", LineNum, pLink);
  1063. AllDone:
  1064. if (pPrefix != NULL)
  1065. free(pPrefix);
  1066. if (dwErr != ERROR_SUCCESS) {
  1067. free(pgLink);
  1068. pgLink = NULL;
  1069. }
  1070. if (fSwDebug == TRUE)
  1071. MyPrintf(L"CmdLink exit %d\r\n", dwErr);
  1072. return dwErr;
  1073. }
  1074. DWORD
  1075. CmdLinkUnmap(
  1076. PDFS_VOLUME_LIST pDfsVolList,
  1077. LPWSTR pLink,
  1078. ULONG LineNum)
  1079. {
  1080. DWORD dwErr = ERROR_NOT_FOUND;
  1081. LONG Min;
  1082. LONG Max;
  1083. LONG Res;
  1084. PDFS_VOLUME pVol = NULL;
  1085. LONG Cur = 0;
  1086. LONG i;
  1087. ULONG Size;
  1088. PWCHAR wCp;
  1089. BOOLEAN fPrefixAllocated = FALSE;
  1090. LPWSTR pPrefix = NULL;
  1091. if (fSwDebug == TRUE)
  1092. MyPrintf(L"CmdLinkUnmap(%ws,%d)\r\n",
  1093. pLink,
  1094. LineNum);
  1095. //
  1096. // Allow two ways to specify a link
  1097. // relative (no leading \\)
  1098. // or absolute (leading \\)
  1099. //
  1100. //
  1101. // Trim extra leading \'s
  1102. //
  1103. while (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP)
  1104. pLink++;
  1105. if (*pLink == UNICODE_PATH_SEP) {
  1106. if (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP)
  1107. pLink++;
  1108. pPrefix = pLink;
  1109. } else {
  1110. //
  1111. // Build full prefix name
  1112. //
  1113. Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) +
  1114. sizeof(WCHAR) +
  1115. wcslen(pLink) * sizeof(WCHAR) +
  1116. sizeof(WCHAR);
  1117. pPrefix = (LPWSTR) malloc(Size);
  1118. if (pPrefix == NULL) {
  1119. dwErr = ERROR_OUTOFMEMORY;
  1120. goto Cleanup;
  1121. }
  1122. wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix);
  1123. wcscat(pPrefix, UNICODE_PATH_SEP_STR);
  1124. wcscat(pPrefix, pLink);
  1125. fPrefixAllocated = TRUE;
  1126. }
  1127. //
  1128. // See if this link is there. Binary Search.
  1129. //
  1130. if (pDfsVolList->VolCount > 0) {
  1131. Min = 0;
  1132. Max = pDfsVolList->VolCount-1;
  1133. while (Min <= Max) {
  1134. Cur = (Min + Max) / 2;
  1135. Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix);
  1136. if (Res == 0) {
  1137. dwErr = ERROR_SUCCESS;
  1138. break;
  1139. } else if (Res < 0) {
  1140. Min = Cur + 1;
  1141. } else {
  1142. Max = Cur - 1;
  1143. }
  1144. }
  1145. }
  1146. if (dwErr != ERROR_SUCCESS) {
  1147. MyPrintf(L"UNMAP line %d: link %ws not found (skipped)\r\n", LineNum, pLink);
  1148. goto Cleanup;
  1149. }
  1150. if (fSwDebug == TRUE)
  1151. MyPrintf(L"Found match at %d\r\n", Cur);
  1152. pVol = pDfsVolList->Volumes[Cur];
  1153. if (pDfsVolList->DfsType == STDDFS) {
  1154. pVol->vFlags |= VFLAGS_DELETE;
  1155. } else if (pDfsVolList->DfsType == DOMDFS) {
  1156. DfsFreeVol(pDfsVolList->Volumes[Cur]);
  1157. free(pDfsVolList->Volumes[Cur]);
  1158. RtlMoveMemory(
  1159. &pDfsVolList->Volumes[Cur],
  1160. &pDfsVolList->Volumes[Cur+1],
  1161. sizeof(PDFS_VOLUME) * (pDfsVolList->VolCount-((ULONG)Cur)-1));
  1162. pDfsVolList->VolCount--;
  1163. pDfsVolList->Volumes[pDfsVolList->VolCount] = NULL;
  1164. }
  1165. Cleanup:
  1166. if (pPrefix != NULL && fPrefixAllocated == TRUE)
  1167. free(pPrefix);
  1168. if (dwErr != ERROR_SUCCESS) {
  1169. free(pgLink);
  1170. pgLink = NULL;
  1171. }
  1172. if (fSwDebug == TRUE)
  1173. MyPrintf(L"CmdLinkUnmap exit %d\r\n", dwErr);
  1174. return dwErr;
  1175. }
  1176. DWORD
  1177. CmdLinkMod(
  1178. PDFS_VOLUME_LIST pDfsVolList,
  1179. LPWSTR pLink,
  1180. LPWSTR pShortLink,
  1181. LPWSTR pComment,
  1182. LPWSTR pTimeout,
  1183. LPWSTR pState,
  1184. LPWSTR pType,
  1185. LPWSTR pGUID,
  1186. ULONG LineNum)
  1187. {
  1188. DWORD dwErr = ERROR_NOT_FOUND;
  1189. LONG Min;
  1190. LONG Max;
  1191. LONG Res;
  1192. PDFS_VOLUME pVol = NULL;
  1193. LONG Cur = 0;
  1194. LONG i;
  1195. ULONG Size;
  1196. PWCHAR wCp;
  1197. BOOLEAN fPrefixAllocated = FALSE;
  1198. LPWSTR pPrefix = NULL;
  1199. LPWSTR pShortPrefix = NULL;
  1200. if (fSwDebug == TRUE)
  1201. MyPrintf(L"CmdLinkMod(%ws,%ws,%ws,%ws,%ws,%ws,%ws,%d)\r\n",
  1202. pLink,
  1203. pShortLink,
  1204. pComment,
  1205. pTimeout,
  1206. pState,
  1207. pType,
  1208. pGUID,
  1209. LineNum);
  1210. //
  1211. // Allow two ways to specify a link
  1212. // relative (no leading \\)
  1213. // or absolute (leading \\)
  1214. //
  1215. //
  1216. // Trim extra leading \'s
  1217. //
  1218. while (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP)
  1219. pLink++;
  1220. if (*pLink == UNICODE_PATH_SEP) {
  1221. if (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP)
  1222. pLink++;
  1223. pPrefix = pLink;
  1224. } else {
  1225. //
  1226. // Build full prefix name
  1227. //
  1228. Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) +
  1229. sizeof(WCHAR) +
  1230. wcslen(pLink) * sizeof(WCHAR) +
  1231. sizeof(WCHAR);
  1232. pPrefix = (LPWSTR) malloc(Size);
  1233. if (pPrefix == NULL) {
  1234. dwErr = ERROR_OUTOFMEMORY;
  1235. goto Cleanup;
  1236. }
  1237. wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix);
  1238. wcscat(pPrefix, UNICODE_PATH_SEP_STR);
  1239. wcscat(pPrefix, pLink);
  1240. fPrefixAllocated = TRUE;
  1241. }
  1242. //
  1243. // See if this link is there. Binary Search.
  1244. //
  1245. if (pDfsVolList->VolCount > 0) {
  1246. Min = 0;
  1247. Max = pDfsVolList->VolCount-1;
  1248. while (Min <= Max) {
  1249. Cur = (Min + Max) / 2;
  1250. Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix);
  1251. if (Res == 0) {
  1252. dwErr = ERROR_SUCCESS;
  1253. break;
  1254. } else if (Res < 0) {
  1255. Min = Cur + 1;
  1256. } else {
  1257. Max = Cur - 1;
  1258. }
  1259. }
  1260. }
  1261. if (dwErr != ERROR_SUCCESS) {
  1262. MyPrintf(L"MOD line %d: link %ws not found (skipped)\r\n", LineNum, pLink);
  1263. goto Cleanup;
  1264. }
  1265. if (fSwDebug == TRUE)
  1266. MyPrintf(L"Found match at %d\r\n", Cur);
  1267. pVol = pDfsVolList->Volumes[Cur];
  1268. if (pShortLink != NULL) {
  1269. while (*pShortLink == UNICODE_PATH_SEP)
  1270. pShortLink++;
  1271. Size = wcslen(pDfsVolList->Volumes[0]->wszShortPrefix) * sizeof(WCHAR) +
  1272. sizeof(WCHAR) +
  1273. wcslen(pShortLink) * sizeof(WCHAR) +
  1274. sizeof(WCHAR);
  1275. wCp = (LPWSTR) malloc(Size);
  1276. if (wCp == NULL) {
  1277. dwErr = ERROR_OUTOFMEMORY;
  1278. goto Cleanup;
  1279. }
  1280. wcscpy(wCp, pDfsVolList->Volumes[0]->wszShortPrefix);
  1281. wcscat(wCp, UNICODE_PATH_SEP_STR);
  1282. wcscat(wCp, pShortLink);
  1283. if (pVol->wszShortPrefix != NULL)
  1284. free(pVol->wszShortPrefix);
  1285. pVol->wszShortPrefix = wCp;
  1286. }
  1287. if (pComment != NULL) {
  1288. wCp = (PWCHAR)malloc((wcslen(pComment)+1) * sizeof(WCHAR));
  1289. if (wCp == NULL) {
  1290. dwErr = ERROR_OUTOFMEMORY;
  1291. goto Cleanup;
  1292. }
  1293. if (pVol->wszComment != NULL)
  1294. free(pVol->wszComment);
  1295. pVol->wszComment = wCp;
  1296. wcscpy(pVol->wszComment, pComment);
  1297. }
  1298. if (pGUID != NULL && wcslen(pGUID) == (sizeof(GUID) * 2))
  1299. StringToGuid(pGUID, &pVol->idVolume);
  1300. if (pType != NULL) {
  1301. if (pType[0] == L'0' && (pType[1] == L'x' || pType[1] == L'X'))
  1302. pVol->dwType = AtoHex(pType, &dwErr);
  1303. else
  1304. pVol->dwType = AtoDec(pType, &dwErr);
  1305. if (dwErr != ERROR_SUCCESS) {
  1306. MyPrintf(L"bad value %ws\r\n", pType);
  1307. goto Cleanup;
  1308. }
  1309. }
  1310. if (pState != NULL) {
  1311. if (pState[0] == L'0' && (pState[1] == L'x' || pState[1] == L'X'))
  1312. pVol->dwState = AtoHex(pState, &dwErr);
  1313. else
  1314. pVol->dwState = AtoDec(pState, &dwErr);
  1315. if (dwErr != ERROR_SUCCESS) {
  1316. MyPrintf(L"bad value %ws\r\n", pState);
  1317. goto Cleanup;
  1318. }
  1319. }
  1320. if (pTimeout != NULL) {
  1321. if (pTimeout[0] == L'0' && (pTimeout[1] == L'x' || pTimeout[1] == L'X'))
  1322. pVol->dwTimeout = AtoHex(pTimeout, &dwErr);
  1323. else
  1324. pVol->dwTimeout = AtoDec(pTimeout, &dwErr);
  1325. if (dwErr != ERROR_SUCCESS) {
  1326. MyPrintf(L"bad value %ws\r\n", pTimeout);
  1327. goto Cleanup;
  1328. }
  1329. }
  1330. pVol->vFlags |= VFLAGS_MODIFY;
  1331. Cleanup:
  1332. if (pPrefix != NULL && fPrefixAllocated == TRUE)
  1333. free(pPrefix);
  1334. if (pShortPrefix != NULL)
  1335. free(pShortPrefix);
  1336. if (dwErr != ERROR_SUCCESS) {
  1337. free(pgLink);
  1338. pgLink = NULL;
  1339. }
  1340. if (fSwDebug == TRUE)
  1341. MyPrintf(L"CmdLinkMod exit %d\r\n", dwErr);
  1342. return dwErr;
  1343. }
  1344. DWORD
  1345. CmdAdd(
  1346. PDFS_VOLUME_LIST pDfsVolList,
  1347. LPWSTR pLink,
  1348. LPWSTR pAltName,
  1349. LPWSTR pState,
  1350. LPWSTR pType,
  1351. ULONG LineNum)
  1352. {
  1353. DWORD dwErr = ERROR_NOT_FOUND;
  1354. LONG Min;
  1355. LONG Max;
  1356. LONG Res;
  1357. PDFS_VOLUME pVol = NULL;
  1358. DFS_REPLICA_INFO *pReplInfo;
  1359. LONG Cur = 0;
  1360. PVOID pVoid;
  1361. LPWSTR pPrefix = NULL;
  1362. ULONG Size;
  1363. if (fSwDebug == TRUE)
  1364. MyPrintf(L"CmdAdd(%ws,%ws,%ws,%ws,%d)\r\n",
  1365. pLink,
  1366. pAltName,
  1367. pState,
  1368. pType,
  1369. LineNum);
  1370. if (pLink == NULL) {
  1371. dwErr = ERROR_INVALID_PARAMETER;
  1372. MyPrintf(L"ADD line %d: No link specified (skipped)\r\n", LineNum);
  1373. goto Cleanup;
  1374. }
  1375. //
  1376. // Trim leading \'s
  1377. //
  1378. while (*pLink == UNICODE_PATH_SEP)
  1379. pLink++;
  1380. //
  1381. // Build full prefix name
  1382. //
  1383. Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) +
  1384. sizeof(WCHAR) +
  1385. wcslen(pLink) * sizeof(WCHAR) +
  1386. sizeof(WCHAR);
  1387. pPrefix = (LPWSTR) malloc(Size);
  1388. if (pPrefix == NULL) {
  1389. dwErr = ERROR_OUTOFMEMORY;
  1390. goto Cleanup;
  1391. }
  1392. wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix);
  1393. wcscat(pPrefix, UNICODE_PATH_SEP_STR);
  1394. wcscat(pPrefix, pLink);
  1395. //
  1396. // See if this link is there. Binary Search.
  1397. //
  1398. if (pDfsVolList->VolCount > 0) {
  1399. Min = 0;
  1400. Max = pDfsVolList->VolCount-1;
  1401. while (Min <= Max) {
  1402. Cur = (Min + Max) / 2;
  1403. Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix);
  1404. if (Res == 0) {
  1405. dwErr = ERROR_SUCCESS;
  1406. break;
  1407. } else if (Res < 0) {
  1408. Min = Cur + 1;
  1409. } else {
  1410. Max = Cur - 1;
  1411. }
  1412. }
  1413. }
  1414. if (dwErr != ERROR_SUCCESS) {
  1415. MyPrintf(L"ADD line %d: link %ws not found (skipped)\r\n", LineNum, pPrefix);
  1416. goto Cleanup;
  1417. }
  1418. pVol = pDfsVolList->Volumes[Cur];
  1419. if (fSwDebug == TRUE)
  1420. MyPrintf(L"Found match at %d\r\n", Cur);
  1421. if (pVol->ReplCount == 0) {
  1422. pVol->ReplicaInfo = (DFS_REPLICA_INFO *) malloc( INIT_ALT_COUNT * sizeof(DFS_REPLICA_INFO));
  1423. if (pVol->ReplicaInfo == NULL) {
  1424. dwErr = ERROR_OUTOFMEMORY;
  1425. goto Cleanup;
  1426. }
  1427. RtlZeroMemory(pVol->ReplicaInfo, INIT_ALT_COUNT * sizeof(DFS_REPLICA_INFO));
  1428. pVol->ReplCount = 0;
  1429. pVol->AllocatedReplCount = INIT_ALT_COUNT;
  1430. }
  1431. if (pVol->ReplCount >= (pVol->AllocatedReplCount-1)) {
  1432. pVoid = realloc(
  1433. pVol->ReplicaInfo,
  1434. (pVol->AllocatedReplCount + INIT_ALT_COUNT) * sizeof(DFS_REPLICA_INFO));
  1435. if (pVoid == NULL) {
  1436. dwErr = ERROR_OUTOFMEMORY;
  1437. goto Cleanup;
  1438. }
  1439. pVol->ReplicaInfo = (DFS_REPLICA_INFO *) pVoid;
  1440. RtlZeroMemory(
  1441. &pVol->ReplicaInfo[pVol->ReplCount],
  1442. INIT_ALT_COUNT * sizeof(DFS_REPLICA_INFO));
  1443. pVol->AllocatedReplCount += INIT_ALT_COUNT;
  1444. }
  1445. pReplInfo = &pVol->ReplicaInfo[pVol->ReplCount];
  1446. dwErr = DfspBreakName(
  1447. pAltName,
  1448. &pReplInfo->pwszServerName,
  1449. &pReplInfo->pwszShareName);
  1450. if (dwErr != ERROR_SUCCESS)
  1451. goto Cleanup;
  1452. if (pState != NULL) {
  1453. if (pState[0] == L'0' && (pState[1] == L'x' || pState[1] == L'X'))
  1454. pReplInfo->ulReplicaState = AtoHex(pState, &dwErr);
  1455. else
  1456. pReplInfo->ulReplicaState = AtoDec(pState, &dwErr);
  1457. if (dwErr != ERROR_SUCCESS) {
  1458. MyPrintf(L"bad value %ws\r\n", pState);
  1459. goto Cleanup;
  1460. }
  1461. } else {
  1462. pReplInfo->ulReplicaState = 0x2;
  1463. }
  1464. if (pType != NULL) {
  1465. if (pType[0] == L'0' && (pType[1] == L'x' || pType[1] == L'X'))
  1466. pReplInfo->ulReplicaType = AtoHex(pType, &dwErr);
  1467. else
  1468. pReplInfo->ulReplicaType = AtoDec(pType, &dwErr);
  1469. if (dwErr != ERROR_SUCCESS) {
  1470. MyPrintf(L"bad value %ws\r\n", pType);
  1471. goto Cleanup;
  1472. }
  1473. } else {
  1474. pReplInfo->ulReplicaType = 0x2;
  1475. }
  1476. pVol->ReplCount++;
  1477. pVol->vFlags |= VFLAGS_MODIFY;
  1478. Cleanup:
  1479. if (pPrefix != NULL)
  1480. free(pPrefix);
  1481. if (fSwDebug == TRUE)
  1482. MyPrintf(L"CmdAdd exit %d\r\n", dwErr);
  1483. return dwErr;
  1484. }
  1485. DWORD
  1486. CmdSiteMap(
  1487. PDFS_VOLUME_LIST pDfsVolList,
  1488. LPWSTR pServer,
  1489. ULONG LineNum)
  1490. {
  1491. DWORD dwErr = ERROR_SUCCESS;
  1492. PDFSM_SITE_ENTRY pSiteEntry = NULL;
  1493. PLIST_ENTRY pListHead;
  1494. PLIST_ENTRY pLink;
  1495. LONG Res;
  1496. if (fSwDebug == TRUE)
  1497. MyPrintf(L"CmdSiteMap(%ws)\r\n", pServer);
  1498. //
  1499. // See if this server is already in the site table
  1500. //
  1501. pListHead = &pDfsVolList->SiteList;
  1502. if (pListHead->Flink != NULL) {
  1503. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  1504. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  1505. Res = _wcsicmp(pSiteEntry->ServerName, pServer);
  1506. if (Res == 0) {
  1507. pSiteEntry = NULL;
  1508. // we skip, it is ok.
  1509. //dwErr = ERROR_DUP_NAME;
  1510. MyPrintf(L"ADDSITE line %d: duplicate site %ws (skipped)\r\n", LineNum, pServer);
  1511. pgSite = NULL;
  1512. goto AllDone;
  1513. }
  1514. }
  1515. }
  1516. //
  1517. // Not a dup - create a new one
  1518. //
  1519. pSiteEntry = (PDFSM_SITE_ENTRY) malloc(sizeof(DFSM_SITE_ENTRY));
  1520. if (pSiteEntry == NULL) {
  1521. dwErr = ERROR_OUTOFMEMORY;
  1522. goto AllDone;
  1523. }
  1524. RtlZeroMemory(pSiteEntry, sizeof(DFSM_SITE_ENTRY));
  1525. dwErr = DupString(&pSiteEntry->ServerName, pServer);
  1526. if (dwErr != ERROR_SUCCESS)
  1527. goto AllDone;
  1528. //
  1529. // Link it in
  1530. //
  1531. InsertHeadList(&pDfsVolList->SiteList, &pSiteEntry->Link);
  1532. pDfsVolList->SiteCount++;
  1533. pDfsVolList->sFlags |= VFLAGS_MODIFY;
  1534. //
  1535. // Indicate that we are done with the pSiteEntry
  1536. //
  1537. pSiteEntry = NULL;
  1538. AllDone:
  1539. if (pSiteEntry != NULL) {
  1540. if (pSiteEntry->ServerName != NULL)
  1541. free(pSiteEntry->ServerName);
  1542. free(pSiteEntry);
  1543. }
  1544. if (fSwDebug == TRUE)
  1545. MyPrintf(L"CmdSiteMap exit %d\n", dwErr);
  1546. return dwErr;
  1547. }
  1548. DWORD
  1549. CmdSite(
  1550. PDFS_VOLUME_LIST pDfsVolList,
  1551. LPWSTR pServer,
  1552. ULONG LineNum)
  1553. {
  1554. DWORD dwErr = ERROR_NOT_FOUND;
  1555. PDFSM_SITE_ENTRY pSiteEntry = NULL;
  1556. PLIST_ENTRY pListHead;
  1557. PLIST_ENTRY pLink;
  1558. LONG Res;
  1559. if (fSwDebug == TRUE)
  1560. MyPrintf(L"CmdSite(%ws)\r\n", pServer);
  1561. //
  1562. // See if this server is in the site table
  1563. //
  1564. pListHead = &pDfsVolList->SiteList;
  1565. if (pListHead->Flink != NULL) {
  1566. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  1567. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  1568. Res = _wcsicmp(pSiteEntry->ServerName, pServer);
  1569. if (Res == 0) {
  1570. dwErr = ERROR_SUCCESS;
  1571. break;
  1572. }
  1573. }
  1574. }
  1575. if (dwErr != ERROR_SUCCESS) {
  1576. MyPrintf(L"SITE line %d: link %ws not found (skipped)\r\n", LineNum, pServer);
  1577. free(pgSite);
  1578. pgSite = NULL;
  1579. }
  1580. if (fSwDebug == TRUE)
  1581. MyPrintf(L"CmdSite exit %d\n", dwErr);
  1582. return dwErr;
  1583. }
  1584. DWORD
  1585. CmdAddSiteToServer(
  1586. PDFS_VOLUME_LIST pDfsVolList,
  1587. LPWSTR pServer,
  1588. LPWSTR pSite,
  1589. ULONG LineNum)
  1590. {
  1591. DWORD dwErr = ERROR_NOT_FOUND;
  1592. PDFSM_SITE_ENTRY pSiteEntry = NULL;
  1593. PDFSM_SITE_ENTRY pSiteEntryNew = NULL;
  1594. PLIST_ENTRY pListHead;
  1595. PLIST_ENTRY pLink;
  1596. ULONG cSites;
  1597. ULONG Size;
  1598. LONG Res;
  1599. if (fSwDebug == TRUE)
  1600. MyPrintf(L"CmdAddSiteToServer(%ws,%ws)\r\n", pServer, pSite);
  1601. if (pDfsVolList == NULL || pSite == NULL || pServer == NULL) {
  1602. dwErr = ERROR_INVALID_PARAMETER;
  1603. goto Cleanup;
  1604. }
  1605. //
  1606. // See if this server is in the site table
  1607. //
  1608. pListHead = &pDfsVolList->SiteList;
  1609. if (pListHead->Flink != NULL) {
  1610. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  1611. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  1612. Res = _wcsicmp(pSiteEntry->ServerName, pServer);
  1613. if (Res == 0) {
  1614. dwErr = ERROR_SUCCESS;
  1615. break;
  1616. }
  1617. }
  1618. }
  1619. if (dwErr != ERROR_SUCCESS) {
  1620. MyPrintf(L"ADD line %d: Server %ws not found (skipped)\r\n", LineNum, pServer);
  1621. free(pgSite);
  1622. pgSite = NULL;
  1623. goto Cleanup;
  1624. }
  1625. //
  1626. // Check if site already in the list
  1627. //
  1628. for (cSites = 0; cSites < pSiteEntry->Info.cSites; cSites++) {
  1629. Res = _wcsicmp(pSiteEntry->Info.Site[cSites].SiteName, pSite);
  1630. if (Res == 0) {
  1631. //we skip, it is okay.
  1632. //dwErr = ERROR_DUP_NAME;
  1633. MyPrintf(L"ADD line %d: Site %ws: duplicate (skipped)\r\n", LineNum, pSite);
  1634. pSiteEntry = NULL;
  1635. goto Cleanup;
  1636. }
  1637. }
  1638. cSites = pSiteEntry->Info.cSites + 1;
  1639. Size = sizeof(DFSM_SITE_ENTRY) + cSites * sizeof(DFS_SITENAME_INFO);
  1640. pSiteEntryNew = (PDFSM_SITE_ENTRY) malloc(Size);
  1641. if (pSiteEntryNew == NULL) {
  1642. dwErr = ERROR_OUTOFMEMORY;
  1643. goto Cleanup;
  1644. }
  1645. RtlZeroMemory(pSiteEntryNew, Size);
  1646. RtlMoveMemory(pSiteEntryNew, pSiteEntry, Size - sizeof(DFS_SITENAME_INFO));
  1647. //
  1648. // Add the new site to the end
  1649. //
  1650. pSiteEntryNew->Info.Site[cSites-1].SiteFlags = 0;
  1651. dwErr = DupString(&pSiteEntryNew->Info.Site[cSites-1].SiteName, pSite);
  1652. if (dwErr != ERROR_SUCCESS) {
  1653. pSiteEntry = NULL;
  1654. goto Cleanup;
  1655. }
  1656. pSiteEntryNew->Info.cSites++;
  1657. RemoveEntryList(&pSiteEntry->Link);
  1658. InsertHeadList(&pDfsVolList->SiteList, &pSiteEntryNew->Link);
  1659. pSiteEntryNew = NULL;
  1660. Cleanup:
  1661. if (pSiteEntryNew != NULL)
  1662. free(pSiteEntryNew);
  1663. if (pSiteEntry != NULL)
  1664. free(pSiteEntry);
  1665. if (fSwDebug == TRUE)
  1666. MyPrintf(L"CmdAddSiteToServer exit %d\n", dwErr);
  1667. return dwErr;
  1668. }
  1669. DWORD
  1670. CmdSiteUnmap(
  1671. PDFS_VOLUME_LIST pDfsVolList,
  1672. LPWSTR pServer,
  1673. ULONG LineNum)
  1674. {
  1675. DWORD dwErr = ERROR_NOT_FOUND;
  1676. PDFSM_SITE_ENTRY pSiteEntry = NULL;
  1677. PLIST_ENTRY pListHead;
  1678. PLIST_ENTRY pLink;
  1679. LONG Res;
  1680. if (fSwDebug == TRUE)
  1681. MyPrintf(L"CmdSiteUnnap(%ws)\r\n", pServer);
  1682. //
  1683. // See if this server is already in the site table
  1684. //
  1685. pListHead = &pDfsVolList->SiteList;
  1686. if (pListHead->Flink != NULL) {
  1687. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  1688. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  1689. Res = _wcsicmp(pSiteEntry->ServerName, pServer);
  1690. if (Res == 0) {
  1691. RemoveEntryList(&pSiteEntry->Link);
  1692. pDfsVolList->SiteCount--;
  1693. pDfsVolList->sFlags |= VFLAGS_MODIFY;
  1694. dwErr = ERROR_SUCCESS;
  1695. goto AllDone;
  1696. }
  1697. }
  1698. }
  1699. pSiteEntry = NULL;
  1700. MyPrintf(L"UNMAP line %d: server %ws not found (skipped)\r\n", LineNum, pServer);
  1701. AllDone:
  1702. if (pSiteEntry != NULL) {
  1703. if (pSiteEntry->ServerName != NULL)
  1704. free(pSiteEntry->ServerName);
  1705. free(pSiteEntry);
  1706. }
  1707. if (fSwDebug == TRUE)
  1708. MyPrintf(L"CmdSiteUnmap exit %d\n", dwErr);
  1709. return dwErr;
  1710. }
  1711. DWORD
  1712. DfspBreakName(
  1713. LPWSTR pPath,
  1714. LPWSTR *ppServerName,
  1715. LPWSTR *ppShareName)
  1716. {
  1717. DWORD dwErr = ERROR_SUCCESS;
  1718. LPWSTR pServerName = NULL;
  1719. LPWSTR pShareName = NULL;
  1720. WCHAR *wCp1 = NULL;
  1721. WCHAR *wCp2 = NULL;
  1722. ULONG Len = 0;
  1723. if (fSwDebug == TRUE)
  1724. MyPrintf(L"DfspBreakName(%ws)\r\n", pPath);
  1725. wCp1 = pPath;
  1726. while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
  1727. wCp1++;
  1728. if (*wCp1 == UNICODE_NULL) {
  1729. dwErr = ERROR_INVALID_PARAMETER;
  1730. goto Cleanup;
  1731. }
  1732. wCp2 = wCp1;
  1733. while (*wCp2 != UNICODE_PATH_SEP && *wCp2 != UNICODE_NULL)
  1734. wCp2++;
  1735. if (*wCp2 == UNICODE_NULL) {
  1736. dwErr = ERROR_INVALID_PARAMETER;
  1737. goto Cleanup;
  1738. }
  1739. Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR));
  1740. pServerName = (LPWSTR)malloc(Len + sizeof(WCHAR));
  1741. if (pServerName == NULL) {
  1742. dwErr = ERROR_OUTOFMEMORY;
  1743. goto Cleanup;
  1744. }
  1745. RtlZeroMemory(pServerName,Len+sizeof(WCHAR));
  1746. RtlCopyMemory(pServerName, wCp1, Len);
  1747. wCp1 = wCp2;
  1748. while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
  1749. wCp1++;
  1750. if (*wCp1 == UNICODE_NULL) {
  1751. dwErr = ERROR_INVALID_PARAMETER;
  1752. goto Cleanup;
  1753. }
  1754. wCp2 = wCp1;
  1755. while (*wCp2 != UNICODE_NULL)
  1756. wCp2++;
  1757. Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR));
  1758. pShareName = (LPWSTR)malloc(Len + sizeof(WCHAR));
  1759. if (pShareName == NULL) {
  1760. dwErr = ERROR_OUTOFMEMORY;
  1761. goto Cleanup;
  1762. }
  1763. RtlZeroMemory(pShareName,Len+sizeof(WCHAR));
  1764. RtlCopyMemory(pShareName, wCp1, Len);
  1765. *ppServerName = pServerName;
  1766. *ppShareName = pShareName;
  1767. Cleanup:
  1768. if (dwErr != ERROR_SUCCESS) {
  1769. if (pServerName != NULL)
  1770. free(pServerName);
  1771. if (pShareName != NULL)
  1772. free(pShareName);
  1773. }
  1774. if (fSwDebug == TRUE)
  1775. MyPrintf(L"DfspBreakName returning %d\r\n", dwErr);
  1776. return dwErr;
  1777. }
  1778. BOOLEAN
  1779. CmdProcessInfileArg(LPWSTR Arg)
  1780. {
  1781. LONG ArgLen;
  1782. BOOLEAN dwErr = FALSE;
  1783. BOOLEAN FoundAnArg = FALSE;
  1784. BOOLEAN FoundASwitch = FALSE;
  1785. PWCHAR wCp = NULL;
  1786. if (fSwDebug == TRUE)
  1787. MyPrintf(L"ProcessInfileArg(%ws)\r\n", Arg);
  1788. if ( Arg != NULL && wcslen(Arg) > 1) {
  1789. dwErr = TRUE;
  1790. ArgLen = wcslen(Arg);
  1791. if (_wcsnicmp(Arg, ArgLink, ArgLenLink) == 0) {
  1792. FoundAnArg = fArgLink = TRUE;
  1793. if (ArgLen > ArgLenLink) {
  1794. DupString(&pgLink, &Arg[ArgLenLink]);
  1795. DupString(&pgSite, NULL);
  1796. }
  1797. } else if (_wcsnicmp(Arg, ArgSite, ArgLenSite) == 0) {
  1798. FoundAnArg = fArgSite = TRUE;
  1799. if (ArgLen > ArgLenSite) {
  1800. DupString(&pgSite, &Arg[ArgLenSite]);
  1801. DupString(&pgLink, NULL);
  1802. }
  1803. } else if (_wcsnicmp(Arg, ArgShortPrefix, ArgLenShortPrefix) == 0) {
  1804. FoundAnArg = fArgShortPrefix = TRUE;
  1805. if (ArgLen > ArgLenShortPrefix)
  1806. pgShortLink = &Arg[ArgLenShortPrefix];
  1807. } else if (_wcsnicmp(Arg, ArgTimeout, ArgLenTimeout) == 0) {
  1808. FoundAnArg = fArgTimeout = TRUE;
  1809. if (ArgLen > ArgLenTimeout)
  1810. pgTimeout = &Arg[ArgLenTimeout];
  1811. } else if (_wcsnicmp(Arg, ArgType, ArgLenType) == 0) {
  1812. FoundAnArg = fArgType = TRUE;
  1813. if (ArgLen > ArgLenType)
  1814. pgType = &Arg[ArgLenType];
  1815. } else if (_wcsnicmp(Arg, ArgState, ArgLenState) == 0) {
  1816. FoundAnArg = fArgState = TRUE;
  1817. if (ArgLen > ArgLenState)
  1818. pgState = &Arg[ArgLenState];
  1819. } else if (_wcsnicmp(Arg, ArgComment, ArgLenComment) == 0) {
  1820. FoundAnArg = fArgComment = TRUE;
  1821. if (ArgLen > ArgLenComment)
  1822. pgComment = &Arg[ArgLenComment];
  1823. } else if (_wcsnicmp(Arg, ArgAdd, ArgLenAdd) == 0) {
  1824. FoundAnArg = fArgAdd = TRUE;
  1825. if (ArgLen > ArgLenAdd)
  1826. pgAddArg = &Arg[ArgLenAdd];
  1827. } else if (_wcsnicmp(Arg, ArgGuid, ArgLenGuid) == 0) {
  1828. FoundAnArg = fArgGuid = TRUE;
  1829. if (ArgLen > ArgLenGuid)
  1830. pgGuid = &Arg[ArgLenGuid];
  1831. } else if (_wcsnicmp(Arg, ArgDcName, ArgLenDcName) == 0) {
  1832. FoundAnArg = fArgDcName = TRUE;
  1833. if (ArgLen > ArgLenDcName)
  1834. DupString(&pgDcName, &Arg[ArgLenDcName]);
  1835. } else if (_wcsnicmp(Arg, ArgLoad, ArgLenLoad) == 0) {
  1836. FoundAnArg = fArgLoad = TRUE;
  1837. if (ArgLen > ArgLenLoad)
  1838. DupString(&pgDfsName, &Arg[ArgLenLoad]);
  1839. } else if (_wcsnicmp(Arg, ArgSave, ArgLenSave) == 0) {
  1840. FoundAnArg = fArgSave = TRUE;
  1841. if (ArgLen > ArgLenSave)
  1842. DupString(&pgDfsName, &Arg[ArgLenSave]);
  1843. } else if (_wcsnicmp(Arg, ArgAddRoot, ArgLenAddRoot) == 0) {
  1844. FoundAnArg = fArgAddRoot = TRUE;
  1845. if (ArgLen > ArgLenAddRoot)
  1846. pgDomDfsName = &Arg[ArgLenAddRoot];
  1847. } else if (_wcsnicmp(Arg, ArgRemRoot, ArgLenRemRoot) == 0) {
  1848. FoundAnArg = fArgRemRoot = TRUE;
  1849. if (ArgLen > ArgLenRemRoot)
  1850. pgDomDfsName = &Arg[ArgLenRemRoot];
  1851. } else if (_wcsnicmp(Arg, ArgServer, ArgLenServer) == 0) {
  1852. FoundAnArg = fArgServer = TRUE;
  1853. if (ArgLen > ArgLenServer)
  1854. pgServerName = &Arg[ArgLenServer];
  1855. } else if (_wcsnicmp(Arg, ArgShare, ArgLenShare) == 0) {
  1856. FoundAnArg = fArgShare = TRUE;
  1857. if (ArgLen > ArgLenShare)
  1858. pgShareName = &Arg[ArgLenShare];
  1859. }
  1860. if (_wcsicmp(Arg, SwMap) == 0) {
  1861. FoundASwitch = fSwMap = TRUE;
  1862. } else if (_wcsicmp(Arg, SwUnMap) == 0) {
  1863. FoundASwitch = fSwUnMap = TRUE;
  1864. } else if (_wcsicmp(Arg, SwMod) == 0) {
  1865. FoundASwitch = fSwMod = TRUE;
  1866. }
  1867. if (FoundAnArg == FALSE && FoundASwitch == FALSE) {
  1868. ErrorMessage(MSG_UNRECOGNIZED_OPTION, Arg);
  1869. dwErr = FALSE;
  1870. goto AllDone;
  1871. }
  1872. }
  1873. AllDone:
  1874. if (fSwDebug == TRUE)
  1875. MyPrintf(L"ProcessInfileArg exit %d\r\n", dwErr);
  1876. return dwErr;
  1877. }
  1878. int _cdecl
  1879. DfspVolCompare(
  1880. const void *p1,
  1881. const void *p2)
  1882. {
  1883. PDFS_VOLUME pVol1 = *((PDFS_VOLUME *) p1);
  1884. PDFS_VOLUME pVol2 = *((PDFS_VOLUME *) p2);
  1885. return _wcsicmp(pVol1->wszPrefix, pVol2->wszPrefix);
  1886. }
  1887. VOID
  1888. DfspSortVolList(
  1889. PDFS_VOLUME_LIST pDfsVolList)
  1890. {
  1891. ULONG i;
  1892. PDFS_VOLUME *pVols = pDfsVolList->Volumes;
  1893. if (pDfsVolList->VolCount < 2)
  1894. return;
  1895. for (i = 0; i < pDfsVolList->VolCount-1; i++) {
  1896. if (_wcsicmp(pVols[i]->wszPrefix, pVols[i+1]->wszPrefix) > 0) {
  1897. qsort(pVols, pDfsVolList->VolCount, sizeof(PDFS_VOLUME), DfspVolCompare);
  1898. break;
  1899. }
  1900. }
  1901. }
  1902. DWORD
  1903. DupString(
  1904. LPWSTR *wCpp,
  1905. LPWSTR s)
  1906. {
  1907. DWORD dwErr = ERROR_SUCCESS;
  1908. if (*wCpp != NULL) {
  1909. free(*wCpp);
  1910. *wCpp = NULL;
  1911. }
  1912. if (s == NULL || wcslen(s) == 0)
  1913. goto Cleanup;
  1914. *wCpp = (LPWSTR)malloc((wcslen(s)+1) * sizeof(WCHAR));
  1915. if (*wCpp == NULL) {
  1916. dwErr = ERROR_OUTOFMEMORY;
  1917. goto Cleanup;
  1918. }
  1919. wcscpy(*wCpp, s);
  1920. Cleanup:
  1921. return dwErr;
  1922. }
  1923. DWORD
  1924. CmdExport(
  1925. LPWSTR pOutfile,
  1926. LPWSTR pDomDfsName,
  1927. LPWSTR pDcName,
  1928. PSEC_WINNT_AUTH_IDENTITY pAuthIdent)
  1929. {
  1930. DWORD dwErr = ERROR_SUCCESS;
  1931. HANDLE hFile = INVALID_HANDLE_VALUE;
  1932. DFS_VOLUME_LIST DfsVolList = { 0 };
  1933. PDFS_VOLUME_LIST pDfsVolList = &DfsVolList;
  1934. if (fSwDebug == TRUE)
  1935. MyPrintf(L"CmdExport(%ws,%ws,%ws)\r\n", pOutfile, pDomDfsName, pDcName);
  1936. hFile = CreateFile(
  1937. pOutfile,
  1938. GENERIC_WRITE,
  1939. 0,
  1940. 0,
  1941. CREATE_ALWAYS,
  1942. FILE_ATTRIBUTE_NORMAL,
  1943. NULL);
  1944. if (hFile == INVALID_HANDLE_VALUE) {
  1945. dwErr = GetLastError();
  1946. goto Cleanup;
  1947. }
  1948. dwErr = CmdLoad(
  1949. pDfsVolList,
  1950. pDomDfsName,
  1951. pDcName);
  1952. if (dwErr != ERROR_SUCCESS)
  1953. goto Cleanup;
  1954. if(pDfsVolList != NULL) {
  1955. if (pDfsVolList->RootServers != NULL) {
  1956. // pDomDfSName is \\Dfs\Share, we just want Share
  1957. LPWSTR pDfsName = pDomDfsName;
  1958. for(int i=0; i<3 && pDfsName; pDfsName++){
  1959. if(*pDfsName == UNICODE_PATH_SEP)
  1960. i++;
  1961. }
  1962. MyFPrintf(hFile, L"// uncomment the addroot lines if\r\n");
  1963. MyFPrintf(hFile, L"// you want the script to create the root\r\n");
  1964. for (ULONG cRoot = 0; pDfsVolList->RootServers[cRoot+1] != NULL; cRoot++) {
  1965. LPWSTR pServer, pShare, pStr;
  1966. // we start with \\server\share, need to split in two.
  1967. // grab the share part
  1968. pShare = pDfsVolList->RootServers[cRoot];
  1969. for(int i=0; i<3 && pShare; pShare++){
  1970. if(*pShare == UNICODE_PATH_SEP)
  1971. i++;
  1972. }
  1973. // for the server we need to copy it...
  1974. pServer = (LPWSTR) malloc(wcslen(pDfsVolList->RootServers[cRoot])
  1975. * sizeof(WCHAR));
  1976. if(pServer == NULL) {
  1977. dwErr = ERROR_OUTOFMEMORY;
  1978. goto Cleanup;
  1979. }
  1980. wcscpy(pServer, pDfsVolList->RootServers[cRoot]);
  1981. pStr = pServer;
  1982. for(int i=0; i<3 && pStr; pStr++){
  1983. if(*pStr == UNICODE_PATH_SEP)
  1984. i++;
  1985. }
  1986. *(--pStr) = '\0'; // replace the '\' in server\share with '\0'
  1987. MyFPrintf(hFile, L"// ADDROOT:%ws SERVER:%ws SHARE:%ws\r\n",
  1988. pDfsName,
  1989. pServer+2,// remove leading "\\"
  1990. pShare);
  1991. if(pServer)
  1992. free(pServer);
  1993. }
  1994. }
  1995. }
  1996. MyFPrintf(hFile, L"// Load the dfs information\r\n");
  1997. MyFPrintf(hFile, L"LOAD:%ws ", pDomDfsName);
  1998. if (pDcName != NULL)
  1999. MyFPrintf(hFile, L"DCNAME:%ws\r\n", pDcName);
  2000. MyFPrintf(hFile, L"\r\n");
  2001. MyFPrintf(hFile, L"\r\n");
  2002. DfspExportFile(hFile, pDfsVolList);
  2003. MyFPrintf(hFile, L"// Save the dfs information\r\n");
  2004. MyFPrintf(hFile, L"SAVE:\r\n");
  2005. MyFPrintf(hFile, L"\r\n");
  2006. Cleanup:
  2007. if (hFile != INVALID_HANDLE_VALUE) {
  2008. FlushFileBuffers(hFile);
  2009. CloseHandle(hFile);
  2010. }
  2011. DfsFreeVolList(pDfsVolList);
  2012. if (fSwDebug == TRUE)
  2013. MyPrintf(L"CmdExport exit %d\r\n", dwErr);
  2014. return dwErr;
  2015. }
  2016. VOID
  2017. DfspExportFile(
  2018. HANDLE hHandle,
  2019. PDFS_VOLUME_LIST pDfsVolList)
  2020. {
  2021. ULONG cVol;
  2022. ULONG cRepl;
  2023. ULONG cSite;
  2024. ULONG i;
  2025. PLIST_ENTRY pListHead;
  2026. PLIST_ENTRY pLink;
  2027. PDFSM_SITE_ENTRY pSiteEntry;
  2028. WCHAR wszGuid[sizeof(GUID) * sizeof(WCHAR) + sizeof(WCHAR)];
  2029. DfspSortVolList(pDfsVolList);
  2030. MyFPrintf(hHandle, L"// Link Information\r\n");
  2031. for (cVol = 1; cVol < pDfsVolList->VolCount; cVol++) {
  2032. PWCHAR pPrefix = NULL;
  2033. PWCHAR pShortPrefix = NULL;
  2034. for (pPrefix = &pDfsVolList->Volumes[cVol]->wszPrefix[0];
  2035. pPrefix && *pPrefix != UNICODE_PATH_SEP;
  2036. pPrefix++)
  2037. NOTHING;
  2038. // if we stopped here we would have dfsname\dfsshare\link
  2039. // we want just link.
  2040. if(pPrefix)
  2041. pPrefix++;
  2042. while(pPrefix && *pPrefix != UNICODE_PATH_SEP)
  2043. pPrefix++;
  2044. // do it twice
  2045. if(pPrefix)
  2046. pPrefix++;
  2047. while(pPrefix && *pPrefix != UNICODE_PATH_SEP)
  2048. pPrefix++;
  2049. for (pShortPrefix = &pDfsVolList->Volumes[cVol]->wszShortPrefix[0];
  2050. pShortPrefix && *pShortPrefix != UNICODE_PATH_SEP;
  2051. pShortPrefix++)
  2052. NOTHING;
  2053. // if we stopped here we would have dfsname\dfsshare\link
  2054. // we want just link.
  2055. if(pShortPrefix)
  2056. pShortPrefix++;
  2057. while(pShortPrefix && *pShortPrefix != UNICODE_PATH_SEP)
  2058. pShortPrefix++;
  2059. // do it twice
  2060. if(pShortPrefix)
  2061. pShortPrefix++;
  2062. while(pShortPrefix && *pShortPrefix != UNICODE_PATH_SEP)
  2063. pShortPrefix++;
  2064. if(pPrefix)
  2065. pPrefix++;
  2066. if(pShortPrefix)
  2067. pShortPrefix++;
  2068. MyFPrintf(hHandle, L"LINK:%ws /MAP ", pPrefix);
  2069. if (_wcsicmp(pPrefix, pShortPrefix) != 0)
  2070. MyFPrintf(hHandle, L"SHORTPREFIX:%ws ", pShortPrefix);
  2071. MyFPrintf(
  2072. hHandle,
  2073. L"GUID:%ws ", GuidToStringEx(&pDfsVolList->Volumes[cVol]->idVolume,
  2074. wszGuid));
  2075. if (pDfsVolList->Volumes[cVol]->dwState != 0x1)
  2076. MyFPrintf(hHandle, L"STATE:0x%x ", pDfsVolList->Volumes[cVol]->dwState);
  2077. if (pDfsVolList->Volumes[cVol]->dwType != 0x1)
  2078. MyFPrintf(hHandle, L"TYPE:0x%x ", pDfsVolList->Volumes[cVol]->dwState);
  2079. if (pDfsVolList->Volumes[cVol]->dwTimeout != 300)
  2080. MyFPrintf(hHandle, L"TIMEOUT:%d ", pDfsVolList->Volumes[cVol]->dwTimeout);
  2081. if (
  2082. pDfsVolList->Volumes[cVol]->wszComment != NULL
  2083. &&
  2084. wcslen(pDfsVolList->Volumes[cVol]->wszComment) > 0
  2085. )
  2086. MyFPrintf(hHandle, L"COMMENT:\"%ws\"", pDfsVolList->Volumes[cVol]->wszComment);
  2087. MyFPrintf(hHandle, L"\r\n");
  2088. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->ReplCount; cRepl++) {
  2089. MyFPrintf(hHandle, L" ADD:\\\\%ws\\%ws ",
  2090. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszServerName,
  2091. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszShareName);
  2092. if (pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaState != 0x2)
  2093. MyFPrintf(
  2094. hHandle,
  2095. L"STATE:0x%x ",
  2096. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaState);
  2097. if (pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaType != 0x2)
  2098. MyFPrintf(
  2099. hHandle,
  2100. L"TYPE:0x%x\r\n",
  2101. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaType);
  2102. MyFPrintf(hHandle, L"\r\n");
  2103. }
  2104. MyFPrintf(hHandle, L"\r\n");
  2105. }
  2106. pListHead = &pDfsVolList->SiteList;
  2107. if (pListHead->Flink != NULL) {
  2108. MyFPrintf(hHandle, L"// Site Information\r\n");
  2109. MyFPrintf(hHandle, L"\r\n");
  2110. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  2111. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  2112. MyFPrintf(hHandle, L"SITE:%ws /MAP \r\n", pSiteEntry->ServerName);
  2113. for (i = 0; i < pSiteEntry->Info.cSites; i++) {
  2114. MyFPrintf(hHandle, L" ADD:%ws\r\n", pSiteEntry->Info.Site[i].SiteName);
  2115. }
  2116. MyFPrintf(hHandle, L"\r\n");
  2117. }
  2118. MyFPrintf(hHandle, L"\r\n");
  2119. }
  2120. return;
  2121. }