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.

276 lines
7.9 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2000, Microsoft Corporation
  4. //
  5. // File: DfsReferral.cxx
  6. //
  7. // Contents: This file contains the functionality to generate a referral
  8. //
  9. //
  10. // History: Jan 16 2001, Authors: RohanP/UdayH
  11. //
  12. //-----------------------------------------------------------------------------
  13. #include "DfsReferral.hxx"
  14. #include "Align.h"
  15. #include "dfstrusteddomain.hxx"
  16. #include "dfsadsiapi.hxx"
  17. #include "DfsDomainInformation.hxx"
  18. #include "DomainControllerSupport.hxx"
  19. #include "dfsreferral.tmh" // logging
  20. DFSSTATUS
  21. DfsGetCompatRootFolder(
  22. PUNICODE_STRING pName,
  23. DfsRootFolder **ppNewRoot );
  24. DFSSTATUS
  25. DfsLookupCompatFolder(
  26. DfsRootFolder *pRoot,
  27. PUNICODE_STRING pName,
  28. PUNICODE_STRING pRemainingName,
  29. DfsFolder **ppFolder )
  30. {
  31. DFSSTATUS Status = ERROR_SUCCESS;
  32. //
  33. // if the rest of the name is empty, we need the root folder
  34. // itself, so acquire a reference on the root folder and return it
  35. // as a folder.
  36. //
  37. if (pName->Length == 0)
  38. {
  39. *ppFolder = (DfsFolder *)pRoot;
  40. pRoot->AcquireReference();
  41. }
  42. else
  43. {
  44. Status = pRoot->LookupFolderByLogicalName( pName,
  45. pRemainingName,
  46. ppFolder );
  47. }
  48. return Status;
  49. }
  50. //+-------------------------------------------------------------------------
  51. //
  52. // Function: DfsGetRootFolder
  53. //
  54. // Arguments: pName - The logical name
  55. // pRemainingName - the name beyond the root
  56. // ppRoot - the Dfs root found.
  57. //
  58. // Returns: ERROR_SUCCESS
  59. // Error code otherwise
  60. //
  61. //
  62. // Description: This routine runs through all the stores and looks up
  63. // a root with the matching name context and share name.
  64. // If multiple stores have the same share, the highest
  65. // priority store wins (the store registered first is the
  66. // highest priority store)
  67. // A referenced root is returned, and the caller is
  68. // responsible for releasing the reference.
  69. //
  70. //--------------------------------------------------------------------------
  71. DFSSTATUS
  72. DfsGetCompatReferralData(
  73. PUNICODE_STRING pName,
  74. PUNICODE_STRING pRemainingName,
  75. DfsFolderReferralData **ppReferralData,
  76. PBOOLEAN pCacheHit )
  77. {
  78. DfsRootFolder *pNewRoot = NULL;
  79. DfsFolder *pFolder = NULL;
  80. DFSSTATUS Status = ERROR_SUCCESS;
  81. UNICODE_STRING ServerName, ShareName, Rest;
  82. //
  83. // Break up the path into name components.
  84. //
  85. Status = DfsGetPathComponents( pName,
  86. &ServerName,
  87. &ShareName,
  88. &Rest );
  89. //
  90. // Now find the Root folder for the name, and then lookup the link
  91. // folder using the rest of the name.
  92. //
  93. if (Status == ERROR_SUCCESS)
  94. {
  95. Status = DfsCheckRootADObjectExistence( NULL,
  96. &ShareName,
  97. NULL );
  98. }
  99. if (Status == ERROR_SUCCESS)
  100. {
  101. Status = DfsGetCompatRootFolder( &ShareName,
  102. &pNewRoot );
  103. if (Status == ERROR_SUCCESS)
  104. {
  105. Status = DfsLookupCompatFolder( pNewRoot,
  106. &Rest,
  107. pRemainingName,
  108. &pFolder );
  109. //
  110. //Generate the referral data so we can create a referral
  111. // to return to the client.
  112. //
  113. if (Status == ERROR_SUCCESS)
  114. {
  115. Status = pFolder->GetReferralData( ppReferralData,
  116. pCacheHit,
  117. FALSE );
  118. pFolder->ReleaseReference();
  119. }
  120. //
  121. // We had created this root folder temporarily, just so we
  122. // can get the referral information. we dont want this root
  123. // to live forever.
  124. // So remove all the link folders in the root, being careful
  125. // that we dont delete any directories if this machine is hosting
  126. // this root itself.
  127. //
  128. // We then release the reference on the root to delete it.
  129. //
  130. pNewRoot->RemoveAllLinkFolders(FALSE);
  131. pNewRoot->ReleaseReference();
  132. if (Status == ERROR_SUCCESS)
  133. {
  134. (*ppReferralData)->SetTime();
  135. (*ppReferralData)->DetachFromFolder();
  136. }
  137. }
  138. }
  139. return Status;
  140. }
  141. DFSSTATUS
  142. DfsGetRootReferralData(
  143. PUNICODE_STRING pShareName,
  144. PUNICODE_STRING pRemainingName,
  145. PUNICODE_STRING pRest,
  146. DfsFolderReferralData **ppReferralData,
  147. PBOOLEAN pCacheHit )
  148. {
  149. DfsRootFolder *pNewRoot = NULL;
  150. DfsFolder *pFolder = NULL;
  151. DFSSTATUS Status = ERROR_SUCCESS;
  152. //
  153. // Now find the Root folder for the name, and then lookup the link
  154. // folder using the rest of the name.
  155. //
  156. Status = DfsGetCompatRootFolder( pShareName,
  157. &pNewRoot );
  158. if (Status == ERROR_SUCCESS)
  159. {
  160. Status = DfsLookupCompatFolder( pNewRoot,
  161. pRest,
  162. pRemainingName,
  163. &pFolder );
  164. //
  165. //Generate the referral data so we can create a referral
  166. // to return to the client.
  167. //
  168. if (Status == ERROR_SUCCESS)
  169. {
  170. Status = pFolder->GetReferralData( ppReferralData,
  171. pCacheHit,
  172. FALSE );
  173. pFolder->ReleaseReference();
  174. }
  175. //
  176. // We had created this root folder temporarily, just so we
  177. // can get the referral information. we dont want this root
  178. // to live forever.
  179. // So remove all the link folders in the root, being careful
  180. // that we dont delete any directories if this machine is hosting
  181. // this root itself.
  182. //
  183. // We then release the reference on the root to delete it.
  184. //
  185. pNewRoot->RemoveAllLinkFolders(FALSE);
  186. pNewRoot->ReleaseReference();
  187. if (Status == ERROR_SUCCESS)
  188. {
  189. (*ppReferralData)->SetTime();
  190. (*ppReferralData)->DetachFromFolder();
  191. }
  192. }
  193. return Status;
  194. }
  195. DFSSTATUS
  196. DfsGetRootReferralDataEx(
  197. PUNICODE_STRING pName,
  198. PUNICODE_STRING pRemainingName,
  199. DfsFolderReferralData **ppReferralData,
  200. PBOOLEAN pCacheHit)
  201. {
  202. DFSSTATUS Status = ERROR_SUCCESS;
  203. UNICODE_STRING ServerName, ShareName, Rest;
  204. do
  205. {
  206. //
  207. // Break up the path into name components.
  208. //
  209. Status = DfsGetPathComponents( pName,
  210. &ServerName,
  211. &ShareName,
  212. &Rest );
  213. if(Status != ERROR_SUCCESS)
  214. {
  215. break;
  216. }
  217. Status = DfsGetRootReferralData(&ShareName,
  218. pRemainingName,
  219. &Rest,
  220. ppReferralData,
  221. pCacheHit );
  222. if(Status != ERROR_SUCCESS)
  223. {
  224. break;
  225. }
  226. }while (0);
  227. return Status;
  228. }