Leaked source code of windows server 2003
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.

590 lines
17 KiB

  1. //--------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: dfsprocessroots.cxx
  6. //
  7. //--------------------------------------------------------------------------
  8. #include <stdio.h>
  9. #include <nt.h>
  10. #include <ntrtl.h>
  11. #include <nturtl.h>
  12. #include <windows.h>
  13. #include <shellapi.h>
  14. #include <winldap.h>
  15. #include <stdlib.h>
  16. #include <dfslink.hxx>
  17. #include <dfsroot.hxx>
  18. #include <dfstarget.hxx>
  19. #include "dfsutil.hxx"
  20. #include "dfspathname.hxx"
  21. #include "misc.hxx"
  22. #include <strsafe.h>
  23. #define MAX_APPEND_SIZE 16
  24. #define MAX_BACKUP_NAME_SIZE 512
  25. #define TIME_STR_LEN 256
  26. WCHAR BackupName[MAX_BACKUP_NAME_SIZE];
  27. WCHAR TimeStr[TIME_STR_LEN];
  28. DFSSTATUS
  29. CreateBackupFile(
  30. DfsRoot *pOperateRoot,
  31. HANDLE *pBackupHandle )
  32. {
  33. size_t CurrentChCount;
  34. SYSTEMTIME CurrentTime;
  35. LPWSTR Prefix = L"dfsutil.backup.";
  36. DfsPathName PathName;
  37. HANDLE BackupHandle;
  38. DFSSTATUS Status;
  39. HRESULT Hr = S_OK;
  40. Status = PathName.CreatePathName(pOperateRoot->GetLinkNameString());
  41. if (Status != ERROR_SUCCESS)
  42. {
  43. return Status;
  44. }
  45. GetLocalTime( &CurrentTime );
  46. Hr = StringCchPrintf(TimeStr,
  47. TIME_STR_LEN,
  48. L"%02d.%02d.%04d.%02d.%02d.%02d.%03d",
  49. CurrentTime.wMonth,
  50. CurrentTime.wDay,
  51. CurrentTime.wYear,
  52. CurrentTime.wHour,
  53. CurrentTime.wMinute,
  54. CurrentTime.wSecond,
  55. CurrentTime.wMilliseconds );
  56. CurrentChCount = MAX_BACKUP_NAME_SIZE;
  57. if (SUCCEEDED(Hr))
  58. {
  59. Hr = StringCchCopyEx( BackupName,
  60. CurrentChCount,
  61. PathName.GetServerString(),
  62. NULL,
  63. &CurrentChCount,
  64. STRSAFE_IGNORE_NULLS);
  65. }
  66. if (SUCCEEDED(Hr))
  67. {
  68. Hr = StringCchCatNEx( BackupName,
  69. CurrentChCount,
  70. L".",
  71. sizeof( L"." ) / sizeof( WCHAR ),
  72. NULL,
  73. &CurrentChCount,
  74. STRSAFE_IGNORE_NULLS);
  75. }
  76. if (SUCCEEDED(Hr))
  77. {
  78. Hr = StringCchCatNEx( BackupName,
  79. CurrentChCount,
  80. PathName.GetShareString(),
  81. MAX_APPEND_SIZE,
  82. NULL,
  83. &CurrentChCount,
  84. STRSAFE_IGNORE_NULLS);
  85. }
  86. if (SUCCEEDED(Hr))
  87. {
  88. Hr = StringCchCatNEx( BackupName,
  89. CurrentChCount,
  90. L".",
  91. sizeof( L"." ) / sizeof( WCHAR ),
  92. NULL,
  93. &CurrentChCount,
  94. STRSAFE_IGNORE_NULLS);
  95. }
  96. if (SUCCEEDED(Hr))
  97. {
  98. Hr = StringCchCatNEx( BackupName,
  99. CurrentChCount,
  100. Prefix,
  101. MAX_APPEND_SIZE,
  102. NULL,
  103. &CurrentChCount,
  104. STRSAFE_IGNORE_NULLS);
  105. }
  106. if (SUCCEEDED(Hr))
  107. {
  108. Hr = StringCchCatEx( BackupName,
  109. CurrentChCount,
  110. TimeStr,
  111. NULL,
  112. &CurrentChCount,
  113. STRSAFE_IGNORE_NULLS);
  114. }
  115. if (!SUCCEEDED(Hr))
  116. {
  117. return HRESULT_CODE(Hr);
  118. }
  119. Status = CreateDfsFile(BackupName, &BackupHandle);
  120. if (Status == ERROR_SUCCESS)
  121. {
  122. *pBackupHandle = BackupHandle;
  123. ShowInformation((L"Backup of %ws before modifications being written to %ws\n",
  124. PathName.GetPathString(),
  125. BackupName));
  126. }
  127. return Status;
  128. }
  129. DFSSTATUS
  130. DfsGenerateBackupFile(
  131. DfsRoot *pOperateRoot,
  132. HANDLE BackupHandle )
  133. {
  134. DFSSTATUS Status = ERROR_SUCCESS;
  135. HANDLE UseBackup = BackupHandle;
  136. if (BackupHandle == INVALID_HANDLE_VALUE)
  137. {
  138. Status = CreateBackupFile(pOperateRoot, &UseBackup);
  139. }
  140. if (Status == ERROR_SUCCESS)
  141. {
  142. Status = DumpRoots( pOperateRoot, UseBackup, TRUE);
  143. }
  144. if (Status == ERROR_SUCCESS)
  145. {
  146. FlushFileBuffers(BackupHandle);
  147. }
  148. return Status;
  149. }
  150. DFSSTATUS
  151. DfsUpdateMetadata(
  152. DfsRoot *pOperateRoot,
  153. DfsRoot *pMasterRoot )
  154. {
  155. DFSSTATUS Status = ERROR_SUCCESS;
  156. DfsString *pRootString = pOperateRoot->GetRootApiName();
  157. DebugInformation((L"UpdateMetadata for roots %x and %x\n",
  158. pOperateRoot, pMasterRoot));
  159. if (pOperateRoot != NULL)
  160. {
  161. Status = pOperateRoot->ApplyApiChanges( pRootString->GetString(),
  162. pOperateRoot->GetMode(),
  163. pOperateRoot->GetVersion() );
  164. DebugInformation((L"ApplyApiChanges for root %x, Status %x\n",
  165. pOperateRoot, Status));
  166. }
  167. if (Status == ERROR_SUCCESS)
  168. {
  169. if (pMasterRoot != NULL)
  170. {
  171. Status = pMasterRoot->ApplyApiChanges(pRootString->GetString(),
  172. pOperateRoot->GetMode(),
  173. pOperateRoot->GetVersion() );
  174. DebugInformation((L"ApplyApiChanges for root %x, Status %x\n",
  175. pMasterRoot, Status));
  176. }
  177. }
  178. DebugInformation((L"UpdateMetadata for roots %x and %x, done Status %x\n",
  179. pOperateRoot, pMasterRoot, Status));
  180. return Status;
  181. }
  182. DFSSTATUS
  183. DfsProcessRoots(
  184. DfsRoot *pOperateRoot,
  185. DfsRoot *pMasterRoot )
  186. {
  187. DFSSTATUS Status = ERROR_SUCCESS;
  188. DfsLink *pLink, *pExistingLink;
  189. DfsTarget *pTarget, *pExistingTarget;
  190. for (pLink = pMasterRoot->GetFirstLink();
  191. pLink != NULL;
  192. pLink = pLink->GetNextLink())
  193. {
  194. DFSSTATUS LinkStatus;
  195. LinkStatus = pOperateRoot->FindMatchingLink( pLink->GetLinkNameCountedString(),
  196. &pExistingLink );
  197. if (LinkStatus == ERROR_SUCCESS)
  198. {
  199. for (pTarget = pLink->GetFirstTarget();
  200. pTarget != NULL;
  201. pTarget = pTarget->GetNextTarget())
  202. {
  203. DFSSTATUS TargetStatus;
  204. TargetStatus = pExistingLink->FindMatchingTarget( pTarget->GetTargetServer(),
  205. pTarget->GetTargetFolder(),
  206. &pExistingTarget);
  207. if (TargetStatus == ERROR_SUCCESS)
  208. {
  209. pExistingTarget->ResetChangeStatus();
  210. pTarget->ResetChangeStatus();
  211. if ((pTarget->IsMatchingState(pExistingTarget->GetTargetState())) == FALSE)
  212. {
  213. pTarget->SetChangeStatus(UPDATE_TARGET_STATE);
  214. }
  215. pExistingLink->ResetChangeStatus();
  216. pLink->ResetChangeStatus();
  217. }
  218. else
  219. {
  220. if (pTarget->IsMatchingState(DEFAULT_TARGET_STATE) == FALSE)
  221. {
  222. pTarget->SetChangeStatus(UPDATE_TARGET_STATE);
  223. }
  224. }
  225. }
  226. if (pExistingLink->GetFirstTarget() == NULL)
  227. {
  228. pExistingLink->ResetChangeStatus();
  229. }
  230. if (pLink->IsMatchingState(pExistingLink->GetLinkState()) == FALSE)
  231. {
  232. pLink->SetChangeStatus(UPDATE_LINK_STATE);
  233. }
  234. if (pLink->IsMatchingTimeout(pExistingLink->GetLinkTimeout()) == FALSE)
  235. {
  236. pLink->SetChangeStatus(UPDATE_LINK_TIMEOUT);
  237. }
  238. if (pLink->IsMatchingComment(pExistingLink->GetLinkCommentCountedString())== FALSE)
  239. {
  240. pLink->SetChangeStatus(UPDATE_LINK_COMMENT);
  241. }
  242. }
  243. else
  244. {
  245. if (pLink->IsMatchingState(DEFAULT_LINK_STATE) == FALSE)
  246. {
  247. pLink->SetChangeStatus(UPDATE_LINK_STATE);
  248. }
  249. if (pLink->IsMatchingTimeout(DEFAULT_LINK_TIMEOUT) == FALSE)
  250. {
  251. pLink->SetChangeStatus(UPDATE_LINK_TIMEOUT);
  252. }
  253. for (pTarget = pLink->GetFirstTarget();
  254. pTarget != NULL;
  255. pTarget = pTarget->GetNextTarget())
  256. {
  257. if (pTarget->IsMatchingState(DEFAULT_TARGET_STATE) == FALSE)
  258. {
  259. pTarget->SetChangeStatus(UPDATE_TARGET_STATE);
  260. }
  261. }
  262. }
  263. }
  264. DebugInformation((L"DfsProcessRoots for %x and %x, done Status %x\n",
  265. pOperateRoot,
  266. pMasterRoot,
  267. Status));
  268. return Status;
  269. }
  270. DFSSTATUS
  271. DfsUpdate(
  272. DfsRoot *pOperateRoot,
  273. DfsRoot *pMasterRoot )
  274. {
  275. DFSSTATUS Status;
  276. Status = DfsProcessRoots( pOperateRoot,
  277. pMasterRoot );
  278. if (Status == ERROR_SUCCESS)
  279. {
  280. Status = DfsUpdateMetadata(pOperateRoot,
  281. pMasterRoot);
  282. }
  283. if (Status == ERROR_SUCCESS)
  284. {
  285. PDFS_UPDATE_STATISTICS pOperateStats;
  286. PDFS_UPDATE_STATISTICS pMasterStats;
  287. pOperateStats = pOperateRoot->GetRootStatistics();
  288. pMasterStats = pMasterRoot->GetRootStatistics();
  289. pOperateStats->LinkModified += pMasterStats->LinkModified;
  290. pOperateStats->LinkAdded += pMasterStats->LinkAdded;
  291. pOperateStats->LinkDeleted += pMasterStats->LinkDeleted;
  292. pOperateStats->TargetModified += pMasterStats->TargetModified;
  293. pOperateStats->TargetAdded += pMasterStats->TargetAdded;
  294. pOperateStats->TargetDeleted += pMasterStats->TargetDeleted;
  295. pOperateStats->ApiCount += pMasterStats->ApiCount;
  296. ShowInformation((L"\nUpdate Statistics: Number of Apis %d\n",
  297. pOperateStats->ApiCount));
  298. ShowInformation((L"Links: Added %d Deleted %d Modified %d\n",
  299. pOperateStats->LinkAdded,
  300. pOperateStats->LinkDeleted,
  301. pOperateStats->LinkModified));
  302. ShowInformation((L"Targets: Added %d Deleted %d Modified %d\n",
  303. pOperateStats->TargetAdded,
  304. pOperateStats->TargetDeleted,
  305. pOperateStats->TargetModified));
  306. }
  307. return Status;
  308. }
  309. DFSSTATUS
  310. SetDfsRoots(
  311. DfsRoot *pOperateRoot,
  312. DfsRoot *pMasterRoot,
  313. HANDLE BackupHandle,
  314. BOOLEAN NoBackup )
  315. {
  316. DFSSTATUS Status;
  317. PUNICODE_STRING pRootToUpdate = pOperateRoot->GetLinkNameCountedString();
  318. if (NoBackup == FALSE)
  319. {
  320. Status = DfsGenerateBackupFile(pOperateRoot, BackupHandle);
  321. if (Status != ERROR_SUCCESS)
  322. {
  323. return Status;
  324. }
  325. }
  326. pOperateRoot->SetRootApiName(pRootToUpdate);
  327. pOperateRoot->SetRootWriteable();
  328. pOperateRoot->MarkForDelete();
  329. pMasterRoot->MarkForAddition();
  330. Status = DfsUpdate( pOperateRoot,
  331. pMasterRoot );
  332. if (Status == ERROR_SUCCESS)
  333. {
  334. Status = pOperateRoot->UpdateMetadata();
  335. }
  336. if (Status == ERROR_SUCCESS)
  337. {
  338. (VOID) ReSynchronizeRootTargets(pOperateRoot->GetLinkNameString());
  339. }
  340. return Status;
  341. }
  342. DFSSTATUS
  343. MergeDfsRoots(
  344. DfsRoot *pOperateRoot,
  345. DfsRoot *pMasterRoot,
  346. HANDLE BackupHandle,
  347. BOOLEAN NoBackup )
  348. {
  349. DFSSTATUS Status;
  350. PUNICODE_STRING pRootToUpdate = pOperateRoot->GetLinkNameCountedString();
  351. if (NoBackup == FALSE)
  352. {
  353. Status = DfsGenerateBackupFile(pOperateRoot, BackupHandle);
  354. if (Status != ERROR_SUCCESS)
  355. {
  356. return Status;
  357. }
  358. }
  359. pOperateRoot->SetRootApiName(pRootToUpdate);
  360. pOperateRoot->SetRootWriteable();
  361. pMasterRoot->MarkForAddition();
  362. Status = DfsUpdate( pOperateRoot,
  363. pMasterRoot );
  364. if (Status == ERROR_SUCCESS)
  365. {
  366. Status = pOperateRoot->UpdateMetadata();
  367. }
  368. if (Status == ERROR_SUCCESS)
  369. {
  370. (VOID) ReSynchronizeRootTargets(pOperateRoot->GetLinkNameString());
  371. }
  372. return Status;
  373. }
  374. ULONG
  375. DfsShowVerifyInformation(
  376. LPWSTR RootName,
  377. DfsRoot *pOperateRoot)
  378. {
  379. DfsLink *pLink;
  380. DfsTarget *pTarget;
  381. ULONG Errors = 0;
  382. for (pLink = pOperateRoot->GetFirstLink();
  383. pLink != NULL;
  384. pLink = pLink->GetNextLink())
  385. {
  386. if (pLink->MarkedForDelete())
  387. {
  388. ShowInformation((L"%wS\\%wS, link additional\n",
  389. RootName,
  390. pLink->GetLinkNameString()));
  391. Errors++;
  392. }
  393. if (pLink->MarkedForAddition())
  394. {
  395. ShowInformation((L"%wS\\%wS, link missing\n",
  396. RootName,
  397. pLink->GetLinkNameString()));
  398. Errors++;
  399. }
  400. if (pLink->MarkedForCommentUpdate())
  401. {
  402. ShowInformation((L"%wS\\%wS, link Comment mismatch\n",
  403. RootName,
  404. pLink->GetLinkNameString()));
  405. Errors++;
  406. }
  407. if (pLink->MarkedForStateUpdate())
  408. {
  409. ShowInformation((L"%wS\\%wS, link State mismatch\n",
  410. RootName,
  411. pLink->GetLinkNameString()));
  412. Errors++;
  413. }
  414. if (pLink->MarkedForTimeoutUpdate())
  415. {
  416. ShowInformation((L"%wS\\%wS, link Timeout mismatch\n",
  417. RootName,
  418. pLink->GetLinkNameString()));
  419. Errors++;
  420. }
  421. for (pTarget = pLink->GetFirstTarget();
  422. (pTarget != NULL);
  423. pTarget = pTarget->GetNextTarget())
  424. {
  425. if (pTarget->MarkedForDelete())
  426. {
  427. ShowInformation((L"%wS\\%wS, Target (Server %wS, Folder %wS) Additional\n",
  428. RootName,
  429. pLink->GetLinkNameString(),
  430. pTarget->GetTargetServerString(),
  431. pTarget->GetTargetFolderString()));
  432. Errors++;
  433. }
  434. if (pTarget->MarkedForAddition())
  435. {
  436. ShowInformation((L"%wS\\%wS, Target (Server %wS, Folder %wS) Missing\n",
  437. RootName,
  438. pLink->GetLinkNameString(),
  439. pTarget->GetTargetServerString(),
  440. pTarget->GetTargetFolderString()));
  441. Errors++;
  442. }
  443. if (pTarget->MarkedForStateUpdate())
  444. {
  445. ShowInformation((L"%wS\\%wS, Target (Server %wS, Folder %wS) State mismatch\n",
  446. RootName,
  447. pLink->GetLinkNameString(),
  448. pTarget->GetTargetServerString(),
  449. pTarget->GetTargetFolderString()));
  450. Errors++;
  451. }
  452. }
  453. }
  454. return Errors;
  455. }
  456. DFSSTATUS
  457. VerifyDfsRoots(
  458. DfsRoot *pOperateRoot,
  459. DfsRoot *pMasterRoot )
  460. {
  461. DFSSTATUS Status;
  462. ULONG Errors = 0;
  463. pOperateRoot->MarkForDelete();
  464. pMasterRoot->MarkForAddition();
  465. Status = DfsProcessRoots( pOperateRoot,
  466. pMasterRoot );
  467. if (Status == ERROR_SUCCESS)
  468. {
  469. Errors = DfsShowVerifyInformation(
  470. pOperateRoot->GetLinkNameString(),
  471. pOperateRoot);
  472. Errors += DfsShowVerifyInformation(
  473. pOperateRoot->GetLinkNameString(),
  474. pMasterRoot);
  475. }
  476. if (Errors == 0)
  477. {
  478. ShowInformation((L"\n\nVerification successful for Namespace %wS\n\n",
  479. pOperateRoot->GetLinkNameString()));
  480. }
  481. else
  482. {
  483. ShowInformation((L"\n\nVerification detected %d inconsistencies for Namespace %wS\n\n",
  484. Errors,
  485. pOperateRoot->GetLinkNameString()));
  486. }
  487. return Status;
  488. }