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.

3358 lines
92 KiB

  1. //--------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: ftsup.cxx
  6. //
  7. //--------------------------------------------------------------------------
  8. #define UNICODE
  9. #include <stdio.h>
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <windows.h>
  14. #include <winldap.h>
  15. #include <stdlib.h>
  16. #include <dsgetdc.h>
  17. #include <lm.h>
  18. #include <dfsstr.h>
  19. #include <dfsmrshl.h>
  20. #include <marshal.hxx>
  21. #include <lmdfs.h>
  22. #include <dfspriv.h>
  23. #include <csites.hxx>
  24. #include <dfsm.hxx>
  25. #include <recon.hxx>
  26. #include <rpc.h>
  27. #include "struct.hxx"
  28. #include "ftsup.hxx"
  29. #include "rootsup.hxx"
  30. #include "dfsacl.hxx"
  31. #include "misc.hxx"
  32. #include "fileio.hxx"
  33. #include "messages.h"
  34. DWORD
  35. CmdUnmapOneRoot(
  36. LPWSTR pwszDomDfsName,
  37. LPWSTR pwszRootName,
  38. LPWSTR pwszDcName,
  39. LPWSTR pwszDomainName,
  40. PSEC_WINNT_AUTH_IDENTITY pAuthIdent);
  41. DWORD
  42. DfsUpdateSiteReferralInfo(
  43. PDFS_VOLUME_LIST pDfsVolList,
  44. LPWSTR wszPrefixMatch,
  45. ULONG Set);
  46. DWORD
  47. DfsGetFtVol(
  48. PDFS_VOLUME_LIST pDfsVolList,
  49. LPWSTR wszFtDfsName,
  50. LPWSTR pwszDcName,
  51. LPWSTR pwszDomainName,
  52. PSEC_WINNT_AUTH_IDENTITY pAuthIdent)
  53. {
  54. DWORD dwErr = ERROR_SUCCESS;
  55. ULONG cbBlob = 0;
  56. BYTE *pBlob = NULL;
  57. WCHAR wszDcName[MAX_PATH+1];
  58. if (fSwDebug == TRUE)
  59. MyPrintf(L"DfsGetFtVol(%ws,%ws,%ws)\r\n", wszFtDfsName, pwszDcName, pwszDomainName);
  60. if (pwszDcName == NULL) {
  61. dwErr = DfspGetPdc(wszDcName, pwszDomainName);
  62. } else {
  63. wcscpy(wszDcName, pwszDcName);
  64. }
  65. if (dwErr != ERROR_SUCCESS)
  66. goto Cleanup;
  67. ErrorMessage(MSG_CONNECTING, wszDcName);
  68. //
  69. // Get blob & root list from Ds
  70. //
  71. dwErr = DfsGetDsBlob(
  72. wszFtDfsName,
  73. DfsConfigContainer,
  74. wszDcName,
  75. pAuthIdent,
  76. &cbBlob,
  77. &pBlob,
  78. &pDfsVolList->RootServers);
  79. if (dwErr != ERROR_SUCCESS)
  80. goto Cleanup;
  81. //
  82. // Unserialize it
  83. //
  84. dwErr = DfsGetVolList(
  85. cbBlob,
  86. pBlob,
  87. pDfsVolList);
  88. pDfsVolList->DfsType = DOMDFS;
  89. Cleanup:
  90. if (pBlob != NULL)
  91. free(pBlob);
  92. if (fSwDebug == TRUE)
  93. MyPrintf(L"DfsGetFtVol exit %d\r\n", dwErr);
  94. return dwErr;
  95. }
  96. //+------------------------------------------------------------------------
  97. //
  98. // Function: DfsGetDsBlob
  99. //
  100. // Synopsis: Reads a Dfs BLOB from the DS
  101. //
  102. // History: 11/19/98 JHarper Created
  103. //
  104. //-------------------------------------------------------------------------
  105. DWORD
  106. DfsGetDsBlob(
  107. LPWSTR wszFtDfsName,
  108. LPWSTR wszContainerName,
  109. LPWSTR wszDcName,
  110. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  111. ULONG *pcbBlob,
  112. BYTE **ppBlob,
  113. LPWSTR **ppRootServers)
  114. {
  115. DWORD dwErr;
  116. LDAP *pldap = NULL;
  117. PLDAPMessage pMsg = NULL;
  118. PLDAP_BERVAL *rgldapPktBlob = NULL;
  119. PLDAP_BERVAL pldapPktBlob;
  120. LDAPMessage *pmsgServers;
  121. DWORD i;
  122. WCHAR *wszConfigurationDN = NULL;
  123. WCHAR wszDfsConfigDN[MAX_PATH+1];
  124. LPWSTR rgAttrs[5];
  125. BYTE *pBlob = NULL;
  126. if (fSwDebug == TRUE)
  127. MyPrintf(L"DfsGetDsBlob(%ws,%ws, %ws)\r\n", wszFtDfsName, wszContainerName, wszDcName);
  128. dwErr = DfspLdapOpen(wszDcName, pAuthIdent, &pldap, wszContainerName, &wszConfigurationDN);
  129. if (dwErr != ERROR_SUCCESS)
  130. goto Cleanup;
  131. //
  132. // Build the entry name we want to search in
  133. //
  134. wcscpy(wszDfsConfigDN,L"CN=");
  135. wcscat(wszDfsConfigDN,wszFtDfsName);
  136. wcscat(wszDfsConfigDN,L",");
  137. wcscat(wszDfsConfigDN,wszConfigurationDN);
  138. if (fSwDebug == TRUE)
  139. MyPrintf(L"wszDfsConfigDN=[%ws]\r\n", wszDfsConfigDN);
  140. rgAttrs[0] = L"pKT";
  141. rgAttrs[1] = NULL;
  142. dwErr = ldap_search_s(
  143. pldap,
  144. wszDfsConfigDN,
  145. LDAP_SCOPE_BASE,
  146. L"(objectClass=*)",
  147. rgAttrs,
  148. 0,
  149. &pMsg);
  150. if (dwErr != LDAP_SUCCESS) {
  151. dwErr = LdapMapErrorToWin32(dwErr);
  152. goto Cleanup;
  153. }
  154. pmsgServers = ldap_first_entry(pldap, pMsg);
  155. if (pmsgServers == NULL) {
  156. dwErr = ERROR_OUTOFMEMORY;
  157. goto Cleanup;
  158. }
  159. rgldapPktBlob = ldap_get_values_len(
  160. pldap,
  161. pMsg,
  162. L"pKT");
  163. if (rgldapPktBlob == NULL || *rgldapPktBlob == NULL) {
  164. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  165. goto Cleanup;
  166. }
  167. pldapPktBlob = rgldapPktBlob[0];
  168. pBlob = (BYTE *)malloc(pldapPktBlob->bv_len + sizeof(DWORD));
  169. if (pBlob == NULL) {
  170. dwErr = ERROR_OUTOFMEMORY;
  171. goto Cleanup;
  172. }
  173. RtlZeroMemory(pBlob, pldapPktBlob->bv_len + sizeof(DWORD));
  174. MyPrintf(L"\r\n");
  175. MyPrintf(L" ------ Blob is %d bytes...\r\n", pldapPktBlob->bv_len);
  176. MyPrintf(L"\r\n");
  177. RtlCopyMemory(pBlob, pldapPktBlob->bv_val, pldapPktBlob->bv_len);
  178. *ppBlob = pBlob;
  179. *pcbBlob = pldapPktBlob->bv_len;
  180. dwErr = NetDfsRootServerEnum(
  181. pldap,
  182. wszDfsConfigDN,
  183. ppRootServers);
  184. Cleanup:
  185. if (rgldapPktBlob != NULL)
  186. ldap_value_free_len(rgldapPktBlob);
  187. if (pMsg != NULL)
  188. ldap_msgfree(pMsg);
  189. if (pldap != NULL)
  190. ldap_unbind(pldap);
  191. if (wszConfigurationDN != NULL)
  192. free(wszConfigurationDN);
  193. if (fSwDebug == TRUE)
  194. MyPrintf(L"DfsGetDsBlob returning %d\r\n", dwErr);
  195. return (dwErr);
  196. }
  197. //+------------------------------------------------------------------------
  198. //
  199. // Function: DfsPutDsBlob
  200. //
  201. // Synopsis: Updates a Dfs BLOB in the DS
  202. //
  203. // History: 12/8/98 JHarper Created
  204. //
  205. //-------------------------------------------------------------------------
  206. DWORD
  207. DfsPutDsBlob(
  208. LPWSTR wszFtDfsName,
  209. LPWSTR wszContainerName,
  210. LPWSTR wszDcName,
  211. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  212. ULONG cbBlob,
  213. BYTE *pBlob,
  214. LPWSTR *pRootServers)
  215. {
  216. DWORD dwErr;
  217. LDAP *pldap = NULL;
  218. GUID idNewPkt;
  219. LDAP_BERVAL ldapVal;
  220. PLDAP_BERVAL rgldapVals[2];
  221. LDAPModW ldapMod;
  222. LDAP_BERVAL ldapIdVal;
  223. PLDAP_BERVAL rgldapIdVals[2];
  224. LDAPModW ldapIdMod;
  225. PLDAPModW rgldapMods[4];
  226. WCHAR *wszConfigurationDN = NULL;
  227. LDAPModW ldapModServer;
  228. WCHAR wszDfsConfigDN[MAX_PATH+1];
  229. if (fSwDebug == TRUE)
  230. MyPrintf(L"DfsPutDsBlob(%ws,%ws, %ws)\r\n", wszFtDfsName, wszContainerName, wszDcName);
  231. dwErr = DfspLdapOpen(wszDcName, pAuthIdent, &pldap, wszContainerName, &wszConfigurationDN);
  232. if (dwErr != ERROR_SUCCESS)
  233. goto Cleanup;
  234. //
  235. // Build the entry name
  236. //
  237. wcscpy(wszDfsConfigDN,L"CN=");
  238. wcscat(wszDfsConfigDN,wszFtDfsName);
  239. wcscat(wszDfsConfigDN,L",");
  240. wcscat(wszDfsConfigDN,wszConfigurationDN);
  241. if (fSwDebug == TRUE)
  242. MyPrintf(L"wszDfsConfigDN=[%ws]\r\n", wszDfsConfigDN);
  243. dwErr = UuidCreate( &idNewPkt );
  244. if(dwErr != RPC_S_OK) {
  245. goto Cleanup;
  246. }
  247. ldapIdVal.bv_len = sizeof(GUID);
  248. ldapIdVal.bv_val = (PCHAR) &idNewPkt;
  249. rgldapIdVals[0] = &ldapIdVal;
  250. rgldapIdVals[1] = NULL;
  251. ldapIdMod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  252. ldapIdMod.mod_type = L"pKTGuid";
  253. ldapIdMod.mod_vals.modv_bvals = rgldapIdVals;
  254. ldapVal.bv_len = cbBlob;
  255. ldapVal.bv_val = (PCHAR) pBlob;
  256. rgldapVals[0] = &ldapVal;
  257. rgldapVals[1] = NULL;
  258. ldapMod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  259. ldapMod.mod_type = L"pKT";
  260. ldapMod.mod_vals.modv_bvals = rgldapVals;
  261. ldapModServer.mod_op = LDAP_MOD_REPLACE;
  262. ldapModServer.mod_type = L"remoteServerName";
  263. ldapModServer.mod_vals.modv_strvals = pRootServers;
  264. rgldapMods[0] = &ldapMod;
  265. rgldapMods[1] = &ldapIdMod;
  266. rgldapMods[2] = &ldapModServer;
  267. rgldapMods[3] = NULL;
  268. if (fSwDebug == TRUE)
  269. MyPrintf(L"Writing BLOB of %d bytes\r\n", cbBlob);
  270. dwErr = ldap_modify_s(
  271. pldap,
  272. wszDfsConfigDN,
  273. rgldapMods);
  274. if (fSwDebug == TRUE) {
  275. MyPrintf(L"ldap_modify_s returned %d(0x%x)\r\n", dwErr, dwErr);
  276. }
  277. ldap_unbind(pldap);
  278. pldap = NULL;
  279. if (dwErr != LDAP_SUCCESS) {
  280. dwErr = LdapMapErrorToWin32(dwErr);
  281. } else {
  282. dwErr = ERROR_SUCCESS;
  283. }
  284. Cleanup:
  285. if (pldap != NULL)
  286. ldap_unbind( pldap );
  287. if (wszConfigurationDN != NULL)
  288. free(wszConfigurationDN);
  289. if (fSwDebug == TRUE)
  290. MyPrintf(L"DfsPutDsBlob returning %d\r\n", dwErr);
  291. return (dwErr);
  292. }
  293. //+------------------------------------------------------------------------
  294. //
  295. // Function: DfsGetVolList
  296. //
  297. // Synopsis: Unserializes an FtDfs BLOB and creates
  298. // a volume list representing an FtDfs.
  299. //
  300. // History: 11/19/98 JHarper Created
  301. //
  302. //-------------------------------------------------------------------------
  303. DWORD
  304. DfsGetVolList(
  305. ULONG cbBlob,
  306. BYTE *pBlob,
  307. PDFS_VOLUME_LIST pDfsVolList)
  308. {
  309. DWORD dwErr;
  310. DWORD cObj;
  311. DWORD cVol;
  312. LDAP_PKT LdapPkt;
  313. MARSHAL_BUFFER marshalBuffer;
  314. NTSTATUS NtStatus;
  315. if (fSwDebug == TRUE)
  316. MyPrintf(L"DfsGetVolList()\r\n");
  317. RtlZeroMemory(&LdapPkt, sizeof(LDAP_PKT));
  318. if (cbBlob > sizeof(DWORD)) {
  319. _GetULong(pBlob, pDfsVolList->Version);
  320. if (fSwDebug == TRUE) {
  321. MyPrintf(L"Blob Version = %d\r\n", pDfsVolList->Version);
  322. MyPrintf(L"BLOB is %d bytes:\r\n", cbBlob);
  323. }
  324. MarshalBufferInitialize(
  325. &marshalBuffer,
  326. cbBlob - sizeof(DWORD),
  327. pBlob + sizeof(DWORD));
  328. NtStatus = DfsRtlGet(&marshalBuffer, &MiLdapPkt, &LdapPkt);
  329. if (!NT_SUCCESS(NtStatus)) {
  330. dwErr = RtlNtStatusToDosError(NtStatus);
  331. goto Cleanup;
  332. }
  333. if (fSwDebug == TRUE) {
  334. MyPrintf(L" %d objects found\r\n", LdapPkt.cLdapObjects);
  335. for (cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  336. MyPrintf(L"%d:name=%ws size=%d p=0x%p\r\n",
  337. cObj,
  338. LdapPkt.rgldapObjects[cObj].wszObjectName,
  339. LdapPkt.rgldapObjects[cObj].cbObjectData,
  340. LdapPkt.rgldapObjects[cObj].pObjectData);
  341. // DumpBuf(
  342. // LdapPkt.rgldapObjects[cObj].pObjectData,
  343. // LdapPkt.rgldapObjects[cObj].cbObjectData);
  344. }
  345. }
  346. for (cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  347. if (wcscmp(LdapPkt.rgldapObjects[cObj].wszObjectName, L"\\siteroot") != 0) {
  348. pDfsVolList->VolCount++;
  349. }
  350. }
  351. pDfsVolList->Volumes = (PDFS_VOLUME *) malloc(pDfsVolList->VolCount * sizeof(PDFS_VOLUME));
  352. if (pDfsVolList->Volumes == NULL) {
  353. dwErr = ERROR_OUTOFMEMORY;
  354. goto Cleanup;
  355. }
  356. RtlZeroMemory(pDfsVolList->Volumes, pDfsVolList->VolCount * sizeof(PDFS_VOLUME));
  357. //
  358. // Save the true/allocated size so to optimize deletions/additions
  359. //
  360. pDfsVolList->AllocatedVolCount = pDfsVolList->VolCount;
  361. if (fSwDebug == TRUE)
  362. MyPrintf(L"===============================\r\n");
  363. for (cVol = cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  364. if (wcscmp(LdapPkt.rgldapObjects[cObj].wszObjectName, L"\\siteroot") == 0) {
  365. dwErr = DfsGetSiteTable(
  366. pDfsVolList,
  367. &LdapPkt.rgldapObjects[cObj]);
  368. } else {
  369. pDfsVolList->Volumes[cVol] = (PDFS_VOLUME) malloc(sizeof(DFS_VOLUME));
  370. if (pDfsVolList->Volumes[cVol] == NULL) {
  371. dwErr = ERROR_OUTOFMEMORY;
  372. goto Cleanup;
  373. }
  374. RtlZeroMemory(pDfsVolList->Volumes[cVol], sizeof(DFS_VOLUME));
  375. dwErr = DfsGetVolume(
  376. pDfsVolList->Volumes[cVol],
  377. &LdapPkt.rgldapObjects[cObj]);
  378. }
  379. if (dwErr != ERROR_SUCCESS)
  380. goto Cleanup;
  381. cVol++;
  382. }
  383. } else if (cbBlob == sizeof(DWORD)) {
  384. if (fSwDebug == TRUE)
  385. MyPrintf(L"pKT BLOB is simply one DWORD\r\n");
  386. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  387. } else {
  388. if (fSwDebug == TRUE)
  389. MyPrintf(L"pKT BLOB is corrupt!\r\n");
  390. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  391. }
  392. Cleanup:
  393. FreeLdapPkt(&LdapPkt);
  394. //
  395. // Do any recovery needed
  396. //
  397. // 447511, do this only if volumes is not null
  398. if (pDfsVolList->Volumes != NULL) {
  399. dwErr = DfsRecoverVolList(pDfsVolList);
  400. }
  401. if (fSwDebug == TRUE)
  402. MyPrintf(L"DfsGetVolList returning %d\r\n", dwErr);
  403. return( dwErr );
  404. }
  405. //+------------------------------------------------------------------------
  406. //
  407. // Function: DfsGetVolume
  408. //
  409. // Synopsis: Unserializes the data in a buffer/blob to a volume
  410. //
  411. // History: 11/19/98 JHarper Created
  412. //
  413. //-------------------------------------------------------------------------
  414. DWORD
  415. DfsGetVolume(
  416. PDFS_VOLUME pVolume,
  417. PLDAP_OBJECT pLdapObject)
  418. {
  419. DFS_VOLUME_PROPERTIES VolProps;
  420. DWORD dwErr = ERROR_SUCCESS;
  421. MARSHAL_BUFFER marshalBuffer;
  422. NTSTATUS NtStatus;
  423. PBYTE pBuffer = NULL;
  424. if (fSwDebug == TRUE)
  425. MyPrintf(L"DfsGetVolume(%ws,%d)\r\n",
  426. pLdapObject->wszObjectName,
  427. pLdapObject->cbObjectData);
  428. RtlZeroMemory(&VolProps, sizeof(DFS_VOLUME_PROPERTIES));
  429. pVolume->wszObjectName = (WCHAR *) malloc(
  430. (wcslen(pLdapObject->wszObjectName)+1) * sizeof(WCHAR));
  431. if (pVolume->wszObjectName == NULL) {
  432. dwErr = ERROR_OUTOFMEMORY;
  433. goto Cleanup;
  434. }
  435. wcscpy(
  436. pVolume->wszObjectName,
  437. pLdapObject->wszObjectName);
  438. MarshalBufferInitialize(
  439. &marshalBuffer,
  440. pLdapObject->cbObjectData,
  441. pLdapObject->pObjectData);
  442. NtStatus = DfsRtlGet(
  443. &marshalBuffer,
  444. &MiVolumeProperties,
  445. &VolProps);
  446. if (!NT_SUCCESS(NtStatus)) {
  447. dwErr = RtlNtStatusToDosError(NtStatus);
  448. goto Cleanup;
  449. }
  450. VolProps.dwTimeout = 300;
  451. if (
  452. (marshalBuffer.Current < marshalBuffer.Last)
  453. &&
  454. (marshalBuffer.Last - marshalBuffer.Current) == sizeof(ULONG)
  455. ) {
  456. DfsRtlGetUlong(&marshalBuffer, &VolProps.dwTimeout);
  457. }
  458. pVolume->idVolume = VolProps.idVolume;
  459. pVolume->wszPrefix = VolProps.wszPrefix;
  460. pVolume->wszShortPrefix = VolProps.wszShortPrefix;
  461. pVolume->dwType = VolProps.dwType;
  462. pVolume->dwState = VolProps.dwState;
  463. pVolume->wszComment = VolProps.wszComment;
  464. pVolume->dwTimeout = VolProps.dwTimeout;
  465. pVolume->ftPrefix = VolProps.ftPrefix;
  466. pVolume->ftState = VolProps.ftState;
  467. pVolume->ftComment = VolProps.ftComment;
  468. pVolume->dwVersion = VolProps.dwVersion;
  469. pVolume->cbRecovery = VolProps.cbRecovery;
  470. pVolume->pRecovery = VolProps.pRecovery;
  471. pBuffer = VolProps.pSvc;
  472. if (fSwDebug == TRUE)
  473. MyPrintf(L"VolProps.cbSvc = %d\r\n", VolProps.cbSvc);
  474. dwErr = UnSerializeReplicaList(
  475. &pVolume->ReplCount,
  476. &pVolume->AllocatedReplCount,
  477. &pVolume->ReplicaInfo,
  478. &pVolume->FtModification,
  479. &pBuffer);
  480. if (dwErr != ERROR_SUCCESS)
  481. goto Cleanup;
  482. //
  483. // Get deleted replicas
  484. //
  485. if (pBuffer < (pBuffer + VolProps.cbSvc)) {
  486. dwErr = UnSerializeReplicaList(
  487. &pVolume->DelReplCount,
  488. &pVolume->AllocatedDelReplCount,
  489. &pVolume->DelReplicaInfo,
  490. &pVolume->DelFtModification,
  491. &pBuffer);
  492. }
  493. Cleanup:
  494. if (VolProps.pSvc != NULL)
  495. MarshalBufferFree(VolProps.pSvc);
  496. if (fSwDebug == TRUE)
  497. MyPrintf(L"DfsGetVolume returning %d\r\n", dwErr);
  498. return dwErr;
  499. }
  500. //+------------------------------------------------------------------------
  501. //
  502. // Function: DfsFreeVolList
  503. //
  504. // Synopsis: Frees the volume list and associated substructures representing
  505. // an FtDfs.
  506. //
  507. // History: 11/19/98 JHarper Created
  508. //
  509. //-------------------------------------------------------------------------
  510. VOID
  511. DfsFreeVolList(
  512. PDFS_VOLUME_LIST pDfsVolList)
  513. {
  514. ULONG cVol;
  515. ULONG cSite;
  516. ULONG i;
  517. PLIST_ENTRY pListHead;
  518. PDFSM_SITE_ENTRY pSiteEntry;
  519. if (pDfsVolList->VolCount > 0 && pDfsVolList->Volumes) {
  520. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  521. DfsFreeVol(pDfsVolList->Volumes[cVol]);
  522. free(pDfsVolList->Volumes[cVol]);
  523. pDfsVolList->Volumes[cVol] = NULL;
  524. }
  525. pDfsVolList->VolCount = 0;
  526. }
  527. if (pDfsVolList->Volumes != NULL) {
  528. free(pDfsVolList->Volumes);
  529. pDfsVolList->Volumes = NULL;
  530. }
  531. if (pDfsVolList->RootServers != NULL) {
  532. free(pDfsVolList->RootServers);
  533. pDfsVolList->RootServers = NULL;
  534. }
  535. pListHead = &pDfsVolList->SiteList;
  536. if (pListHead->Flink != NULL) {
  537. while (pListHead->Flink != pListHead) {
  538. pSiteEntry = CONTAINING_RECORD(pListHead->Flink, DFSM_SITE_ENTRY, Link);
  539. RemoveEntryList(pListHead->Flink);
  540. for (i = 0; i < pSiteEntry->Info.cSites; i++) {
  541. if (pSiteEntry->Info.Site[i].SiteName != NULL)
  542. MarshalBufferFree(pSiteEntry->Info.Site[i].SiteName);
  543. }
  544. if (pSiteEntry->ServerName != NULL)
  545. MarshalBufferFree(pSiteEntry->ServerName);
  546. free(pSiteEntry);
  547. }
  548. }
  549. }
  550. VOID
  551. DfsFreeRootLocalVol(
  552. PDFS_ROOTLOCALVOL pRootLocalVol,
  553. ULONG cRootLocalVol)
  554. {
  555. ULONG cRoot;
  556. ULONG cVol;
  557. if (pRootLocalVol == NULL)
  558. return;
  559. for (cRoot = 0; cRoot < cRootLocalVol; cRoot++) {
  560. if (pRootLocalVol[cRoot].wszObjectName != NULL)
  561. delete [] pRootLocalVol[cRoot].wszObjectName;
  562. if (pRootLocalVol[cRoot].wszEntryPath)
  563. delete [] pRootLocalVol[cRoot].wszEntryPath;
  564. if (pRootLocalVol[cRoot].wszShortEntryPath)
  565. delete [] pRootLocalVol[cRoot].wszShortEntryPath;
  566. if (pRootLocalVol[cRoot].wszShareName)
  567. delete [] pRootLocalVol[cRoot].wszShareName;
  568. if (pRootLocalVol[cRoot].wszStorageId)
  569. delete [] pRootLocalVol[cRoot].wszStorageId;
  570. for (cVol = 0; cVol < pRootLocalVol[cRoot].cLocalVolCount; cVol++) {
  571. if (pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszObjectName != NULL)
  572. delete [] pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszObjectName;
  573. if (pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszEntryPath != NULL)
  574. delete pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszEntryPath;
  575. }
  576. if (pRootLocalVol[cRoot].pDfsLocalVol)
  577. delete [] pRootLocalVol[cRoot].pDfsLocalVol;
  578. }
  579. delete [] pRootLocalVol;
  580. }
  581. //+------------------------------------------------------------------------
  582. //
  583. // Function: DfsFreeVol
  584. //
  585. // Synopsis: Frees the volume and associated substructures representing
  586. // an FtDfs volume
  587. //
  588. // History: 12/16/98 JHarper Created
  589. //
  590. //-------------------------------------------------------------------------
  591. VOID
  592. DfsFreeVol(
  593. PDFS_VOLUME pVol)
  594. {
  595. ULONG cRepl;
  596. if (pVol->ReplCount > 0 && pVol->ReplicaInfo != NULL) {
  597. for (cRepl = 0; cRepl < pVol->ReplCount; cRepl++) {
  598. DfsFreeRepl(&pVol->ReplicaInfo[cRepl]);
  599. }
  600. }
  601. if (pVol->DelReplCount > 0 && pVol->DelReplicaInfo != NULL) {
  602. for (cRepl = 0; cRepl < pVol->DelReplCount; cRepl++) {
  603. DfsFreeRepl(&pVol->DelReplicaInfo[cRepl]);
  604. }
  605. }
  606. if (pVol->wszPrefix != NULL)
  607. MarshalBufferFree(pVol->wszPrefix);
  608. if (pVol->wszShortPrefix != NULL)
  609. MarshalBufferFree(pVol->wszShortPrefix);
  610. if (pVol->wszComment != NULL)
  611. MarshalBufferFree(pVol->wszComment);
  612. if (pVol->pRecovery != NULL)
  613. MarshalBufferFree(pVol->pRecovery);
  614. if (pVol->ReplicaInfo != NULL)
  615. free(pVol->ReplicaInfo);
  616. if (pVol->DelReplicaInfo != NULL)
  617. free(pVol->DelReplicaInfo);
  618. if (pVol->FtModification != NULL)
  619. free(pVol->FtModification);
  620. if (pVol->DelFtModification != NULL)
  621. free(pVol->DelFtModification);
  622. if (pVol->wszObjectName != NULL)
  623. free(pVol->wszObjectName);
  624. RtlZeroMemory(pVol, sizeof(DFS_VOLUME));
  625. }
  626. //+------------------------------------------------------------------------
  627. //
  628. // Function: DfsFreeRepl
  629. //
  630. // Synopsis: Frees the Replica and associated substructures representing
  631. // an FtDfs replica
  632. //
  633. // History: 12/16/98 JHarper Created
  634. //
  635. //-------------------------------------------------------------------------
  636. VOID
  637. DfsFreeRepl(
  638. PDFS_REPLICA_INFO pRepl)
  639. {
  640. if (pRepl->pwszServerName != NULL)
  641. MarshalBufferFree(pRepl->pwszServerName);
  642. if (pRepl->pwszShareName != NULL)
  643. MarshalBufferFree(pRepl->pwszShareName);
  644. RtlZeroMemory(pRepl, sizeof(DFS_REPLICA_INFO));
  645. }
  646. //+------------------------------------------------------------------------
  647. //
  648. // Function: DfsPutVolList
  649. //
  650. // Synopsis: Serializes the structs representing a Dfs volume and
  651. // creates a BLOB.
  652. //
  653. // History: 11/19/98 JHarper Created
  654. //
  655. //-------------------------------------------------------------------------
  656. DWORD
  657. DfsPutVolList(
  658. ULONG *pcbBlob,
  659. BYTE **ppBlob,
  660. PDFS_VOLUME_LIST pDfsVolList)
  661. {
  662. ULONG cVol;
  663. ULONG cRepl;
  664. ULONG cObj;
  665. ULONG cBuffer = 0;
  666. ULONG dwRecovery = 0;
  667. ULONG cSite;
  668. DWORD dwErr = ERROR_SUCCESS;
  669. PBYTE Buffer;
  670. MARSHAL_BUFFER marshalBuffer;
  671. NTSTATUS NtStatus;
  672. DFS_VOLUME_PROPERTIES VolProps;
  673. LDAP_PKT LdapPkt;
  674. PLIST_ENTRY pListHead;
  675. PLIST_ENTRY pLink;
  676. PDFSM_SITE_ENTRY pSiteEntry;
  677. if (fSwDebug == TRUE)
  678. MyPrintf(L"DfsPutVolList()\r\n");
  679. LdapPkt.cLdapObjects = pDfsVolList->VolCount + 1;
  680. LdapPkt.rgldapObjects = (PLDAP_OBJECT) malloc(LdapPkt.cLdapObjects * sizeof(LDAP_OBJECT));
  681. if (LdapPkt.rgldapObjects == NULL) {
  682. dwErr = ERROR_OUTOFMEMORY;
  683. goto Cleanup;
  684. }
  685. RtlZeroMemory(LdapPkt.rgldapObjects, LdapPkt.cLdapObjects * sizeof(LDAP_OBJECT));
  686. //
  687. // For each volume, serialize the replicas, then the volume
  688. //
  689. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  690. RtlZeroMemory(&VolProps, sizeof(DFS_VOLUME_PROPERTIES));
  691. LdapPkt.rgldapObjects[cVol].wszObjectName = (WCHAR *) MarshalBufferAllocate(
  692. (wcslen(pDfsVolList->Volumes[cVol]->wszObjectName)+1) * sizeof(WCHAR));
  693. if (LdapPkt.rgldapObjects[cVol].wszObjectName == NULL) {
  694. dwErr = ERROR_OUTOFMEMORY;
  695. goto Cleanup;
  696. }
  697. wcscpy(
  698. LdapPkt.rgldapObjects[cVol].wszObjectName,
  699. pDfsVolList->Volumes[cVol]->wszObjectName);
  700. //
  701. // Serialize the replicas
  702. //
  703. dwErr = SerializeReplicaList(
  704. pDfsVolList->Volumes[cVol]->ReplCount,
  705. pDfsVolList->Volumes[cVol]->ReplicaInfo,
  706. pDfsVolList->Volumes[cVol]->FtModification,
  707. pDfsVolList->Volumes[cVol]->DelReplCount,
  708. pDfsVolList->Volumes[cVol]->DelReplicaInfo,
  709. pDfsVolList->Volumes[cVol]->DelFtModification,
  710. &VolProps.cbSvc,
  711. &VolProps.pSvc);
  712. if (dwErr != ERROR_SUCCESS) {
  713. dwErr = ERROR_OUTOFMEMORY;
  714. goto Cleanup;
  715. }
  716. if (fSwDebug == TRUE)
  717. MyPrintf(L" cbSvc = %d\r\n", VolProps.cbSvc);
  718. VolProps.idVolume = pDfsVolList->Volumes[cVol]->idVolume;
  719. VolProps.wszPrefix = pDfsVolList->Volumes[cVol]->wszPrefix;
  720. VolProps.wszShortPrefix = pDfsVolList->Volumes[cVol]->wszShortPrefix;
  721. VolProps.dwType = pDfsVolList->Volumes[cVol]->dwType;
  722. VolProps.dwState = pDfsVolList->Volumes[cVol]->dwState;
  723. VolProps.wszComment = pDfsVolList->Volumes[cVol]->wszComment;
  724. VolProps.dwTimeout = pDfsVolList->Volumes[cVol]->dwTimeout;
  725. VolProps.ftPrefix = pDfsVolList->Volumes[cVol]->ftPrefix;
  726. VolProps.ftState = pDfsVolList->Volumes[cVol]->ftState;
  727. VolProps.ftComment = pDfsVolList->Volumes[cVol]->ftComment;
  728. VolProps.dwVersion = pDfsVolList->Volumes[cVol]->dwVersion;
  729. if (pDfsVolList->Volumes[cVol]->cbRecovery != 0) {
  730. VolProps.cbRecovery = pDfsVolList->Volumes[cVol]->cbRecovery;
  731. VolProps.pRecovery = pDfsVolList->Volumes[cVol]->pRecovery;
  732. } else {
  733. VolProps.pRecovery = (PBYTE) MarshalBufferAllocate(sizeof(DWORD));
  734. if (VolProps.pRecovery != NULL) {
  735. RtlZeroMemory(VolProps.pRecovery, sizeof(DWORD));
  736. VolProps.cbRecovery = sizeof(DWORD);
  737. } else {
  738. VolProps.cbRecovery = 0;
  739. VolProps.pRecovery = NULL;
  740. }
  741. }
  742. //
  743. // Now serialize the volume
  744. cBuffer = 0;
  745. NtStatus = DfsRtlSize(&MiVolumeProperties, &VolProps, &cBuffer);
  746. if (!NT_SUCCESS(NtStatus)) {
  747. MarshalBufferFree(VolProps.pSvc);
  748. dwErr = RtlNtStatusToDosError(NtStatus);
  749. goto Cleanup;
  750. }
  751. cBuffer += sizeof(ULONG);
  752. if (fSwDebug == TRUE)
  753. MyPrintf(L"VolProps marshaled size = %d\r\n", cBuffer);
  754. Buffer = (PBYTE) MarshalBufferAllocate(cBuffer);
  755. if (Buffer == NULL) {
  756. MarshalBufferFree(VolProps.pSvc);
  757. dwErr = ERROR_OUTOFMEMORY;
  758. goto Cleanup;
  759. }
  760. LdapPkt.rgldapObjects[cVol].pObjectData = (PCHAR) Buffer;
  761. LdapPkt.rgldapObjects[cVol].cbObjectData = cBuffer;
  762. MarshalBufferInitialize(
  763. &marshalBuffer,
  764. cBuffer,
  765. Buffer);
  766. NtStatus = DfsRtlPut(&marshalBuffer, &MiVolumeProperties, &VolProps);
  767. if (!NT_SUCCESS(NtStatus)) {
  768. MarshalBufferFree(VolProps.pSvc);
  769. dwErr = RtlNtStatusToDosError(NtStatus);
  770. goto Cleanup;
  771. }
  772. NtStatus = DfsRtlPutUlong(&marshalBuffer, &VolProps.dwTimeout);
  773. if (!NT_SUCCESS(NtStatus)) {
  774. MarshalBufferFree(VolProps.pSvc);
  775. dwErr = RtlNtStatusToDosError(NtStatus);
  776. goto Cleanup;
  777. }
  778. MarshalBufferFree(VolProps.pSvc);
  779. }
  780. //
  781. // Serialize the site table
  782. //
  783. cBuffer = sizeof(ULONG) + sizeof(GUID);
  784. //
  785. // Add the size of all the entries
  786. //
  787. pListHead = &pDfsVolList->SiteList;
  788. if (pListHead->Flink != NULL) {
  789. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  790. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  791. if (fSwDebug == TRUE)
  792. MyPrintf(L"pSiteEntry for %ws\r\n", pSiteEntry->ServerName);
  793. NtStatus = DfsRtlSize(&MiDfsmSiteEntry, pSiteEntry, &cBuffer);
  794. if (!NT_SUCCESS(NtStatus)) {
  795. dwErr = RtlNtStatusToDosError(NtStatus);
  796. goto Cleanup;
  797. }
  798. }
  799. }
  800. //
  801. // Get a buffer big enough
  802. //
  803. Buffer = (BYTE *) MarshalBufferAllocate(cBuffer);
  804. if (Buffer == NULL) {
  805. dwErr = ERROR_OUTOFMEMORY;
  806. goto Cleanup;
  807. }
  808. LdapPkt.rgldapObjects[pDfsVolList->VolCount].wszObjectName =
  809. (WCHAR *)MarshalBufferAllocate(sizeof(L"\\siteroot"));
  810. if (LdapPkt.rgldapObjects[pDfsVolList->VolCount].wszObjectName == NULL) {
  811. dwErr = ERROR_OUTOFMEMORY;
  812. goto Cleanup;
  813. }
  814. wcscpy(LdapPkt.rgldapObjects[pDfsVolList->VolCount].wszObjectName, L"\\siteroot");
  815. LdapPkt.rgldapObjects[pDfsVolList->VolCount].pObjectData = (PCHAR) Buffer;
  816. LdapPkt.rgldapObjects[pDfsVolList->VolCount].cbObjectData = cBuffer;
  817. MarshalBufferInitialize(
  818. &marshalBuffer,
  819. cBuffer,
  820. Buffer);
  821. //
  822. // Put the guid, then the object count in the beginning of the buffer
  823. //
  824. DfsRtlPutGuid(&marshalBuffer, &pDfsVolList->SiteGuid);
  825. DfsRtlPutUlong(&marshalBuffer, &pDfsVolList->SiteCount);
  826. if (pListHead->Flink != NULL) {
  827. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  828. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  829. DfsRtlPut(&marshalBuffer,&MiDfsmSiteEntry, pSiteEntry);
  830. if (!NT_SUCCESS(NtStatus)) {
  831. dwErr = RtlNtStatusToDosError(NtStatus);
  832. goto Cleanup;
  833. }
  834. }
  835. }
  836. if (fSwDebug == TRUE) {
  837. MyPrintf(L"After reserialization, %d objects found\r\n", LdapPkt.cLdapObjects);
  838. for (cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  839. MyPrintf(L"%d:name=%ws size=%d p=0x%p\r\n",
  840. cObj,
  841. LdapPkt.rgldapObjects[cObj].wszObjectName,
  842. LdapPkt.rgldapObjects[cObj].cbObjectData,
  843. LdapPkt.rgldapObjects[cObj].pObjectData);
  844. // DumpBuf(
  845. // LdapPkt.rgldapObjects[cObj].pObjectData,
  846. // LdapPkt.rgldapObjects[cObj].cbObjectData);
  847. }
  848. }
  849. //
  850. // Finally, serialize all the volumes and the site table into a blob
  851. //
  852. cBuffer = 0;
  853. NtStatus = DfsRtlSize(&MiLdapPkt, &LdapPkt, &cBuffer);
  854. if (!NT_SUCCESS(NtStatus)) {
  855. dwErr = RtlNtStatusToDosError(dwErr);
  856. goto Cleanup;
  857. }
  858. cBuffer += sizeof(DWORD);
  859. if (fSwDebug == TRUE)
  860. MyPrintf(L"New ldap size = %d\r\n", cBuffer);
  861. Buffer = (PBYTE) malloc(cBuffer);
  862. if (Buffer == NULL) {
  863. dwErr = ERROR_OUTOFMEMORY;
  864. goto Cleanup;
  865. }
  866. *((PDWORD) Buffer) = 2; // Version #
  867. MarshalBufferInitialize(
  868. &marshalBuffer,
  869. cBuffer,
  870. Buffer + sizeof(DWORD));
  871. NtStatus = DfsRtlPut(&marshalBuffer, &MiLdapPkt, &LdapPkt);
  872. if (!NT_SUCCESS(NtStatus)) {
  873. dwErr = RtlNtStatusToDosError(dwErr);
  874. goto Cleanup;
  875. }
  876. if (fSwDebug == TRUE)
  877. MyPrintf(L"Remarshal succeeded cBuffer = %d\r\n", cBuffer);
  878. *pcbBlob = cBuffer;
  879. *ppBlob = Buffer;
  880. Buffer = NULL;
  881. Cleanup:
  882. FreeLdapPkt(&LdapPkt);
  883. if (dwErr != ERROR_SUCCESS && Buffer != NULL)
  884. free(Buffer);
  885. if (fSwDebug == TRUE)
  886. MyPrintf(L"DfsPutVolList exit %d\r\n", dwErr);
  887. return dwErr;
  888. }
  889. //+------------------------------------------------------------------------
  890. //
  891. // Function: FreeLdapPkt
  892. //
  893. // Synopsis: Frees an LDAP_PKT structure and all substructures.
  894. //
  895. // History: 11/19/98 JHarper Created
  896. //
  897. //-------------------------------------------------------------------------
  898. VOID
  899. FreeLdapPkt(
  900. LDAP_PKT *pLdapPkt)
  901. {
  902. ULONG cObj;
  903. if (pLdapPkt->rgldapObjects != NULL) {
  904. for (cObj = 0; cObj < pLdapPkt->cLdapObjects; cObj++) {
  905. if (pLdapPkt->rgldapObjects[cObj].wszObjectName != NULL)
  906. MarshalBufferFree(pLdapPkt->rgldapObjects[cObj].wszObjectName);
  907. if (pLdapPkt->rgldapObjects[cObj].pObjectData != NULL)
  908. MarshalBufferFree(pLdapPkt->rgldapObjects[cObj].pObjectData);
  909. }
  910. MarshalBufferFree(pLdapPkt->rgldapObjects);
  911. }
  912. }
  913. //+------------------------------------------------------------------------
  914. //
  915. // Function: SerializeReplicaList
  916. //
  917. // Synopsis: This method serializes the replica info list and the
  918. // deleted replica info list into a buffer.
  919. //
  920. // Returns: [ERROR_SUCCESS] -- If all went well.
  921. //
  922. // [ERROR_OUTOFMEMORY] - If unable to allocate the target buffer.
  923. //
  924. // History: 11/19/98 JHarper Created
  925. //
  926. //-------------------------------------------------------------------------
  927. DWORD
  928. SerializeReplicaList(
  929. ULONG ReplCount,
  930. DFS_REPLICA_INFO *pReplicaInfo,
  931. FILETIME *pFtModification,
  932. ULONG DelReplCount,
  933. DFS_REPLICA_INFO *pDelReplicaInfo,
  934. FILETIME *pDelFtModification,
  935. ULONG *cBuffer,
  936. PBYTE *ppBuffer)
  937. {
  938. DWORD dwErr = ERROR_SUCCESS;
  939. ULONG TotalSize;
  940. ULONG i;
  941. ULONG *pSize;
  942. BYTE *Buffer = NULL;
  943. ULONG *SizeBuffer = NULL;
  944. if (fSwDebug == TRUE)
  945. MyPrintf(L"SerializeReplicaList(%d,%d)\r\n", ReplCount, DelReplCount);
  946. pSize = SizeBuffer = (PULONG) malloc(sizeof(ULONG) * (ReplCount + DelReplCount));
  947. if (SizeBuffer == NULL) {
  948. return ERROR_OUTOFMEMORY;
  949. }
  950. //
  951. // Need all the size values now and later for marshalling stuff.
  952. // So we collect them here into an array.
  953. //
  954. TotalSize = 0;
  955. pSize = SizeBuffer;
  956. for (i = 0; i < ReplCount; i++) {
  957. *pSize = GetReplicaMarshalSize(&pReplicaInfo[i], &pFtModification[i]);
  958. TotalSize += *pSize;
  959. pSize++;
  960. }
  961. for (i = 0; i < DelReplCount; i++) {
  962. *pSize = GetReplicaMarshalSize(&pDelReplicaInfo[i], &pDelFtModification[i]);
  963. TotalSize += *pSize;
  964. pSize++;
  965. }
  966. //
  967. // Allocate the byte Buffer we need to pass back
  968. //
  969. // TotalSize is the size required just to marshal all the replicas and
  970. // their last-modification-timestamps.
  971. //
  972. // In addition, we need:
  973. //
  974. // 1 ULONG for storing the count of replicas
  975. // ReplCount ULONGs for storing the marshal size of each replica.
  976. // 1 ULONG for count of deleted replicas
  977. // DelReplCount ULONGS for storing the marshal size of each deleted Repl
  978. //
  979. //
  980. // First calc the size of the Buffer.
  981. //
  982. TotalSize += sizeof(ULONG) * (1 + ReplCount + 1 + DelReplCount);
  983. *ppBuffer = Buffer = (PBYTE) malloc(TotalSize);
  984. if (Buffer == NULL) {
  985. free(SizeBuffer);
  986. return ERROR_OUTOFMEMORY;
  987. }
  988. //
  989. // Set the number of entries to follow in the Buffer at the start.
  990. //
  991. _PutULong(Buffer, ReplCount);
  992. Buffer += sizeof(ULONG);
  993. pSize = SizeBuffer;
  994. for (i = 0; i < ReplCount; i++) {
  995. //
  996. // Marshall each replica Entry into the Buffer.
  997. // Remember we first need to put the size of the marshalled
  998. // replica entry to follow, then the FILETIME for the replica,
  999. // and finally, the marshalled replica entry structure.
  1000. //
  1001. _PutULong(Buffer, *pSize);
  1002. Buffer += sizeof(ULONG);
  1003. dwErr = SerializeReplica(
  1004. &pReplicaInfo[i],
  1005. pFtModification ? &pFtModification[i] : NULL,
  1006. Buffer,
  1007. *pSize);
  1008. if (dwErr != ERROR_SUCCESS) {
  1009. free(*ppBuffer);
  1010. return dwErr;
  1011. }
  1012. Buffer += *pSize;
  1013. pSize++;
  1014. }
  1015. //
  1016. // Now marshal the deleted Repl list.
  1017. //
  1018. _PutULong(Buffer, DelReplCount);
  1019. Buffer += sizeof(ULONG);
  1020. for (i = 0; i < DelReplCount; i++) {
  1021. _PutULong(Buffer, *pSize);
  1022. Buffer += sizeof(ULONG);
  1023. dwErr = SerializeReplica(
  1024. &pDelReplicaInfo[i],
  1025. pDelFtModification ? &pDelFtModification[i] : NULL,
  1026. Buffer,
  1027. *pSize);
  1028. if (dwErr != ERROR_SUCCESS) {
  1029. free(*ppBuffer);
  1030. return dwErr;
  1031. }
  1032. Buffer += *pSize;
  1033. pSize++;
  1034. }
  1035. *cBuffer = TotalSize;
  1036. if (fSwDebug == TRUE)
  1037. MyPrintf(L"SerializeReplicaList exit %d\r\n", dwErr);
  1038. return( dwErr );
  1039. }
  1040. //+------------------------------------------------------------------------
  1041. //
  1042. // Member: SerializeReplica
  1043. //
  1044. // Synopsis: Serializes a replica info structure
  1045. //
  1046. // Notes: The size of the buffer should have been calculated using
  1047. // the function GetReplicaMarshalSize()
  1048. //
  1049. // History: 13-May-93 SudK Created.
  1050. // 19-Nov-98 Jharper Modified.
  1051. //
  1052. //-------------------------------------------------------------------------
  1053. DWORD
  1054. SerializeReplica(
  1055. DFS_REPLICA_INFO *pDfsReplicaInfo,
  1056. FILETIME *pFtModification,
  1057. PBYTE Buffer,
  1058. ULONG Size)
  1059. {
  1060. DWORD dwErr;
  1061. MARSHAL_BUFFER MarshalBuffer;
  1062. NTSTATUS NtStatus;
  1063. SYSTEMTIME st;
  1064. FILETIME FtModification;
  1065. if (pFtModification == NULL) {
  1066. GetSystemTime( &st );
  1067. SystemTimeToFileTime( &st, &FtModification );
  1068. pFtModification = &FtModification;
  1069. }
  1070. MarshalBufferInitialize(&MarshalBuffer, Size, Buffer);
  1071. NtStatus = DfsRtlPut(&MarshalBuffer, &MiFileTime, pFtModification);
  1072. if (NT_SUCCESS(NtStatus))
  1073. NtStatus = DfsRtlPut(&MarshalBuffer, &MiDfsReplicaInfo, pDfsReplicaInfo);
  1074. dwErr = RtlNtStatusToDosError(NtStatus);
  1075. return dwErr;
  1076. }
  1077. //+----------------------------------------------------------------------
  1078. //
  1079. // Member: GetReplicaMarshalSize, public
  1080. //
  1081. // Synopsis: Returns the size of a buffer required to marshal this
  1082. // replica.
  1083. //
  1084. // History: 12-May-93 SudK Created.
  1085. // 19-Nov-98 Jharper Modified.
  1086. //
  1087. //-----------------------------------------------------------------------
  1088. ULONG
  1089. GetReplicaMarshalSize(
  1090. DFS_REPLICA_INFO *pDfsReplicaInfo,
  1091. FILETIME *pFtModification)
  1092. {
  1093. ULONG Size = 0;
  1094. NTSTATUS NtStatus;
  1095. SYSTEMTIME st;
  1096. FILETIME FtModification;
  1097. if (pFtModification == NULL) {
  1098. GetSystemTime( &st );
  1099. SystemTimeToFileTime( &st, &FtModification );
  1100. pFtModification = &FtModification;
  1101. }
  1102. NtStatus = DfsRtlSize(&MiFileTime, pFtModification, &Size);
  1103. if (NT_SUCCESS(NtStatus))
  1104. NtStatus = DfsRtlSize(&MiDfsReplicaInfo, pDfsReplicaInfo, &Size);
  1105. return(Size);
  1106. }
  1107. //+------------------------------------------------------------------------
  1108. //
  1109. // Member: UnSerializeReplicaList
  1110. //
  1111. // Synopsis: Unserializes a buffer into a relica list.
  1112. //
  1113. // History: 20-Nov-98 Jharper created
  1114. //
  1115. //-------------------------------------------------------------------------
  1116. DWORD
  1117. UnSerializeReplicaList(
  1118. ULONG *pReplCount,
  1119. ULONG *pAllocatedReplCount,
  1120. DFS_REPLICA_INFO **ppReplicaInfo,
  1121. FILETIME **ppFtModification,
  1122. BYTE **ppBuffer)
  1123. {
  1124. DFS_REPLICA_INFO *pReplicaInfo = NULL;
  1125. FILETIME *pFtModification = NULL;
  1126. ULONG ReplCount;
  1127. BYTE *pBuffer = *ppBuffer;
  1128. ULONG cRepl;
  1129. ULONG Size;
  1130. DWORD dwErr = ERROR_SUCCESS;
  1131. MARSHAL_BUFFER marshalBuffer;
  1132. NTSTATUS NtStatus;
  1133. if (fSwDebug == TRUE)
  1134. MyPrintf(L"UnSerializeReplicaList()\r\n");
  1135. //
  1136. // Get # replicas
  1137. //
  1138. _GetULong(pBuffer, ReplCount);
  1139. pBuffer += sizeof(ULONG);
  1140. pReplicaInfo = (DFS_REPLICA_INFO *) malloc(sizeof(DFS_REPLICA_INFO) * ReplCount);
  1141. pFtModification = (FILETIME *) malloc(sizeof(FILETIME) * ReplCount);
  1142. if(pReplicaInfo == NULL || pFtModification == NULL) {
  1143. dwErr = ERROR_OUTOFMEMORY;
  1144. goto Cleanup;
  1145. }
  1146. //
  1147. // Now get each replica
  1148. //
  1149. for (cRepl = 0; cRepl < ReplCount; cRepl++) {
  1150. _GetULong(pBuffer, Size);
  1151. pBuffer += sizeof(ULONG);
  1152. MarshalBufferInitialize(
  1153. &marshalBuffer,
  1154. Size,
  1155. pBuffer);
  1156. NtStatus = DfsRtlGet(
  1157. &marshalBuffer,
  1158. &MiFileTime,
  1159. &pFtModification[cRepl]);
  1160. if (NT_SUCCESS(NtStatus)) {
  1161. NtStatus = DfsRtlGet(
  1162. &marshalBuffer,
  1163. &MiDfsReplicaInfo,
  1164. &pReplicaInfo[cRepl]);
  1165. }
  1166. if (NT_SUCCESS(NtStatus)) {
  1167. pBuffer += Size;
  1168. }
  1169. }
  1170. *ppReplicaInfo = pReplicaInfo;
  1171. *ppFtModification = pFtModification;
  1172. *ppBuffer = pBuffer;
  1173. *pAllocatedReplCount = *pReplCount = ReplCount;
  1174. Cleanup:
  1175. if (dwErr != ERROR_SUCCESS) {
  1176. if (pReplicaInfo != NULL)
  1177. free(pReplicaInfo);
  1178. if (pFtModification != NULL)
  1179. free(pFtModification);
  1180. }
  1181. if (fSwDebug == TRUE)
  1182. MyPrintf(L"UnSerializeReplicaList exit %d\r\n", dwErr);
  1183. return dwErr;
  1184. }
  1185. //+------------------------------------------------------------------------
  1186. //
  1187. // Function: DfsGetSiteTable
  1188. //
  1189. // Synopsis: Unserializes the buffer passed in into a dfs site table.
  1190. //
  1191. // Returns: [ERROR_SUCCESS] -- If all went well.
  1192. //
  1193. // [ERROR_OUTOFMEMORY] - If unable to allocate the target buffer.
  1194. //
  1195. // History: 11/19/98 JHarper Created
  1196. //
  1197. //-------------------------------------------------------------------------
  1198. DWORD
  1199. DfsGetSiteTable(
  1200. PDFS_VOLUME_LIST pDfsVolList,
  1201. PLDAP_OBJECT pLdapObject)
  1202. {
  1203. DWORD dwErr = ERROR_SUCCESS;
  1204. NTSTATUS NtStatus;
  1205. ULONG cSite;
  1206. PDFSM_SITE_ENTRY pSiteEntry;
  1207. PDFSM_SITE_ENTRY pTmpSiteEntry;
  1208. MARSHAL_BUFFER marshalBuffer;
  1209. BYTE *pBuffer = NULL;
  1210. ULONG Size;
  1211. if (fSwDebug == TRUE)
  1212. MyPrintf(L"DfsGetSiteTable(%d)\r\n", pLdapObject->cbObjectData);
  1213. InitializeListHead(&pDfsVolList->SiteList);
  1214. MarshalBufferInitialize(
  1215. &marshalBuffer,
  1216. pLdapObject->cbObjectData,
  1217. pLdapObject->pObjectData);
  1218. NtStatus = DfsRtlGetGuid(&marshalBuffer, &pDfsVolList->SiteGuid);
  1219. if (!NT_SUCCESS(NtStatus)) {
  1220. dwErr = RtlNtStatusToDosError(NtStatus);
  1221. goto Cleanup;
  1222. }
  1223. NtStatus = DfsRtlGetUlong(&marshalBuffer, &pDfsVolList->SiteCount);
  1224. if (!NT_SUCCESS(NtStatus)) {
  1225. dwErr = RtlNtStatusToDosError(NtStatus);
  1226. goto Cleanup;
  1227. }
  1228. pBuffer = (BYTE *)malloc(pLdapObject->cbObjectData);
  1229. if (pBuffer == NULL) {
  1230. dwErr = ERROR_OUTOFMEMORY;
  1231. goto Cleanup;
  1232. }
  1233. pTmpSiteEntry = (PDFSM_SITE_ENTRY)pBuffer;
  1234. for (cSite = 0; cSite < pDfsVolList->SiteCount; cSite++) {
  1235. RtlZeroMemory(pBuffer, pLdapObject->cbObjectData);
  1236. NtStatus = DfsRtlGet(
  1237. &marshalBuffer,
  1238. &MiDfsmSiteEntry,
  1239. pBuffer);
  1240. if (!NT_SUCCESS(NtStatus)) {
  1241. dwErr = RtlNtStatusToDosError(NtStatus);
  1242. goto Cleanup;
  1243. }
  1244. Size = sizeof(DFSM_SITE_ENTRY) + (pTmpSiteEntry->Info.cSites * sizeof(DFS_SITENAME_INFO));
  1245. pSiteEntry = (PDFSM_SITE_ENTRY) malloc(Size);
  1246. if (pSiteEntry == NULL) {
  1247. dwErr = ERROR_OUTOFMEMORY;
  1248. goto Cleanup;
  1249. }
  1250. RtlCopyMemory(pSiteEntry, pBuffer, Size);
  1251. InsertHeadList(&pDfsVolList->SiteList, &pSiteEntry->Link);
  1252. }
  1253. Cleanup:
  1254. if (pBuffer != NULL)
  1255. free(pBuffer);
  1256. if (fSwDebug == TRUE)
  1257. MyPrintf(L"DfsGetSiteTable exit dwErr=%d\r\n", dwErr);
  1258. return dwErr;
  1259. }
  1260. //+----------------------------------------------------------------------------
  1261. //
  1262. // Function: GetNetInfoEx
  1263. //
  1264. // Synopsis: Gets information about the volume.
  1265. //
  1266. // Arguments: [Level] -- Level of Information desired.
  1267. //
  1268. // [pDfsVol] - Pointer to DFS_VOLUME to use to fill the info
  1269. //
  1270. // [pInfo] -- Pointer to info struct to be filled. Pointer
  1271. // members will be allocated using MIDL_user_allocate.
  1272. // The type of this variable is LPDFS_INFO_3, but one
  1273. // can pass in pointers to lower levels, and only the
  1274. // fields appropriate for the level will be touched.
  1275. //
  1276. // [pcbInfo] -- On successful return, contains the size in
  1277. // bytes of the returned info. The returned size does
  1278. // not include the size of the DFS_INFO_3 struct itself.
  1279. //
  1280. // Returns: ERROR_SUCCESS -- Successfully returning info
  1281. //
  1282. // ERROR_OUTOFMEMORY -- Out of memory
  1283. //
  1284. //-----------------------------------------------------------------------------
  1285. DWORD
  1286. GetNetInfoEx(
  1287. PDFS_VOLUME pDfsVol,
  1288. DWORD Level,
  1289. LPDFS_INFO_3 pInfo,
  1290. LPDWORD pcbInfo)
  1291. {
  1292. DWORD dwErr = ERROR_SUCCESS;
  1293. DWORD cbInfo = 0;
  1294. DWORD cbItem;
  1295. ULONG i;
  1296. if (fSwDebug == TRUE)
  1297. MyPrintf(L"GetNetInfoEx(%ws,%d)\r\n", pDfsVol->wszPrefix, Level);
  1298. //
  1299. // See if this is a Level 100 or 101. If so, we handle them right away
  1300. // and return
  1301. if (Level == 100) {
  1302. LPDFS_INFO_100 pInfo100 = (LPDFS_INFO_100) pInfo;
  1303. if (pDfsVol->wszComment != NULL) {
  1304. cbItem = (wcslen(pDfsVol->wszComment) + 1) * sizeof(WCHAR);
  1305. pInfo100->Comment = (LPWSTR) MIDL_user_allocate(cbItem);
  1306. if (pInfo100->Comment != NULL) {
  1307. wcscpy(pInfo100->Comment, pDfsVol->wszComment);
  1308. cbInfo += cbItem;
  1309. goto AllDone;
  1310. } else {
  1311. dwErr = ERROR_OUTOFMEMORY;
  1312. goto AllDone;
  1313. }
  1314. } else {
  1315. pInfo100->Comment = (LPWSTR) MIDL_user_allocate(sizeof(WCHAR));
  1316. if (pInfo100->Comment != NULL) {
  1317. pInfo100->Comment[0] = UNICODE_NULL;
  1318. cbInfo += sizeof(WCHAR);
  1319. goto AllDone;
  1320. } else {
  1321. dwErr = ERROR_OUTOFMEMORY;
  1322. goto AllDone;
  1323. }
  1324. }
  1325. }
  1326. if (Level == 101) {
  1327. LPDFS_INFO_101 pInfo101 = (LPDFS_INFO_101) pInfo;
  1328. pInfo->State = pDfsVol->dwState;
  1329. goto AllDone;
  1330. }
  1331. //
  1332. // level 4 isn't just an extension of 3, so handle it seperately
  1333. //
  1334. if (Level == 4) {
  1335. LPDFS_INFO_4 pInfo4 = (LPDFS_INFO_4) pInfo;
  1336. cbItem = sizeof(UNICODE_PATH_SEP) + (wcslen(pDfsVol->wszPrefix) + 1) * sizeof(WCHAR);
  1337. pInfo4->EntryPath = (LPWSTR) MIDL_user_allocate(cbItem);
  1338. if (pInfo4->EntryPath != NULL) {
  1339. pInfo4->EntryPath[0] = UNICODE_PATH_SEP;
  1340. wcscpy(&pInfo4->EntryPath[1], pDfsVol->wszPrefix);
  1341. cbInfo += cbItem;
  1342. } else {
  1343. dwErr = ERROR_OUTOFMEMORY;
  1344. goto AllDone;
  1345. }
  1346. if (pDfsVol->wszComment != NULL) {
  1347. cbItem = (wcslen(pDfsVol->wszComment)+1) * sizeof(WCHAR);
  1348. pInfo4->Comment = (LPWSTR) MIDL_user_allocate(cbItem);
  1349. if (pInfo4->Comment != NULL) {
  1350. wcscpy( pInfo4->Comment, pDfsVol->wszComment );
  1351. cbInfo += cbItem;
  1352. } else {
  1353. dwErr = ERROR_OUTOFMEMORY;
  1354. goto AllDone;
  1355. }
  1356. } else {
  1357. pInfo4->Comment = (LPWSTR) MIDL_user_allocate(sizeof(WCHAR));
  1358. if (pInfo4->Comment != NULL) {
  1359. pInfo4->Comment[0] = UNICODE_NULL;
  1360. cbInfo += sizeof(WCHAR);
  1361. } else {
  1362. dwErr = ERROR_OUTOFMEMORY;
  1363. goto AllDone;
  1364. }
  1365. }
  1366. pInfo4->State = pDfsVol->dwState;
  1367. pInfo4->Timeout = pDfsVol->dwTimeout;
  1368. pInfo4->Guid = pDfsVol->idVolume;
  1369. pInfo4->NumberOfStorages = pDfsVol->ReplCount;
  1370. cbItem = pInfo4->NumberOfStorages * sizeof(DFS_STORAGE_INFO);
  1371. pInfo4->Storage = (LPDFS_STORAGE_INFO) MIDL_user_allocate(cbItem);
  1372. if (pInfo4->Storage != NULL) {
  1373. cbInfo += cbItem;
  1374. for (i = 0; i < pDfsVol->ReplCount; i++) {
  1375. dwErr = GetNetStorageInfo(&pDfsVol->ReplicaInfo[i],&pInfo4->Storage[i],&cbItem);
  1376. cbInfo += cbItem;
  1377. }
  1378. if (dwErr != ERROR_SUCCESS) {
  1379. for (; i > 0; i--) {
  1380. MIDL_user_free(pInfo4->Storage[i-1].ServerName);
  1381. MIDL_user_free(pInfo4->Storage[i-1].ShareName);
  1382. }
  1383. }
  1384. } else {
  1385. dwErr = ERROR_OUTOFMEMORY;
  1386. }
  1387. //
  1388. // See if we need to clean up...
  1389. //
  1390. if (dwErr != ERROR_SUCCESS) {
  1391. if (pInfo4->EntryPath != NULL) {
  1392. MIDL_user_free(pInfo4->EntryPath);
  1393. }
  1394. if (pInfo4->Storage != NULL) {
  1395. MIDL_user_free(pInfo4->Storage);
  1396. }
  1397. goto AllDone;
  1398. } else {
  1399. *pcbInfo = cbInfo;
  1400. }
  1401. goto AllDone;
  1402. }
  1403. //
  1404. // Level is 1,2 or 3
  1405. //
  1406. //
  1407. // Fill in the Level 1 stuff
  1408. //
  1409. cbItem = sizeof(UNICODE_PATH_SEP) + (wcslen(pDfsVol->wszPrefix)+1) * sizeof(WCHAR);
  1410. pInfo->EntryPath = (LPWSTR) MIDL_user_allocate(cbItem);
  1411. if (pInfo->EntryPath != NULL) {
  1412. pInfo->EntryPath[0] = UNICODE_PATH_SEP;
  1413. wcscpy(&pInfo->EntryPath[1], pDfsVol->wszPrefix);
  1414. cbInfo += cbItem;
  1415. } else {
  1416. dwErr = ERROR_OUTOFMEMORY;
  1417. goto AllDone;
  1418. }
  1419. //
  1420. // Fill in the Level 2 stuff if needed
  1421. //
  1422. if (Level > 1) {
  1423. pInfo->State = pDfsVol->dwState;
  1424. pInfo->NumberOfStorages = pDfsVol->ReplCount;
  1425. if (pDfsVol->wszComment != NULL) {
  1426. cbItem = (wcslen(pDfsVol->wszComment)+1) * sizeof(WCHAR);
  1427. pInfo->Comment = (LPWSTR) MIDL_user_allocate(cbItem);
  1428. if (pInfo->Comment != NULL) {
  1429. wcscpy( pInfo->Comment, pDfsVol->wszComment );
  1430. cbInfo += cbItem;
  1431. } else {
  1432. dwErr = ERROR_OUTOFMEMORY;
  1433. }
  1434. } else {
  1435. pInfo->Comment = (LPWSTR) MIDL_user_allocate(sizeof(WCHAR));
  1436. if (pInfo->Comment != NULL) {
  1437. pInfo->Comment[0] = UNICODE_NULL;
  1438. cbInfo += sizeof(WCHAR);
  1439. } else {
  1440. dwErr = ERROR_OUTOFMEMORY;
  1441. }
  1442. }
  1443. }
  1444. //
  1445. // Fill in the Level 3 stuff if needed
  1446. //
  1447. if (dwErr == ERROR_SUCCESS && Level > 2) {
  1448. cbItem = pInfo->NumberOfStorages * sizeof(DFS_STORAGE_INFO);
  1449. pInfo->Storage = (LPDFS_STORAGE_INFO) MIDL_user_allocate(cbItem);
  1450. if (pInfo->Storage != NULL) {
  1451. cbInfo += cbItem;
  1452. for (i = 0; i < pDfsVol->ReplCount; i++) {
  1453. dwErr = GetNetStorageInfo(&pDfsVol->ReplicaInfo[i], &pInfo->Storage[i], &cbItem);
  1454. cbInfo += cbItem;
  1455. }
  1456. if (dwErr != ERROR_SUCCESS) {
  1457. for (; i > 0; i--) {
  1458. MIDL_user_free(pInfo->Storage[i-1].ServerName);
  1459. MIDL_user_free(pInfo->Storage[i-1].ShareName);
  1460. }
  1461. }
  1462. } else {
  1463. dwErr = ERROR_OUTOFMEMORY;
  1464. }
  1465. }
  1466. //
  1467. // See if we need to clean up...
  1468. //
  1469. if (dwErr != ERROR_SUCCESS) {
  1470. if (Level > 1) {
  1471. if (pInfo->EntryPath != NULL) {
  1472. MIDL_user_free(pInfo->EntryPath);
  1473. }
  1474. }
  1475. if (Level > 2) {
  1476. if (pInfo->Storage != NULL) {
  1477. MIDL_user_free(pInfo->Storage);
  1478. }
  1479. }
  1480. }
  1481. AllDone:
  1482. //
  1483. // Finally, we are done
  1484. //
  1485. if (dwErr == ERROR_SUCCESS)
  1486. *pcbInfo = cbInfo;
  1487. if (fSwDebug == TRUE)
  1488. MyPrintf(L"GetNetInfoEx returning %d\r\n", dwErr);
  1489. return(dwErr);
  1490. }
  1491. DWORD
  1492. GetNetStorageInfo(
  1493. PDFS_REPLICA_INFO pRepl,
  1494. LPDFS_STORAGE_INFO pInfo,
  1495. LPDWORD pcbInfo)
  1496. {
  1497. DWORD dwErr = ERROR_SUCCESS;
  1498. LPWSTR wszShare;
  1499. DWORD cbInfo = 0, cbItem;
  1500. if (fSwDebug == TRUE)
  1501. MyPrintf(L"GetNetStorageInfo(\\\\%ws\\%ws)\r\n",
  1502. pRepl->pwszServerName,
  1503. pRepl->pwszShareName);
  1504. pInfo->State = pRepl->ulReplicaState;
  1505. cbItem = (wcslen(pRepl->pwszServerName) + 1) * sizeof(WCHAR);
  1506. pInfo->ServerName = (LPWSTR) MIDL_user_allocate(cbItem);
  1507. if (pInfo->ServerName != NULL) {
  1508. wcscpy(pInfo->ServerName, pRepl->pwszServerName);
  1509. cbInfo += cbItem;
  1510. } else {
  1511. dwErr = ERROR_OUTOFMEMORY;
  1512. }
  1513. if (dwErr == ERROR_SUCCESS) {
  1514. cbItem = (wcslen(pRepl->pwszShareName) + 1) * sizeof(WCHAR);
  1515. pInfo->ShareName = (LPWSTR) MIDL_user_allocate(cbItem);
  1516. if (pInfo->ShareName != NULL) {
  1517. wcscpy( pInfo->ShareName, pRepl->pwszShareName );
  1518. cbInfo += cbItem;
  1519. } else {
  1520. MIDL_user_free( pInfo->ServerName );
  1521. dwErr = ERROR_OUTOFMEMORY;
  1522. }
  1523. }
  1524. if (dwErr == ERROR_SUCCESS)
  1525. *pcbInfo = cbInfo;
  1526. if (fSwDebug == TRUE)
  1527. MyPrintf(L"GetStorageInfo returning %d\r\n", dwErr);
  1528. return( dwErr );
  1529. }
  1530. //+------------------------------------------------------------------------
  1531. //
  1532. // Function: DfsRemoveRootReplica
  1533. //
  1534. // Synopsis: Removes a Dfs root replica from the dfs root replica list
  1535. //
  1536. // History: 12/16/98 JHarper Created
  1537. //
  1538. //-------------------------------------------------------------------------
  1539. DWORD
  1540. DfsRemoveRootReplica(
  1541. PDFS_VOLUME_LIST pDfsVolList,
  1542. LPWSTR RootName)
  1543. {
  1544. ULONG cVol;
  1545. ULONG cRepl;
  1546. ULONG cRoot;
  1547. DWORD dwErr = ERROR_SUCCESS;
  1548. if (fSwDebug == TRUE)
  1549. MyPrintf(L"DfsRemoveRootReplica(%ws)\r\n", RootName);
  1550. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  1551. if (wcscmp(pDfsVolList->Volumes[cVol]->wszObjectName,L"\\domainroot") != 0)
  1552. continue;
  1553. ScanReplicas:
  1554. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->ReplCount; cRepl++) {
  1555. if (
  1556. _wcsicmp(
  1557. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszServerName,
  1558. RootName) == 0
  1559. ) {
  1560. DfsReplDeleteByIndex(pDfsVolList->Volumes[cVol], cRepl);
  1561. goto ScanReplicas;
  1562. }
  1563. }
  1564. break;
  1565. }
  1566. //
  1567. // Remove from RootServers list, if it is there
  1568. //
  1569. ScanRoots:
  1570. if (pDfsVolList->RootServers != NULL) {
  1571. ULONG cCount = 0;
  1572. for (cCount = 0; pDfsVolList->RootServers[cCount] != NULL; cCount++)
  1573. NOTHING;
  1574. for (cRoot = 0; cRoot < cCount; cRoot++) {
  1575. if (fSwDebug == TRUE)
  1576. MyPrintf(L" %d: %ws\r\n", cRoot, pDfsVolList->RootServers[cRoot]);
  1577. if (wcslen(pDfsVolList->RootServers[cRoot]) > 2
  1578. &&
  1579. _wcsnicmp(&pDfsVolList->RootServers[cRoot][2], RootName, wcslen(RootName)) == 0) {
  1580. LPWSTR VolRoot = &pDfsVolList->RootServers[cRoot][2];
  1581. WCHAR Next = 0;
  1582. if (wcslen(RootName) != wcslen(VolRoot)) {
  1583. Next = VolRoot[wcslen(RootName)];
  1584. }
  1585. MyPrintf(L"Found match: next is %wc\n", Next);
  1586. if (Next == 0 || Next == L'.' || Next == L'\\') {
  1587. for (; cRoot < (cCount - 1); cRoot++)
  1588. pDfsVolList->RootServers[cRoot] = pDfsVolList->RootServers[cRoot+1];
  1589. pDfsVolList->RootServers[cCount-1] = NULL;
  1590. goto ScanRoots;
  1591. }
  1592. }
  1593. }
  1594. }
  1595. if (fSwDebug == TRUE)
  1596. MyPrintf(L"DfsRemoveRootReplica exit %d\r\n", dwErr);
  1597. return dwErr;
  1598. }
  1599. //+----------------------------------------------------------------------------
  1600. //
  1601. // Function: DfsRecoverVolList, public
  1602. //
  1603. // Synopsis: Walks the dfs_volume list, checking the recovery params, and
  1604. // applying any recovery needed. Also applies the deleted replica
  1605. // list to the volume's replica list.
  1606. //
  1607. // Arguments: [pDfsVolList] -- Pointer to DFS_VOLUME_LIST work on.
  1608. //
  1609. // Returns:
  1610. //
  1611. //-----------------------------------------------------------------------------
  1612. DWORD
  1613. DfsRecoverVolList(
  1614. PDFS_VOLUME_LIST pDfsVolList)
  1615. {
  1616. DWORD dwErr = ERROR_SUCCESS;
  1617. ULONG iVol;
  1618. ULONG iRepl;
  1619. ULONG iDelRepl;
  1620. PDFS_VOLUME pVol;
  1621. ULONG RecoveryState;
  1622. ULONG Operation;
  1623. ULONG OperState;
  1624. if (fSwDebug == TRUE)
  1625. MyPrintf(L"DfsRecoverVolList(%d volumes)\r\n", pDfsVolList->VolCount);
  1626. ReStart:
  1627. for (iVol = 0; dwErr == ERROR_SUCCESS && iVol < pDfsVolList->VolCount; iVol++) {
  1628. pVol = pDfsVolList->Volumes[iVol];
  1629. if (pVol->cbRecovery >= sizeof(ULONG)) {
  1630. _GetULong(pVol->pRecovery, RecoveryState);
  1631. if (DFS_GET_RECOVERY_STATE(RecoveryState) != DFS_RECOVERY_STATE_NONE) {
  1632. Operation = DFS_GET_RECOVERY_STATE(RecoveryState);
  1633. OperState = DFS_GET_OPER_STAGE(RecoveryState);
  1634. switch (Operation) {
  1635. case DFS_RECOVERY_STATE_CREATING:
  1636. if (fSwDebug == TRUE)
  1637. MyPrintf(L"DFS_RECOVERY_STATE_CREATING\r\n");
  1638. dwErr = DfsVolDelete(pDfsVolList, iVol);
  1639. goto ReStart;
  1640. case DFS_RECOVERY_STATE_ADD_SERVICE:
  1641. if (fSwDebug == TRUE)
  1642. MyPrintf(L"DFS_RECOVERY_STATE_ADD_SERVICE\r\n");
  1643. // dwErr = RecoverFromAddService(OperState);
  1644. ASSERT(L"DFS_RECOVERY_STATE_ADD_SERVICE - WHY?\r\n");
  1645. break;
  1646. case DFS_RECOVERY_STATE_REMOVE_SERVICE:
  1647. if (fSwDebug == TRUE)
  1648. MyPrintf(L"DFS_RECOVERY_STATE_REMOVE_SERVICE\r\n");
  1649. // dwErr = RecoverFromRemoveService(OperState);
  1650. ASSERT(L"DFS_RECOVERY_STATE_REMOVE_SERVICE - WHY?\r\n");
  1651. break;
  1652. case DFS_RECOVERY_STATE_DELETE:
  1653. if (fSwDebug == TRUE)
  1654. MyPrintf(L"DFS_RECOVERY_STATE_DELETE\r\n");
  1655. dwErr = DfsVolDelete(pDfsVolList, iVol);
  1656. goto ReStart;
  1657. default:
  1658. if (fSwDebug == TRUE)
  1659. MyPrintf(L"default\r\n");
  1660. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  1661. }
  1662. }
  1663. }
  1664. if (pVol->pRecovery != NULL)
  1665. MarshalBufferFree(pVol->pRecovery);
  1666. pVol->pRecovery = NULL;
  1667. pVol->cbRecovery = 0;
  1668. }
  1669. if (dwErr != ERROR_SUCCESS)
  1670. goto AllDone;
  1671. //
  1672. // Now apply deleted replica list to each volume
  1673. //
  1674. for (iVol = 0; dwErr == ERROR_SUCCESS && iVol < pDfsVolList->VolCount; iVol++) {
  1675. pVol = pDfsVolList->Volumes[iVol];
  1676. for (iDelRepl = 0; dwErr == ERROR_SUCCESS && iDelRepl < pVol->DelReplCount; iDelRepl++) {
  1677. #if 0 // XXX This appears to be wrong - don't do it.
  1678. dwErr = DfsReplDeleteByName(
  1679. pVol,
  1680. pVol->DelReplicaInfo[iDelRepl].pwszServerName,
  1681. pVol->DelReplicaInfo[iDelRepl].pwszShareName);
  1682. #endif
  1683. DfsFreeRepl(&pVol->DelReplicaInfo[iDelRepl]);
  1684. }
  1685. if (pVol->DelReplicaInfo != NULL) {
  1686. free(pVol->DelReplicaInfo);
  1687. pVol->DelReplicaInfo = NULL;
  1688. }
  1689. if (pVol->DelFtModification != NULL) {
  1690. free(pVol->DelFtModification);
  1691. pVol->DelFtModification = NULL;
  1692. }
  1693. pVol->DelReplCount = 0;
  1694. }
  1695. AllDone:
  1696. if (fSwDebug == TRUE)
  1697. MyPrintf(L"DfsRecoverVolList returning %d\r\n", dwErr);
  1698. return dwErr;
  1699. }
  1700. //+----------------------------------------------------------------------------
  1701. //
  1702. // Function: DfsVolDelete, public
  1703. //
  1704. // Synopsis: Removes a DFS_VOLUME from DFS_VOLUME_LIST
  1705. //
  1706. // Arguments: [pDfsVolList] -- Pointer to DFS_VOLUME_LIST work on.
  1707. // [iVol] -- Index of volume to delete
  1708. //
  1709. // Returns:
  1710. //
  1711. //-----------------------------------------------------------------------------
  1712. DWORD
  1713. DfsVolDelete(
  1714. PDFS_VOLUME_LIST pDfsVolList,
  1715. ULONG iVol)
  1716. {
  1717. ULONG i;
  1718. DWORD dwErr = ERROR_SUCCESS;
  1719. ASSERT(iVol < pDfsVolList->VolCount);
  1720. if (fSwDebug == TRUE)
  1721. MyPrintf(L"DfsVolDelete(%d)\r\n", iVol);
  1722. //
  1723. // Free any memory this Volume is using
  1724. //
  1725. DfsFreeVol(pDfsVolList->Volumes[iVol]);
  1726. free(pDfsVolList->Volumes[iVol]);
  1727. pDfsVolList->Volumes[iVol] = NULL;
  1728. //
  1729. // Since we're shrinking the list, we simply clip out the entry we don't want
  1730. // and adjust the count.
  1731. //
  1732. for (i = iVol+1; i < pDfsVolList->VolCount; i++)
  1733. pDfsVolList->Volumes[i-1] = pDfsVolList->Volumes[i];
  1734. pDfsVolList->VolCount--;
  1735. pDfsVolList->Volumes[pDfsVolList->VolCount] = NULL;
  1736. if (fSwDebug == TRUE)
  1737. MyPrintf(L"DfsVolDelete returning %d\r\n", dwErr);
  1738. return dwErr;
  1739. }
  1740. //+----------------------------------------------------------------------------
  1741. //
  1742. // Function: DfsReplDeleteByIndex, public
  1743. //
  1744. // Synopsis: Removes a PDFS_REPLICA_INFO from a DFS_VOLUME's replica list
  1745. //
  1746. // Arguments: [pDfsVol] -- Pointer to DFS_VOLUME work on.
  1747. // [iRepl] -- Index of replica to delete
  1748. //
  1749. // Returns:
  1750. //
  1751. //-----------------------------------------------------------------------------
  1752. DWORD
  1753. DfsReplDeleteByIndex(
  1754. PDFS_VOLUME pVol,
  1755. ULONG iRepl)
  1756. {
  1757. ULONG i;
  1758. DWORD dwErr = ERROR_SUCCESS;
  1759. ASSERT(iRepl < pVol->ReplCount);
  1760. if (fSwDebug == TRUE)
  1761. MyPrintf(L"DfsReplDeleteByIndex(%d)\r\n", iRepl);
  1762. //
  1763. // Free any memory this replica is using
  1764. //
  1765. DfsFreeRepl(&pVol->ReplicaInfo[iRepl]);
  1766. //
  1767. // Since we're shrinking the list(s), we simply clip out the entry we don't want
  1768. // and adjust the count.
  1769. //
  1770. for (i = iRepl+1; i < pVol->ReplCount; i++) {
  1771. pVol->ReplicaInfo[i-1] = pVol->ReplicaInfo[i];
  1772. pVol->FtModification[i-1] = pVol->FtModification[i];
  1773. }
  1774. pVol->ReplCount--;
  1775. RtlZeroMemory(&pVol->ReplicaInfo[pVol->ReplCount], sizeof(DFS_REPLICA_INFO));
  1776. if (fSwDebug == TRUE)
  1777. MyPrintf(L"DfsReplDeleteByIndex returning %d\r\n", dwErr);
  1778. return dwErr;
  1779. }
  1780. //+----------------------------------------------------------------------------
  1781. //
  1782. // Function: DfsReplDeleteByName, public
  1783. //
  1784. // Synopsis: Removes a PDFS_REPLICA_INFO from a DFS_VOLUME's replica list. Simply
  1785. // looks up the replica by name and then calls DfsReplDeleteByIndex()
  1786. //
  1787. // Arguments: [pDfsVol] -- Pointer to DFS_VOLUME work on.
  1788. // [pwszServername] - Server Name
  1789. // [pwszShareName] - Share Name
  1790. //
  1791. // Returns:
  1792. //
  1793. //-----------------------------------------------------------------------------
  1794. DWORD
  1795. DfsReplDeleteByName(
  1796. PDFS_VOLUME pVol,
  1797. LPWSTR pwszServerName,
  1798. LPWSTR pwszShareName)
  1799. {
  1800. ULONG iRep;
  1801. DWORD dwErr = ERROR_SUCCESS;
  1802. if (fSwDebug == TRUE)
  1803. MyPrintf(L"DfsReplDeleteByName(%ws,%ws)\r\n", pwszServerName, pwszShareName);
  1804. if (pwszServerName == NULL || pwszShareName == NULL) {
  1805. dwErr = ERROR_INVALID_PARAMETER;
  1806. goto AllDone;
  1807. }
  1808. ReStart:
  1809. //
  1810. // Scan the volume's replica list, and if there is a match on the
  1811. // passed-in servername and sharename, remove the replica.
  1812. //
  1813. for (iRep = 0; iRep < pVol->ReplCount; iRep++) {
  1814. if (_wcsicmp(pVol->ReplicaInfo[iRep].pwszServerName, pwszServerName) == 0
  1815. &&
  1816. _wcsicmp(pVol->ReplicaInfo[iRep].pwszShareName, pwszShareName) == 0
  1817. ) {
  1818. dwErr = DfsReplDeleteByIndex(pVol, iRep);
  1819. goto ReStart;
  1820. }
  1821. }
  1822. AllDone:
  1823. if (fSwDebug == TRUE)
  1824. MyPrintf(L"DfsReplDeleteByName returning %d\r\n", dwErr);
  1825. return dwErr;
  1826. }
  1827. //+----------------------------------------------------------------------------
  1828. //
  1829. // Function: DfsDelReplDelete, public
  1830. //
  1831. // Synopsis: Removes a PDFS_REPLICA_INFO from a DFS_VOLUME's deleted replica list
  1832. //
  1833. // Arguments: [pDfsVol] -- Pointer to DFS_VOLUME work on.
  1834. // [iDelRepl] -- Index of Deleted replica to delete
  1835. //
  1836. // Returns:
  1837. //
  1838. //-----------------------------------------------------------------------------
  1839. DWORD
  1840. DfsDelReplDelete(
  1841. PDFS_VOLUME pVol,
  1842. ULONG iDelRepl)
  1843. {
  1844. ULONG i;
  1845. DWORD dwErr = ERROR_SUCCESS;
  1846. ASSERT(iDelRepl < pVol->DelReplCount);
  1847. if (fSwDebug == TRUE)
  1848. MyPrintf(L"DfsDelReplDelete(%d)\r\n", iDelRepl);
  1849. //
  1850. // Free any memory this replica is using
  1851. //
  1852. DfsFreeRepl(&pVol->DelReplicaInfo[iDelRepl]);
  1853. //
  1854. // Since we're shrinking the list(s), we simply clip out the entry we don't want
  1855. // and adjust the count.
  1856. //
  1857. for (i = iDelRepl+1; i < pVol->DelReplCount; i++) {
  1858. pVol->DelReplicaInfo[i-1] = pVol->DelReplicaInfo[i];
  1859. pVol->DelFtModification[i-1] = pVol->DelFtModification[i];
  1860. }
  1861. pVol->DelReplCount--;
  1862. RtlZeroMemory(&pVol->DelReplicaInfo[pVol->DelReplCount], sizeof(DFS_REPLICA_INFO));
  1863. if (fSwDebug == TRUE)
  1864. MyPrintf(L"DfsDelReplDelete returning %d\r\n", dwErr);
  1865. return dwErr;
  1866. }
  1867. //+----------------------------------------------------------------------------
  1868. //
  1869. // Function: DfspLdapOpen
  1870. //
  1871. // Synopsis: Open ldap storage and returns the object name of the
  1872. // Dfs-Configuration object.
  1873. //
  1874. // Arguments: DfsEntryPath - wszDcName - Dc name to be used
  1875. // ppldap -- pointer to pointer to ldap obj, filled in on success
  1876. // pwszObjectName -- pointer to LPWSTR for name of dfs-config object
  1877. //
  1878. // Returns: [ERROR_SUCCESS] -- Successfully returning list
  1879. //
  1880. // [??] - From ldap open/bind, etc.
  1881. //
  1882. //-----------------------------------------------------------------------------
  1883. DWORD
  1884. DfspLdapOpen(
  1885. LPWSTR wszDcName,
  1886. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  1887. LDAP **ppldap,
  1888. LPWSTR pwszObjectPrefix,
  1889. LPWSTR *pwszObjectName)
  1890. {
  1891. DWORD dwErr;
  1892. DWORD i;
  1893. ULONG Size;
  1894. PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
  1895. PLDAPMessage pMsg = NULL;
  1896. LDAP *pldap = NULL;
  1897. WCHAR wszConfigurationDN[MAX_PATH+1];
  1898. LPWSTR rgAttrs[5];
  1899. if (fSwDebug)
  1900. MyPrintf(L"DfspLdapOpen(%ws)\r\n", wszDcName);
  1901. if (fSwDebug && pAuthIdent != NULL) {
  1902. MyPrintf(L"User:%ws\r\n", pAuthIdent->User);
  1903. MyPrintf(L"Domain:%ws\r\n", pAuthIdent->Domain);
  1904. MyPrintf(L"Password:%ws\r\n", pAuthIdent->Password);
  1905. }
  1906. if ( ppldap == NULL || pwszObjectName == NULL) {
  1907. dwErr = ERROR_INVALID_PARAMETER;
  1908. goto Cleanup;
  1909. }
  1910. if (*ppldap == NULL && wszDcName == NULL) {
  1911. dwErr = ERROR_INVALID_PARAMETER;
  1912. goto Cleanup;
  1913. }
  1914. if (*ppldap == NULL) {
  1915. pldap = ldap_init(wszDcName, LDAP_PORT);
  1916. if (pldap == NULL) {
  1917. if (fSwDebug == TRUE)
  1918. MyPrintf(L"DfspLdapOpen:ldap_init failed\r\n");
  1919. dwErr = ERROR_INVALID_NAME;
  1920. goto Cleanup;
  1921. }
  1922. dwErr = ldap_set_option(pldap, LDAP_OPT_AREC_EXCLUSIVE, LDAP_OPT_ON);
  1923. if (dwErr != LDAP_SUCCESS) {
  1924. pldap = NULL;
  1925. goto Cleanup;
  1926. }
  1927. dwErr = ldap_bind_s(pldap, NULL, (LPWSTR)pAuthIdent, LDAP_AUTH_SSPI);
  1928. if (dwErr != LDAP_SUCCESS) {
  1929. if (fSwDebug == TRUE)
  1930. MyPrintf(L"ldap_bind_s failed with ldap error %d\r\n", dwErr);
  1931. pldap = NULL;
  1932. dwErr = LdapMapErrorToWin32(dwErr);
  1933. goto Cleanup;
  1934. }
  1935. } else {
  1936. pldap = *ppldap;
  1937. }
  1938. //
  1939. // Get attribute "defaultNameContext" containing name of entry we'll be
  1940. // using for our DN
  1941. //
  1942. rgAttrs[0] = L"defaultnamingContext";
  1943. rgAttrs[1] = NULL;
  1944. dwErr = ldap_search_s(
  1945. pldap,
  1946. L"",
  1947. LDAP_SCOPE_BASE,
  1948. L"(objectClass=*)",
  1949. rgAttrs,
  1950. 0,
  1951. &pMsg);
  1952. if (dwErr == LDAP_SUCCESS) {
  1953. PLDAPMessage pEntry = NULL;
  1954. PWCHAR *rgszNamingContexts = NULL;
  1955. DWORD i, cNamingContexts;
  1956. dwErr = ERROR_SUCCESS;
  1957. if ((pEntry = ldap_first_entry(pldap, pMsg)) != NULL &&
  1958. (rgszNamingContexts = ldap_get_values(pldap, pEntry, rgAttrs[0])) != NULL &&
  1959. (cNamingContexts = ldap_count_values(rgszNamingContexts)) > 0) {
  1960. wcscpy( wszConfigurationDN, *rgszNamingContexts );
  1961. } else {
  1962. dwErr = ERROR_UNEXP_NET_ERR;
  1963. }
  1964. if (rgszNamingContexts != NULL)
  1965. ldap_value_free( rgszNamingContexts );
  1966. } else {
  1967. dwErr = LdapMapErrorToWin32(dwErr);
  1968. }
  1969. if (dwErr != ERROR_SUCCESS) {
  1970. if (fSwDebug == TRUE)
  1971. MyPrintf(L"Unable to find Configuration naming context\r\n");
  1972. goto Cleanup;
  1973. }
  1974. //
  1975. // Create string with full object name
  1976. //
  1977. Size = wcslen(pwszObjectPrefix) * sizeof(WCHAR) +
  1978. sizeof(WCHAR) +
  1979. wcslen(wszConfigurationDN) * sizeof(WCHAR) +
  1980. sizeof(WCHAR);
  1981. *pwszObjectName = (LPWSTR)malloc(Size);
  1982. if (*pwszObjectName == NULL) {
  1983. dwErr = ERROR_OUTOFMEMORY;
  1984. goto Cleanup;
  1985. }
  1986. wcscpy(*pwszObjectName,pwszObjectPrefix);
  1987. wcscat(*pwszObjectName,L",");
  1988. wcscat(*pwszObjectName,wszConfigurationDN);
  1989. if (fSwDebug == TRUE)
  1990. MyPrintf(L"DfsLdapOpen:object name=[%ws]\r\n", *pwszObjectName);
  1991. Cleanup:
  1992. if (pDCInfo != NULL)
  1993. NetApiBufferFree( pDCInfo );
  1994. if (dwErr != ERROR_SUCCESS && *ppldap == NULL) {
  1995. ldap_unbind( pldap );
  1996. pldap = NULL;
  1997. }
  1998. if (pMsg != NULL)
  1999. ldap_msgfree( pMsg );
  2000. if (*ppldap == NULL)
  2001. *ppldap = pldap;
  2002. if (fSwDebug == TRUE)
  2003. MyPrintf(L"DfsLdapOpen:returning %d\r\n", dwErr);
  2004. return( dwErr );
  2005. }
  2006. //+----------------------------------------------------------------------------
  2007. //
  2008. // Function: DfspGetPdc
  2009. //
  2010. // Synopsis: Gets the PDC
  2011. //
  2012. // Arguments: None
  2013. //
  2014. // Returns: ERROR_SUCCESS or failure
  2015. //
  2016. //-----------------------------------------------------------------------------
  2017. DWORD
  2018. DfspGetPdc(
  2019. LPWSTR pwszPdcName,
  2020. LPWSTR pwszDomainName)
  2021. {
  2022. DWORD dwErr;
  2023. PDOMAIN_CONTROLLER_INFO pDCInfo;
  2024. if (fSwDebug == TRUE)
  2025. MyPrintf(L"DfspGetPdc(%ws)\r\n", pwszDomainName);
  2026. dwErr = DsGetDcName(
  2027. NULL, // Computer to remote to
  2028. pwszDomainName, // Domain - use local domain
  2029. NULL, // Domain Guid
  2030. NULL, // Site Guid
  2031. DS_PDC_REQUIRED | DS_FORCE_REDISCOVERY,
  2032. &pDCInfo);
  2033. if (dwErr == ERROR_SUCCESS) {
  2034. wcscpy(pwszPdcName, &pDCInfo->DomainControllerName[2]);
  2035. NetApiBufferFree(pDCInfo);
  2036. }
  2037. if (fSwDebug == TRUE)
  2038. MyPrintf(L"DfspGetPdc() returning %d\r\n", dwErr);
  2039. return dwErr;
  2040. }
  2041. // ====================================================================
  2042. // MIDL allocate and free
  2043. // ====================================================================
  2044. PVOID
  2045. MIDL_user_allocate(ULONG len)
  2046. {
  2047. return malloc(len);
  2048. }
  2049. VOID
  2050. MIDL_user_free(void * ptr)
  2051. {
  2052. free(ptr);
  2053. }
  2054. void
  2055. DumpBuf(PCHAR cp, ULONG len)
  2056. {
  2057. ULONG i, j, c;
  2058. for (i = 0; i < len; i += 16) {
  2059. MyPrintf(L"%08x ", i /* +(ULONG)cp */);
  2060. for (j = 0; j < 16; j++) {
  2061. if (j == 8)
  2062. MyPrintf(L" ");
  2063. if (i+j < len) {
  2064. c = cp[i+j] & 0xff;
  2065. MyPrintf(L"%02x ", c);
  2066. } else {
  2067. MyPrintf(L" ");
  2068. }
  2069. }
  2070. MyPrintf(L" ");
  2071. for (j = 0; j < 16; j++) {
  2072. if (j == 8)
  2073. MyPrintf(L"|");
  2074. if (i+j < len) {
  2075. c = cp[i+j] & 0xff;
  2076. if (c < ' ' || c > '~')
  2077. c = '.';
  2078. MyPrintf(L"%c", c);
  2079. } else {
  2080. MyPrintf(L" ");
  2081. }
  2082. }
  2083. MyPrintf(L"\r\n");
  2084. }
  2085. }
  2086. //+------------------------------------------------------------------------
  2087. //
  2088. // Function: DfsDumpVolList
  2089. //
  2090. // Synopsis: Prints the volume information represented by the volume
  2091. // list passed in.
  2092. //
  2093. // Returns: Usually.
  2094. //
  2095. //-------------------------------------------------------------------------
  2096. VOID
  2097. DfsDumpVolList(
  2098. PDFS_VOLUME_LIST pDfsVolList)
  2099. {
  2100. ULONG cVol;
  2101. ULONG cRepl;
  2102. ULONG cSite;
  2103. ULONG cRoot;
  2104. ULONG i;
  2105. GUID guid;
  2106. PLIST_ENTRY pListHead;
  2107. PLIST_ENTRY pLink;
  2108. PDFSM_SITE_ENTRY pSiteEntry;
  2109. WCHAR wszGuid[sizeof(GUID) * sizeof(WCHAR) + sizeof(WCHAR)];
  2110. MyPrintf(L"****************************************\r\n");
  2111. MyPrintf(L"Type is %d (%ws)\r\n",
  2112. pDfsVolList->DfsType,
  2113. pDfsVolList->DfsType == DOMUNKNONN ? L"Unknown" :
  2114. pDfsVolList->DfsType == DOMDFS ? L"DomDfs" :
  2115. L"StdDfs");
  2116. if (pDfsVolList->RootServers != NULL) {
  2117. MyPrintf(L"remoteServerName:");
  2118. for (cRoot = 0; pDfsVolList->RootServers[cRoot] != NULL; cRoot++)
  2119. MyPrintf(L"[%ws]", pDfsVolList->RootServers[cRoot]);
  2120. MyPrintf(L"\r\n");
  2121. }
  2122. MyPrintf(L"There are %d dfs-links in this Dfs.\r\n", pDfsVolList->VolCount);
  2123. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  2124. MyPrintf(L"------------------------\r\n");
  2125. MyPrintf(L"ID:\r\n");
  2126. MyPrintf(L" Name=%ws\r\n", pDfsVolList->Volumes[cVol]->wszObjectName);
  2127. MyPrintf(L" Prefix: %ws\r\n", pDfsVolList->Volumes[cVol]->wszPrefix);
  2128. MyPrintf(L" ShortPrefix: %ws\r\n", pDfsVolList->Volumes[cVol]->wszShortPrefix);
  2129. MyPrintf(L" idVolume: %ws\r\n",
  2130. GuidToStringEx(&pDfsVolList->Volumes[cVol]->idVolume, wszGuid));
  2131. MyPrintf(L" Comment: %ws\r\n", pDfsVolList->Volumes[cVol]->wszComment);
  2132. MyPrintf(L" Timeout: %d\r\n", pDfsVolList->Volumes[cVol]->dwTimeout);
  2133. MyPrintf(L" Type: %x\r\n", pDfsVolList->Volumes[cVol]->dwType);
  2134. MyPrintf(L" cbRecovery: %d\r\n", pDfsVolList->Volumes[cVol]->cbRecovery);
  2135. MyPrintf(L"Svc:\r\n");
  2136. MyPrintf(L" ReplCount=%d\r\n", pDfsVolList->Volumes[cVol]->ReplCount);
  2137. MyPrintf(L" AllocatedReplCount=%d\r\n", pDfsVolList->Volumes[cVol]->AllocatedReplCount);
  2138. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->ReplCount; cRepl++) {
  2139. MyPrintf(L" [%d]ReplicaState=0x%x\r\n",
  2140. cRepl, pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaState);
  2141. MyPrintf(L" [%d]ReplicaType=0x%x\r\n",
  2142. cRepl, pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaType);
  2143. MyPrintf(L" [%d]ServerName=%ws\r\n",
  2144. cRepl, pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszServerName);
  2145. MyPrintf(L" [%d]ShareName=%ws\r\n",
  2146. cRepl, pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszShareName);
  2147. }
  2148. MyPrintf(L"Recovery:\r\n");
  2149. MyPrintf(L" DelReplCount=%d\r\n", pDfsVolList->Volumes[cVol]->DelReplCount);
  2150. MyPrintf(L" AllocatedDelReplCount=%d\r\n", pDfsVolList->Volumes[cVol]->AllocatedDelReplCount);
  2151. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->DelReplCount; cRepl++) {
  2152. MyPrintf(L" [%d]ReplicaState=0x%x\r\n",
  2153. cRepl, pDfsVolList->Volumes[cVol]->DelReplicaInfo[cRepl].ulReplicaState);
  2154. MyPrintf(L" [%d]ReplicaType=0x%x\r\n",
  2155. cRepl, pDfsVolList->Volumes[cVol]->DelReplicaInfo[cRepl].ulReplicaType);
  2156. MyPrintf(L" [%d]ServerName=%ws\r\n",
  2157. cRepl, pDfsVolList->Volumes[cVol]->DelReplicaInfo[cRepl].pwszServerName);
  2158. MyPrintf(L" [%d]ShareName=%ws\r\n",
  2159. cRepl, pDfsVolList->Volumes[cVol]->DelReplicaInfo[cRepl].pwszShareName);
  2160. }
  2161. MyPrintf(L"\r\n");
  2162. }
  2163. pListHead = &pDfsVolList->SiteList;
  2164. if (pListHead->Flink != NULL) {
  2165. MyPrintf(L"---------SiteTable-------\r\n");
  2166. guid = pDfsVolList->SiteGuid;
  2167. MyPrintf(L"SiteTableGuid:"
  2168. L"%08lX-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X\r\n",
  2169. guid.Data1, guid.Data2, guid.Data3, (int) guid.Data4[0],
  2170. (int) guid.Data4[1], (int) guid.Data4[2], (int) guid.Data4[3],
  2171. (int) guid.Data4[4], (int) guid.Data4[5],
  2172. (int) guid.Data4[6], (int) guid.Data4[7]);
  2173. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  2174. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  2175. MyPrintf(L"[%ws-%d sites]\r\n",
  2176. pSiteEntry->ServerName,
  2177. pSiteEntry->Info.cSites);
  2178. for (i = 0; i < pSiteEntry->Info.cSites; i++) {
  2179. MyPrintf(L"\t%ws\r\n", pSiteEntry->Info.Site[i].SiteName);
  2180. }
  2181. }
  2182. }
  2183. }
  2184. VOID
  2185. DfsDumpExitPtList(
  2186. PDFS_ROOTLOCALVOL pRootLocalVol,
  2187. ULONG cRootLocalVol)
  2188. {
  2189. ULONG cRoot;
  2190. ULONG cVol;
  2191. for (cRoot = 0; cRoot < cRootLocalVol; cRoot++) {
  2192. if (pRootLocalVol[cRoot].wszObjectName == NULL)
  2193. continue;
  2194. MyPrintf(L"LocalVolume ROOT:[%ws]\r\n", pRootLocalVol[cRoot].wszObjectName);
  2195. if (pRootLocalVol[cRoot].wszEntryPath)
  2196. MyPrintf(L"EntryPath:[%ws]\r\n", pRootLocalVol[cRoot].wszEntryPath);
  2197. if (pRootLocalVol[cRoot].wszShortEntryPath)
  2198. MyPrintf(L"ShortEntryPath:[%ws]\r\n", pRootLocalVol[cRoot].wszShortEntryPath);
  2199. if (pRootLocalVol[cRoot].wszShareName)
  2200. MyPrintf(L"ShareName:[%ws]\r\n", pRootLocalVol[cRoot].wszShareName);
  2201. if (pRootLocalVol[cRoot].wszStorageId)
  2202. MyPrintf(L"StorageId:[%ws]\r\n", pRootLocalVol[cRoot].wszStorageId);
  2203. MyPrintf(L"EntryType:0x%x\r\n", pRootLocalVol[cRoot].dwEntryType);
  2204. MyPrintf(L"cLocalVolCount:%d\r\n", pRootLocalVol[cRoot].cLocalVolCount);
  2205. for (cVol = 0; cVol < pRootLocalVol[cRoot].cLocalVolCount; cVol++) {
  2206. if (pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszObjectName != NULL)
  2207. MyPrintf(L" [%ws]\r\n", pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszObjectName);
  2208. if (pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszEntryPath != NULL)
  2209. MyPrintf(L" [%ws]\r\n", pRootLocalVol[cRoot].pDfsLocalVol[cVol].wszEntryPath);
  2210. }
  2211. }
  2212. }
  2213. //+----------------------------------------------------------------------------
  2214. //
  2215. // Function: GuidToStringEx
  2216. //
  2217. // Synopsis: Converts a GUID to a 32 char wchar null terminated string.
  2218. //
  2219. // Arguments: [pGuid] -- Pointer to Guid structure.
  2220. // [pwszGuid] -- wchar buffer into which to put the string
  2221. // representation of the GUID. Must be atleast
  2222. // 2 * sizeof(GUID) + 1 long.
  2223. //
  2224. // Returns: The string passed in
  2225. //
  2226. //-----------------------------------------------------------------------------
  2227. const WCHAR rgwchHexDigits[] = L"0123456789ABCDEF";
  2228. LPWSTR
  2229. GuidToStringEx(
  2230. GUID *pGuid,
  2231. LPWSTR pwszGuid)
  2232. {
  2233. PBYTE pbBuffer = (PBYTE) pGuid;
  2234. USHORT i;
  2235. for(i = 0; i < sizeof(GUID); i++) {
  2236. pwszGuid[2 * i] = rgwchHexDigits[(pbBuffer[i] >> 4) & 0xF];
  2237. pwszGuid[2 * i + 1] = rgwchHexDigits[pbBuffer[i] & 0xF];
  2238. }
  2239. pwszGuid[2 * i] = UNICODE_NULL;
  2240. return pwszGuid;
  2241. }
  2242. //+----------------------------------------------------------------------------
  2243. //
  2244. // Function: StringToGuid
  2245. //
  2246. // Synopsis: Converts a 32 wchar null terminated string to a GUID.
  2247. //
  2248. // Arguments: [pwszGuid] -- the string to convert
  2249. // [pGuid] -- Pointer to destination GUID.
  2250. //
  2251. // Returns: Nothing
  2252. //
  2253. //-----------------------------------------------------------------------------
  2254. #define HEX_DIGIT_TO_INT(d, i) \
  2255. ASSERT(((d) >= L'0' && (d) <= L'9') || \
  2256. ((d) >= L'A' && (d) <= L'F')); \
  2257. if ((d) <= L'9') { \
  2258. i = (d) - L'0'; \
  2259. } else { \
  2260. i = (d) - L'A' + 10; \
  2261. }
  2262. VOID
  2263. StringToGuid(
  2264. PWSTR pwszGuid,
  2265. GUID *pGuid)
  2266. {
  2267. PBYTE pbBuffer = (PBYTE) pGuid;
  2268. USHORT i, n;
  2269. for (i = 0; i < sizeof(GUID); i++) {
  2270. HEX_DIGIT_TO_INT(pwszGuid[2 * i], n);
  2271. pbBuffer[i] = n << 4;
  2272. HEX_DIGIT_TO_INT(pwszGuid[2 * i + 1], n);
  2273. pbBuffer[i] |= n;
  2274. }
  2275. }
  2276. //+------------------------------------------------------------------------
  2277. //
  2278. // Function: DfsViewVolList
  2279. //
  2280. // Synopsis: Prints the volume information represented by the volume
  2281. // list passed in, in the 'dfscmd/view /full' format, and
  2282. // also prints the site table.
  2283. //
  2284. //-------------------------------------------------------------------------
  2285. VOID
  2286. DfsViewVolList(
  2287. PDFS_VOLUME_LIST pDfsVolList,
  2288. ULONG Level)
  2289. {
  2290. ULONG cRoot;
  2291. ULONG cVol;
  2292. ULONG cRepl;
  2293. ULONG cSite;
  2294. ULONG i;
  2295. PLIST_ENTRY pListHead;
  2296. PLIST_ENTRY pLink;
  2297. PDFSM_SITE_ENTRY pSiteEntry;
  2298. WCHAR wszGuid[sizeof(GUID) * sizeof(WCHAR) + sizeof(WCHAR)];
  2299. if (Level <= 1) {
  2300. MyPrintf(L"Type is %ws\r\n",
  2301. pDfsVolList->DfsType == DOMUNKNONN ? L"Unknown" :
  2302. pDfsVolList->DfsType == DOMDFS ? L"DomDfs" :
  2303. L"StdDfs");
  2304. MyPrintf(L"There are %d dfs-links in this Dfs.\r\n", pDfsVolList->VolCount);
  2305. if (Level == 1) {
  2306. MyPrintf(L"Version:%d\r\n", pDfsVolList->Version);
  2307. if (pDfsVolList->RootServers != NULL) {
  2308. MyPrintf(L"remoteServerName:");
  2309. for (cRoot = 0; pDfsVolList->RootServers[cRoot] != NULL; cRoot++)
  2310. MyPrintf(L"[%ws]", pDfsVolList->RootServers[cRoot]);
  2311. MyPrintf(L"\r\n");
  2312. }
  2313. }
  2314. MyPrintf(L"\r\n");
  2315. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  2316. MyPrintf(L"\\%ws [%ws]\r\n",
  2317. pDfsVolList->Volumes[cVol]->wszPrefix,
  2318. pDfsVolList->Volumes[cVol]->wszComment);
  2319. if (Level == 1) {
  2320. MyPrintf(L" GUID: %ws\r\n",
  2321. GuidToStringEx(&pDfsVolList->Volumes[cVol]->idVolume, wszGuid));
  2322. MyPrintf(L" ShortPrefix: %ws\r\n", pDfsVolList->Volumes[cVol]->wszShortPrefix);
  2323. MyPrintf(L" ObjectName: %ws\r\n", pDfsVolList->Volumes[cVol]->wszObjectName);
  2324. MyPrintf(L" State:0x%x Type:0x%x Version:0x%x\r\n",
  2325. pDfsVolList->Volumes[cVol]->dwState,
  2326. pDfsVolList->Volumes[cVol]->dwType,
  2327. pDfsVolList->Volumes[cVol]->dwVersion);
  2328. }
  2329. MyPrintf(L" Timeout is %d seconds\r\n", pDfsVolList->Volumes[cVol]->dwTimeout);
  2330. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->ReplCount; cRepl++) {
  2331. MyPrintf(L" \\\\%ws\\%ws\r\n",
  2332. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszServerName,
  2333. pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszShareName);
  2334. if (Level == 1) {
  2335. ULONG State = pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaState;
  2336. ULONG Type = pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaType;
  2337. MyPrintf(L" State:0x%x %ws Type:0x%x %ws\r\n",
  2338. State,
  2339. State & DFS_STORAGE_STATE_OFFLINE ?
  2340. L"(DFS_STORAGE_STATE_OFFLINE)" :
  2341. State & DFS_STORAGE_STATE_ONLINE ?
  2342. L"(DFS_STORAGE_STATE_ONLINE)" : L"",
  2343. Type,
  2344. Type == DFS_STORAGE_TYPE_DFS ?
  2345. L"(DFS_STORAGE_TYPE_DFS)" : L"(DFS_STORAGE_TYPE_NONDFS)");
  2346. }
  2347. }
  2348. MyPrintf(L"\r\n");
  2349. }
  2350. MyPrintf(L"\r\n");
  2351. pListHead = &pDfsVolList->SiteList;
  2352. if (pListHead->Flink != NULL) {
  2353. MyPrintf(L"Site information:\r\n");
  2354. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  2355. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  2356. MyPrintf(L"%ws\r\n", pSiteEntry->ServerName);
  2357. for (i = 0; i < pSiteEntry->Info.cSites; i++) {
  2358. MyPrintf(L" %ws\r\n", pSiteEntry->Info.Site[i].SiteName);
  2359. }
  2360. }
  2361. }
  2362. }
  2363. }
  2364. DWORD
  2365. CmdDomUnmap(
  2366. LPWSTR pwszDomDfsName,
  2367. LPWSTR pwszRootName,
  2368. LPWSTR pwszDcName,
  2369. PSEC_WINNT_AUTH_IDENTITY pAuthIdent)
  2370. {
  2371. DWORD dwErr = ERROR_SUCCESS;
  2372. WCHAR wszDfsConfigDN[MAX_PATH+1];
  2373. WCHAR *wszConfigurationDN = NULL;
  2374. LDAP *pldap = NULL;
  2375. LPWSTR pwszDfsName = NULL;
  2376. LPWSTR pwszShareName = NULL;
  2377. LPWSTR pwszDomName = NULL;
  2378. LPWSTR pwszRootServer = NULL;
  2379. LPWSTR pwszRootShare = NULL;
  2380. BOOLEAN IsDomainName = FALSE;
  2381. if (fSwDebug == TRUE)
  2382. MyPrintf(L"CmdDomUnmap(%ws,%ws,%ws,0x%p)\r\n",
  2383. pwszDomDfsName,
  2384. pwszRootName,
  2385. pwszDcName,
  2386. pAuthIdent);
  2387. if (pwszDomDfsName == NULL) {
  2388. dwErr = ERROR_INVALID_PARAMETER;
  2389. goto Cleanup;
  2390. }
  2391. dwErr = DfspParseName(
  2392. pwszDomDfsName,
  2393. &pwszDomName,
  2394. &pwszDfsName);
  2395. if (dwErr != ERROR_SUCCESS)
  2396. goto Cleanup;
  2397. dwErr = DfspIsDomainName(
  2398. pwszDomName,
  2399. pwszDcName,
  2400. &IsDomainName);
  2401. if (dwErr != ERROR_SUCCESS)
  2402. goto Cleanup;
  2403. if (IsDomainName != TRUE) {
  2404. dwErr = ERROR_NO_SUCH_DOMAIN;
  2405. goto Cleanup;
  2406. }
  2407. if (pwszDcName == NULL) {
  2408. dwErr = DfspGetPdc(wszDcName, pwszDomName);
  2409. } else {
  2410. wcscpy(wszDcName, pwszDcName);
  2411. }
  2412. if (dwErr != ERROR_SUCCESS)
  2413. goto Cleanup;
  2414. ErrorMessage(MSG_CONNECTING, wszDcName);
  2415. //
  2416. // If pwszRootName is not NULL, we delete one root only
  2417. //
  2418. if (pwszRootName != NULL) {
  2419. dwErr = DfspParseName(
  2420. pwszRootName,
  2421. &pwszRootServer,
  2422. &pwszRootShare);
  2423. if (dwErr != ERROR_SUCCESS)
  2424. goto Cleanup;
  2425. dwErr = CmdUnmapOneRoot(
  2426. pwszDfsName,
  2427. pwszRootServer,
  2428. wszDcName,
  2429. pwszDomName,
  2430. pAuthIdent);
  2431. goto Cleanup;
  2432. }
  2433. //
  2434. // Delete the whole thing...
  2435. //
  2436. dwErr = DfspLdapOpen(wszDcName, pAuthIdent, &pldap, DfsConfigContainer, &wszConfigurationDN);
  2437. if (dwErr != ERROR_SUCCESS)
  2438. goto Cleanup;
  2439. //
  2440. // Build the entry name we want to delete
  2441. //
  2442. wcscpy(wszDfsConfigDN,L"CN=");
  2443. wcscat(wszDfsConfigDN,pwszDfsName);
  2444. wcscat(wszDfsConfigDN,L",");
  2445. wcscat(wszDfsConfigDN,wszConfigurationDN);
  2446. MyPrintf(L"DS object to delete:\"%ws\"\r\n", wszDfsConfigDN);
  2447. dwErr = ldap_delete_s( pldap, wszDfsConfigDN);
  2448. if (dwErr != LDAP_SUCCESS)
  2449. dwErr = LdapMapErrorToWin32(dwErr);
  2450. Cleanup:
  2451. if (pldap != NULL)
  2452. ldap_unbind( pldap );
  2453. if (wszConfigurationDN != NULL)
  2454. free(wszConfigurationDN);
  2455. if (pwszDfsName != NULL)
  2456. free(pwszDfsName);
  2457. if (pwszShareName != NULL)
  2458. free(pwszShareName);
  2459. if (pwszDomName != NULL)
  2460. free(pwszDomName);
  2461. if (pwszRootServer != NULL)
  2462. free(pwszRootServer);
  2463. if (pwszRootShare != NULL)
  2464. free(pwszRootShare);
  2465. if (fSwDebug == TRUE)
  2466. MyPrintf(L"CmdDomUnmap exit %d\r\n", dwErr);
  2467. return dwErr;
  2468. }
  2469. DWORD
  2470. CmdUnmapOneRoot(
  2471. LPWSTR pwszDomDfsName,
  2472. LPWSTR pwszRootName,
  2473. LPWSTR pwszDcName,
  2474. LPWSTR pwszDomainName,
  2475. PSEC_WINNT_AUTH_IDENTITY pAuthIdent)
  2476. {
  2477. DWORD dwErr = ERROR_SUCCESS;
  2478. DFS_VOLUME_LIST DfsVolList = { 0 };
  2479. ULONG cbBlob = 0;
  2480. BYTE *pBlob = NULL;
  2481. if (fSwDebug != 0)
  2482. MyPrintf(L"CmdUnmapOneRoot(%ws,%ws,%ws,%ws)\r\n",
  2483. pwszDomDfsName,
  2484. pwszRootName,
  2485. pwszDcName,
  2486. pwszDomainName);
  2487. //
  2488. // Get blob from Ds
  2489. //
  2490. dwErr = DfsGetDsBlob(
  2491. pwszDomDfsName,
  2492. DfsConfigContainer,
  2493. pwszDcName,
  2494. pAuthIdent,
  2495. &cbBlob,
  2496. &pBlob,
  2497. &DfsVolList.RootServers);
  2498. if (dwErr != ERROR_SUCCESS)
  2499. goto Cleanup;
  2500. //
  2501. // Unserialize it
  2502. //
  2503. dwErr = DfsGetVolList(
  2504. cbBlob,
  2505. pBlob,
  2506. &DfsVolList);
  2507. if (dwErr != ERROR_SUCCESS)
  2508. goto Cleanup;
  2509. //
  2510. // Free the blob
  2511. //
  2512. free(pBlob);
  2513. pBlob = NULL;
  2514. if (fSwDebug != 0)
  2515. DfsDumpVolList(&DfsVolList);
  2516. //
  2517. // Remove the root/server/machine
  2518. //
  2519. dwErr = DfsRemoveRootReplica(&DfsVolList, pwszRootName);
  2520. if (dwErr != ERROR_SUCCESS)
  2521. goto Cleanup;
  2522. if (fSwDebug != 0)
  2523. DfsDumpVolList(&DfsVolList);
  2524. //
  2525. // Serialize it
  2526. //
  2527. dwErr = DfsPutVolList(
  2528. &cbBlob,
  2529. &pBlob,
  2530. &DfsVolList);
  2531. if (dwErr != ERROR_SUCCESS)
  2532. goto Cleanup;
  2533. //
  2534. // Update the DS
  2535. //
  2536. dwErr = DfsPutDsBlob(
  2537. pwszDomDfsName,
  2538. DfsConfigContainer,
  2539. pwszDcName,
  2540. pAuthIdent,
  2541. cbBlob,
  2542. pBlob,
  2543. DfsVolList.RootServers);
  2544. //
  2545. // Free the volume list we created
  2546. //
  2547. DfsFreeVolList(&DfsVolList);
  2548. Cleanup:
  2549. if (pBlob != NULL)
  2550. free(pBlob);
  2551. if (DfsVolList.VolCount > 0 && DfsVolList.Volumes != NULL)
  2552. DfsFreeVolList(&DfsVolList);
  2553. if (fSwDebug != 0)
  2554. MyPrintf(L"CmdUnmapOneRoot returning %d\r\n", dwErr);
  2555. return( dwErr );
  2556. }
  2557. DWORD
  2558. DfsSetFtOnSite(
  2559. LPWSTR pwszDomainName,
  2560. LPWSTR pwszShareName,
  2561. LPWSTR pwszLinkName,
  2562. LPWSTR pwszDcName,
  2563. PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
  2564. ULONG Set)
  2565. {
  2566. DWORD dwErr = ERROR_SUCCESS;
  2567. DFS_VOLUME_LIST DfsVolList = { 0 };
  2568. ULONG cbBlob = 0;
  2569. BYTE *pBlob = NULL;
  2570. WCHAR wszDcName[MAX_PATH+1];
  2571. if (fSwDebug != 0)
  2572. MyPrintf(L"DfsSetFtOnSite(%ws,%ws,%ws)\r\n",
  2573. pwszDomainName,
  2574. pwszShareName,
  2575. pwszLinkName);
  2576. if (pwszDcName == NULL) {
  2577. dwErr = DfspGetPdc(wszDcName, pwszDomainName);
  2578. } else {
  2579. wcscpy(wszDcName, pwszDcName);
  2580. }
  2581. if (dwErr != ERROR_SUCCESS)
  2582. goto Cleanup;
  2583. //
  2584. // Get blob from Ds
  2585. //
  2586. dwErr = DfsGetDsBlob(
  2587. pwszShareName,
  2588. DfsConfigContainer,
  2589. wszDcName,
  2590. pAuthIdent,
  2591. &cbBlob,
  2592. &pBlob,
  2593. &DfsVolList.RootServers);
  2594. if (dwErr != ERROR_SUCCESS)
  2595. goto Cleanup;
  2596. //
  2597. // Unserialize it
  2598. //
  2599. dwErr = DfsGetVolList(
  2600. cbBlob,
  2601. pBlob,
  2602. &DfsVolList);
  2603. if (dwErr != ERROR_SUCCESS)
  2604. goto Cleanup;
  2605. //
  2606. // Free the blob
  2607. //
  2608. free(pBlob);
  2609. pBlob = NULL;
  2610. if (fSwDebug != 0)
  2611. DfsDumpVolList(&DfsVolList);
  2612. //
  2613. // Update the site referral info: either set or reset the flag
  2614. //
  2615. dwErr = DfsUpdateSiteReferralInfo(&DfsVolList, pwszLinkName, Set);
  2616. if (dwErr != ERROR_SUCCESS)
  2617. goto Cleanup;
  2618. if (fSwDebug != 0)
  2619. DfsDumpVolList(&DfsVolList);
  2620. //
  2621. // Serialize it
  2622. //
  2623. dwErr = DfsPutVolList(
  2624. &cbBlob,
  2625. &pBlob,
  2626. &DfsVolList);
  2627. if (dwErr != ERROR_SUCCESS)
  2628. goto Cleanup;
  2629. //
  2630. // Update the DS
  2631. //
  2632. dwErr = DfsPutDsBlob(
  2633. pwszShareName,
  2634. DfsConfigContainer,
  2635. wszDcName,
  2636. pAuthIdent,
  2637. cbBlob,
  2638. pBlob,
  2639. DfsVolList.RootServers);
  2640. //
  2641. // Free the volume list we created
  2642. //
  2643. DfsFreeVolList(&DfsVolList);
  2644. Cleanup:
  2645. if (pBlob != NULL)
  2646. free(pBlob);
  2647. if (DfsVolList.VolCount > 0 && DfsVolList.Volumes != NULL)
  2648. DfsFreeVolList(&DfsVolList);
  2649. if (fSwDebug != 0)
  2650. MyPrintf(L"CmdUnmapOneRoot returning %d\r\n", dwErr);
  2651. return( dwErr );
  2652. }
  2653. //+------------------------------------------------------------------------
  2654. //
  2655. // Function: DfsUpdateSiteReferralInfo(
  2656. //
  2657. // Synopsis: Update the referral site info for the volume
  2658. //
  2659. //-------------------------------------------------------------------------
  2660. DWORD
  2661. DfsUpdateSiteReferralInfo(
  2662. PDFS_VOLUME_LIST pDfsVolList,
  2663. LPWSTR wszPrefixMatch,
  2664. ULONG Set)
  2665. {
  2666. ULONG cVol;
  2667. ULONG cRepl;
  2668. ULONG cRoot;
  2669. DWORD dwErr = ERROR_SUCCESS;
  2670. LPWSTR usePrefix;
  2671. BOOLEAN found = FALSE;
  2672. if (fSwDebug == TRUE)
  2673. MyPrintf(L"DfsUpdateSiteReferralInfo(%ws)\r\n", wszPrefixMatch);
  2674. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  2675. usePrefix = pDfsVolList->Volumes[cVol]->wszPrefix;
  2676. DfspGetLinkName(usePrefix, &usePrefix);
  2677. if (fSwDebug) {
  2678. MyPrintf(L"Checking for Match (%ws, %ws), keyname (%ws)\n",
  2679. usePrefix,
  2680. pDfsVolList->Volumes[cVol]->wszShortPrefix,
  2681. wszPrefixMatch);
  2682. }
  2683. if (_wcsicmp(usePrefix, wszPrefixMatch) == 0) {
  2684. if (fSwDebug) {
  2685. MyPrintf(L"Match found prefix (%ws, %ws), keyname (%ws)\n",
  2686. usePrefix,
  2687. pDfsVolList->Volumes[cVol]->wszShortPrefix,
  2688. wszPrefixMatch);
  2689. }
  2690. found = TRUE;
  2691. if (Set) {
  2692. if (pDfsVolList->Volumes[cVol]->dwType & PKT_ENTRY_TYPE_INSITE_ONLY) {
  2693. ErrorMessage(MSG_SITE_INFO_ALREADY_SET,
  2694. pDfsVolList->Volumes[cVol]->wszPrefix);
  2695. }
  2696. else {
  2697. ErrorMessage(MSG_SITE_INFO_NOW_SET,
  2698. pDfsVolList->Volumes[cVol]->wszPrefix);
  2699. pDfsVolList->Volumes[cVol]->dwType |= PKT_ENTRY_TYPE_INSITE_ONLY;
  2700. }
  2701. }
  2702. else {
  2703. if (pDfsVolList->Volumes[cVol]->dwType & PKT_ENTRY_TYPE_INSITE_ONLY) {
  2704. ErrorMessage(MSG_SITE_INFO_NOW_SET,
  2705. pDfsVolList->Volumes[cVol]->wszPrefix);
  2706. pDfsVolList->Volumes[cVol]->dwType &= ~PKT_ENTRY_TYPE_INSITE_ONLY;
  2707. }
  2708. else {
  2709. ErrorMessage(MSG_SITE_INFO_ALREADY_SET,
  2710. pDfsVolList->Volumes[cVol]->wszPrefix);
  2711. dwErr = ERROR_REQUEST_ABORTED;
  2712. }
  2713. }
  2714. break;
  2715. }
  2716. }
  2717. if (!found) {
  2718. ErrorMessage(MSG_LINK_NOT_FOUND, wszPrefixMatch);
  2719. dwErr = ERROR_PATH_NOT_FOUND;
  2720. }
  2721. if (fSwDebug == TRUE)
  2722. MyPrintf(L"DfsUpdateSiteReferralInfo exit %d\r\n", dwErr);
  2723. return dwErr;
  2724. }