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.

424 lines
10 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stddef.h>
  8. #include <shellapi.h>
  9. #include "dfsadmin.h"
  10. DFSSTATUS
  11. AddRootToPrefixTable(
  12. struct _DFS_PREFIX_TABLE **ppTable,
  13. PROOT_DEF pRoot );
  14. PLINK_DEF
  15. CreateNewLinkEntry(
  16. LPWSTR LinkName );
  17. PTARGET_DEF
  18. CreateNewTargetEntry(
  19. LPWSTR ServerName,
  20. LPWSTR ShareName,
  21. ULONG State );
  22. PLINK_DEF
  23. GetLinkEntry(
  24. struct _DFS_PREFIX_TABLE *pTable,
  25. LPWSTR NameString );
  26. PTARGET_DEF
  27. GetTargetEntry(
  28. PLINK_DEF pLink,
  29. LPWSTR ServerName,
  30. LPWSTR ShareName );
  31. PLINK_DEF
  32. MergeLinkInfo(
  33. PDFS_INFO_4 pBuf,
  34. struct _DFS_PREFIX_TABLE *pPrefixTable );
  35. DFSSTATUS
  36. DfsMerge (
  37. PROOT_DEF pRoot,
  38. LPWSTR NameSpace )
  39. {
  40. LPBYTE pBuffer = NULL;
  41. DWORD ResumeHandle = 0;
  42. DWORD EntriesRead = 0;
  43. DWORD PrefMaxLen = -1;
  44. DWORD Level = 4;
  45. DFSSTATUS Status;
  46. NTSTATUS NtStatus;
  47. PDFS_INFO_4 pCurrentBuffer;
  48. DWORD i;
  49. PLINK_DEF pGrownLinks = NULL, pLink;
  50. struct _DFS_PREFIX_TABLE *pPrefixTable;
  51. Status = AddRootToPrefixTable( &pPrefixTable,
  52. pRoot );
  53. if (Status != ERROR_SUCCESS)
  54. {
  55. printf("DfsVerify: create prefix table failed %x\n", Status);
  56. return Status;
  57. }
  58. if (DebugOut)
  59. {
  60. fwprintf(DebugOut, L"Contacting %wS for enumeration \n", NameSpace);
  61. }
  62. Status = NetDfsEnum( NameSpace,
  63. Level,
  64. PrefMaxLen,
  65. &pBuffer,
  66. &EntriesRead,
  67. &ResumeHandle);
  68. if (DebugOut)
  69. {
  70. fwprintf(DebugOut, L"Enumeration for %wS is complete %d entries\n",
  71. NameSpace,
  72. EntriesRead);
  73. }
  74. if (Status != ERROR_SUCCESS)
  75. {
  76. printf("Export: cannot enum %wS: error %x\n", NameSpace, Status);
  77. return Status;
  78. }
  79. pCurrentBuffer = (PDFS_INFO_4)pBuffer;
  80. NtStatus = DfsPrefixTableAcquireWriteLock( pPrefixTable);
  81. if (NtStatus != STATUS_SUCCESS)
  82. {
  83. printf("Unable to take prefix table lock, %x\n", NtStatus);
  84. return NtStatus;
  85. }
  86. for (i = 0; i < EntriesRead; i++)
  87. {
  88. pLink = MergeLinkInfo( pCurrentBuffer,
  89. pPrefixTable);
  90. if (pLink != NULL)
  91. {
  92. if (pGrownLinks == NULL)
  93. {
  94. pGrownLinks = pRoot->pLinks;
  95. }
  96. NEXT_LINK_OBJECT(pLink) = pGrownLinks;
  97. pGrownLinks = pLink;
  98. }
  99. pCurrentBuffer++;
  100. }
  101. DfsPrefixTableReleaseLock(pPrefixTable);
  102. if (pGrownLinks != NULL)
  103. {
  104. pRoot->pLinks = pGrownLinks;
  105. }
  106. return Status;
  107. }
  108. PTARGET_DEF
  109. CreateNewTargetEntry(
  110. LPWSTR ServerName,
  111. LPWSTR ShareName,
  112. ULONG State )
  113. {
  114. DFSSTATUS Status;
  115. UNICODE_STRING TargetName;
  116. PTARGET_DEF pTarget = NULL;
  117. Status = DfsCreateUnicodePathString( &TargetName,
  118. 2, // unc path: 2 leading sep.
  119. ServerName,
  120. ShareName );
  121. if (Status == ERROR_SUCCESS)
  122. {
  123. pTarget = CreateTargetDef(IN_NAMESPACE, TargetName.Buffer, State);
  124. DfsFreeUnicodeString(&TargetName);
  125. }
  126. return pTarget;
  127. }
  128. PLINK_DEF
  129. CreateNewLinkEntry(
  130. LPWSTR LinkName )
  131. {
  132. PLINK_DEF pLink;
  133. pLink = CreateLinkDef(IN_NAMESPACE, LinkName, NULL);
  134. return pLink;
  135. }
  136. VOID
  137. UpdateLinkEntry(
  138. PLINK_DEF pLink,
  139. ULONG State,
  140. ULONG Timeout,
  141. LPWSTR Comment )
  142. {
  143. if (State != 0)
  144. {
  145. AddObjectStateValue(&pLink->BaseObject, State);
  146. }
  147. if (Timeout != 0)
  148. {
  149. AddObjectTimeoutValue(&pLink->BaseObject, Timeout);
  150. }
  151. if (Comment != NULL)
  152. {
  153. AddObjectComment(&pLink->BaseObject, Comment);
  154. }
  155. }
  156. DFSSTATUS
  157. AddRootToPrefixTable(
  158. struct _DFS_PREFIX_TABLE **ppTable,
  159. PROOT_DEF pRoot )
  160. {
  161. struct _DFS_PREFIX_TABLE *pTable = NULL;
  162. NTSTATUS NtStatus;
  163. PLINK_DEF pLink;
  164. UNICODE_STRING LinkName;
  165. ULONG Links = 0;
  166. NtStatus = DfsInitializePrefixTable( &pTable,
  167. FALSE,
  168. NULL );
  169. if (NtStatus != STATUS_SUCCESS)
  170. {
  171. return NtStatus;
  172. }
  173. NtStatus = DfsPrefixTableAcquireWriteLock( pTable);
  174. if (NtStatus != STATUS_SUCCESS)
  175. {
  176. printf("Unable to take prefix table lock, %x\n", NtStatus);
  177. return NtStatus;
  178. }
  179. for (pLink = pRoot->pLinks; pLink != NULL; pLink = NEXT_LINK_OBJECT(pLink))
  180. {
  181. RtlInitUnicodeString(&LinkName, pLink->LinkObjectName);
  182. NtStatus = DfsInsertInPrefixTableLocked( pTable,
  183. &LinkName,
  184. (PVOID)(pLink) );
  185. if (NtStatus == STATUS_SUCCESS)
  186. {
  187. pLink->LinkObjectFlags |= IN_TABLE;
  188. }
  189. else {
  190. printf(" AddRootToPrefixTable: Link %wZ, Status 0x%x\n, Links %d",
  191. &LinkName, NtStatus, Links);
  192. break;
  193. }
  194. Links++;
  195. }
  196. DfsPrefixTableReleaseLock(pTable);
  197. *ppTable = pTable;
  198. return NtStatus;
  199. }
  200. DFSSTATUS
  201. DeletePrefixTable(
  202. struct _DFS_PREFIX_TABLE *pTable,
  203. PROOT_DEF pRoot )
  204. {
  205. PLINK_DEF pLink;
  206. NTSTATUS NtStatus;
  207. UNICODE_STRING LinkName;
  208. NtStatus = DfsPrefixTableAcquireWriteLock( pTable);
  209. if (NtStatus != STATUS_SUCCESS)
  210. {
  211. printf("Unable to take prefix table lock, %x\n", NtStatus);
  212. return NtStatus;
  213. }
  214. for (pLink = pRoot->pLinks; pLink != NULL; pLink = NEXT_LINK_OBJECT(pLink))
  215. {
  216. if ((pLink->LinkObjectFlags & IN_TABLE) == TRUE)
  217. {
  218. RtlInitUnicodeString(&LinkName, pLink->LinkObjectName);
  219. NtStatus = DfsRemoveFromPrefixTableLocked( pTable,
  220. &LinkName,
  221. (PVOID)(pLink) );
  222. if (NtStatus == STATUS_SUCCESS)
  223. {
  224. pLink->LinkObjectFlags &= ~IN_TABLE;
  225. }
  226. else {
  227. break;
  228. }
  229. }
  230. }
  231. DfsPrefixTableReleaseLock(pTable);
  232. DfsDereferencePrefixTable( pTable );
  233. return NtStatus;
  234. }
  235. PLINK_DEF
  236. GetLinkEntry(
  237. struct _DFS_PREFIX_TABLE *pTable,
  238. LPWSTR NameString )
  239. {
  240. NTSTATUS Status;
  241. UNICODE_STRING Name;
  242. UNICODE_STRING Suffix;
  243. PLINK_DEF pLink;
  244. RtlInitUnicodeString( &Name, NameString );
  245. Status = DfsFindUnicodePrefixLocked( pTable,
  246. &Name,
  247. &Suffix,
  248. &pLink,
  249. NULL );
  250. if (Status == STATUS_SUCCESS)
  251. {
  252. return pLink;
  253. }
  254. if (Status != STATUS_OBJECT_PATH_NOT_FOUND)
  255. {
  256. printf("GetLinkEntry: unexpected status %x\n", Status);
  257. }
  258. return NULL;
  259. }
  260. PTARGET_DEF
  261. GetTargetEntry(
  262. PLINK_DEF pLink,
  263. LPWSTR ServerName,
  264. LPWSTR ShareName )
  265. {
  266. PTARGET_DEF pTarget, pReturn = NULL;
  267. UNICODE_STRING TargetName;
  268. DFSSTATUS Status;
  269. Status = DfsCreateUnicodePathString( &TargetName,
  270. 2, // unc path: 2 leading sep.
  271. ServerName,
  272. ShareName );
  273. if (Status != ERROR_SUCCESS)
  274. {
  275. printf("GetTargetEntry: failed to create string\n");
  276. return NULL;
  277. }
  278. for (pTarget = pLink->LinkObjectTargets; pTarget != NULL; pTarget = pTarget->NextTarget)
  279. {
  280. if (_wcsicmp(TargetName.Buffer, pTarget->Name) == 0)
  281. {
  282. pReturn = pTarget;
  283. break;
  284. }
  285. }
  286. DfsFreeUnicodeString(&TargetName);
  287. return pReturn;
  288. }
  289. PLINK_DEF
  290. MergeLinkInfo(
  291. PDFS_INFO_4 pBuf,
  292. struct _DFS_PREFIX_TABLE *pPrefixTable )
  293. {
  294. PLINK_DEF pLink, pReturn = NULL;
  295. DWORD i;
  296. PDFS_STORAGE_INFO pStorage;
  297. UNICODE_STRING LinkName, ServerName, ShareName, Remains;
  298. DFSSTATUS Status;
  299. PTARGET_DEF pTargetList = NULL, pTarget;
  300. RtlInitUnicodeString( &LinkName, pBuf->EntryPath);
  301. if (DebugOut)
  302. {
  303. fwprintf(DebugOut, L"Link %ws in namespace, with %d targets.Merging\n",
  304. pBuf->EntryPath, pBuf->NumberOfStorages);
  305. }
  306. Status = DfsGetPathComponents(&LinkName,
  307. &ServerName,
  308. &ShareName,
  309. &Remains);
  310. if (Remains.Length == 0)
  311. {
  312. return NULL;
  313. }
  314. if ((pLink = GetLinkEntry(pPrefixTable,
  315. Remains.Buffer)) == NULL)
  316. {
  317. pLink = CreateNewLinkEntry(Remains.Buffer);
  318. UpdateLinkEntry( pLink, pBuf->State, pBuf->Timeout, pBuf->Comment);
  319. pReturn = pLink;
  320. }
  321. SetObjectInNameSpace(pLink);
  322. for(i = 0, pStorage = pBuf->Storage;
  323. i < pBuf->NumberOfStorages;
  324. i++, pStorage = pBuf->Storage+i) {
  325. if ((pTarget = GetTargetEntry(pLink,
  326. pStorage->ServerName,
  327. pStorage->ShareName)) == NULL)
  328. {
  329. pTarget = CreateNewTargetEntry(pStorage->ServerName,
  330. pStorage->ShareName,
  331. pStorage->State);
  332. if (pTargetList == NULL)
  333. {
  334. pTargetList = pLink->LinkObjectTargets;
  335. }
  336. if (pTarget != NULL) {
  337. pTarget->NextTarget = pTargetList;
  338. }
  339. pTargetList = pTarget;
  340. }
  341. SetInNameSpace(pTarget);
  342. }
  343. if (pTargetList != NULL)
  344. {
  345. pLink->LinkObjectTargets = pTargetList;
  346. }
  347. return pReturn;
  348. }