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.

412 lines
9.2 KiB

  1. //--------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: dfsroot.hxx
  6. //
  7. //--------------------------------------------------------------------------
  8. #ifndef __DFS_UTIL_ROOT__
  9. #define __DFS_UTIL_ROOT__
  10. #include "DfsLink.hxx"
  11. #include "dfsStrings.hxx"
  12. class DfsRoot : public DfsLink
  13. {
  14. private:
  15. DfsString _RootApiName;
  16. ULONG _LinkCount;
  17. ULONG _ApiCount;
  18. DfsLink *_pLinks;
  19. DfsLink *_pLastLink;
  20. DfsTarget *_pTargets;
  21. PVOID _Handle;
  22. BOOLEAN _Writeable;
  23. DFS_API_MODE _Mode;
  24. ULONG _Version;
  25. DFS_UPDATE_STATISTICS _Statistics;
  26. struct _DFS_PREFIX_TABLE *_pLinkTable;
  27. public:
  28. DfsRoot()
  29. {
  30. _pLinks = NULL;
  31. _pTargets = NULL;
  32. _pLinkTable = NULL;
  33. _pLastLink = NULL;
  34. _LinkCount = 0;
  35. _ApiCount = 0;
  36. _Mode = MODE_API;
  37. _Handle = NULL;
  38. _Writeable = FALSE;
  39. _Version = 4;
  40. RtlZeroMemory(&_Statistics, sizeof(DFS_UPDATE_STATISTICS));
  41. }
  42. DFSSTATUS
  43. Initialize( LPWSTR NameSpace, DFS_API_MODE Mode, LPWSTR DCName )
  44. {
  45. DFSSTATUS Status = ERROR_SUCCESS;
  46. DFS_API_MODE UseMode = MODE_API;
  47. if ((Mode == MODE_DIRECT) || (Mode == MODE_EITHER))
  48. {
  49. Status = DfsDirectApiOpen( NameSpace, DCName, &_Handle);
  50. if (Status == ERROR_SUCCESS)
  51. {
  52. UseMode = MODE_DIRECT;
  53. }
  54. else if (Mode == MODE_EITHER)
  55. {
  56. Status = ERROR_SUCCESS;
  57. UseMode = MODE_API;
  58. }
  59. }
  60. if (Status == ERROR_SUCCESS)
  61. {
  62. _Mode = UseMode;
  63. }
  64. return Status;
  65. }
  66. VOID
  67. Close()
  68. {
  69. DFSSTATUS Status;
  70. if (_Mode == MODE_DIRECT)
  71. {
  72. Status = DfsDirectApiClose( _Handle );
  73. }
  74. _Handle = NULL;
  75. return NOTHING;
  76. }
  77. BOOLEAN
  78. IsRootWriteable()
  79. {
  80. return _Writeable;
  81. }
  82. DFS_API_MODE
  83. GetMode()
  84. {
  85. return _Mode;
  86. }
  87. DFSSTATUS
  88. RootBlobSize( PULONG pBlobSize )
  89. {
  90. DFSSTATUS Status = ERROR_NOT_SUPPORTED;
  91. *pBlobSize = 0;
  92. if (_Handle != NULL)
  93. {
  94. Status = DfsGetBlobSize(_Handle, pBlobSize);
  95. }
  96. return Status;
  97. }
  98. DFSSTATUS
  99. RootGetSiteBlob( PVOID *ppBuffer, PULONG pBlobSize )
  100. {
  101. DFSSTATUS Status = ERROR_NOT_SUPPORTED;
  102. *pBlobSize = 0;
  103. if (_Handle != NULL)
  104. {
  105. Status = DfsGetSiteBlob(_Handle, ppBuffer, pBlobSize);
  106. }
  107. return Status;
  108. }
  109. DFSSTATUS
  110. RootSetSiteBlob( PVOID pBuffer, ULONG BlobSize )
  111. {
  112. DFSSTATUS Status = ERROR_NOT_SUPPORTED;
  113. if (_Handle != NULL)
  114. {
  115. Status = DfsSetSiteBlob(_Handle, pBuffer, BlobSize);
  116. }
  117. return Status;
  118. }
  119. DFSSTATUS
  120. GetExtendedAttributes( PULONG pAttrib )
  121. {
  122. DFSSTATUS Status = ERROR_NOT_SUPPORTED;
  123. *pAttrib = 0;
  124. if (_Handle != NULL)
  125. {
  126. Status = DfsExtendedRootAttributes(_Handle,
  127. pAttrib,
  128. NULL,
  129. FALSE);
  130. }
  131. return Status;
  132. }
  133. ULONG
  134. GetLinkCount()
  135. {
  136. return _LinkCount;
  137. }
  138. VOID
  139. SetRootWriteable()
  140. {
  141. _Writeable = TRUE;
  142. if (_Handle != NULL)
  143. {
  144. SetDirectHandleWriteable(_Handle);
  145. }
  146. }
  147. VOID
  148. ResetRootWriteable()
  149. {
  150. _Writeable = FALSE;
  151. if (_Handle != NULL)
  152. {
  153. ResetDirectHandleWriteable(_Handle);
  154. }
  155. }
  156. VOID
  157. SetRootApiName( PUNICODE_STRING pRootName)
  158. {
  159. _RootApiName.SetStringToPointer(pRootName);
  160. }
  161. DfsString *
  162. GetRootApiName()
  163. {
  164. return &_RootApiName;
  165. }
  166. DFSSTATUS
  167. UpdateMetadata()
  168. {
  169. DFSSTATUS Status = ERROR_SUCCESS;
  170. if (_Mode == MODE_DIRECT)
  171. {
  172. if (IsRootWriteable())
  173. {
  174. Status = DfsDirectApiCommitChanges(_Handle);
  175. }
  176. else
  177. {
  178. Status = ERROR_INVALID_PARAMETER;
  179. }
  180. }
  181. return Status;
  182. }
  183. ~DfsRoot()
  184. {
  185. // handle all the objects correctly here. Since
  186. // this is only a utility, we may not currently care
  187. // of this memory leak.
  188. }
  189. DfsLink *
  190. GetFirstLink()
  191. {
  192. return _pLinks;
  193. }
  194. ULONG
  195. GetVersion()
  196. {
  197. return _Version;
  198. }
  199. DFSSTATUS
  200. FindMatchingLink( PUNICODE_STRING pLinkName,
  201. DfsLink **ppLink )
  202. {
  203. NTSTATUS NtStatus;
  204. UNICODE_STRING Suffix;
  205. if (_pLinkTable == NULL)
  206. {
  207. return ERROR_NOT_FOUND;
  208. }
  209. NtStatus = DfsPrefixTableAcquireReadLock( _pLinkTable );
  210. if (NtStatus == STATUS_SUCCESS)
  211. {
  212. NtStatus = DfsFindUnicodePrefixLocked( _pLinkTable,
  213. pLinkName,
  214. &Suffix,
  215. (PVOID *)ppLink,
  216. NULL );
  217. DfsPrefixTableReleaseLock( _pLinkTable );
  218. }
  219. return RtlNtStatusToDosError(NtStatus);
  220. }
  221. ULONG
  222. AddLinks(DfsLink *pLink )
  223. {
  224. NTSTATUS NtStatus = STATUS_SUCCESS;
  225. DFSSTATUS Status = ERROR_SUCCESS;
  226. DfsLink *pLastLink;
  227. DfsLink *pProcessLink;
  228. if (_pLinkTable == NULL)
  229. {
  230. NtStatus = DfsInitializePrefixTable( &_pLinkTable,
  231. FALSE,
  232. NULL );
  233. }
  234. if (NtStatus == STATUS_SUCCESS)
  235. {
  236. NtStatus = DfsPrefixTableAcquireWriteLock( _pLinkTable);
  237. if (NtStatus == STATUS_SUCCESS)
  238. {
  239. for (pProcessLink = pLink;
  240. (pProcessLink != NULL) && (NtStatus == STATUS_SUCCESS);
  241. pProcessLink = pProcessLink->GetNextLink())
  242. {
  243. NtStatus = DfsInsertInPrefixTableLocked( _pLinkTable,
  244. pProcessLink->GetLinkNameCountedString(),
  245. (PVOID)(pProcessLink));
  246. if (NtStatus == STATUS_SUCCESS)
  247. {
  248. pLastLink = pProcessLink;
  249. }
  250. _LinkCount++;
  251. }
  252. DfsPrefixTableReleaseLock(_pLinkTable);
  253. }
  254. }
  255. if (NtStatus == STATUS_SUCCESS)
  256. {
  257. if (_pLastLink == NULL)
  258. {
  259. _pLinks = pLink;
  260. }
  261. else
  262. {
  263. _pLastLink->AddNextLink(pLink);
  264. }
  265. _pLastLink = pLastLink;
  266. }
  267. return RtlNtStatusToDosError(NtStatus);
  268. }
  269. VOID
  270. MarkForDelete()
  271. {
  272. DfsLink *pLink;
  273. for (pLink = _pLinks;
  274. pLink != NULL;
  275. pLink = pLink->GetNextLink())
  276. {
  277. pLink->MarkForDelete();
  278. }
  279. }
  280. VOID
  281. MarkForAddition()
  282. {
  283. DfsLink *pLink;
  284. for (pLink = _pLinks;
  285. pLink != NULL;
  286. pLink = pLink->GetNextLink())
  287. {
  288. pLink->MarkForAddition();
  289. }
  290. }
  291. PDFS_UPDATE_STATISTICS
  292. GetRootStatistics()
  293. {
  294. return &_Statistics;
  295. }
  296. VOID
  297. ProgressBar( ULONG Link,
  298. ULONG ApiCount)
  299. {
  300. if ((Link > 0) && ((Link % 500) == 0))
  301. {
  302. ShowInformation((L"."));
  303. }
  304. else if ((ApiCount > 0) && ((ApiCount % 20) == 0))
  305. {
  306. ShowInformation((L"."));
  307. }
  308. }
  309. DFSSTATUS
  310. ApplyApiChanges(LPWSTR RootName,
  311. DFS_API_MODE Mode,
  312. ULONG Version)
  313. {
  314. DFSSTATUS Status = ERROR_SUCCESS;
  315. DfsLink *pLink;
  316. ULONG Link;
  317. for (Link = 0, pLink = _pLinks;
  318. ((pLink != NULL) && (Status == ERROR_SUCCESS));
  319. Link++, pLink = pLink->GetNextLink())
  320. {
  321. BOOLEAN RetryOnce = FALSE;
  322. Retry:
  323. Status = pLink->ApplyApiChanges( RootName,
  324. Mode,
  325. Version,
  326. &_Statistics);
  327. if (Status == 2668)
  328. {
  329. if (RetryOnce == FALSE)
  330. {
  331. RetryOnce = TRUE;
  332. Version = 3;
  333. goto Retry;
  334. }
  335. }
  336. ProgressBar(Link, _Statistics.ApiCount);
  337. }
  338. return Status;
  339. }
  340. };
  341. #endif // __DFS_UTIL_ROOT__