ReactOS 0.4.15-dev-7924-g5949c20
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 "lsasrv.h"
11
12/* FUNCTIONS ***************************************************************/
13
14static
17{
18 return (Type == REG_SZ) || (Type == REG_EXPAND_SZ) || (Type == REG_MULTI_SZ);
19}
20
21
24{
25 return NtClose(KeyHandle);
26}
27
28
30LsapRegCreateKey(IN HANDLE ParentKeyHandle,
34{
38
40
42 &Name,
44 ParentKeyHandle,
45 NULL);
46
47 /* Create the key */
48 return ZwCreateKey(KeyHandle,
51 0,
52 NULL,
53 0,
55}
56
57
61{
64 HANDLE TargetKey;
66
72 ParentKeyHandle,
73 NULL);
74 Status = NtOpenKey(&TargetKey,
75 DELETE,
77 if (!NT_SUCCESS(Status))
78 return Status;
79
80 Status = NtDeleteKey(TargetKey);
81
82 NtClose(TargetKey);
83
84 return Status;
85}
86
87
90{
91 return NtDeleteKey(KeyHandle);
92}
93
94
100{
105
106 /* Check if we have a name */
107 if (Length)
108 {
109 /* Allocate a buffer for it */
110 BufferLength = sizeof(KEY_BASIC_INFORMATION) + Length * sizeof(WCHAR);
111
112 KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
113 if (KeyInfo == NULL)
114 return STATUS_NO_MEMORY;
115 }
116
117 /* Enumerate the key */
118 Status = ZwEnumerateKey(KeyHandle,
119 Index,
121 KeyInfo,
124 if (NT_SUCCESS(Status))
125 {
126 /* Check if the name fits */
127 if (KeyInfo->NameLength < (Length * sizeof(WCHAR)))
128 {
129 /* Copy it */
131 KeyInfo->Name,
132 KeyInfo->NameLength);
133
134 /* Terminate the string */
135 Buffer[KeyInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
136 }
137 else
138 {
139 /* Otherwise, we ran out of buffer space */
141 }
142 }
143
144 /* Free the buffer and return status */
145 if (KeyInfo)
146 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
147
148 return Status;
149}
150
151
153LsapRegOpenKey(IN HANDLE ParentKeyHandle,
157{
160
162
164 &Name,
166 ParentKeyHandle,
167 NULL);
168
169 return NtOpenKey(KeyHandle,
172}
173
174
177 OUT PULONG SubKeyCount,
178 OUT PULONG MaxSubKeyNameLength,
179 OUT PULONG ValueCount)
180{
181 KEY_FULL_INFORMATION FullInfoBuffer;
184
185 FullInfoBuffer.ClassLength = 0;
187
190 &FullInfoBuffer,
191 sizeof(KEY_FULL_INFORMATION),
192 &Length);
193 TRACE("NtQueryKey() returned status 0x%08lX\n", Status);
194 if (!NT_SUCCESS(Status))
195 return Status;
196
197 if (SubKeyCount != NULL)
198 *SubKeyCount = FullInfoBuffer.SubKeys;
199
200 if (MaxSubKeyNameLength != NULL)
201 *MaxSubKeyNameLength = FullInfoBuffer.MaxNameLen;
202
203 if (ValueCount != NULL)
204 *ValueCount = FullInfoBuffer.Values;
205
206 return Status;
207}
208
209
213{
215
217 ValueName);
218
220 &Name);
221}
222
223
226 IN ULONG Index,
228 IN OUT PULONG NameLength,
232{
237
238 TRACE("Index: %lu\n", Index);
239
240 /* Calculate the required buffer length */
242 BufferLength += (MAX_PATH + 1) * sizeof(WCHAR);
243 if (Data != NULL)
245
246 /* Allocate the value buffer */
247 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
248 if (ValueInfo == NULL)
249 return STATUS_NO_MEMORY;
250
251 /* Enumerate the value*/
252 Status = ZwEnumerateValueKey(KeyHandle,
253 Index,
255 ValueInfo,
258 if (NT_SUCCESS(Status))
259 {
260 if (Name != NULL)
261 {
262 /* Check if the name fits */
263 if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR)))
264 {
265 /* Copy it */
267 ValueInfo->Name,
268 ValueInfo->NameLength);
269
270 /* Terminate the string */
271 Name[ValueInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
272 }
273 else
274 {
275 /* Otherwise, we ran out of buffer space */
277 goto done;
278 }
279 }
280
281 if (Data != NULL)
282 {
283 /* Check if the data fits */
284 if (ValueInfo->DataLength <= *DataLength)
285 {
286 /* Copy it */
288 (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
289 ValueInfo->DataLength);
290
291 /* if the type is REG_SZ and data is not 0-terminated
292 * and there is enough space in the buffer NT appends a \0 */
293 if (IsStringType(ValueInfo->Type) &&
294 ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
295 {
296 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
297 if ((ptr > (WCHAR *)Data) && ptr[-1])
298 *ptr = UNICODE_NULL;
299 }
300 }
301 else
302 {
304 goto done;
305 }
306 }
307 }
308
309done:
311 {
312 if (Type != NULL)
313 *Type = ValueInfo->Type;
314
315 if (NameLength != NULL)
316 *NameLength = ValueInfo->NameLength;
317
318 if (DataLength != NULL)
319 *DataLength = ValueInfo->DataLength;
320 }
321
322 /* Free the buffer and return status */
323 if (ValueInfo)
324 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
325
326 return Status;
327}
328
329
336{
341
343 ValueName);
344
345 if (DataLength != NULL)
347
349
350 /* Allocate memory for the value */
351 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
352 if (ValueInfo == NULL)
353 return STATUS_NO_MEMORY;
354
355 /* Query the value */
356 Status = ZwQueryValueKey(KeyHandle,
357 &Name,
359 ValueInfo,
361 &BufferLength);
363 {
364 if (Type != NULL)
365 *Type = ValueInfo->Type;
366
367 if (DataLength != NULL)
368 *DataLength = ValueInfo->DataLength;
369 }
370
371 /* Check if the caller wanted data back, and we got it */
372 if ((NT_SUCCESS(Status)) && (Data != NULL))
373 {
374 /* Copy it */
376 ValueInfo->Data,
377 ValueInfo->DataLength);
378
379 /* if the type is REG_SZ and data is not 0-terminated
380 * and there is enough space in the buffer NT appends a \0 */
381 if (IsStringType(ValueInfo->Type) &&
382 ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
383 {
384 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
385 if ((ptr > (WCHAR *)Data) && ptr[-1])
386 *ptr = UNICODE_NULL;
387 }
388 }
389
390 /* Free the memory and return status */
391 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
392
393 if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW))
395
396 return Status;
397}
398
399
403 ULONG Type,
404 LPVOID Data,
406{
408
410 ValueName);
411
412 return ZwSetValueKey(KeyHandle,
413 &Name,
414 0,
415 Type,
416 Data,
417 DataLength);
418}
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:32
#define MAX_PATH
Definition: compat.h:34
NTSTATUS LsapRegDeleteSubKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName)
Definition: registry.c:59
NTSTATUS LsapRegEnumerateValue(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:225
NTSTATUS LsapRegQueryValue(IN HANDLE KeyHandle, IN LPWSTR ValueName, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL)
Definition: registry.c:331
NTSTATUS LsapRegQueryKeyInfo(IN HANDLE KeyHandle, OUT PULONG SubKeyCount, OUT PULONG MaxSubKeyNameLength, OUT PULONG ValueCount)
Definition: registry.c:176
NTSTATUS LsapRegOpenKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName, IN ACCESS_MASK DesiredAccess, OUT HANDLE KeyHandle)
Definition: registry.c:153
NTSTATUS LsapRegSetValue(HANDLE KeyHandle, LPWSTR ValueName, ULONG Type, LPVOID Data, ULONG DataLength)
Definition: registry.c:401
NTSTATUS LsapRegCloseKey(IN HANDLE KeyHandle)
Definition: registry.c:23
NTSTATUS LsapRegDeleteKey(IN HANDLE KeyHandle)
Definition: registry.c:89
NTSTATUS LsapRegDeleteValue(IN HANDLE KeyHandle, IN LPWSTR ValueName)
Definition: registry.c:211
NTSTATUS LsapRegCreateKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName, IN ACCESS_MASK DesiredAccess, OUT HANDLE KeyHandle)
Definition: registry.c:30
static BOOLEAN IsStringType(ULONG Type)
Definition: registry.c:16
NTSTATUS LsapRegEnumerateSubKey(IN HANDLE KeyHandle, IN ULONG Index, IN ULONG Length, OUT LPWSTR Buffer)
Definition: registry.c:96
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
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#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