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.

2422 lines
62 KiB

  1. //
  2. // Copyright (C) 1997, Microsoft Corporation
  3. //
  4. // File: ftsup.cxx
  5. //
  6. // Contents: This module contains the functions which deal with ftdfs removal
  7. //
  8. // History: 07-Dec-1998 JHarper Created.
  9. //
  10. //--------------------------------------------------------------------------
  11. #include "headers.hxx"
  12. #pragma hdrstop
  13. #include "marshal.hxx"
  14. #include "winldap.h"
  15. #include "dsgetdc.h"
  16. #include "setup.hxx"
  17. #include "ftsup.hxx"
  18. #include "dfsmwml.h"
  19. #if DBG
  20. void
  21. DumpBuf(
  22. PCHAR cp,
  23. ULONG len);
  24. #endif // DBG
  25. extern PLDAP pLdapConnection;
  26. //+------------------------------------------------------------------------
  27. //
  28. // Function: DfsGetDsBlob
  29. //
  30. // Synopsis: Reads a Dfs BLOB from the DS
  31. //
  32. // History: 11/19/98 JHarper Created
  33. //
  34. //-------------------------------------------------------------------------
  35. DWORD
  36. DfsGetDsBlob(
  37. LPWSTR wszFtDfsName,
  38. LPWSTR wszDcName,
  39. ULONG *pcbBlob,
  40. BYTE **ppBlob)
  41. {
  42. DWORD dwErr;
  43. LDAP *pldap = NULL;
  44. PLDAPMessage pMsg = NULL;
  45. PLDAP_BERVAL *rgldapPktBlob = NULL;
  46. PLDAP_BERVAL pldapPktBlob;
  47. LDAPMessage *pmsgServers;
  48. DWORD i;
  49. WCHAR *wszConfigurationDN = NULL;
  50. WCHAR wszDfsConfigDN[MAX_PATH+1];
  51. LPWSTR rgAttrs[5];
  52. BYTE *pBlob = NULL;
  53. ULONG cLen = 0;
  54. #if DBG
  55. if (DfsSvcVerbose)
  56. DbgPrint("DfsGetDsBlob(%ws,%ws)\n", wszFtDfsName, wszDcName);
  57. #endif
  58. dwErr = DfspLdapOpen(wszDcName, &pldap, &wszConfigurationDN);
  59. if (dwErr != ERROR_SUCCESS)
  60. goto Cleanup;
  61. //
  62. // Build the entry name we want to search in
  63. //
  64. cLen = wcslen(L"CN=") +
  65. wcslen(wszFtDfsName) +
  66. wcslen(L",") +
  67. wcslen(wszConfigurationDN) +
  68. 1;
  69. if (cLen > MAX_PATH) {
  70. dwErr = ERROR_DS_NAME_TOO_LONG;
  71. goto Cleanup;
  72. }
  73. wcscpy(wszDfsConfigDN,L"CN=");
  74. wcscat(wszDfsConfigDN,wszFtDfsName);
  75. wcscat(wszDfsConfigDN,L",");
  76. wcscat(wszDfsConfigDN,wszConfigurationDN);
  77. #if DBG
  78. if (DfsSvcVerbose)
  79. DbgPrint("wszDfsConfigDN=[%ws]\n", wszDfsConfigDN);
  80. #endif
  81. rgAttrs[0] = L"pKT";
  82. rgAttrs[1] = NULL;
  83. if (DfsSvcLdap)
  84. DbgPrint("DfsGetDsBlob:ldap_search_s(%ws)\n", rgAttrs[0]);
  85. dwErr = ldap_search_sW(
  86. pldap,
  87. wszDfsConfigDN,
  88. LDAP_SCOPE_BASE,
  89. L"(objectClass=*)",
  90. rgAttrs,
  91. 0,
  92. &pMsg);
  93. DFSM_TRACE_ERROR_HIGH(dwErr, ALL_ERROR,
  94. DfsGetDsBlob_Error_ldap_search_sW,
  95. LOGULONG(dwErr));
  96. if (dwErr != LDAP_SUCCESS) {
  97. dwErr = LdapMapErrorToWin32(dwErr);
  98. goto Cleanup;
  99. }
  100. pmsgServers = ldap_first_entry(pldap, pMsg);
  101. if (pmsgServers == NULL) {
  102. dwErr = ERROR_OUTOFMEMORY;
  103. goto Cleanup;
  104. }
  105. rgldapPktBlob = ldap_get_values_lenW(
  106. pldap,
  107. pMsg,
  108. L"pKT");
  109. if (rgldapPktBlob == NULL || *rgldapPktBlob == NULL) {
  110. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  111. goto Cleanup;
  112. }
  113. pldapPktBlob = rgldapPktBlob[0];
  114. pBlob = (BYTE *)malloc(pldapPktBlob->bv_len);
  115. if (pBlob == NULL) {
  116. dwErr = ERROR_OUTOFMEMORY;
  117. goto Cleanup;
  118. }
  119. RtlCopyMemory(pBlob, pldapPktBlob->bv_val, pldapPktBlob->bv_len);
  120. *ppBlob = pBlob;
  121. *pcbBlob = pldapPktBlob->bv_len;
  122. Cleanup:
  123. if (rgldapPktBlob != NULL)
  124. ldap_value_free_len(rgldapPktBlob);
  125. if (pMsg != NULL)
  126. ldap_msgfree( pMsg );
  127. if (pldap != NULL && pldap != pLdapConnection) {
  128. if (DfsSvcLdap)
  129. DbgPrint("DfsGetDsBlob:ldap_unbind()\n");
  130. ldap_unbind( pldap );
  131. }
  132. if (wszConfigurationDN != NULL)
  133. free(wszConfigurationDN);
  134. #if DBG
  135. if (DfsSvcVerbose)
  136. DbgPrint("DfsGetDsBlob returning %d\n", dwErr);
  137. #endif
  138. return (dwErr);
  139. }
  140. //+------------------------------------------------------------------------
  141. //
  142. // Function: DfsPutDsBlob
  143. //
  144. // Synopsis: Updates a Dfs BLOB in the DS
  145. //
  146. // History: 12/8/98 JHarper Created
  147. //
  148. //-------------------------------------------------------------------------
  149. DWORD
  150. DfsPutDsBlob(
  151. LPWSTR wszFtDfsName,
  152. LPWSTR wszDcName,
  153. ULONG cbBlob,
  154. BYTE *pBlob)
  155. {
  156. DWORD dwErr;
  157. LDAP *pldap = NULL;
  158. GUID idNewPkt;
  159. LDAP_BERVAL ldapVal;
  160. PLDAP_BERVAL rgldapVals[2];
  161. LDAPModW ldapMod;
  162. LDAP_BERVAL ldapIdVal;
  163. PLDAP_BERVAL rgldapIdVals[2];
  164. LDAPModW ldapIdMod;
  165. PLDAPModW rgldapMods[3];
  166. WCHAR *wszConfigurationDN = NULL;
  167. WCHAR wszDfsConfigDN[MAX_PATH+1];
  168. #if DBG
  169. if (DfsSvcVerbose)
  170. DbgPrint("DfsPutDsBlob(%ws,%ws)\n", wszFtDfsName, wszDcName);
  171. #endif
  172. dwErr = DfspLdapOpen(wszDcName, &pldap, &wszConfigurationDN);
  173. if (dwErr != ERROR_SUCCESS)
  174. goto Cleanup;
  175. //
  176. // Build the entry name
  177. //
  178. wcscpy(wszDfsConfigDN,L"CN=");
  179. wcscat(wszDfsConfigDN,wszFtDfsName);
  180. wcscat(wszDfsConfigDN,L",");
  181. wcscat(wszDfsConfigDN,wszConfigurationDN);
  182. #if DBG
  183. if (DfsSvcVerbose)
  184. DbgPrint("wszDfsConfigDN=[%ws]\n", wszDfsConfigDN);
  185. #endif
  186. UuidCreate( &idNewPkt );
  187. ldapIdVal.bv_len = sizeof(GUID);
  188. ldapIdVal.bv_val = (PCHAR) &idNewPkt;
  189. rgldapIdVals[0] = &ldapIdVal;
  190. rgldapIdVals[1] = NULL;
  191. ldapIdMod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  192. ldapIdMod.mod_type = L"pKTGuid";
  193. ldapIdMod.mod_vals.modv_bvals = rgldapIdVals;
  194. ldapVal.bv_len = cbBlob;
  195. ldapVal.bv_val = (PCHAR) pBlob;
  196. rgldapVals[0] = &ldapVal;
  197. rgldapVals[1] = NULL;
  198. ldapMod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  199. ldapMod.mod_type = L"pKT";
  200. ldapMod.mod_vals.modv_bvals = rgldapVals;
  201. rgldapMods[0] = &ldapMod;
  202. rgldapMods[1] = &ldapIdMod;
  203. rgldapMods[2] = NULL;
  204. #if DBG
  205. if (DfsSvcVerbose)
  206. DbgPrint("Writing BLOB of %d bytes\n", cbBlob);
  207. #endif
  208. if (DfsSvcLdap)
  209. DbgPrint("DfsPutDsBlob:ldap_modify(%ws)\n", L"pKTGuid and pKT");
  210. dwErr = ldap_modify_sW(
  211. pldap,
  212. wszDfsConfigDN,
  213. rgldapMods);
  214. DFSM_TRACE_ERROR_HIGH(dwErr, ALL_ERROR,
  215. DfsPutDsBlob_Error_ldap_modify_sW,
  216. LOGULONG(dwErr));
  217. #if DBG
  218. if (DfsSvcVerbose) {
  219. DbgPrint("ldap_modify_sW returned %d\n", dwErr);
  220. }
  221. #endif
  222. if (pldap != pLdapConnection) {
  223. if (DfsSvcLdap)
  224. DbgPrint("DfsPutDsBlob(1):ldap_unbind()\n");
  225. ldap_unbind(pldap);
  226. pldap = NULL;
  227. }
  228. if (dwErr != LDAP_SUCCESS) {
  229. dwErr = LdapMapErrorToWin32(dwErr);
  230. } else {
  231. dwErr = ERROR_SUCCESS;
  232. }
  233. Cleanup:
  234. if (pldap != NULL && pldap != pLdapConnection) {
  235. if (DfsSvcLdap)
  236. DbgPrint("DfsPutDsBlob(2):ldap_unbind()\n");
  237. ldap_unbind( pldap );
  238. }
  239. if (wszConfigurationDN != NULL)
  240. free(wszConfigurationDN);
  241. #if DBG
  242. if (DfsSvcVerbose)
  243. DbgPrint("DfsPutDsBlob returning %d\n", dwErr);
  244. #endif
  245. return (dwErr);
  246. }
  247. //+------------------------------------------------------------------------
  248. //
  249. // Function: DfsGetVolList
  250. //
  251. // Synopsis: Unserializes an FtDfs BLOB and creates
  252. // a volume list representing an FtDfs.
  253. //
  254. // History: 11/19/98 JHarper Created
  255. //
  256. //-------------------------------------------------------------------------
  257. DWORD
  258. DfsGetVolList(
  259. ULONG cbBlob,
  260. BYTE *pBlob,
  261. PDFS_VOLUME_LIST pDfsVolList)
  262. {
  263. DWORD dwErr;
  264. DWORD cObj;
  265. DWORD cVol;
  266. LDAP_PKT LdapPkt;
  267. MARSHAL_BUFFER marshalBuffer;
  268. NTSTATUS NtStatus;
  269. #if DBG
  270. if (DfsSvcVerbose)
  271. DbgPrint("DfsGetVolList()\n");
  272. #endif
  273. RtlZeroMemory(&LdapPkt, sizeof(LDAP_PKT));
  274. if (cbBlob > sizeof(DWORD)) {
  275. _GetULong(pBlob, pDfsVolList->Version);
  276. #if DBG
  277. if (DfsSvcVerbose) {
  278. DbgPrint("Blob Version = %d\n", pDfsVolList->Version);
  279. DbgPrint("BLOB is %d bytes:\n", cbBlob);
  280. }
  281. #endif
  282. MarshalBufferInitialize(
  283. &marshalBuffer,
  284. cbBlob - sizeof(DWORD),
  285. pBlob + sizeof(DWORD));
  286. NtStatus = DfsRtlGet(&marshalBuffer, &MiLdapPkt, &LdapPkt);
  287. if (!NT_SUCCESS(NtStatus)) {
  288. dwErr = RtlNtStatusToDosError(NtStatus);
  289. goto Cleanup;
  290. }
  291. #if DBG
  292. if (DfsSvcVerbose) {
  293. DbgPrint(" %d objects found\n", LdapPkt.cLdapObjects);
  294. for (cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  295. DbgPrint("%d:name=%ws size=%d p=0x%x\n",
  296. cObj,
  297. LdapPkt.rgldapObjects[cObj].wszObjectName,
  298. LdapPkt.rgldapObjects[cObj].cbObjectData,
  299. LdapPkt.rgldapObjects[cObj].pObjectData);
  300. // DumpBuf(
  301. // LdapPkt.rgldapObjects[cObj].pObjectData,
  302. // LdapPkt.rgldapObjects[cObj].cbObjectData);
  303. }
  304. }
  305. #endif
  306. for (cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  307. if (wcscmp(LdapPkt.rgldapObjects[cObj].wszObjectName, L"\\siteroot") != 0) {
  308. pDfsVolList->VolCount++;
  309. }
  310. }
  311. pDfsVolList->Volumes = (PDFS_VOLUME) malloc(pDfsVolList->VolCount * sizeof(DFS_VOLUME));
  312. if (pDfsVolList->Volumes == NULL) {
  313. dwErr = ERROR_OUTOFMEMORY;
  314. goto Cleanup;
  315. }
  316. RtlZeroMemory(pDfsVolList->Volumes, pDfsVolList->VolCount * sizeof(DFS_VOLUME));
  317. //
  318. // Save the true/allocated size so to optimize deletions/additions
  319. //
  320. pDfsVolList->AllocatedVolCount = pDfsVolList->VolCount;
  321. #if DBG
  322. if (DfsSvcVerbose)
  323. DbgPrint("===============================\n");
  324. #endif
  325. for (cVol = cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  326. if (wcscmp(LdapPkt.rgldapObjects[cObj].wszObjectName, L"\\siteroot") == 0) {
  327. dwErr = DfsGetSiteTable(
  328. pDfsVolList,
  329. &LdapPkt.rgldapObjects[cObj]);
  330. } else {
  331. dwErr = DfsGetVolume(
  332. &pDfsVolList->Volumes[cVol],
  333. &LdapPkt.rgldapObjects[cObj]);
  334. }
  335. if (dwErr != ERROR_SUCCESS)
  336. goto Cleanup;
  337. cVol++;
  338. }
  339. } else if (cbBlob == sizeof(DWORD)) {
  340. #if DBG
  341. if (DfsSvcVerbose)
  342. DbgPrint("pKT BLOB is simply one DWORD\n");
  343. #endif
  344. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  345. } else {
  346. #if DBG
  347. if (DfsSvcVerbose)
  348. DbgPrint("pKT BLOB is corrupt!\n");
  349. #endif
  350. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  351. }
  352. Cleanup:
  353. FreeLdapPkt(&LdapPkt);
  354. //
  355. // Do any recovery needed
  356. //
  357. if(pDfsVolList && pDfsVolList->Volumes) {
  358. DWORD dwErr2 = DfsRecoverVolList(pDfsVolList);
  359. if(dwErr == ERROR_SUCCESS) {
  360. // this is to prevent masking the previous error.
  361. dwErr = dwErr2;
  362. }
  363. }
  364. #if DBG
  365. if (DfsSvcVerbose)
  366. DbgPrint("DfsGetVolList returning %d\n", dwErr);
  367. #endif
  368. return( dwErr );
  369. }
  370. //+------------------------------------------------------------------------
  371. //
  372. // Function: DfsGetVolume
  373. //
  374. // Synopsis: Unserializes the data in a buffer/blob to a volume
  375. //
  376. // History: 11/19/98 JHarper Created
  377. //
  378. //-------------------------------------------------------------------------
  379. DWORD
  380. DfsGetVolume(
  381. PDFS_VOLUME pVolume,
  382. PLDAP_OBJECT pLdapObject)
  383. {
  384. DFS_VOLUME_PROPERTIES VolProps;
  385. DWORD dwErr = ERROR_SUCCESS;
  386. MARSHAL_BUFFER marshalBuffer;
  387. NTSTATUS NtStatus;
  388. PBYTE pBuffer = NULL;
  389. #if DBG
  390. if (DfsSvcVerbose)
  391. DbgPrint("DfsGetVolume(%ws,%d)\n",
  392. pLdapObject->wszObjectName,
  393. pLdapObject->cbObjectData);
  394. #endif
  395. RtlZeroMemory(&VolProps, sizeof(DFS_VOLUME_PROPERTIES));
  396. pVolume->wszObjectName = (WCHAR *) malloc(
  397. (wcslen(pLdapObject->wszObjectName)+1) * sizeof(WCHAR));
  398. if (pVolume->wszObjectName == NULL) {
  399. dwErr = ERROR_OUTOFMEMORY;
  400. goto Cleanup;
  401. }
  402. wcscpy(
  403. pVolume->wszObjectName,
  404. pLdapObject->wszObjectName);
  405. MarshalBufferInitialize(
  406. &marshalBuffer,
  407. pLdapObject->cbObjectData,
  408. pLdapObject->pObjectData);
  409. NtStatus = DfsRtlGet(
  410. &marshalBuffer,
  411. &MiVolumeProperties,
  412. &VolProps);
  413. if (!NT_SUCCESS(NtStatus)) {
  414. dwErr = RtlNtStatusToDosError(NtStatus);
  415. goto Cleanup;
  416. }
  417. VolProps.dwTimeout = 300;
  418. if (
  419. (marshalBuffer.Current < marshalBuffer.Last)
  420. &&
  421. (marshalBuffer.Last - marshalBuffer.Current) == sizeof(ULONG)
  422. ) {
  423. DfsRtlGetUlong(&marshalBuffer, &VolProps.dwTimeout);
  424. }
  425. pVolume->idVolume = VolProps.idVolume;
  426. pVolume->wszPrefix = VolProps.wszPrefix;
  427. pVolume->wszShortPrefix = VolProps.wszShortPrefix;
  428. pVolume->dwType = VolProps.dwType;
  429. pVolume->dwState = VolProps.dwState;
  430. pVolume->wszComment = VolProps.wszComment;
  431. pVolume->dwTimeout = VolProps.dwTimeout;
  432. pVolume->ftPrefix = VolProps.ftPrefix;
  433. pVolume->ftState = VolProps.ftState;
  434. pVolume->ftComment = VolProps.ftComment;
  435. pVolume->dwVersion = VolProps.dwVersion;
  436. pVolume->cbRecovery = VolProps.cbRecovery;
  437. pVolume->pRecovery = VolProps.pRecovery;
  438. pBuffer = VolProps.pSvc;
  439. #if DBG
  440. if (DfsSvcVerbose)
  441. DbgPrint("VolProps.cbSvc = %d\n", VolProps.cbSvc);
  442. #endif
  443. dwErr = UnSerializeReplicaList(
  444. &pVolume->ReplCount,
  445. &pVolume->AllocatedReplCount,
  446. &pVolume->ReplicaInfo,
  447. &pVolume->FtModification,
  448. &pBuffer);
  449. if (dwErr != ERROR_SUCCESS) {
  450. goto Cleanup;
  451. }
  452. //
  453. // Get deleted replicas
  454. //
  455. if (pBuffer < (pBuffer + VolProps.cbSvc)) {
  456. dwErr = UnSerializeReplicaList(
  457. &pVolume->DelReplCount,
  458. &pVolume->AllocatedDelReplCount,
  459. &pVolume->DelReplicaInfo,
  460. &pVolume->DelFtModification,
  461. &pBuffer);
  462. if (dwErr != ERROR_SUCCESS) {
  463. goto Cleanup;
  464. }
  465. }
  466. Cleanup:
  467. if (VolProps.pSvc != NULL)
  468. MarshalBufferFree(VolProps.pSvc);
  469. #if DBG
  470. if (DfsSvcVerbose)
  471. DbgPrint("DfsGetVolume returning %d\n", dwErr);
  472. #endif
  473. return dwErr;
  474. }
  475. //+------------------------------------------------------------------------
  476. //
  477. // Function: DfsFreeVolList
  478. //
  479. // Synopsis: Frees the volume list and associated substructures representing
  480. // an FtDfs.
  481. //
  482. // History: 11/19/98 JHarper Created
  483. //
  484. //-------------------------------------------------------------------------
  485. VOID
  486. DfsFreeVolList(
  487. PDFS_VOLUME_LIST pDfsVolList)
  488. {
  489. ULONG cVol;
  490. ULONG cSite;
  491. ULONG i;
  492. PLIST_ENTRY pListHead;
  493. PDFSM_SITE_ENTRY pSiteEntry;
  494. #if DBG
  495. if (DfsSvcVerbose)
  496. DbgPrint("DfsFreeVolList()\n");
  497. #endif
  498. if (pDfsVolList->VolCount > 0 && pDfsVolList->Volumes) {
  499. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  500. DfsFreeVol(&pDfsVolList->Volumes[cVol]);
  501. }
  502. }
  503. if (pDfsVolList->Volumes != NULL)
  504. free(pDfsVolList->Volumes);
  505. pListHead = &pDfsVolList->SiteList;
  506. if (pListHead->Flink != NULL) {
  507. while (pListHead->Flink != pListHead) {
  508. pSiteEntry = CONTAINING_RECORD(pListHead->Flink, DFSM_SITE_ENTRY, Link);
  509. RemoveEntryList(pListHead->Flink);
  510. for (i = 0; i < pSiteEntry->Info.cSites; i++) {
  511. if (pSiteEntry->Info.Site[i].SiteName != NULL)
  512. MarshalBufferFree(pSiteEntry->Info.Site[i].SiteName);
  513. }
  514. if (pSiteEntry->ServerName != NULL)
  515. MarshalBufferFree(pSiteEntry->ServerName);
  516. free(pSiteEntry);
  517. }
  518. }
  519. RtlZeroMemory(pDfsVolList, sizeof(DFS_VOLUME_LIST));
  520. #if DBG
  521. if (DfsSvcVerbose)
  522. DbgPrint("DfsFreeVolList exit\n");
  523. #endif
  524. }
  525. //+------------------------------------------------------------------------
  526. //
  527. // Function: DfsFreeVol
  528. //
  529. // Synopsis: Frees the volume and associated substructures representing
  530. // an FtDfs volume
  531. //
  532. // History: 12/16/98 JHarper Created
  533. //
  534. //-------------------------------------------------------------------------
  535. VOID
  536. DfsFreeVol(
  537. PDFS_VOLUME pVol)
  538. {
  539. ULONG cRepl;
  540. #if DBG
  541. if (DfsSvcVerbose & 0x80000000)
  542. DbgPrint("DfsFreeVol()\n");
  543. #endif
  544. if (pVol->ReplCount > 0 && pVol->ReplicaInfo != NULL) {
  545. for (cRepl = 0; cRepl < pVol->ReplCount; cRepl++) {
  546. DfsFreeRepl(&pVol->ReplicaInfo[cRepl]);
  547. }
  548. }
  549. if (pVol->DelReplCount > 0 && pVol->DelReplicaInfo != NULL) {
  550. for (cRepl = 0; cRepl < pVol->DelReplCount; cRepl++) {
  551. DfsFreeRepl(&pVol->DelReplicaInfo[cRepl]);
  552. }
  553. }
  554. if (pVol->wszPrefix != NULL)
  555. MarshalBufferFree(pVol->wszPrefix);
  556. if (pVol->wszShortPrefix != NULL)
  557. MarshalBufferFree(pVol->wszShortPrefix);
  558. if (pVol->wszComment != NULL)
  559. MarshalBufferFree(pVol->wszComment);
  560. if (pVol->pRecovery != NULL)
  561. MarshalBufferFree(pVol->pRecovery);
  562. if (pVol->ReplicaInfo != NULL)
  563. free(pVol->ReplicaInfo);
  564. if (pVol->DelReplicaInfo != NULL)
  565. free(pVol->DelReplicaInfo);
  566. if (pVol->FtModification != NULL)
  567. free(pVol->FtModification);
  568. if (pVol->DelFtModification != NULL)
  569. free(pVol->DelFtModification);
  570. if (pVol->wszObjectName != NULL)
  571. free(pVol->wszObjectName);
  572. RtlZeroMemory(pVol, sizeof(DFS_VOLUME));
  573. #if DBG
  574. if (DfsSvcVerbose & 0x80000000)
  575. DbgPrint("DfsFreeVol exit\n");
  576. #endif
  577. }
  578. //+------------------------------------------------------------------------
  579. //
  580. // Function: DfsFreeRepl
  581. //
  582. // Synopsis: Frees the Replica and associated substructures representing
  583. // an FtDfs replica
  584. //
  585. // History: 12/16/98 JHarper Created
  586. //
  587. //-------------------------------------------------------------------------
  588. VOID
  589. DfsFreeRepl(
  590. PDFS_REPLICA_INFO pRepl)
  591. {
  592. #if DBG
  593. if (DfsSvcVerbose & 0x80000000)
  594. DbgPrint("DfsFreeRepl()\n");
  595. #endif
  596. if (pRepl->pwszServerName != NULL)
  597. MarshalBufferFree(pRepl->pwszServerName);
  598. if (pRepl->pwszShareName != NULL)
  599. MarshalBufferFree(pRepl->pwszShareName);
  600. RtlZeroMemory(pRepl, sizeof(DFS_REPLICA_INFO));
  601. #if DBG
  602. if (DfsSvcVerbose & 0x80000000)
  603. DbgPrint("DfsFreeRepl exit\n");
  604. #endif
  605. }
  606. //+------------------------------------------------------------------------
  607. //
  608. // Function: DfsPutVolList
  609. //
  610. // Synopsis: Serializes the structs representing a Dfs volume and
  611. // creates a BLOB.
  612. //
  613. // History: 11/19/98 JHarper Created
  614. //
  615. //-------------------------------------------------------------------------
  616. DWORD
  617. DfsPutVolList(
  618. ULONG *pcbBlob,
  619. BYTE **ppBlob,
  620. PDFS_VOLUME_LIST pDfsVolList)
  621. {
  622. ULONG cVol;
  623. ULONG cRepl;
  624. ULONG cObj;
  625. ULONG cBuffer;
  626. ULONG cSite;
  627. DWORD dwErr = ERROR_SUCCESS;
  628. PBYTE Buffer = NULL;
  629. MARSHAL_BUFFER marshalBuffer;
  630. NTSTATUS NtStatus;
  631. DFS_VOLUME_PROPERTIES VolProps;
  632. LDAP_PKT LdapPkt;
  633. PLIST_ENTRY pListHead;
  634. PLIST_ENTRY pLink;
  635. PDFSM_SITE_ENTRY pSiteEntry;
  636. #if DBG
  637. if (DfsSvcVerbose)
  638. DbgPrint("DfsPutVolList()\n");
  639. #endif
  640. LdapPkt.cLdapObjects = pDfsVolList->VolCount + 1;
  641. LdapPkt.rgldapObjects = (PLDAP_OBJECT) malloc(LdapPkt.cLdapObjects * sizeof(LDAP_OBJECT));
  642. if (LdapPkt.rgldapObjects == NULL) {
  643. dwErr = ERROR_OUTOFMEMORY;
  644. goto Cleanup;
  645. }
  646. RtlZeroMemory(LdapPkt.rgldapObjects, LdapPkt.cLdapObjects * sizeof(LDAP_OBJECT));
  647. //
  648. // For each volume, serialize the replicas, then the volume
  649. //
  650. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  651. RtlZeroMemory(&VolProps, sizeof(DFS_VOLUME_PROPERTIES));
  652. LdapPkt.rgldapObjects[cVol].wszObjectName = (WCHAR *) MarshalBufferAllocate(
  653. (wcslen(pDfsVolList->Volumes[cVol].wszObjectName)+1) * sizeof(WCHAR));
  654. if (LdapPkt.rgldapObjects[cVol].wszObjectName == NULL) {
  655. dwErr = ERROR_OUTOFMEMORY;
  656. goto Cleanup;
  657. }
  658. wcscpy(LdapPkt.rgldapObjects[cVol].wszObjectName, pDfsVolList->Volumes[cVol].wszObjectName);
  659. //
  660. // Serialize the replicas
  661. //
  662. dwErr = SerializeReplicaList(
  663. pDfsVolList->Volumes[cVol].ReplCount,
  664. pDfsVolList->Volumes[cVol].ReplicaInfo,
  665. pDfsVolList->Volumes[cVol].FtModification,
  666. pDfsVolList->Volumes[cVol].DelReplCount,
  667. pDfsVolList->Volumes[cVol].DelReplicaInfo,
  668. pDfsVolList->Volumes[cVol].DelFtModification,
  669. &VolProps.cbSvc,
  670. &VolProps.pSvc);
  671. if (dwErr != ERROR_SUCCESS) {
  672. dwErr = ERROR_OUTOFMEMORY;
  673. goto Cleanup;
  674. }
  675. #if DBG
  676. if (DfsSvcVerbose)
  677. DbgPrint(" cbSvc = %d\n", VolProps.cbSvc);
  678. #endif
  679. VolProps.idVolume = pDfsVolList->Volumes[cVol].idVolume;
  680. VolProps.wszPrefix = pDfsVolList->Volumes[cVol].wszPrefix;
  681. VolProps.wszShortPrefix = pDfsVolList->Volumes[cVol].wszShortPrefix;
  682. VolProps.dwType = pDfsVolList->Volumes[cVol].dwType;
  683. VolProps.dwState = pDfsVolList->Volumes[cVol].dwState;
  684. VolProps.wszComment = pDfsVolList->Volumes[cVol].wszComment;
  685. VolProps.dwTimeout = pDfsVolList->Volumes[cVol].dwTimeout;
  686. VolProps.ftPrefix = pDfsVolList->Volumes[cVol].ftPrefix;
  687. VolProps.ftState = pDfsVolList->Volumes[cVol].ftState;
  688. VolProps.ftComment = pDfsVolList->Volumes[cVol].ftComment;
  689. VolProps.dwVersion = pDfsVolList->Volumes[cVol].dwVersion;
  690. VolProps.cbRecovery = pDfsVolList->Volumes[cVol].cbRecovery;
  691. VolProps.pRecovery = pDfsVolList->Volumes[cVol].pRecovery;
  692. //
  693. // Now serialize the volume
  694. cBuffer = 0;
  695. NtStatus = DfsRtlSize(&MiVolumeProperties, &VolProps, &cBuffer);
  696. if (!NT_SUCCESS(NtStatus)) {
  697. MarshalBufferFree(VolProps.pSvc);
  698. dwErr = RtlNtStatusToDosError(NtStatus);
  699. goto Cleanup;
  700. }
  701. cBuffer += sizeof(ULONG);
  702. #if DBG
  703. if (DfsSvcVerbose)
  704. DbgPrint("VolProps marshaled size = %d\n", cBuffer);
  705. #endif
  706. Buffer = (PBYTE) MarshalBufferAllocate(cBuffer);
  707. if (Buffer == NULL) {
  708. MarshalBufferFree(VolProps.pSvc);
  709. dwErr = ERROR_OUTOFMEMORY;
  710. goto Cleanup;
  711. }
  712. LdapPkt.rgldapObjects[cVol].pObjectData = (PCHAR) Buffer;
  713. LdapPkt.rgldapObjects[cVol].cbObjectData = cBuffer;
  714. MarshalBufferInitialize(
  715. &marshalBuffer,
  716. cBuffer,
  717. Buffer);
  718. NtStatus = DfsRtlPut(&marshalBuffer, &MiVolumeProperties, &VolProps);
  719. if (!NT_SUCCESS(NtStatus)) {
  720. MarshalBufferFree(VolProps.pSvc);
  721. dwErr = RtlNtStatusToDosError(NtStatus);
  722. goto Cleanup;
  723. }
  724. NtStatus = DfsRtlPutUlong(&marshalBuffer, &VolProps.dwTimeout);
  725. if (!NT_SUCCESS(NtStatus)) {
  726. MarshalBufferFree(VolProps.pSvc);
  727. dwErr = RtlNtStatusToDosError(NtStatus);
  728. goto Cleanup;
  729. }
  730. MarshalBufferFree(VolProps.pSvc);
  731. }
  732. //
  733. // Serialize the site table
  734. //
  735. cBuffer = sizeof(ULONG) + sizeof(GUID);
  736. //
  737. // Add the size of all the entries
  738. //
  739. pListHead = &pDfsVolList->SiteList;
  740. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  741. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  742. #if DBG
  743. if (DfsSvcVerbose)
  744. DbgPrint("pSiteEntry for %ws\n", pSiteEntry->ServerName);
  745. #endif
  746. NtStatus = DfsRtlSize(&MiDfsmSiteEntry, pSiteEntry, &cBuffer);
  747. if (!NT_SUCCESS(NtStatus)) {
  748. dwErr = RtlNtStatusToDosError(NtStatus);
  749. goto Cleanup;
  750. }
  751. }
  752. //
  753. // Get a buffer big enough
  754. //
  755. Buffer = (BYTE *) MarshalBufferAllocate(cBuffer);
  756. if (Buffer == NULL) {
  757. dwErr = ERROR_OUTOFMEMORY;
  758. goto Cleanup;
  759. }
  760. LdapPkt.rgldapObjects[pDfsVolList->VolCount].wszObjectName =
  761. (WCHAR *)MarshalBufferAllocate(sizeof(L"\\siteroot"));
  762. if (LdapPkt.rgldapObjects[pDfsVolList->VolCount].wszObjectName == NULL) {
  763. dwErr = ERROR_OUTOFMEMORY;
  764. goto Cleanup;
  765. }
  766. wcscpy(LdapPkt.rgldapObjects[pDfsVolList->VolCount].wszObjectName, L"\\siteroot");
  767. LdapPkt.rgldapObjects[pDfsVolList->VolCount].pObjectData = (PCHAR) Buffer;
  768. LdapPkt.rgldapObjects[pDfsVolList->VolCount].cbObjectData = cBuffer;
  769. MarshalBufferInitialize(
  770. &marshalBuffer,
  771. cBuffer,
  772. Buffer);
  773. //
  774. // Put the guid, then the object count in the beginning of the buffer
  775. //
  776. DfsRtlPutGuid(&marshalBuffer, &pDfsVolList->SiteGuid);
  777. DfsRtlPutUlong(&marshalBuffer, &pDfsVolList->SiteCount);
  778. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  779. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  780. DfsRtlPut(&marshalBuffer,&MiDfsmSiteEntry, pSiteEntry);
  781. if (!NT_SUCCESS(NtStatus)) {
  782. dwErr = RtlNtStatusToDosError(NtStatus);
  783. goto Cleanup;
  784. }
  785. }
  786. #if DBG
  787. if (DfsSvcVerbose) {
  788. DbgPrint("After reserialization, %d objects found\n", LdapPkt.cLdapObjects);
  789. for (cObj = 0; cObj < LdapPkt.cLdapObjects; cObj++) {
  790. DbgPrint("%d:name=%ws size=%d p=0x%x\n",
  791. cObj,
  792. LdapPkt.rgldapObjects[cObj].wszObjectName,
  793. LdapPkt.rgldapObjects[cObj].cbObjectData,
  794. LdapPkt.rgldapObjects[cObj].pObjectData);
  795. // DumpBuf(
  796. // LdapPkt.rgldapObjects[cObj].pObjectData,
  797. // LdapPkt.rgldapObjects[cObj].cbObjectData);
  798. }
  799. }
  800. #endif
  801. //
  802. // Finally, serialize all the volumes and the site table into a blob
  803. //
  804. cBuffer = 0;
  805. NtStatus = DfsRtlSize(&MiLdapPkt, &LdapPkt, &cBuffer);
  806. if (!NT_SUCCESS(NtStatus)) {
  807. dwErr = RtlNtStatusToDosError(dwErr);
  808. goto Cleanup;
  809. }
  810. cBuffer += sizeof(DWORD);
  811. #if DBG
  812. if (DfsSvcVerbose)
  813. DbgPrint("New ldap size = %d\n", cBuffer);
  814. #endif
  815. Buffer = (PBYTE) malloc(cBuffer);
  816. if (Buffer == NULL) {
  817. dwErr = ERROR_OUTOFMEMORY;
  818. goto Cleanup;
  819. }
  820. // 447486. Fix prefix bug. use memory after checking for null
  821. *((PDWORD) Buffer) = 2; // Version #
  822. MarshalBufferInitialize(
  823. &marshalBuffer,
  824. cBuffer,
  825. Buffer + sizeof(DWORD));
  826. NtStatus = DfsRtlPut(&marshalBuffer, &MiLdapPkt, &LdapPkt);
  827. if (!NT_SUCCESS(NtStatus)) {
  828. dwErr = RtlNtStatusToDosError(dwErr);
  829. goto Cleanup;
  830. }
  831. #if DBG
  832. if (DfsSvcVerbose)
  833. DbgPrint("Remarshal succeeded cBuffer = %d\n", cBuffer);
  834. #endif
  835. *pcbBlob = cBuffer;
  836. *ppBlob = Buffer;
  837. Buffer = NULL;
  838. Cleanup:
  839. FreeLdapPkt(&LdapPkt);
  840. if (dwErr != ERROR_SUCCESS && Buffer != NULL)
  841. free(Buffer);
  842. #if DBG
  843. if (DfsSvcVerbose)
  844. DbgPrint("DfsPutVolList exit %d\n", dwErr);
  845. #endif
  846. return dwErr;
  847. }
  848. //+------------------------------------------------------------------------
  849. //
  850. // Function: FreeLdapPkt
  851. //
  852. // Synopsis: Frees an LDAP_PKT structure and all substructures.
  853. //
  854. // History: 11/19/98 JHarper Created
  855. //
  856. //-------------------------------------------------------------------------
  857. VOID
  858. FreeLdapPkt(
  859. LDAP_PKT *pLdapPkt)
  860. {
  861. ULONG cObj;
  862. if (pLdapPkt->rgldapObjects != NULL) {
  863. for (cObj = 0; cObj < pLdapPkt->cLdapObjects; cObj++) {
  864. if (pLdapPkt->rgldapObjects[cObj].wszObjectName != NULL)
  865. MarshalBufferFree(pLdapPkt->rgldapObjects[cObj].wszObjectName);
  866. if (pLdapPkt->rgldapObjects[cObj].pObjectData != NULL)
  867. MarshalBufferFree(pLdapPkt->rgldapObjects[cObj].pObjectData);
  868. }
  869. MarshalBufferFree(pLdapPkt->rgldapObjects);
  870. }
  871. }
  872. //+------------------------------------------------------------------------
  873. //
  874. // Function: SerializeReplicaList
  875. //
  876. // Synopsis: This method serializes the replica info list and the
  877. // deleted replica info list into a buffer.
  878. //
  879. // Returns: [ERROR_SUCCESS] -- If all went well.
  880. //
  881. // [ERROR_OUTOFMEMORY] - If unable to allocate the target buffer.
  882. //
  883. // History: 11/19/98 JHarper Created
  884. //
  885. //-------------------------------------------------------------------------
  886. DWORD
  887. SerializeReplicaList(
  888. ULONG ReplCount,
  889. DFS_REPLICA_INFO *pReplicaInfo,
  890. FILETIME *pFtModification,
  891. ULONG DelReplCount,
  892. DFS_REPLICA_INFO *pDelReplicaInfo,
  893. FILETIME *pDelFtModification,
  894. ULONG *cBuffer,
  895. PBYTE *ppBuffer)
  896. {
  897. DWORD dwErr = ERROR_SUCCESS;
  898. ULONG TotalSize;
  899. ULONG i;
  900. ULONG *pSize;
  901. BYTE *Buffer = NULL;
  902. ULONG *SizeBuffer = NULL;
  903. #if DBG
  904. if (DfsSvcVerbose)
  905. DbgPrint("SerializeReplicaList(%d,%d)\n", ReplCount, DelReplCount);
  906. #endif
  907. pSize = SizeBuffer = (PULONG) malloc(sizeof(ULONG) * (ReplCount + DelReplCount));
  908. if (SizeBuffer == NULL) {
  909. return ERROR_OUTOFMEMORY;
  910. }
  911. //
  912. // Need all the size values now and later for marshalling stuff.
  913. // So we collect them here into an array.
  914. //
  915. TotalSize = 0;
  916. pSize = SizeBuffer;
  917. for (i = 0; i < ReplCount; i++) {
  918. *pSize = GetReplicaMarshalSize(&pReplicaInfo[i], &pFtModification[i]);
  919. TotalSize += *pSize;
  920. pSize++;
  921. }
  922. for (i = 0; i < DelReplCount; i++) {
  923. *pSize = GetReplicaMarshalSize(&pDelReplicaInfo[i], &pDelFtModification[i]);
  924. TotalSize += *pSize;
  925. pSize++;
  926. }
  927. //
  928. // Allocate the byte Buffer we need to pass back
  929. //
  930. // TotalSize is the size required just to marshal all the replicas and
  931. // their last-modification-timestamps.
  932. //
  933. // In addition, we need:
  934. //
  935. // 1 ULONG for storing the count of replicas
  936. // ReplCount ULONGs for storing the marshal size of each replica.
  937. // 1 ULONG for count of deleted replicas
  938. // DelReplCount ULONGS for storing the marshal size of each deleted Repl
  939. //
  940. //
  941. // First calc the size of the Buffer.
  942. //
  943. TotalSize += sizeof(ULONG) * (1 + ReplCount + 1 + DelReplCount);
  944. *ppBuffer = Buffer = (PBYTE) malloc(TotalSize);
  945. if (Buffer == NULL) {
  946. free(SizeBuffer);
  947. return ERROR_OUTOFMEMORY;
  948. }
  949. //
  950. // Set the number of entries to follow in the Buffer at the start.
  951. //
  952. _PutULong(Buffer, ReplCount);
  953. Buffer += sizeof(ULONG);
  954. pSize = SizeBuffer;
  955. for (i = 0; i < ReplCount; i++) {
  956. //
  957. // Marshall each replica Entry into the Buffer.
  958. // Remember we first need to put the size of the marshalled
  959. // replica entry to follow, then the FILETIME for the replica,
  960. // and finally, the marshalled replica entry structure.
  961. //
  962. _PutULong(Buffer, *pSize);
  963. Buffer += sizeof(ULONG);
  964. dwErr = SerializeReplica(&pReplicaInfo[i], &pFtModification[i], Buffer, *pSize);
  965. if (dwErr != ERROR_SUCCESS) {
  966. free(*ppBuffer);
  967. return dwErr;
  968. }
  969. Buffer += *pSize;
  970. pSize++;
  971. }
  972. //
  973. // Now marshal the deleted Repl list.
  974. //
  975. _PutULong(Buffer, DelReplCount);
  976. Buffer += sizeof(ULONG);
  977. for (i = 0; i < DelReplCount; i++) {
  978. _PutULong(Buffer, *pSize);
  979. Buffer += sizeof(ULONG);
  980. dwErr = SerializeReplica(&pDelReplicaInfo[i], &pDelFtModification[i], Buffer, *pSize);
  981. if (dwErr != ERROR_SUCCESS) {
  982. free(*ppBuffer);
  983. return dwErr;
  984. }
  985. Buffer += *pSize;
  986. pSize++;
  987. }
  988. *cBuffer = TotalSize;
  989. #if DBG
  990. if (DfsSvcVerbose)
  991. DbgPrint("SerializeReplicaList exit %d\n", dwErr);
  992. #endif
  993. return( dwErr );
  994. }
  995. //+------------------------------------------------------------------------
  996. //
  997. // Member: SerializeReplica
  998. //
  999. // Synopsis: Serializes a replica info structure
  1000. //
  1001. // Notes: The size of the buffer should have been calculated using
  1002. // the function GetReplicaMarshalSize()
  1003. //
  1004. // History: 13-May-93 SudK Created.
  1005. // 19-Nov-98 Jharper Modified.
  1006. //
  1007. //-------------------------------------------------------------------------
  1008. DWORD
  1009. SerializeReplica(
  1010. DFS_REPLICA_INFO *pDfsReplicaInfo,
  1011. FILETIME *pFtModification,
  1012. PBYTE Buffer,
  1013. ULONG Size)
  1014. {
  1015. DWORD dwErr;
  1016. MARSHAL_BUFFER MarshalBuffer;
  1017. NTSTATUS NtStatus;
  1018. MarshalBufferInitialize(&MarshalBuffer, Size, Buffer);
  1019. NtStatus = DfsRtlPut(&MarshalBuffer, &MiFileTime, pFtModification);
  1020. if (NT_SUCCESS(NtStatus))
  1021. NtStatus = DfsRtlPut(&MarshalBuffer, &MiDfsReplicaInfo, pDfsReplicaInfo);
  1022. dwErr = RtlNtStatusToDosError(NtStatus);
  1023. return dwErr;
  1024. }
  1025. //+----------------------------------------------------------------------
  1026. //
  1027. // Member: GetReplicaMarshalSize, public
  1028. //
  1029. // Synopsis: Returns the size of a buffer required to marshal this
  1030. // replica.
  1031. //
  1032. // History: 12-May-93 SudK Created.
  1033. // 19-Nov-98 Jharper Modified.
  1034. //
  1035. //-----------------------------------------------------------------------
  1036. ULONG
  1037. GetReplicaMarshalSize(
  1038. DFS_REPLICA_INFO *pDfsReplicaInfo,
  1039. FILETIME *pFtModification)
  1040. {
  1041. ULONG Size = 0;
  1042. NTSTATUS NtStatus;
  1043. NtStatus = DfsRtlSize(&MiFileTime, pFtModification, &Size);
  1044. if (NT_SUCCESS(NtStatus))
  1045. NtStatus = DfsRtlSize(&MiDfsReplicaInfo, pDfsReplicaInfo, &Size);
  1046. return(Size);
  1047. }
  1048. //+------------------------------------------------------------------------
  1049. //
  1050. // Member: UnSerializeReplicaList
  1051. //
  1052. // Synopsis: Unserializes a buffer into a relica list.
  1053. //
  1054. // History: 20-Nov-98 Jharper created
  1055. //
  1056. //-------------------------------------------------------------------------
  1057. DWORD
  1058. UnSerializeReplicaList(
  1059. ULONG *pReplCount,
  1060. ULONG *pAllocatedReplCount,
  1061. DFS_REPLICA_INFO **ppReplicaInfo,
  1062. FILETIME **ppFtModification,
  1063. BYTE **ppBuffer)
  1064. {
  1065. DFS_REPLICA_INFO *pReplicaInfo = NULL;
  1066. FILETIME *pFtModification = NULL;
  1067. ULONG ReplCount;
  1068. BYTE *pBuffer = *ppBuffer;
  1069. ULONG cRepl;
  1070. ULONG Size;
  1071. DWORD dwErr = ERROR_SUCCESS;
  1072. MARSHAL_BUFFER marshalBuffer;
  1073. NTSTATUS NtStatus;
  1074. //
  1075. // Get # replicas
  1076. //
  1077. _GetULong(pBuffer, ReplCount);
  1078. pBuffer += sizeof(ULONG);
  1079. pReplicaInfo = (DFS_REPLICA_INFO *) malloc(sizeof(DFS_REPLICA_INFO) * ReplCount);
  1080. pFtModification = (FILETIME *) malloc(sizeof(FILETIME) * ReplCount);
  1081. if(pReplicaInfo == NULL || pFtModification == NULL) {
  1082. dwErr = ERROR_OUTOFMEMORY;
  1083. goto Cleanup;
  1084. }
  1085. //
  1086. // Now get each replica
  1087. //
  1088. for (cRepl = 0; cRepl < ReplCount; cRepl++) {
  1089. _GetULong(pBuffer, Size);
  1090. pBuffer += sizeof(ULONG);
  1091. MarshalBufferInitialize(
  1092. &marshalBuffer,
  1093. Size,
  1094. pBuffer);
  1095. NtStatus = DfsRtlGet(
  1096. &marshalBuffer,
  1097. &MiFileTime,
  1098. &pFtModification[cRepl]);
  1099. if (NT_SUCCESS(NtStatus)) {
  1100. NtStatus = DfsRtlGet(
  1101. &marshalBuffer,
  1102. &MiDfsReplicaInfo,
  1103. &pReplicaInfo[cRepl]);
  1104. }
  1105. if (NT_SUCCESS(NtStatus)) {
  1106. pBuffer += Size;
  1107. }
  1108. }
  1109. *ppReplicaInfo = pReplicaInfo;
  1110. *ppFtModification = pFtModification;
  1111. *ppBuffer = pBuffer;
  1112. *pAllocatedReplCount = *pReplCount = ReplCount;
  1113. Cleanup:
  1114. if (dwErr != ERROR_SUCCESS) {
  1115. if (pReplicaInfo != NULL)
  1116. free(pReplicaInfo);
  1117. if (pFtModification != NULL)
  1118. free(pFtModification);
  1119. }
  1120. return dwErr;
  1121. }
  1122. //+------------------------------------------------------------------------
  1123. //
  1124. // Function: DfsGetSiteTable
  1125. //
  1126. // Synopsis: Unserializes the buffer passed in into a dfs site table.
  1127. //
  1128. // Returns: [ERROR_SUCCESS] -- If all went well.
  1129. //
  1130. // [ERROR_OUTOFMEMORY] - If unable to allocate the target buffer.
  1131. //
  1132. // History: 11/19/98 JHarper Created
  1133. //
  1134. //-------------------------------------------------------------------------
  1135. DWORD
  1136. DfsGetSiteTable(
  1137. PDFS_VOLUME_LIST pDfsVolList,
  1138. PLDAP_OBJECT pLdapObject)
  1139. {
  1140. DWORD dwErr = ERROR_SUCCESS;
  1141. NTSTATUS NtStatus;
  1142. ULONG cSite;
  1143. PDFSM_SITE_ENTRY pSiteEntry;
  1144. PDFSM_SITE_ENTRY pTmpSiteEntry;
  1145. MARSHAL_BUFFER marshalBuffer;
  1146. BYTE *pBuffer = NULL;
  1147. ULONG Size;
  1148. #if DBG
  1149. if (DfsSvcVerbose)
  1150. DbgPrint("DfsGetSiteTable(%d)\n", pLdapObject->cbObjectData);
  1151. #endif
  1152. InitializeListHead(&pDfsVolList->SiteList);
  1153. MarshalBufferInitialize(
  1154. &marshalBuffer,
  1155. pLdapObject->cbObjectData,
  1156. pLdapObject->pObjectData);
  1157. NtStatus = DfsRtlGetGuid(&marshalBuffer, &pDfsVolList->SiteGuid);
  1158. if (!NT_SUCCESS(NtStatus)) {
  1159. dwErr = RtlNtStatusToDosError(NtStatus);
  1160. goto Cleanup;
  1161. }
  1162. NtStatus = DfsRtlGetUlong(&marshalBuffer, &pDfsVolList->SiteCount);
  1163. if (!NT_SUCCESS(NtStatus)) {
  1164. dwErr = RtlNtStatusToDosError(NtStatus);
  1165. goto Cleanup;
  1166. }
  1167. pBuffer = (BYTE *)malloc(pLdapObject->cbObjectData);
  1168. if (pBuffer == NULL) {
  1169. dwErr = ERROR_OUTOFMEMORY;
  1170. goto Cleanup;
  1171. }
  1172. pTmpSiteEntry = (PDFSM_SITE_ENTRY)pBuffer;
  1173. for (cSite = 0; cSite < pDfsVolList->SiteCount; cSite++) {
  1174. RtlZeroMemory(pBuffer, pLdapObject->cbObjectData);
  1175. NtStatus = DfsRtlGet(
  1176. &marshalBuffer,
  1177. &MiDfsmSiteEntry,
  1178. pBuffer);
  1179. if (!NT_SUCCESS(NtStatus)) {
  1180. dwErr = RtlNtStatusToDosError(NtStatus);
  1181. goto Cleanup;
  1182. }
  1183. Size = sizeof(DFSM_SITE_ENTRY) + (pTmpSiteEntry->Info.cSites * sizeof(DFS_SITENAME_INFO));
  1184. pSiteEntry = (PDFSM_SITE_ENTRY) malloc(Size);
  1185. if (pSiteEntry == NULL) {
  1186. dwErr = ERROR_OUTOFMEMORY;
  1187. goto Cleanup;
  1188. }
  1189. RtlCopyMemory(pSiteEntry, pBuffer, Size);
  1190. InsertHeadList(&pDfsVolList->SiteList, &pSiteEntry->Link);
  1191. }
  1192. Cleanup:
  1193. if (pBuffer != NULL)
  1194. free(pBuffer);
  1195. #if DBG
  1196. if (DfsSvcVerbose)
  1197. DbgPrint("DfsGetSiteTable exit dwErr=%d\n", dwErr);
  1198. #endif
  1199. return dwErr;
  1200. }
  1201. //+----------------------------------------------------------------------------
  1202. //
  1203. // Function: GetNetInfoEx
  1204. //
  1205. // Synopsis: Gets information about the volume.
  1206. //
  1207. // Arguments: [Level] -- Level of Information desired.
  1208. //
  1209. // [pDfsVol] - Pointer to DFS_VOLUME to use to fill the info
  1210. //
  1211. // [pInfo] -- Pointer to info struct to be filled. Pointer
  1212. // members will be allocated using MIDL_user_allocate.
  1213. // The type of this variable is LPDFS_INFO_3, but one
  1214. // can pass in pointers to lower levels, and only the
  1215. // fields appropriate for the level will be touched.
  1216. //
  1217. // [pcbInfo] -- On successful return, contains the size in
  1218. // bytes of the returned info. The returned size does
  1219. // not include the size of the DFS_INFO_3 struct itself.
  1220. //
  1221. // Returns: ERROR_SUCCESS -- Successfully returning info
  1222. //
  1223. // ERROR_OUTOFMEMORY -- Out of memory
  1224. //
  1225. //-----------------------------------------------------------------------------
  1226. DWORD
  1227. GetNetInfoEx(
  1228. PDFS_VOLUME pDfsVol,
  1229. DWORD Level,
  1230. LPDFS_INFO_3 pInfo,
  1231. LPDWORD pcbInfo)
  1232. {
  1233. DWORD dwErr = ERROR_SUCCESS;
  1234. DWORD cbInfo = 0;
  1235. DWORD cbItem;
  1236. ULONG i;
  1237. #if DBG
  1238. if (DfsSvcVerbose)
  1239. DbgPrint("GetNetInfoEx(%ws,%d)\n", pDfsVol->wszPrefix, Level);
  1240. #endif
  1241. //
  1242. // See if this is a Level 100 or 101. If so, we handle them right away
  1243. // and return
  1244. if (Level == 100) {
  1245. LPDFS_INFO_100 pInfo100 = (LPDFS_INFO_100) pInfo;
  1246. if (pDfsVol->wszComment != NULL) {
  1247. cbItem = (wcslen(pDfsVol->wszComment) + 1) * sizeof(WCHAR);
  1248. pInfo100->Comment = (LPWSTR) MIDL_user_allocate(cbItem);
  1249. if (pInfo100->Comment != NULL) {
  1250. wcscpy(pInfo100->Comment, pDfsVol->wszComment);
  1251. cbInfo += cbItem;
  1252. goto AllDone;
  1253. } else {
  1254. dwErr = ERROR_OUTOFMEMORY;
  1255. goto AllDone;
  1256. }
  1257. } else {
  1258. pInfo100->Comment = (LPWSTR) MIDL_user_allocate(sizeof(WCHAR));
  1259. if (pInfo100->Comment != NULL) {
  1260. pInfo100->Comment[0] = UNICODE_NULL;
  1261. cbInfo += sizeof(WCHAR);
  1262. goto AllDone;
  1263. } else {
  1264. dwErr = ERROR_OUTOFMEMORY;
  1265. goto AllDone;
  1266. }
  1267. }
  1268. }
  1269. if (Level == 101) {
  1270. LPDFS_INFO_101 pInfo101 = (LPDFS_INFO_101) pInfo;
  1271. pInfo->State = pDfsVol->dwState;
  1272. goto AllDone;
  1273. }
  1274. //
  1275. // level 4 isn't just an extension of 3, so handle it seperately
  1276. //
  1277. if (Level == 4) {
  1278. LPDFS_INFO_4 pInfo4 = (LPDFS_INFO_4) pInfo;
  1279. cbItem = sizeof(UNICODE_PATH_SEP) + (wcslen(pDfsVol->wszPrefix) + 1) * sizeof(WCHAR);
  1280. pInfo4->EntryPath = (LPWSTR) MIDL_user_allocate(cbItem);
  1281. if (pInfo4->EntryPath != NULL) {
  1282. pInfo4->EntryPath[0] = UNICODE_PATH_SEP;
  1283. wcscpy(&pInfo4->EntryPath[1], pDfsVol->wszPrefix);
  1284. cbInfo += cbItem;
  1285. } else {
  1286. dwErr = ERROR_OUTOFMEMORY;
  1287. goto AllDone;
  1288. }
  1289. if (pDfsVol->wszComment != NULL) {
  1290. cbItem = (wcslen(pDfsVol->wszComment)+1) * sizeof(WCHAR);
  1291. pInfo4->Comment = (LPWSTR) MIDL_user_allocate(cbItem);
  1292. if (pInfo4->Comment != NULL) {
  1293. wcscpy( pInfo4->Comment, pDfsVol->wszComment );
  1294. cbInfo += cbItem;
  1295. } else {
  1296. dwErr = ERROR_OUTOFMEMORY;
  1297. goto AllDone;
  1298. }
  1299. } else {
  1300. pInfo4->Comment = (LPWSTR) MIDL_user_allocate(sizeof(WCHAR));
  1301. if (pInfo4->Comment != NULL) {
  1302. pInfo4->Comment[0] = UNICODE_NULL;
  1303. cbInfo += sizeof(WCHAR);
  1304. } else {
  1305. dwErr = ERROR_OUTOFMEMORY;
  1306. goto AllDone;
  1307. }
  1308. }
  1309. pInfo4->State = pDfsVol->dwState;
  1310. pInfo4->Timeout = pDfsVol->dwTimeout;
  1311. pInfo4->Guid = pDfsVol->idVolume;
  1312. pInfo4->NumberOfStorages = pDfsVol->ReplCount;
  1313. cbItem = pInfo4->NumberOfStorages * sizeof(DFS_STORAGE_INFO);
  1314. pInfo4->Storage = (LPDFS_STORAGE_INFO) MIDL_user_allocate(cbItem);
  1315. if (pInfo4->Storage != NULL) {
  1316. RtlZeroMemory(pInfo4->Storage, cbItem);
  1317. cbInfo += cbItem;
  1318. for (i = 0; i < pDfsVol->ReplCount; i++) {
  1319. dwErr = GetNetStorageInfo(&pDfsVol->ReplicaInfo[i],&pInfo4->Storage[i],&cbItem);
  1320. cbInfo += cbItem;
  1321. }
  1322. if (dwErr != ERROR_SUCCESS) {
  1323. for (; i > 0; i--) {
  1324. MIDL_user_free(pInfo4->Storage[i-1].ServerName);
  1325. MIDL_user_free(pInfo4->Storage[i-1].ShareName);
  1326. }
  1327. }
  1328. } else {
  1329. dwErr = ERROR_OUTOFMEMORY;
  1330. }
  1331. //
  1332. // See if we need to clean up...
  1333. //
  1334. if (dwErr != ERROR_SUCCESS) {
  1335. if (pInfo4->EntryPath != NULL) {
  1336. MIDL_user_free(pInfo4->EntryPath);
  1337. }
  1338. if (pInfo4->Storage != NULL) {
  1339. MIDL_user_free(pInfo4->Storage);
  1340. }
  1341. goto AllDone;
  1342. } else {
  1343. *pcbInfo = cbInfo;
  1344. }
  1345. goto AllDone;
  1346. }
  1347. //
  1348. // Level is 1,2 or 3
  1349. //
  1350. //
  1351. // Fill in the Level 1 stuff
  1352. //
  1353. cbItem = sizeof(UNICODE_PATH_SEP) + (wcslen(pDfsVol->wszPrefix)+1) * sizeof(WCHAR);
  1354. pInfo->EntryPath = (LPWSTR) MIDL_user_allocate(cbItem);
  1355. if (pInfo->EntryPath != NULL) {
  1356. pInfo->EntryPath[0] = UNICODE_PATH_SEP;
  1357. wcscpy(&pInfo->EntryPath[1], pDfsVol->wszPrefix);
  1358. cbInfo += cbItem;
  1359. } else {
  1360. dwErr = ERROR_OUTOFMEMORY;
  1361. goto AllDone;
  1362. }
  1363. //
  1364. // Fill in the Level 2 stuff if needed
  1365. //
  1366. if (Level > 1) {
  1367. pInfo->State = pDfsVol->dwState;
  1368. pInfo->NumberOfStorages = pDfsVol->ReplCount;
  1369. if (pDfsVol->wszComment != NULL) {
  1370. cbItem = (wcslen(pDfsVol->wszComment)+1) * sizeof(WCHAR);
  1371. pInfo->Comment = (LPWSTR) MIDL_user_allocate(cbItem);
  1372. if (pInfo->Comment != NULL) {
  1373. wcscpy( pInfo->Comment, pDfsVol->wszComment );
  1374. cbInfo += cbItem;
  1375. } else {
  1376. dwErr = ERROR_OUTOFMEMORY;
  1377. }
  1378. } else {
  1379. pInfo->Comment = (LPWSTR) MIDL_user_allocate(sizeof(WCHAR));
  1380. if (pInfo->Comment != NULL) {
  1381. pInfo->Comment[0] = UNICODE_NULL;
  1382. cbInfo += sizeof(WCHAR);
  1383. } else {
  1384. dwErr = ERROR_OUTOFMEMORY;
  1385. }
  1386. }
  1387. }
  1388. //
  1389. // Fill in the Level 3 stuff if needed
  1390. //
  1391. if (dwErr == ERROR_SUCCESS && Level > 2) {
  1392. cbItem = pInfo->NumberOfStorages * sizeof(DFS_STORAGE_INFO);
  1393. pInfo->Storage = (LPDFS_STORAGE_INFO) MIDL_user_allocate(cbItem);
  1394. if (pInfo->Storage != NULL) {
  1395. RtlZeroMemory(pInfo->Storage, cbItem);
  1396. cbInfo += cbItem;
  1397. for (i = 0; i < pDfsVol->ReplCount; i++) {
  1398. dwErr = GetNetStorageInfo(&pDfsVol->ReplicaInfo[i], &pInfo->Storage[i], &cbItem);
  1399. cbInfo += cbItem;
  1400. }
  1401. if (dwErr != ERROR_SUCCESS) {
  1402. for (; i > 0; i--) {
  1403. MIDL_user_free(pInfo->Storage[i-1].ServerName);
  1404. MIDL_user_free(pInfo->Storage[i-1].ShareName);
  1405. }
  1406. }
  1407. } else {
  1408. dwErr = ERROR_OUTOFMEMORY;
  1409. }
  1410. }
  1411. //
  1412. // See if we need to clean up...
  1413. //
  1414. if (dwErr != ERROR_SUCCESS) {
  1415. if (Level > 1) {
  1416. if (pInfo->EntryPath != NULL) {
  1417. MIDL_user_free(pInfo->EntryPath);
  1418. }
  1419. }
  1420. if (Level > 2) {
  1421. if (pInfo->Storage != NULL) {
  1422. MIDL_user_free(pInfo->Storage);
  1423. }
  1424. }
  1425. }
  1426. AllDone:
  1427. //
  1428. // Finally, we are done
  1429. //
  1430. if (dwErr == ERROR_SUCCESS)
  1431. *pcbInfo = cbInfo;
  1432. #if DBG
  1433. if (DfsSvcVerbose)
  1434. DbgPrint("GetNetInfoEx returning %d\n", dwErr);
  1435. #endif
  1436. return(dwErr);
  1437. }
  1438. //+----------------------------------------------------------------------------
  1439. //
  1440. // Function: GetNetStorageInfo, public
  1441. //
  1442. // Synopsis: Returns the replica info in a DFS_STORAGE_INFO struct.
  1443. // Useful for NetDfsXXX APIs.
  1444. //
  1445. // Arguments: [pInfo] -- Pointer to DFS_STORAGE_INFO to fill. Pointer
  1446. // members will be allocated using MIDL_user_allocate.
  1447. //
  1448. // [pcbInfo] -- On successful return, set to size in bytes of
  1449. // returned info. The size does not include the size
  1450. // of the DFS_STORAGE_INFO struct itself.
  1451. //
  1452. // Returns:
  1453. //
  1454. //-----------------------------------------------------------------------------
  1455. DWORD
  1456. GetNetStorageInfo(
  1457. PDFS_REPLICA_INFO pRepl,
  1458. LPDFS_STORAGE_INFO pInfo,
  1459. LPDWORD pcbInfo)
  1460. {
  1461. DWORD dwErr = ERROR_SUCCESS;
  1462. LPWSTR wszShare;
  1463. DWORD cbInfo = 0, cbItem;
  1464. #if DBG
  1465. if (DfsSvcVerbose)
  1466. DbgPrint("GetNetStorageInfo(\\\\%ws\\%ws)\n",
  1467. pRepl->pwszServerName,
  1468. pRepl->pwszShareName);
  1469. #endif
  1470. pInfo->State = pRepl->ulReplicaState;
  1471. cbItem = (wcslen(pRepl->pwszServerName) + 1) * sizeof(WCHAR);
  1472. pInfo->ServerName = (LPWSTR) MIDL_user_allocate(cbItem);
  1473. if (pInfo->ServerName != NULL) {
  1474. wcscpy(pInfo->ServerName, pRepl->pwszServerName);
  1475. cbInfo += cbItem;
  1476. } else {
  1477. dwErr = ERROR_OUTOFMEMORY;
  1478. }
  1479. if (dwErr == ERROR_SUCCESS) {
  1480. cbItem = (wcslen(pRepl->pwszShareName) + 1) * sizeof(WCHAR);
  1481. pInfo->ShareName = (LPWSTR) MIDL_user_allocate(cbItem);
  1482. if (pInfo->ShareName != NULL) {
  1483. wcscpy( pInfo->ShareName, pRepl->pwszShareName );
  1484. cbInfo += cbItem;
  1485. } else {
  1486. MIDL_user_free( pInfo->ServerName );
  1487. pInfo->ServerName = NULL;
  1488. dwErr = ERROR_OUTOFMEMORY;
  1489. }
  1490. }
  1491. if (dwErr == ERROR_SUCCESS)
  1492. *pcbInfo = cbInfo;
  1493. #if DBG
  1494. if (DfsSvcVerbose)
  1495. DbgPrint("GetStorageInfo returning %d\n", dwErr);
  1496. #endif
  1497. return( dwErr );
  1498. }
  1499. //+------------------------------------------------------------------------
  1500. //
  1501. // Function: DfsRemoveRootReplica
  1502. //
  1503. // Synopsis: Removes a Dfs root replica from the dfs root replica list
  1504. //
  1505. // History: 12/16/98 JHarper Created
  1506. //
  1507. //-------------------------------------------------------------------------
  1508. DWORD
  1509. DfsRemoveRootReplica(
  1510. PDFS_VOLUME_LIST pDfsVolList,
  1511. LPWSTR RootName)
  1512. {
  1513. ULONG cVol;
  1514. ULONG cRepl;
  1515. DWORD dwErr = ERROR_SUCCESS;
  1516. #if DBG
  1517. if (DfsSvcVerbose)
  1518. DbgPrint("DfsRemoveRootReplica(%ws)\n", RootName);
  1519. #endif
  1520. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  1521. if (wcscmp(pDfsVolList->Volumes[cVol].wszObjectName,L"\\domainroot") != 0)
  1522. continue;
  1523. ScanReplicas:
  1524. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol].ReplCount; cRepl++) {
  1525. if (
  1526. _wcsicmp(
  1527. pDfsVolList->Volumes[cVol].ReplicaInfo[cRepl].pwszServerName,
  1528. RootName) == 0
  1529. ) {
  1530. DfsReplDeleteByIndex(&pDfsVolList->Volumes[cVol], cRepl);
  1531. goto ScanReplicas;
  1532. }
  1533. }
  1534. break;
  1535. }
  1536. #if DBG
  1537. if (DfsSvcVerbose)
  1538. DbgPrint("DfsRemoveRootReplica exit %d\n", dwErr);
  1539. #endif
  1540. return dwErr;
  1541. }
  1542. //+----------------------------------------------------------------------------
  1543. //
  1544. // Function: DfsRecoverVolList, public
  1545. //
  1546. // Synopsis: Walks the dfs_volume list, checking the recovery params, and
  1547. // applying any recovery needed. Also applies the deleted replica
  1548. // list to the volume's replica list.
  1549. //
  1550. // Arguments: [pDfsVolList] -- Pointer to DFS_VOLUME_LIST work on.
  1551. //
  1552. // Returns:
  1553. //
  1554. //-----------------------------------------------------------------------------
  1555. DWORD
  1556. DfsRecoverVolList(
  1557. PDFS_VOLUME_LIST pDfsVolList)
  1558. {
  1559. DWORD dwErr = ERROR_SUCCESS;
  1560. ULONG iVol;
  1561. ULONG iRepl;
  1562. ULONG iDelRepl;
  1563. PDFS_VOLUME pVol;
  1564. ULONG RecoveryState;
  1565. ULONG Operation;
  1566. ULONG OperState;
  1567. #if DBG
  1568. if (DfsSvcVerbose)
  1569. DbgPrint("DfsRecoverVolList(%d volumes)\n", pDfsVolList->VolCount);
  1570. #endif
  1571. ReStart:
  1572. for (iVol = 0; dwErr == ERROR_SUCCESS && iVol < pDfsVolList->VolCount; iVol++) {
  1573. pVol = &pDfsVolList->Volumes[iVol];
  1574. if (pVol->cbRecovery >= sizeof(ULONG)) {
  1575. _GetULong(pVol->pRecovery, RecoveryState);
  1576. #if DBG
  1577. if (DfsSvcVerbose)
  1578. DbgPrint("RecoveryState[%d]=0x%x\n", iVol, RecoveryState);
  1579. #endif
  1580. if (DFS_GET_RECOVERY_STATE(RecoveryState) != DFS_RECOVERY_STATE_NONE) {
  1581. Operation = DFS_GET_RECOVERY_STATE(RecoveryState);
  1582. OperState = DFS_GET_OPER_STAGE(RecoveryState);
  1583. switch (Operation) {
  1584. case DFS_RECOVERY_STATE_CREATING:
  1585. #if DBG
  1586. if (DfsSvcVerbose)
  1587. DbgPrint("DFS_RECOVERY_STATE_CREATING\n");
  1588. #endif
  1589. dwErr = DfsVolDelete(pDfsVolList, iVol);
  1590. goto ReStart;
  1591. case DFS_RECOVERY_STATE_ADD_SERVICE:
  1592. #if DBG
  1593. if (DfsSvcVerbose)
  1594. DbgPrint("DFS_RECOVERY_STATE_ADD_SERVICE\n");
  1595. #endif
  1596. // dwErr = RecoverFromAddService(OperState);
  1597. ASSERT(L"DFS_RECOVERY_STATE_ADD_SERVICE - WHY?\n");
  1598. break;
  1599. case DFS_RECOVERY_STATE_REMOVE_SERVICE:
  1600. #if DBG
  1601. if (DfsSvcVerbose)
  1602. DbgPrint("DFS_RECOVERY_STATE_REMOVE_SERVICE\n");
  1603. #endif
  1604. // dwErr = RecoverFromRemoveService(OperState);
  1605. ASSERT(L"DFS_RECOVERY_STATE_REMOVE_SERVICE - WHY?\n");
  1606. break;
  1607. case DFS_RECOVERY_STATE_DELETE:
  1608. #if DBG
  1609. if (DfsSvcVerbose)
  1610. DbgPrint("DFS_RECOVERY_STATE_DELETE\n");
  1611. #endif
  1612. dwErr = DfsVolDelete(pDfsVolList, iVol);
  1613. goto ReStart;
  1614. default:
  1615. #if DBG
  1616. if (DfsSvcVerbose)
  1617. DbgPrint("default\n");
  1618. #endif
  1619. dwErr = ERROR_INTERNAL_DB_CORRUPTION;
  1620. }
  1621. }
  1622. }
  1623. if (pVol->pRecovery != NULL)
  1624. MarshalBufferFree(pVol->pRecovery);
  1625. pVol->pRecovery = NULL;
  1626. pVol->cbRecovery = 0;
  1627. }
  1628. if (dwErr != ERROR_SUCCESS)
  1629. goto AllDone;
  1630. //
  1631. // Now apply deleted replica list to each volume
  1632. //
  1633. for (iVol = 0; dwErr == ERROR_SUCCESS && iVol < pDfsVolList->VolCount; iVol++) {
  1634. pVol = &pDfsVolList->Volumes[iVol];
  1635. for (iDelRepl = 0; dwErr == ERROR_SUCCESS && iDelRepl < pVol->DelReplCount; iDelRepl++) {
  1636. #if 0 // XXX This appears to be wrong - don't do it.
  1637. dwErr = DfsReplDeleteByName(
  1638. pVol,
  1639. pVol->DelReplicaInfo[iDelRepl].pwszServerName,
  1640. pVol->DelReplicaInfo[iDelRepl].pwszShareName);
  1641. #endif
  1642. DfsFreeRepl(&pVol->DelReplicaInfo[iDelRepl]);
  1643. }
  1644. if (pVol->DelReplicaInfo != NULL) {
  1645. free(pVol->DelReplicaInfo);
  1646. pVol->DelReplicaInfo = NULL;
  1647. }
  1648. if (pVol->DelFtModification != NULL) {
  1649. free(pVol->DelFtModification);
  1650. pVol->DelFtModification = NULL;
  1651. }
  1652. pVol->DelReplCount = 0;
  1653. }
  1654. AllDone:
  1655. #if DBG
  1656. if (DfsSvcVerbose)
  1657. DbgPrint("DfsRecoverVolList returning %d\n", dwErr);
  1658. #endif
  1659. return dwErr;
  1660. }
  1661. //+----------------------------------------------------------------------------
  1662. //
  1663. // Function: DfsVolDelete, public
  1664. //
  1665. // Synopsis: Removes a DFS_VOLUME from DFS_VOLUME_LIST
  1666. //
  1667. // Arguments: [pDfsVolList] -- Pointer to DFS_VOLUME_LIST work on.
  1668. // [iVol] -- Index of volume to delete
  1669. //
  1670. // Returns:
  1671. //
  1672. //-----------------------------------------------------------------------------
  1673. DWORD
  1674. DfsVolDelete(
  1675. PDFS_VOLUME_LIST pDfsVolList,
  1676. ULONG iVol)
  1677. {
  1678. ULONG i;
  1679. DWORD dwErr = ERROR_SUCCESS;
  1680. ASSERT(iVol < pDfsVolList->VolCount);
  1681. #if DBG
  1682. if (DfsSvcVerbose)
  1683. DbgPrint("DfsVolDelete(%d)\n", iVol);
  1684. #endif
  1685. //
  1686. // Free any memory this Volume is using
  1687. //
  1688. DfsFreeVol(&pDfsVolList->Volumes[iVol]);
  1689. //
  1690. // Since we're shrinking the list, we simply clip out the entry we don't want
  1691. // and adjust the count.
  1692. //
  1693. for (i = iVol+1; i < pDfsVolList->VolCount; i++)
  1694. pDfsVolList->Volumes[i-1] = pDfsVolList->Volumes[i];
  1695. pDfsVolList->VolCount--;
  1696. RtlZeroMemory(&pDfsVolList->Volumes[pDfsVolList->VolCount], sizeof(DFS_VOLUME));
  1697. #if DBG
  1698. if (DfsSvcVerbose)
  1699. DbgPrint("DfsVolDelete returning %d\n", dwErr);
  1700. #endif
  1701. return dwErr;
  1702. }
  1703. //+----------------------------------------------------------------------------
  1704. //
  1705. // Function: DfsReplDeleteByIndex, public
  1706. //
  1707. // Synopsis: Removes a PDFS_REPLICA_INFO from a DFS_VOLUME's replica list
  1708. //
  1709. // Arguments: [pDfsVol] -- Pointer to DFS_VOLUME work on.
  1710. // [iRepl] -- Index of replica to delete
  1711. //
  1712. // Returns:
  1713. //
  1714. //-----------------------------------------------------------------------------
  1715. DWORD
  1716. DfsReplDeleteByIndex(
  1717. PDFS_VOLUME pVol,
  1718. ULONG iRepl)
  1719. {
  1720. ULONG i;
  1721. DWORD dwErr = ERROR_SUCCESS;
  1722. ASSERT(iRepl < pVol->ReplCount);
  1723. #if DBG
  1724. if (DfsSvcVerbose)
  1725. DbgPrint("DfsReplDeleteByIndex(%d)\n", iRepl);
  1726. #endif
  1727. //
  1728. // Free any memory this replica is using
  1729. //
  1730. DfsFreeRepl(&pVol->ReplicaInfo[iRepl]);
  1731. //
  1732. // Since we're shrinking the list(s), we simply clip out the entry we don't want
  1733. // and adjust the count.
  1734. //
  1735. for (i = iRepl+1; i < pVol->ReplCount; i++) {
  1736. pVol->ReplicaInfo[i-1] = pVol->ReplicaInfo[i];
  1737. pVol->FtModification[i-1] = pVol->FtModification[i];
  1738. }
  1739. pVol->ReplCount--;
  1740. RtlZeroMemory(&pVol->ReplicaInfo[pVol->ReplCount], sizeof(DFS_REPLICA_INFO));
  1741. #if DBG
  1742. if (DfsSvcVerbose)
  1743. DbgPrint("DfsReplDeleteByIndex returning %d\n", dwErr);
  1744. #endif
  1745. return dwErr;
  1746. }
  1747. //+----------------------------------------------------------------------------
  1748. //
  1749. // Function: DfsReplDeleteByName, public
  1750. //
  1751. // Synopsis: Removes a PDFS_REPLICA_INFO from a DFS_VOLUME's replica list. Simply
  1752. // looks up the replica by name and then calls DfsReplDeleteByIndex()
  1753. //
  1754. // Arguments: [pDfsVol] -- Pointer to DFS_VOLUME work on.
  1755. // [pwszServername] - Server Name
  1756. // [pwszShareName] - Share Name
  1757. //
  1758. // Returns:
  1759. //
  1760. //-----------------------------------------------------------------------------
  1761. DWORD
  1762. DfsReplDeleteByName(
  1763. PDFS_VOLUME pVol,
  1764. LPWSTR pwszServerName,
  1765. LPWSTR pwszShareName)
  1766. {
  1767. ULONG iRep;
  1768. DWORD dwErr = ERROR_SUCCESS;
  1769. #if DBG
  1770. if (DfsSvcVerbose)
  1771. DbgPrint("DfsReplDeleteByName(%ws,%ws)\n", pwszServerName, pwszShareName);
  1772. #endif
  1773. if (pwszServerName == NULL || pwszShareName == NULL) {
  1774. dwErr = ERROR_INVALID_PARAMETER;
  1775. goto AllDone;
  1776. }
  1777. ReStart:
  1778. //
  1779. // Scan the volume's replica list, and if there is a match on the
  1780. // passed-in servername and sharename, remove the replica.
  1781. //
  1782. for (iRep = 0; iRep < pVol->ReplCount; iRep++) {
  1783. if (_wcsicmp(pVol->ReplicaInfo[iRep].pwszServerName, pwszServerName) == 0
  1784. &&
  1785. _wcsicmp(pVol->ReplicaInfo[iRep].pwszShareName, pwszShareName) == 0
  1786. ) {
  1787. dwErr = DfsReplDeleteByIndex(pVol, iRep);
  1788. goto ReStart;
  1789. }
  1790. }
  1791. AllDone:
  1792. #if DBG
  1793. if (DfsSvcVerbose)
  1794. DbgPrint("DfsReplDeleteByName returning %d\n", dwErr);
  1795. #endif
  1796. return dwErr;
  1797. }
  1798. //+----------------------------------------------------------------------------
  1799. //
  1800. // Function: DfsDelReplDelete, public
  1801. //
  1802. // Synopsis: Removes a PDFS_REPLICA_INFO from a DFS_VOLUME's deleted replica list
  1803. //
  1804. // Arguments: [pDfsVol] -- Pointer to DFS_VOLUME work on.
  1805. // [iDelRepl] -- Index of Deleted replica to delete
  1806. //
  1807. // Returns:
  1808. //
  1809. //-----------------------------------------------------------------------------
  1810. DWORD
  1811. DfsDelReplDelete(
  1812. PDFS_VOLUME pVol,
  1813. ULONG iDelRepl)
  1814. {
  1815. ULONG i;
  1816. DWORD dwErr = ERROR_SUCCESS;
  1817. ASSERT(iDelRepl < pVol->DelReplCount);
  1818. #if DBG
  1819. if (DfsSvcVerbose)
  1820. DbgPrint("DfsDelReplDelete(%d)\n", iDelRepl);
  1821. #endif
  1822. //
  1823. // Free any memory this replica is using
  1824. //
  1825. DfsFreeRepl(&pVol->DelReplicaInfo[iDelRepl]);
  1826. //
  1827. // Since we're shrinking the list(s), we simply clip out the entry we don't want
  1828. // and adjust the count.
  1829. //
  1830. for (i = iDelRepl+1; i < pVol->DelReplCount; i++) {
  1831. pVol->DelReplicaInfo[i-1] = pVol->DelReplicaInfo[i];
  1832. pVol->DelFtModification[i-1] = pVol->DelFtModification[i];
  1833. }
  1834. pVol->DelReplCount--;
  1835. RtlZeroMemory(&pVol->DelReplicaInfo[pVol->DelReplCount], sizeof(DFS_REPLICA_INFO));
  1836. #if DBG
  1837. if (DfsSvcVerbose)
  1838. DbgPrint("DfsDelReplDelete returning %d\n", dwErr);
  1839. #endif
  1840. return dwErr;
  1841. }
  1842. #if DBG
  1843. void
  1844. DumpBuf(PCHAR cp, ULONG len)
  1845. {
  1846. ULONG i, j, c;
  1847. for (i = 0; i < len; i += 16) {
  1848. DbgPrint("%08x ", i /* +(ULONG)cp */);
  1849. for (j = 0; j < 16; j++) {
  1850. if (j == 8)
  1851. DbgPrint(" ");
  1852. if (i+j < len) {
  1853. c = cp[i+j] & 0xff;
  1854. DbgPrint("%02x ", c);
  1855. } else {
  1856. DbgPrint(" ");
  1857. }
  1858. }
  1859. DbgPrint(" ");
  1860. for (j = 0; j < 16; j++) {
  1861. if (j == 8)
  1862. DbgPrint("|");
  1863. if (i+j < len) {
  1864. c = cp[i+j] & 0xff;
  1865. if (c < ' ' || c > '~')
  1866. c = '.';
  1867. DbgPrint("%c", c);
  1868. } else {
  1869. DbgPrint(" ");
  1870. }
  1871. }
  1872. DbgPrint("\n");
  1873. }
  1874. }
  1875. //+------------------------------------------------------------------------
  1876. //
  1877. // Function: DfsDumpVolList
  1878. //
  1879. // Synopsis: Prints the volume information represented by the volume
  1880. // list passed in.
  1881. //
  1882. // Returns: [ERROR_SUCCESS] -- If all went well.
  1883. //
  1884. // History: 11/19/98 JHarper Created
  1885. //
  1886. //-------------------------------------------------------------------------
  1887. VOID
  1888. DfsDumpVolList(
  1889. PDFS_VOLUME_LIST pDfsVolList)
  1890. {
  1891. ULONG cVol;
  1892. ULONG cRepl;
  1893. ULONG cSite;
  1894. ULONG i;
  1895. GUID guid;
  1896. PLIST_ENTRY pListHead;
  1897. PLIST_ENTRY pLink;
  1898. PDFSM_SITE_ENTRY pSiteEntry;
  1899. DbgPrint("****************************************\n");
  1900. for (cVol = 0; cVol < pDfsVolList->VolCount; cVol++) {
  1901. DbgPrint("Name=%ws\n", pDfsVolList->Volumes[cVol].wszObjectName);
  1902. DbgPrint("Prefix: %ws\n", pDfsVolList->Volumes[cVol].wszPrefix);
  1903. DbgPrint("Comment: %ws\n", pDfsVolList->Volumes[cVol].wszComment);
  1904. DbgPrint("cbRecovery: %d\n", pDfsVolList->Volumes[cVol].cbRecovery);
  1905. DbgPrint("ReplCount=%d\n", pDfsVolList->Volumes[cVol].ReplCount);
  1906. DbgPrint("AllocatedReplCount=%d\n", pDfsVolList->Volumes[cVol].AllocatedReplCount);
  1907. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol].ReplCount; cRepl++) {
  1908. DbgPrint("[%d]ServerName=%ws\n",
  1909. cRepl, pDfsVolList->Volumes[cVol].ReplicaInfo[cRepl].pwszServerName);
  1910. DbgPrint("[%d]ShareName=%ws\n",
  1911. cRepl, pDfsVolList->Volumes[cVol].ReplicaInfo[cRepl].pwszShareName);
  1912. }
  1913. DbgPrint("DelReplCount=%d\n", pDfsVolList->Volumes[cVol].DelReplCount);
  1914. DbgPrint("AllocatedDelReplCount=%d\n", pDfsVolList->Volumes[cVol].AllocatedDelReplCount);
  1915. for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol].DelReplCount; cRepl++) {
  1916. DbgPrint("[%d]ServerName=%ws\n",
  1917. cRepl, pDfsVolList->Volumes[cVol].DelReplicaInfo[cRepl].pwszServerName);
  1918. DbgPrint("[%d]ShareName=%ws\n",
  1919. cRepl, pDfsVolList->Volumes[cVol].DelReplicaInfo[cRepl].pwszShareName);
  1920. }
  1921. DbgPrint("\n");
  1922. }
  1923. DbgPrint("---------SiteTable-------\n");
  1924. guid = pDfsVolList->SiteGuid;
  1925. DbgPrint("SiteTableGuid:"
  1926. "%08lX-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X\n",
  1927. guid.Data1, guid.Data2, guid.Data3, (int) guid.Data4[0],
  1928. (int) guid.Data4[1], (int) guid.Data4[2], (int) guid.Data4[3],
  1929. (int) guid.Data4[4], (int) guid.Data4[5],
  1930. (int) guid.Data4[6], (int) guid.Data4[7]);
  1931. pListHead = &pDfsVolList->SiteList;
  1932. if (pListHead->Flink == pListHead)
  1933. return;
  1934. for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) {
  1935. pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link);
  1936. DbgPrint("[%ws-%d sites]\n",
  1937. pSiteEntry->ServerName,
  1938. pSiteEntry->Info.cSites);
  1939. for (i = 0; i < pSiteEntry->Info.cSites; i++) {
  1940. DbgPrint("\t%ws\n", pSiteEntry->Info.Site[i].SiteName);
  1941. }
  1942. }
  1943. DbgPrint("****************************************\n");
  1944. }
  1945. #endif // DBG