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.

462 lines
12 KiB

  1. //
  2. // Copyright (C) 2000, Microsoft Corporation
  3. //
  4. // File: DfsMisc.c
  5. //
  6. // Contents: miscellaneous dfs functions.
  7. //
  8. // History: Dec. 8 2000, Author: udayh
  9. //
  10. //-----------------------------------------------------------------------------
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stddef.h>
  18. #include <malloc.h>
  19. #include "rpc.h"
  20. #include "rpcdce.h"
  21. #include <dfsheader.h>
  22. #include "lm.h"
  23. #include "lmdfs.h"
  24. #include <strsafe.h>
  25. #include <dfsmisc.h>
  26. DFSSTATUS
  27. DfsGenerateUuidString(
  28. LPWSTR *UuidString )
  29. {
  30. RPC_STATUS RpcStatus = RPC_S_OK;
  31. DFSSTATUS Status = ERROR_GEN_FAILURE;
  32. UUID NewUid;
  33. RpcStatus = UuidCreate(&NewUid);
  34. if (RpcStatus == RPC_S_OK)
  35. {
  36. RpcStatus = UuidToString( &NewUid,
  37. UuidString );
  38. if (RpcStatus == RPC_S_OK)
  39. {
  40. Status = ERROR_SUCCESS;
  41. }
  42. }
  43. return Status;
  44. }
  45. VOID
  46. DfsReleaseUuidString(
  47. LPWSTR *UuidString )
  48. {
  49. RpcStringFree(UuidString);
  50. }
  51. //+-------------------------------------------------------------------------
  52. //
  53. // Function: DfsCreateUnicodeString
  54. //
  55. // Arguments: pDest - the destination unicode string
  56. // pSrc - the source unicode string
  57. //
  58. // Returns: SUCCESS or error
  59. //
  60. // Description: This routine creates a new unicode string that is a copy
  61. // of the original. The copied unicode string has a buffer
  62. // that is null terminated, so the buffer can be used as a
  63. // normal string if necessary.
  64. //
  65. //--------------------------------------------------------------------------
  66. DFSSTATUS
  67. DfsCreateUnicodeString(
  68. PUNICODE_STRING pDest,
  69. PUNICODE_STRING pSrc )
  70. {
  71. LPWSTR NewString = NULL;
  72. DFSSTATUS Status = ERROR_SUCCESS;
  73. NewString = malloc(pSrc->Length + sizeof(WCHAR));
  74. if ( NewString == NULL )
  75. {
  76. return ERROR_NOT_ENOUGH_MEMORY;
  77. }
  78. RtlCopyMemory( NewString, pSrc->Buffer, pSrc->Length);
  79. NewString[ pSrc->Length / sizeof(WCHAR)] = UNICODE_NULL;
  80. Status = DfsRtlInitUnicodeStringEx( pDest, NewString );
  81. if(Status != ERROR_SUCCESS)
  82. {
  83. free (NewString);
  84. }
  85. return Status;
  86. }
  87. //+-------------------------------------------------------------------------
  88. //
  89. // Function: DfsCreateUnicodeStringFromString
  90. //
  91. // Arguments: pDest - the destination unicode string
  92. // pSrcString - the source string
  93. //
  94. // Returns: SUCCESS or error
  95. //
  96. // Description: This routine creates a new unicode string that has a copy
  97. // of the passed in source string. The unicode string has
  98. // a buffer that is null terminated, so the buffer can be
  99. // used as a normal string if necessary.
  100. //
  101. //--------------------------------------------------------------------------
  102. DFSSTATUS
  103. DfsCreateUnicodeStringFromString(
  104. PUNICODE_STRING pDest,
  105. LPWSTR pSrcString )
  106. {
  107. DFSSTATUS Status = ERROR_SUCCESS;
  108. UNICODE_STRING Source;
  109. Status = DfsRtlInitUnicodeStringEx( &Source, pSrcString );
  110. if(Status == ERROR_SUCCESS)
  111. {
  112. Status = DfsCreateUnicodeString( pDest, &Source );
  113. }
  114. return Status;
  115. }
  116. //+-------------------------------------------------------------------------
  117. //
  118. // Function: DfsCreateUnicodePathString
  119. //
  120. // Arguments: pDest - the destination unicode string
  121. // Number of leading seperators.
  122. // pFirstComponent - the first componet of the name.
  123. // pRemaining - the rest of the name.
  124. //
  125. // Returns: SUCCESS or error
  126. //
  127. // Description: This routine creates a pathname given two components.
  128. // If it is DOS unc name, it creates a name prefixed with
  129. // \\.
  130. // it just creates a name that is formed by
  131. // combining the first component, followed by a \ followed
  132. // by the rest of the name.
  133. // If it is DOS unc name, it creates a name prefixed with
  134. // \\.
  135. //--------------------------------------------------------------------------
  136. DFSSTATUS
  137. DfsCreateUnicodePathStringFromUnicode(
  138. PUNICODE_STRING pDest,
  139. ULONG NumberOfLeadingSeperators,
  140. PUNICODE_STRING pFirst,
  141. PUNICODE_STRING pRemaining )
  142. {
  143. ULONG NameLen = 0;
  144. LPWSTR NewString = NULL;
  145. DFSSTATUS Status = ERROR_SUCCESS;
  146. ULONG NewOffset = 0;
  147. ULONG Index = 0;
  148. if (NumberOfLeadingSeperators > 2)
  149. {
  150. return ERROR_INVALID_PARAMETER;
  151. }
  152. for (Index = 0; (Index < pFirst->Length) && (NumberOfLeadingSeperators != 0); Index++)
  153. {
  154. if (pFirst->Buffer[Index] != UNICODE_PATH_SEP)
  155. {
  156. break;
  157. }
  158. NumberOfLeadingSeperators--;
  159. }
  160. NameLen += NumberOfLeadingSeperators * sizeof(WCHAR);
  161. NameLen += pFirst->Length;
  162. if (pRemaining && (IsEmptyString(pRemaining->Buffer) == FALSE))
  163. {
  164. NameLen += sizeof(UNICODE_PATH_SEP);
  165. NameLen += pRemaining->Length;
  166. }
  167. NameLen += sizeof(UNICODE_NULL);
  168. if (NameLen > MAXUSHORT)
  169. {
  170. return ERROR_INVALID_PARAMETER;
  171. }
  172. NewString = malloc( NameLen );
  173. if (NewString != NULL)
  174. {
  175. RtlZeroMemory( NewString, NameLen );
  176. for (NewOffset = 0; NewOffset < NumberOfLeadingSeperators; NewOffset++)
  177. {
  178. NewString[NewOffset] = UNICODE_PATH_SEP;
  179. }
  180. RtlCopyMemory( &NewString[NewOffset], pFirst->Buffer, pFirst->Length);
  181. NewOffset += (pFirst->Length / sizeof(WCHAR));
  182. if (pRemaining && (IsEmptyString(pRemaining->Buffer) == FALSE))
  183. {
  184. NewString[NewOffset++] = UNICODE_PATH_SEP;
  185. RtlCopyMemory( &NewString[NewOffset], pRemaining->Buffer, pRemaining->Length);
  186. NewOffset += (pRemaining->Length / sizeof(WCHAR));
  187. }
  188. NewString[NewOffset] = UNICODE_NULL;
  189. Status = DfsRtlInitUnicodeStringEx(pDest, NewString);
  190. if(Status != ERROR_SUCCESS)
  191. {
  192. free(NewString);
  193. }
  194. }
  195. else
  196. {
  197. Status = ERROR_NOT_ENOUGH_MEMORY;
  198. }
  199. return Status;
  200. }
  201. //+-------------------------------------------------------------------------
  202. //
  203. // Function: DfsCreateUnicodePathString
  204. //
  205. // Arguments: pDest - the destination unicode string
  206. // DosUncName - Do we want to create a unc path name?
  207. // pFirstComponent - the first componet of the name.
  208. // pRemaining - the rest of the name.
  209. //
  210. // Returns: SUCCESS or error
  211. //
  212. // Description: This routine creates a pathname given two components.
  213. // If it is DOS unc name, it creates a name prefixed with
  214. // \\.
  215. // it just creates a name that is formed by
  216. // combining the first component, followed by a \ followed
  217. // by the rest of the name.
  218. // If it is DOS unc name, it creates a name prefixed with
  219. // \\.
  220. //--------------------------------------------------------------------------
  221. DFSSTATUS
  222. DfsCreateUnicodePathString(
  223. PUNICODE_STRING pDest,
  224. ULONG NumberOfLeadingSeperators,
  225. LPWSTR pFirstComponent,
  226. LPWSTR pRemaining )
  227. {
  228. ULONG NameLen = 0;
  229. DFSSTATUS Status = ERROR_SUCCESS;
  230. UNICODE_STRING FirstComponent;
  231. UNICODE_STRING Remaining;
  232. Status = DfsRtlInitUnicodeStringEx( &FirstComponent, pFirstComponent);
  233. if(Status != ERROR_SUCCESS)
  234. {
  235. return Status;
  236. }
  237. Status = DfsRtlInitUnicodeStringEx( &Remaining, pRemaining);
  238. if(Status != ERROR_SUCCESS)
  239. {
  240. return Status;
  241. }
  242. Status = DfsCreateUnicodePathStringFromUnicode( pDest,
  243. NumberOfLeadingSeperators,
  244. &FirstComponent,
  245. &Remaining );
  246. return Status;
  247. }
  248. //+-------------------------------------------------------------------------
  249. //
  250. // Function: DfsFreeUnicodeString
  251. //
  252. // Arguments: pString - the unicode string,
  253. //
  254. // Returns: SUCCESS or error
  255. //
  256. // Description: This routine frees up a unicode string that was
  257. // previously created by calling one of the above
  258. // routines.
  259. // Only the unicode strings created by the above functions
  260. // are valid arguments. Passing any other unicode string
  261. // will result in fatal component errors.
  262. //--------------------------------------------------------------------------
  263. VOID
  264. DfsFreeUnicodeString(
  265. PUNICODE_STRING pDfsString )
  266. {
  267. if (pDfsString->Buffer != NULL)
  268. {
  269. free (pDfsString->Buffer);
  270. }
  271. }
  272. DFSSTATUS
  273. DfsApiSizeLevelHeader(
  274. ULONG Level,
  275. LONG * NewSize )
  276. {
  277. ULONG ReturnSize = 0;
  278. DFSSTATUS Status = ERROR_SUCCESS;
  279. if(NewSize == NULL)
  280. {
  281. return ERROR_INVALID_PARAMETER;
  282. }
  283. switch (Level)
  284. {
  285. case 4:
  286. ReturnSize = sizeof(DFS_INFO_4);
  287. break;
  288. case 3:
  289. ReturnSize = sizeof(DFS_INFO_3);
  290. break;
  291. case 2:
  292. ReturnSize = sizeof(DFS_INFO_2);
  293. break;
  294. case 1:
  295. ReturnSize = sizeof(DFS_INFO_1);
  296. break;
  297. case 200:
  298. ReturnSize = sizeof(DFS_INFO_200);
  299. break;
  300. case 300:
  301. ReturnSize = sizeof(DFS_INFO_300);
  302. break;
  303. default:
  304. Status = ERROR_INVALID_PARAMETER;
  305. break;
  306. }
  307. *NewSize = ReturnSize;
  308. return Status;
  309. }
  310. //
  311. // Wrapper around StringCchLength to return DFSSTATUS.
  312. //
  313. DFSSTATUS
  314. DfsStringCchLength(
  315. LPWSTR pStr,
  316. size_t CchMax,
  317. size_t *pCch)
  318. {
  319. DFSSTATUS Status = ERROR_SUCCESS;
  320. HRESULT Hr = S_OK;
  321. Hr = StringCchLengthW( pStr, CchMax, pCch );
  322. if (!SUCCEEDED(Hr))
  323. {
  324. Status = HRESULT_CODE(Hr);
  325. }
  326. return Status;
  327. }
  328. //
  329. // Retrieve a string value from the registry.
  330. // The unicode-string will be allocated on successful return.
  331. //
  332. DFSSTATUS
  333. DfsGetRegValueString(
  334. HKEY Key,
  335. LPWSTR pKeyName,
  336. PUNICODE_STRING pValue )
  337. {
  338. DFSSTATUS Status = ERROR_SUCCESS;
  339. ULONG DataSize = 0;
  340. ULONG DataType = 0;
  341. LPWSTR pRegString = NULL;
  342. Status = RegQueryInfoKey( Key, // Key
  343. NULL, // Class string
  344. NULL, // Size of class string
  345. NULL, // Reserved
  346. NULL, // # of subkeys
  347. NULL, // max size of subkey name
  348. NULL, // max size of class name
  349. NULL, // # of values
  350. NULL, // max size of value name
  351. &DataSize, // max size of value data,
  352. NULL, // security descriptor
  353. NULL ); // Last write time
  354. if (Status == ERROR_SUCCESS)
  355. {
  356. DataSize += sizeof(WCHAR); // NULL Terminator
  357. pRegString = (LPWSTR) malloc( DataSize );
  358. if ( pRegString == NULL )
  359. {
  360. Status = ERROR_NOT_ENOUGH_MEMORY;
  361. } else
  362. {
  363. Status = RegQueryValueEx( Key,
  364. pKeyName,
  365. NULL,
  366. &DataType,
  367. (LPBYTE)pRegString,
  368. &DataSize );
  369. }
  370. }
  371. if (Status == ERROR_SUCCESS)
  372. {
  373. if (DataType == REG_SZ)
  374. {
  375. Status = DfsRtlInitUnicodeStringEx( pValue, pRegString );
  376. }
  377. else {
  378. Status = ERROR_INVALID_DATA;
  379. }
  380. }
  381. if (Status != ERROR_SUCCESS)
  382. {
  383. if (pRegString != NULL)
  384. {
  385. free( pRegString );
  386. pValue->Buffer = NULL;
  387. }
  388. }
  389. return Status;
  390. }
  391. VOID
  392. DfsReleaseRegValueString(
  393. PUNICODE_STRING pValue )
  394. {
  395. if (pValue != NULL)
  396. {
  397. free( pValue->Buffer );
  398. pValue->Buffer = NULL;
  399. }
  400. }