ReactOS  0.4.14-dev-342-gdc047f9
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 
14 static
15 BOOLEAN
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 
30 LsapRegCreateKey(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,
54  &Disposition);
55 }
56 
57 
59 LsapRegDeleteSubKey(IN HANDLE ParentKeyHandle,
61 {
64  HANDLE TargetKey;
66 
68  (LPWSTR)KeyName);
70  &SubKeyName,
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 
97  IN ULONG Index,
98  IN ULONG Length,
100 {
101  PKEY_BASIC_INFORMATION KeyInfo = NULL;
102  ULONG BufferLength = 0;
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,
122  BufferLength,
123  &ReturnedLength);
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 
152 NTSTATUS
153 LsapRegOpenKey(IN HANDLE ParentKeyHandle,
157 {
160 
162 
164  &Name,
166  ParentKeyHandle,
167  NULL);
168 
169  return NtOpenKey(KeyHandle,
172 }
173 
174 
175 NTSTATUS
177  OUT PULONG SubKeyCount,
178  OUT PULONG MaxSubKeyNameLength,
179  OUT PULONG ValueCount)
180 {
181  KEY_FULL_INFORMATION FullInfoBuffer;
182  ULONG Length;
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 
210 NTSTATUS
213 {
215 
217  ValueName);
218 
220  &Name);
221 }
222 
223 
224 NTSTATUS
226  IN ULONG Index,
227  OUT LPWSTR Name,
228  IN OUT PULONG NameLength,
232 {
233  PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL;
234  ULONG BufferLength = 0;
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,
256  BufferLength,
257  &ReturnedLength);
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 
309 done:
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 
330 NTSTATUS
336 {
339  ULONG BufferLength = 0;
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,
360  BufferLength,
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 
400 NTSTATUS
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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define IN
Definition: typedefs.h:38
Type
Definition: Type.h:6
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
NTSTATUS LsapRegDeleteKey(IN HANDLE KeyHandle)
Definition: registry.c:89
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
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 NTAPI NtQueryKey(IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:632
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJ_OPENIF
Definition: winternl.h:229
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define UNICODE_NULL
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define REG_MULTI_SZ
Definition: nt_native.h:1501
static PVOID ptr
Definition: dispmode.c:27
struct NameRec_ * Name
Definition: cdprocs.h:464
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
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
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:994
NTSTATUS LsapRegQueryKeyInfo(IN HANDLE KeyHandle, OUT PULONG SubKeyCount, OUT PULONG MaxSubKeyNameLength, OUT PULONG ValueCount)
Definition: registry.c:176
NTSTATUS LsapRegCreateKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName, IN ACCESS_MASK DesiredAccess, OUT HANDLE KeyHandle)
Definition: registry.c:30
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
NTSTATUS LsapRegOpenKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName, IN ACCESS_MASK DesiredAccess, OUT HANDLE KeyHandle)
Definition: registry.c:153
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
NTSTATUS LsapRegCloseKey(IN HANDLE KeyHandle)
Definition: registry.c:23
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
NTSTATUS LsapRegEnumerateSubKey(IN HANDLE KeyHandle, IN ULONG Index, IN ULONG Length, OUT LPWSTR Buffer)
Definition: registry.c:96
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
NTSTATUS LsapRegDeleteSubKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName)
Definition: registry.c:59
unsigned int * PULONG
Definition: retypes.h:1
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSTATUS LsapRegSetValue(HANDLE KeyHandle, LPWSTR ValueName, ULONG Type, LPVOID Data, ULONG DataLength)
Definition: registry.c:401
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS LsapRegDeleteValue(IN HANDLE KeyHandle, IN LPWSTR ValueName)
Definition: registry.c:211
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define DELETE
Definition: nt_native.h:57
static BOOLEAN IsStringType(ULONG Type)
Definition: registry.c:16
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68