Source code of Windows XP (NT5)
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.

367 lines
8.7 KiB

  1. /*++
  2. Copyright (c) 1992-2001 Microsoft Corporation
  3. Module Name:
  4. dfsmetaloc.c
  5. Abstract:
  6. DFS metadata locating routines.
  7. Author:
  8. Uday Hegde (udayh) 10-May-2001
  9. Revision History:
  10. --*/
  11. #define UNICODE 1
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <stddef.h>
  19. #include <shellapi.h>
  20. #include <lm.h>
  21. #define DFS_REGISTRY_CHILD_NAME_SIZE_MAX 4096
  22. LPWSTR DfsRootShareValueName = L"RootShare";
  23. LPWSTR OldRegistryString = L"SOFTWARE\\Microsoft\\DfsHost\\volumes";
  24. LPWSTR NewRegistryString = L"SOFTWARE\\Microsoft\\Dfs\\Roots\\Standalone";
  25. LPWSTR DfsOldStandaloneChild = L"domainroot";
  26. DWORD
  27. CheckForShareNameMatch(
  28. HKEY DfsKey,
  29. LPWSTR ChildName,
  30. LPWSTR RootName,
  31. PBOOLEAN pMatch)
  32. {
  33. DWORD Status;
  34. HKEY DfsRootKey;
  35. LPWSTR DfsRootShare = NULL;
  36. ULONG DataSize, DataType, RootShareLength;
  37. *pMatch = FALSE;
  38. Status = RegOpenKeyEx( DfsKey,
  39. ChildName,
  40. 0,
  41. KEY_READ,
  42. &DfsRootKey );
  43. if (Status == ERROR_SUCCESS)
  44. {
  45. Status = RegQueryInfoKey( DfsRootKey, // Key
  46. NULL, // Class string
  47. NULL, // Size of class string
  48. NULL, // Reserved
  49. NULL, // # of subkeys
  50. NULL, // max size of subkey name
  51. NULL, // max size of class name
  52. NULL, // # of values
  53. NULL, // max size of value name
  54. &DataSize, // max size of value data,
  55. NULL, // security descriptor
  56. NULL ); // Last write time
  57. if (Status == ERROR_SUCCESS) {
  58. RootShareLength = DataSize;
  59. DfsRootShare = (LPWSTR) malloc(DataSize);
  60. if (DfsRootShare == NULL) {
  61. Status = ERROR_NOT_ENOUGH_MEMORY;
  62. }
  63. else {
  64. Status = RegQueryValueEx( DfsRootKey,
  65. DfsRootShareValueName,
  66. NULL,
  67. &DataType,
  68. (LPBYTE)DfsRootShare,
  69. &RootShareLength);
  70. if (Status == ERROR_SUCCESS)
  71. {
  72. if (_wcsicmp(DfsRootShare, RootName) == 0)
  73. {
  74. *pMatch = TRUE;
  75. }
  76. }
  77. free(DfsRootShare);
  78. }
  79. }
  80. RegCloseKey( DfsRootKey );
  81. }
  82. //
  83. // we may be dealing with a new key here: which is just being setup.
  84. // return success if any of the above returned error not found.
  85. //
  86. if ((Status == ERROR_NOT_FOUND) ||
  87. (Status == ERROR_FILE_NOT_FOUND))
  88. {
  89. Status = ERROR_SUCCESS;
  90. }
  91. return Status;
  92. }
  93. DWORD
  94. DfsGetMatchingChild(
  95. HKEY DfsKey,
  96. LPWSTR RootName,
  97. LPWSTR FoundChild,
  98. PBOOLEAN pMatch )
  99. {
  100. DWORD Status;
  101. ULONG ChildNum = 0;
  102. do
  103. {
  104. //
  105. // For each child, get the child name.
  106. //
  107. DWORD ChildNameLen = DFS_REGISTRY_CHILD_NAME_SIZE_MAX;
  108. WCHAR ChildName[DFS_REGISTRY_CHILD_NAME_SIZE_MAX];
  109. //
  110. // Now enumerate the children, starting from the first child.
  111. //
  112. Status = RegEnumKeyEx( DfsKey,
  113. ChildNum,
  114. ChildName,
  115. &ChildNameLen,
  116. NULL,
  117. NULL,
  118. NULL,
  119. NULL );
  120. ChildNum++;
  121. if ( Status == ERROR_SUCCESS )
  122. {
  123. Status = CheckForShareNameMatch( DfsKey,
  124. ChildName,
  125. RootName,
  126. pMatch );
  127. if ((Status == ERROR_SUCCESS) && (*pMatch == TRUE))
  128. {
  129. wcscpy(FoundChild, ChildName);
  130. break;
  131. }
  132. }
  133. } while (Status == ERROR_SUCCESS);
  134. //
  135. // If we ran out of children, then return success code.
  136. //
  137. if (Status == ERROR_NO_MORE_ITEMS)
  138. {
  139. Status = ERROR_SUCCESS;
  140. }
  141. return Status;
  142. }
  143. DWORD
  144. CreateShareNameToReturn (
  145. LPWSTR Child1,
  146. LPWSTR Child2,
  147. LPWSTR *pReturnName )
  148. {
  149. DWORD Status;
  150. ULONG LengthNeeded = 0;
  151. PVOID BufferToReturn;
  152. if (Child1 != NULL)
  153. {
  154. LengthNeeded += sizeof(WCHAR);
  155. LengthNeeded += (DWORD) (wcslen(Child1) * sizeof(WCHAR));
  156. }
  157. if (Child2 != NULL)
  158. {
  159. LengthNeeded += sizeof(WCHAR);
  160. LengthNeeded += (DWORD) (wcslen(Child2) * sizeof(WCHAR));
  161. }
  162. LengthNeeded += sizeof(WCHAR);
  163. Status = NetApiBufferAllocate( LengthNeeded, &BufferToReturn );
  164. if (Status == ERROR_SUCCESS)
  165. {
  166. if (Child1 != NULL)
  167. {
  168. wcscpy(BufferToReturn, Child1);
  169. }
  170. if (Child2 != NULL)
  171. {
  172. wcscat(BufferToReturn, L"\\");
  173. wcscat(BufferToReturn, Child2);
  174. }
  175. *pReturnName = BufferToReturn;
  176. }
  177. return Status;
  178. }
  179. DWORD
  180. DfsCheckNewStandaloneRoots(
  181. LPWSTR RootName,
  182. LPWSTR *pMetadataNameLocation )
  183. {
  184. BOOLEAN Found;
  185. HKEY DfsKey;
  186. WCHAR ChildName[MAX_PATH];
  187. DWORD Status;
  188. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  189. NewRegistryString,
  190. 0,
  191. KEY_READ,
  192. &DfsKey );
  193. if (Status == ERROR_SUCCESS)
  194. {
  195. Status = DfsGetMatchingChild( DfsKey,
  196. RootName,
  197. ChildName,
  198. &Found );
  199. if (Status == ERROR_SUCCESS)
  200. {
  201. if (Found)
  202. {
  203. Status = CreateShareNameToReturn(NewRegistryString,
  204. ChildName,
  205. pMetadataNameLocation );
  206. }
  207. else
  208. {
  209. Status = ERROR_NOT_FOUND;
  210. }
  211. }
  212. RegCloseKey( DfsKey );
  213. }
  214. return Status;
  215. }
  216. DWORD
  217. DfsCheckOldStandaloneRoot(
  218. LPWSTR RootName,
  219. LPWSTR *pMetadataNameLocation )
  220. {
  221. BOOLEAN Found;
  222. HKEY DfsKey;
  223. DWORD Status;
  224. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  225. NewRegistryString,
  226. 0,
  227. KEY_READ,
  228. &DfsKey );
  229. if (Status == ERROR_SUCCESS)
  230. {
  231. Status = CheckForShareNameMatch( DfsKey,
  232. DfsOldStandaloneChild,
  233. RootName,
  234. &Found );
  235. if (Status == ERROR_SUCCESS)
  236. {
  237. if (Found)
  238. {
  239. Status = CreateShareNameToReturn( OldRegistryString,
  240. DfsOldStandaloneChild,
  241. pMetadataNameLocation );
  242. }
  243. else
  244. {
  245. Status = ERROR_NOT_FOUND;
  246. }
  247. }
  248. RegCloseKey( DfsKey );
  249. }
  250. return Status;
  251. }
  252. DWORD
  253. GetDfsRootMetadataLocation(
  254. LPWSTR RootName,
  255. LPWSTR *pMetadataNameLocation )
  256. {
  257. DWORD Status;
  258. Status = DfsCheckNewStandaloneRoots( RootName,
  259. pMetadataNameLocation );
  260. if (Status == ERROR_NOT_FOUND)
  261. {
  262. Status = DfsCheckOldStandaloneRoot( RootName,
  263. pMetadataNameLocation );
  264. }
  265. return Status;
  266. }
  267. VOID
  268. ReleaseDfsRootMetadataLocation(
  269. LPWSTR Buffer )
  270. {
  271. NetApiBufferFree(Buffer);
  272. }
  273. #if 0
  274. _cdecl
  275. main(
  276. int argc,
  277. char *argv[])
  278. {
  279. LPWSTR CommandLine;
  280. LPWSTR *argvw;
  281. int argcw,i;
  282. LPWSTR out;
  283. DWORD Status;
  284. //
  285. // Get the command line in Unicode
  286. //
  287. CommandLine = GetCommandLine();
  288. argvw = CommandLineToArgvW(CommandLine, &argcw);
  289. printf("Argvw is %wS\n", argvw[1]);
  290. Status = GetDfsRootMetadataLocation( argvw[1],
  291. &out );
  292. printf("Status is %x out is %ws\n", Status, out);
  293. if (Status == ERROR_SUCCESS)
  294. {
  295. ReleaseDfsRootMetadataLocation(out);
  296. }
  297. exit(0);
  298. }
  299. #endif