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.

260 lines
6.7 KiB

  1. #include <stdio.h>
  2. #include <nt.h>
  3. #include <ntrtl.h>
  4. #include <nturtl.h>
  5. #include <windows.h>
  6. #include <shellapi.h>
  7. #include <winldap.h>
  8. #include <stdlib.h>
  9. #include <dfslink.hxx>
  10. #include <dfsroot.hxx>
  11. #include <dfstarget.hxx>
  12. #include "dfsutil.hxx"
  13. #include "dfspathname.hxx"
  14. #define INFO4(x, y) (((PDFS_INFO_4)x)->y)
  15. #define INFO3(x, y) (((PDFS_INFO_3)x)->y)
  16. #define DFS_INFO(x, y, Level) ((Level == 4) ? INFO4(x, y) : INFO3(x, y))
  17. #define SIZEOF_DFS_INFO(Level) ((Level == 4) ? sizeof(DFS_INFO_4) : sizeof(DFS_INFO_3))
  18. DFSSTATUS
  19. DfsUpdateLinkFromBuffer(
  20. PUNICODE_STRING pName,
  21. PVOID pBuf,
  22. ULONG Level,
  23. BOOLEAN SiteAware,
  24. DfsLink *pLink )
  25. {
  26. DWORD i;
  27. PDFS_STORAGE_INFO pStorage;
  28. DFSSTATUS Status;
  29. DebugInformation((L"Link %ws in namespace, with %d targets\n",
  30. DFS_INFO(pBuf, EntryPath, Level),
  31. DFS_INFO(pBuf, NumberOfStorages, Level)));
  32. Status = pLink->SetLinkName(pName);
  33. if (Status == ERROR_SUCCESS)
  34. {
  35. Status = pLink->SetLinkComment(DFS_INFO(pBuf, Comment, Level));
  36. }
  37. pLink->SetLinkState(DFS_INFO(pBuf, State, Level));
  38. if (Level == 4)
  39. {
  40. pLink->SetLinkTimeout(INFO4(pBuf, Timeout));
  41. }
  42. else
  43. {
  44. pLink->SetLinkTimeout(300);
  45. }
  46. for(i = 0, pStorage = DFS_INFO(pBuf, Storage, Level);
  47. i < DFS_INFO(pBuf, NumberOfStorages, Level);
  48. i++, pStorage = DFS_INFO(pBuf, Storage, Level) + i)
  49. {
  50. DfsTarget *pTarget;
  51. pTarget = new DfsTarget;
  52. if (pTarget == NULL)
  53. {
  54. Status = ERROR_NOT_ENOUGH_MEMORY;
  55. }
  56. if (Status == ERROR_SUCCESS)
  57. {
  58. Status = pTarget->SetTargetServer(pStorage->ServerName,
  59. SiteAware);
  60. }
  61. if (Status == ERROR_SUCCESS)
  62. {
  63. Status = pTarget->SetTargetFolder(pStorage->ShareName);
  64. }
  65. if (Status == ERROR_SUCCESS)
  66. {
  67. pTarget->SetTargetState(pStorage->State);
  68. pLink->AddTarget(pTarget);
  69. }
  70. }
  71. return Status;
  72. }
  73. DFSSTATUS
  74. DfsBuildNameSpaceInformation (
  75. DfsPathName *pNameSpace,
  76. LPWSTR UseDC,
  77. DFS_API_MODE Mode,
  78. BOOLEAN SiteAware,
  79. DfsRoot **ppRoot )
  80. {
  81. LPBYTE pBuffer = NULL;
  82. DWORD ResumeHandle = 0;
  83. DWORD EntriesRead = 0;
  84. DWORD PrefMaxLen = -1;
  85. DWORD Level = 4;
  86. DFSSTATUS Status = ERROR_SUCCESS;
  87. PVOID pCurrentBuffer = NULL;
  88. DWORD i = 0;
  89. LPWSTR UseName = pNameSpace->GetPathString();
  90. DfsRoot *pRoot = NULL;
  91. DfsLink *pLink = NULL, *pStartLink = NULL, *pLastLink = NULL;
  92. ULONG LinkCount = 0;
  93. pRoot = new DfsRoot;
  94. if (pRoot == NULL)
  95. {
  96. return ERROR_NOT_ENOUGH_MEMORY;
  97. }
  98. Status = pRoot->Initialize( UseName, Mode, UseDC );
  99. if (Status != ERROR_SUCCESS)
  100. {
  101. delete pRoot;
  102. return Status;
  103. }
  104. DebugInformation((L"Contacting %wS for enumeration \n", UseName));
  105. Status = DfsApiEnumerate( pRoot->GetMode(),
  106. UseName,
  107. Level,
  108. PrefMaxLen,
  109. &pBuffer,
  110. &EntriesRead,
  111. &ResumeHandle);
  112. //
  113. // if this failed, retry at level 3.
  114. //
  115. if ((Status != ERROR_SUCCESS) &&
  116. (Status != ERROR_NO_MORE_ITEMS))
  117. {
  118. Level--;
  119. Status = DfsApiEnumerate( pRoot->GetMode(),
  120. UseName,
  121. Level,
  122. PrefMaxLen,
  123. &pBuffer,
  124. &EntriesRead,
  125. &ResumeHandle);
  126. }
  127. DebugInformation((L"Enumeration for %wS is complete %d entries, status 0x%x\n",
  128. UseName,
  129. EntriesRead,
  130. Status));
  131. if (Status == ERROR_SUCCESS)
  132. {
  133. pCurrentBuffer = (PVOID)pBuffer;
  134. for (i = 0;
  135. ((i < EntriesRead) && (Status == ERROR_SUCCESS));
  136. i++)
  137. {
  138. UNICODE_STRING LinkName, ServerName, ShareName, Remains;
  139. RtlInitUnicodeString( &LinkName,
  140. DFS_INFO(pCurrentBuffer, EntryPath, Level));
  141. Status = DfsGetPathComponents(&LinkName,
  142. &ServerName,
  143. &ShareName,
  144. &Remains);
  145. if (Remains.Length == 0)
  146. {
  147. if (ShareName.Length != 0)
  148. {
  149. Status = DfsUpdateLinkFromBuffer( &LinkName,
  150. pCurrentBuffer,
  151. Level,
  152. SiteAware,
  153. pRoot );
  154. }
  155. else
  156. {
  157. Status = ERROR_INVALID_PARAMETER;
  158. }
  159. }
  160. else
  161. {
  162. pLink = new DfsLink;
  163. if (pLink == NULL)
  164. {
  165. Status = ERROR_NOT_ENOUGH_MEMORY;
  166. }
  167. if (Status == ERROR_SUCCESS)
  168. {
  169. Status = DfsUpdateLinkFromBuffer( &Remains,
  170. pCurrentBuffer,
  171. Level,
  172. SiteAware,
  173. pLink );
  174. }
  175. if (Status == ERROR_SUCCESS)
  176. {
  177. LinkCount++;
  178. if (pStartLink == NULL)
  179. {
  180. pStartLink = pLink;
  181. }
  182. else
  183. {
  184. pLastLink->AddNextLink(pLink);
  185. }
  186. pLastLink = pLink;
  187. }
  188. }
  189. pCurrentBuffer = (PVOID)((ULONG_PTR)pCurrentBuffer + SIZEOF_DFS_INFO(Level));
  190. }
  191. }
  192. if (Status == ERROR_SUCCESS)
  193. {
  194. pRoot->AddLinks(pStartLink);
  195. }
  196. if (Status == ERROR_SUCCESS)
  197. {
  198. *ppRoot = pRoot;
  199. }
  200. else
  201. {
  202. if(pRoot)
  203. {
  204. delete pRoot;
  205. }
  206. }
  207. return Status;
  208. }