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.

278 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. registry.c
  5. Abstract:
  6. Implement registry functions
  7. Author:
  8. Jiandong Ruan
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "registry.tmh"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGE, SmbQueryValueKey)
  15. #pragma alloc_text(PAGE, SmbReadULong)
  16. #endif
  17. PKEY_VALUE_FULL_INFORMATION
  18. SmbQueryValueKey(
  19. HANDLE hKey,
  20. LPWSTR ValueStringName
  21. )
  22. /*++
  23. Routine Description:
  24. This function retrieves the full information for the specified key.
  25. It allocates local memory for the returned information.
  26. Arguments:
  27. Key : registry handle to the key where the value is.
  28. ValueStringName : name of the value string.
  29. Return Value:
  30. NULL if out of resource or error. Otherwise, the pointer to the full information
  31. --*/
  32. {
  33. DWORD BytesNeeded, BytesAllocated;
  34. NTSTATUS status;
  35. UNICODE_STRING KeyName;
  36. PKEY_VALUE_FULL_INFORMATION Buffer;
  37. PAGED_CODE();
  38. RtlInitUnicodeString(&KeyName, ValueStringName);
  39. Buffer = NULL;
  40. BytesAllocated = 0;
  41. BytesNeeded = 240;
  42. while(1) {
  43. ASSERT(Buffer == NULL);
  44. Buffer = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePoolWithTag(PagedPool, BytesNeeded, SMB_POOL_REGISTRY);
  45. if (Buffer == NULL) {
  46. SmbTrace(SMB_TRACE_REGISTRY, ("(Out of memory)"));
  47. return NULL;
  48. }
  49. BytesAllocated = BytesNeeded;
  50. status = ZwQueryValueKey(
  51. hKey,
  52. &KeyName,
  53. KeyValueFullInformation,
  54. Buffer,
  55. BytesAllocated,
  56. &BytesNeeded
  57. );
  58. if (status == STATUS_SUCCESS) {
  59. break;
  60. }
  61. ASSERT(Buffer);
  62. ExFreePool(Buffer);
  63. Buffer = NULL;
  64. if (BytesNeeded == 0 || (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_BUFFER_OVERFLOW)) {
  65. SmbTrace(SMB_TRACE_REGISTRY, ("return %!status! BytesAllocated=%d BytsNeeded=%d %ws",
  66. status, BytesAllocated, BytesNeeded, ValueStringName));
  67. SmbPrint(SMB_TRACE_REGISTRY, ("SmbQueryValueKey return 0x%08lx BytesAllocated=%d BytsNeeded=%d %ws\n",
  68. status, BytesAllocated, BytesNeeded, ValueStringName));
  69. return NULL;
  70. }
  71. }
  72. ASSERT (status == STATUS_SUCCESS);
  73. ASSERT (Buffer);
  74. return Buffer;
  75. }
  76. LONG
  77. SmbReadLong(
  78. IN HANDLE hKey,
  79. IN WCHAR *KeyName,
  80. IN LONG DefaultValue,
  81. IN LONG MinimumValue
  82. )
  83. {
  84. PKEY_VALUE_FULL_INFORMATION KeyInfo;
  85. LONG Value;
  86. PAGED_CODE();
  87. ASSERT (DefaultValue >= MinimumValue);
  88. Value = DefaultValue;
  89. if (Value < MinimumValue) {
  90. Value = MinimumValue;
  91. }
  92. KeyInfo = SmbQueryValueKey(hKey, KeyName);
  93. if (KeyInfo == NULL) {
  94. return Value;
  95. }
  96. if (KeyInfo->Type == REG_DWORD && KeyInfo->DataLength == sizeof(ULONG)) {
  97. RtlCopyMemory(&Value, (PCHAR)KeyInfo + KeyInfo->DataOffset, sizeof(ULONG));
  98. if (Value < MinimumValue) {
  99. Value = MinimumValue;
  100. }
  101. }
  102. ExFreePool(KeyInfo);
  103. return Value;
  104. }
  105. ULONG
  106. SmbReadULong(
  107. IN HANDLE hKey,
  108. IN WCHAR *KeyName,
  109. IN ULONG DefaultValue,
  110. IN ULONG MinimumValue
  111. )
  112. {
  113. PKEY_VALUE_FULL_INFORMATION KeyInfo;
  114. ULONG Value;
  115. PAGED_CODE();
  116. ASSERT (DefaultValue >= MinimumValue);
  117. Value = DefaultValue;
  118. if (Value < MinimumValue) {
  119. Value = MinimumValue;
  120. }
  121. KeyInfo = SmbQueryValueKey(hKey, KeyName);
  122. if (KeyInfo == NULL) {
  123. return Value;
  124. }
  125. if (KeyInfo->Type == REG_DWORD && KeyInfo->DataLength == sizeof(ULONG)) {
  126. RtlCopyMemory(&Value, (PCHAR)KeyInfo + KeyInfo->DataOffset, sizeof(ULONG));
  127. if (Value < MinimumValue) {
  128. Value = MinimumValue;
  129. }
  130. }
  131. ExFreePool(KeyInfo);
  132. return Value;
  133. }
  134. NTSTATUS
  135. SmbReadRegistry(
  136. IN HANDLE Key,
  137. IN LPWSTR ValueStringName,
  138. IN OUT DWORD *Type,
  139. IN OUT DWORD *Size,
  140. IN OUT PVOID *Buffer
  141. )
  142. /*++
  143. Routine Description:
  144. Read a regisry value
  145. Arguments:
  146. Key The registry handle under which the registry key resides.
  147. ValueStringName The name of registry key
  148. Type The data type of the registry key
  149. Type == NULL The caller is not interested in the data type
  150. Type != NULL The caller want to receive the data type
  151. *Type != REG_NONE The caller can receive the value as any data type.
  152. Size The size (# of bytes) of the registry value.
  153. Size == NULL The caller is not interested in the data size
  154. Size != NULL The caller want to know the data size.
  155. Size != NULL && *Buffer != NULL
  156. The caller has provided a buffer. *Size is the size of
  157. caller-supplied buffer.
  158. Buffer The output buffer
  159. *Buffer == NULL The caller doesn't provide any buffer. This function
  160. should allocate a buffer. The caller is responsible to
  161. free the buffer.
  162. *Buffer != NULL The caller provides a buffer. The size of buffer is specified
  163. in *Size;
  164. Return Value:
  165. STATUS_SUCCESS success
  166. other failure
  167. --*/
  168. {
  169. PKEY_VALUE_FULL_INFORMATION KeyInfo;
  170. ASSERT (Buffer);
  171. if (Buffer == NULL) {
  172. return STATUS_INVALID_PARAMETER;
  173. }
  174. // ASSERT (*Buffer ==> Size && *Size);
  175. ASSERT (!(*Buffer) || (Size && *Size));
  176. if ((*Buffer) && !(Size && *Size)) {
  177. return STATUS_INVALID_PARAMETER;
  178. }
  179. if ((NULL == *Buffer) && Size && *Size) {
  180. ASSERT(0);
  181. return STATUS_INVALID_PARAMETER;
  182. }
  183. KeyInfo = SmbQueryValueKey(
  184. Key,
  185. ValueStringName
  186. );
  187. if (NULL == KeyInfo) {
  188. return STATUS_UNSUCCESSFUL;
  189. }
  190. if (Type && *Type != REG_NONE) {
  191. if (KeyInfo->Type != *Type) {
  192. ExFreePool(KeyInfo);
  193. return STATUS_UNSUCCESSFUL;
  194. }
  195. }
  196. if (NULL == *Buffer) {
  197. *Buffer = ExAllocatePoolWithTag(PagedPool, KeyInfo->DataLength, SMB_POOL_REGISTRY);
  198. if (NULL == *Buffer) {
  199. ExFreePool(KeyInfo);
  200. return STATUS_NO_MEMORY;
  201. }
  202. } else {
  203. if (*Size < KeyInfo->DataLength) {
  204. ExFreePool(KeyInfo);
  205. *Size = KeyInfo->DataLength;
  206. return STATUS_BUFFER_TOO_SMALL;
  207. }
  208. }
  209. //
  210. // From now on, we cannot fail
  211. //
  212. if (Size) {
  213. *Size = KeyInfo->DataLength;
  214. }
  215. if (Type) {
  216. *Type = KeyInfo->Type;
  217. }
  218. RtlCopyMemory(*Buffer, ((PUCHAR)KeyInfo) + KeyInfo->DataOffset, KeyInfo->DataLength);
  219. ExFreePool(KeyInfo);
  220. return STATUS_SUCCESS;
  221. }