ReactOS 0.4.16-dev-88-ga65b6ae
registry.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Security Account Manager (SAM) Server
4 * FILE: reactos/dll/win32/samsrv/registry.c
5 * PURPOSE: Registry helper functions
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10#include "samsrv.h"
11
12#include <ndk/cmfuncs.h>
13#include <ndk/obfuncs.h>
14
15/* FUNCTIONS ***************************************************************/
16
17static
20{
21 return (Type == REG_SZ) || (Type == REG_EXPAND_SZ) || (Type == REG_MULTI_SZ);
22}
23
24
27{
29
30 if (KeyHandle == NULL || *KeyHandle == NULL)
31 return STATUS_SUCCESS;
32
34 if (NT_SUCCESS(Status))
35 *KeyHandle = NULL;
36
37 return Status;
38}
39
40
42SampRegCreateKey(IN HANDLE ParentKeyHandle,
46{
50
52
54 &Name,
56 ParentKeyHandle,
57 NULL);
58
59 /* Create the key */
60 return ZwCreateKey(KeyHandle,
63 0,
64 NULL,
65 0,
67}
68
69
71SampRegDeleteKey(IN HANDLE ParentKeyHandle,
73{
76 HANDLE TargetKey;
78
84 ParentKeyHandle,
85 NULL);
86 Status = NtOpenKey(&TargetKey,
87 DELETE,
89 if (!NT_SUCCESS(Status))
90 return Status;
91
92 Status = NtDeleteKey(TargetKey);
93
94 NtClose(TargetKey);
95
96 return Status;
97}
98
99
102 IN ULONG Index,
105{
110
111 /* Check if we have a name */
112 if (Length)
113 {
114 /* Allocate a buffer for it */
115 BufferLength = sizeof(KEY_BASIC_INFORMATION) + Length * sizeof(WCHAR);
116
117 KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
118 if (KeyInfo == NULL)
119 return STATUS_NO_MEMORY;
120 }
121
122 /* Enumerate the key */
123 Status = ZwEnumerateKey(KeyHandle,
124 Index,
126 KeyInfo,
129 if (NT_SUCCESS(Status))
130 {
131 /* Check if the name fits */
132 if (KeyInfo->NameLength < (Length * sizeof(WCHAR)))
133 {
134 /* Copy it */
136 KeyInfo->Name,
137 KeyInfo->NameLength);
138
139 /* Terminate the string */
140 Buffer[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
141 }
142 else
143 {
144 /* Otherwise, we ran out of buffer space */
146 }
147 }
148
149 /* Free the buffer and return status */
150 if (KeyInfo)
151 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
152
153 return Status;
154}
155
156
158SampRegOpenKey(IN HANDLE ParentKeyHandle,
162{
165
167
169 &Name,
171 ParentKeyHandle,
172 NULL);
173
174 return NtOpenKey(KeyHandle,
177}
178
179
182 OUT PULONG SubKeyCount,
183 OUT PULONG ValueCount)
184{
185 KEY_FULL_INFORMATION FullInfoBuffer;
188
189 FullInfoBuffer.ClassLength = 0;
191
194 &FullInfoBuffer,
195 sizeof(KEY_FULL_INFORMATION),
196 &Length);
197 TRACE("NtQueryKey() returned status 0x%08lX\n", Status);
198 if (!NT_SUCCESS(Status))
199 return Status;
200
201 if (SubKeyCount != NULL)
202 *SubKeyCount = FullInfoBuffer.SubKeys;
203
204 if (ValueCount != NULL)
205 *ValueCount = FullInfoBuffer.Values;
206
207 return Status;
208}
209
210
214{
216
218 ValueName);
219
221 &Name);
222}
223
224
227 IN ULONG Index,
229 IN OUT PULONG NameLength,
233{
238
239 TRACE("Index: %lu\n", Index);
240
241 /* Calculate the required buffer length */
243 BufferLength += (MAX_PATH + 1) * sizeof(WCHAR);
244 if (Data != NULL)
246
247 /* Allocate the value buffer */
248 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
249 if (ValueInfo == NULL)
250 return STATUS_NO_MEMORY;
251
252 /* Enumerate the value*/
253 Status = ZwEnumerateValueKey(KeyHandle,
254 Index,
256 ValueInfo,
259 if (NT_SUCCESS(Status))
260 {
261 if (Name != NULL)
262 {
263 /* Check if the name fits */
264 if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR)))
265 {
266 /* Copy it */
268 ValueInfo->Name,
269 ValueInfo->NameLength);
270
271 /* Terminate the string */
272 Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0;
273 }
274 else
275 {
276 /* Otherwise, we ran out of buffer space */
278 goto done;
279 }
280 }
281
282 if (Data != NULL)
283 {
284 /* Check if the data fits */
285 if (ValueInfo->DataLength <= *DataLength)
286 {
287 /* Copy it */
289 (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
290 ValueInfo->DataLength);
291
292 /* if the type is REG_SZ and data is not 0-terminated
293 * and there is enough space in the buffer NT appends a \0 */
294 if (IsStringType(ValueInfo->Type) &&
295 ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
296 {
297 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
298 if ((ptr > (WCHAR *)Data) && ptr[-1])
299 *ptr = 0;
300 }
301 }
302 else
303 {
305 goto done;
306 }
307 }
308 }
309
310done:
312 {
313 if (Type != NULL)
314 *Type = ValueInfo->Type;
315
316 if (NameLength != NULL)
317 *NameLength = ValueInfo->NameLength;
318
319 if (DataLength != NULL)
320 *DataLength = ValueInfo->DataLength;
321 }
322
323 /* Free the buffer and return status */
324 if (ValueInfo)
325 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
326
327 return Status;
328}
329
330
337{
342
344 ValueName);
345
346 if (DataLength != NULL)
348
350
351 /* Allocate memory for the value */
352 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
353 if (ValueInfo == NULL)
354 return STATUS_NO_MEMORY;
355
356 /* Query the value */
357 Status = ZwQueryValueKey(KeyHandle,
358 &Name,
360 ValueInfo,
362 &BufferLength);
364 {
365 if (Type != NULL)
366 *Type = ValueInfo->Type;
367
368 if (DataLength != NULL)
369 *DataLength = ValueInfo->DataLength;
370 }
371
372 /* Check if the caller wanted data back, and we got it */
373 if ((NT_SUCCESS(Status)) && (Data != NULL))
374 {
375 /* Copy it */
377 ValueInfo->Data,
378 ValueInfo->DataLength);
379
380 /* if the type is REG_SZ and data is not 0-terminated
381 * and there is enough space in the buffer NT appends a \0 */
382 if (IsStringType(ValueInfo->Type) &&
383 ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
384 {
385 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
386 if ((ptr > (WCHAR *)Data) && ptr[-1])
387 *ptr = 0;
388 }
389 }
390
391 /* Free the memory and return status */
392 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
393
394 if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW))
396
397 return Status;
398}
399
400
404 ULONG Type,
405 LPVOID Data,
407{
409
411 ValueName);
412
413 return ZwSetValueKey(KeyHandle,
414 &Name,
415 0,
416 Type,
417 Data,
418 DataLength);
419}
unsigned char BOOLEAN
Type
Definition: Type.h:7
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define MAX_PATH
Definition: compat.h:34
static BOOLEAN IsStringType(ULONG Type)
Definition: registry.c:16
NTSTATUS SampRegQueryValue(IN HANDLE KeyHandle, IN LPCWSTR ValueName, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL)
Definition: registry.c:332
NTSTATUS SampRegCloseKey(IN OUT PHANDLE KeyHandle)
Definition: registry.c:26
NTSTATUS SampRegEnumerateValue(IN HANDLE KeyHandle, IN ULONG Index, OUT LPWSTR Name, IN OUT PULONG NameLength, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL)
Definition: registry.c:226
NTSTATUS SampRegQueryKeyInfo(IN HANDLE KeyHandle, OUT PULONG SubKeyCount, OUT PULONG ValueCount)
Definition: registry.c:181
NTSTATUS SampRegSetValue(HANDLE KeyHandle, LPCWSTR ValueName, ULONG Type, LPVOID Data, ULONG DataLength)
Definition: registry.c:402
NTSTATUS SampRegDeleteKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName)
Definition: registry.c:71
NTSTATUS SampRegOpenKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle)
Definition: registry.c:158
NTSTATUS SampRegDeleteValue(IN HANDLE KeyHandle, IN LPCWSTR ValueName)
Definition: registry.c:212
NTSTATUS SampRegCreateKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle)
Definition: registry.c:42
NTSTATUS SampRegEnumerateSubKey(IN HANDLE KeyHandle, IN ULONG Index, IN ULONG Length, OUT LPWSTR Buffer)
Definition: registry.c:101
Status
Definition: gdiplustypes.h:25
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define REG_SZ
Definition: layer.c:22
static PVOID ptr
Definition: dispmode.c:27
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4725
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyBasicInformation
Definition: nt_native.h:1131
@ KeyFullInformation
Definition: nt_native.h:1133
@ KeyValuePartialInformation
Definition: nt_native.h:1182
@ KeyValueFullInformation
Definition: nt_native.h:1181
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_MULTI_SZ
Definition: nt_native.h:1501
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DELETE
Definition: nt_native.h:57
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
NTSTATUS NTAPI NtQueryKey(IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:632
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185