ReactOS 0.4.16-dev-1946-g52006dd
registry.c File Reference
#include <rtl.h>
#include <ndk/cmfuncs.h>
#include <debug.h>
Include dependency graph for registry.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define TAG_RTLREGISTRY   'vrqR'
 

Functions

NTSTATUS NTAPI RtlpQueryRegistryDirect (IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Buffer)
 
NTSTATUS NTAPI RtlpCallQueryRegistryRoutine (IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PKEY_VALUE_FULL_INFORMATION KeyValueInfo, IN OUT PULONG InfoSize, IN PVOID Context, IN PVOID Environment)
 
 _Success_ (return!=NULL||BufferSize==0)
 
NTSTATUS NTAPI RtlpGetRegistryHandle (IN ULONG RelativeTo, IN PCWSTR Path, IN BOOLEAN Create, IN PHANDLE KeyHandle)
 
FORCEINLINE VOID RtlpCloseRegistryHandle (_In_ ULONG RelativeTo, _In_ HANDLE KeyHandle)
 
NTSTATUS NTAPI RtlCheckRegistryKey (IN ULONG RelativeTo, IN PWSTR Path)
 
NTSTATUS NTAPI RtlCreateRegistryKey (IN ULONG RelativeTo, IN PWSTR Path)
 
NTSTATUS NTAPI RtlDeleteRegistryValue (IN ULONG RelativeTo, IN PCWSTR Path, IN PCWSTR ValueName)
 
NTSTATUS NTAPI RtlWriteRegistryValue (IN ULONG RelativeTo, IN PCWSTR Path, IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength)
 
NTSTATUS NTAPI RtlOpenCurrentUser (IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle)
 
NTSTATUS NTAPI RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath)
 
NTSTATUS NTAPI RtlpNtCreateKey (OUT HANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class, OUT PULONG Disposition)
 
NTSTATUS NTAPI RtlpNtEnumerateSubKey (IN HANDLE KeyHandle, OUT PUNICODE_STRING SubKeyName, IN ULONG Index, IN ULONG Unused)
 
NTSTATUS NTAPI RtlpNtMakeTemporaryKey (IN HANDLE KeyHandle)
 
NTSTATUS NTAPI RtlpNtOpenKey (OUT HANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG Unused)
 
NTSTATUS NTAPI RtlpNtQueryValueKey (IN HANDLE KeyHandle, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL, IN ULONG Unused)
 
NTSTATUS NTAPI RtlpNtSetValueKey (IN HANDLE KeyHandle, IN ULONG Type, IN PVOID Data, IN ULONG DataLength)
 
NTSTATUS NTAPI RtlQueryRegistryValues (IN ULONG RelativeTo, IN PCWSTR Path, IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PVOID Context, IN PVOID Environment OPTIONAL)
 

Variables

SIZE_T RtlpAllocDeallocQueryBufferSize
 
PCWSTR RtlpRegPaths [RTL_REGISTRY_MAXIMUM]
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file registry.c.

◆ TAG_RTLREGISTRY

#define TAG_RTLREGISTRY   'vrqR'

Definition at line 19 of file registry.c.

Function Documentation

◆ _Success_()

_Success_ ( return!  = NULL || BufferSize==0)

Definition at line 427 of file registry.c.

436{
437 PVOID Buffer = NULL;
438
439 /* Assume success */
441
442 /* Free the old buffer */
443 if (OldBuffer) RtlpFreeMemory(OldBuffer, TAG_RTLREGISTRY);
444
445 /* Check if we need to allocate a new one */
446 if (BufferSize)
447 {
448 /* Allocate */
450 if (!(Buffer) && (Status)) *Status = STATUS_NO_MEMORY;
451 }
452
453 /* Return the pointer */
454 return Buffer;
455}
Definition: bufpool.h:45
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
Status
Definition: gdiplustypes.h:25
PVOID NTAPI RtlpAllocateMemory(_In_ ULONG Bytes, _In_ ULONG Tag)
Definition: rtlcompat.c:34
VOID NTAPI RtlpFreeMemory(_In_ PVOID Mem, _In_ ULONG Tag)
Definition: rtlcompat.c:45
#define TAG_RTLREGISTRY
Definition: registry.c:19
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

◆ RtlCheckRegistryKey()

NTSTATUS NTAPI RtlCheckRegistryKey ( IN ULONG  RelativeTo,
IN PWSTR  Path 
)

Definition at line 586 of file registry.c.

588{
592
593 /* Call the helper */
594 Status = RtlpGetRegistryHandle(RelativeTo,
595 Path,
596 FALSE,
597 &KeyHandle);
598 if (!NT_SUCCESS(Status)) return Status;
599
600 /* Close the handle even for RTL_REGISTRY_HANDLE */
602 return STATUS_SUCCESS;
603}
PRTL_UNICODE_STRING_BUFFER Path
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
NTSTATUS NTAPI RtlpGetRegistryHandle(IN ULONG RelativeTo, IN PCWSTR Path, IN BOOLEAN Create, IN PHANDLE KeyHandle)
Definition: registry.c:459

Referenced by IntCreateNewRegistryPath(), and IntCreateRegistryPath().

◆ RtlCreateRegistryKey()

NTSTATUS NTAPI RtlCreateRegistryKey ( IN ULONG  RelativeTo,
IN PWSTR  Path 
)

Definition at line 610 of file registry.c.

612{
616
617 /* Call the helper */
618 Status = RtlpGetRegistryHandle(RelativeTo,
619 Path,
620 TRUE,
621 &KeyHandle);
622 if (!NT_SUCCESS(Status)) return Status;
623
624 /* All went well, close the handle and return status */
626 return STATUS_SUCCESS;
627}
#define TRUE
Definition: types.h:120
FORCEINLINE VOID RtlpCloseRegistryHandle(_In_ ULONG RelativeTo, _In_ HANDLE KeyHandle)
Definition: registry.c:567

Referenced by IntCreateNewRegistryPath().

◆ RtlDeleteRegistryValue()

NTSTATUS NTAPI RtlDeleteRegistryValue ( IN ULONG  RelativeTo,
IN PCWSTR  Path,
IN PCWSTR  ValueName 
)

Definition at line 634 of file registry.c.

637{
642
643 /* Call the helper */
644 Status = RtlpGetRegistryHandle(RelativeTo,
645 Path,
646 TRUE,
647 &KeyHandle);
648 if (!NT_SUCCESS(Status)) return Status;
649
650 /* Initialize the key name and delete it */
653
654 /* Close the handle and return status */
656 return Status;
657}
LPWSTR Name
Definition: desk.c:124
NTSYSAPI NTSTATUS NTAPI ZwDeleteValueKey(__in IN HANDLE Key, __in IN PUNICODE_STRING ValueName)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

◆ RtlFormatCurrentUserKeyPath()

NTSTATUS NTAPI RtlFormatCurrentUserKeyPath ( OUT PUNICODE_STRING  KeyPath)

Definition at line 745 of file registry.c.

746{
748 UCHAR Buffer[256];
749 PSID_AND_ATTRIBUTES SidBuffer;
751 UNICODE_STRING SidString;
754
755 /* Open the thread token */
758 TRUE,
760 &TokenHandle);
761 if (!NT_SUCCESS(Status))
762 {
763 /* We failed, is it because we don't have a thread token? */
764 if (Status != STATUS_NO_TOKEN) return Status;
765
766 /* It is, so use the process token */
767 Status = ZwOpenProcessTokenEx(NtCurrentProcess(),
770 &TokenHandle);
771 if (!NT_SUCCESS(Status)) return Status;
772 }
773
774 /* Now query the token information */
775 SidBuffer = (PSID_AND_ATTRIBUTES)Buffer;
776 Status = ZwQueryInformationToken(TokenHandle,
777 TokenUser,
778 (PVOID)SidBuffer,
779 sizeof(Buffer),
780 &Length);
781
782 /* Close the handle and handle failure */
784 if (!NT_SUCCESS(Status)) return Status;
785
786 /* Convert the SID */
787 Status = RtlConvertSidToUnicodeString(&SidString, SidBuffer[0].Sid, TRUE);
788 if (!NT_SUCCESS(Status)) return Status;
789
790 /* Add the length of the prefix */
791 Length = SidString.Length + sizeof(L"\\REGISTRY\\USER\\");
792
793 /* Initialize a string */
794 RtlInitEmptyUnicodeString(KeyPath,
796 (USHORT)Length);
797 if (!KeyPath->Buffer)
798 {
799 /* Free the string and fail */
800 RtlFreeUnicodeString(&SidString);
801 return STATUS_NO_MEMORY;
802 }
803
804 /* Append the prefix and SID */
805 RtlAppendUnicodeToString(KeyPath, L"\\REGISTRY\\USER\\");
806 RtlAppendUnicodeStringToString(KeyPath, &SidString);
807
808 /* Free the temporary string and return success */
809 RtlFreeUnicodeString(&SidString);
810 return STATUS_SUCCESS;
811}
#define TAG_USTR
Definition: libsupp.c:997
#define RtlpAllocateStringMemory(Bytes, Tag)
Definition: libsupp.c:1000
#define L(x)
Definition: resources.c:13
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define NtCurrentThread()
Definition: winternl.h:5364
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:727
NTSYSAPI NTSTATUS NTAPI ZwOpenThreadTokenEx(_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1165
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NtCurrentProcess()
Definition: nt_native.h:1660
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSYSAPI NTSTATUS NTAPI RtlConvertSidToUnicodeString(OUT PUNICODE_STRING DestinationString, IN PVOID Sid, IN BOOLEAN AllocateDestinationString)
#define STATUS_NO_TOKEN
Definition: ntstatus.h:454
unsigned short USHORT
Definition: pedump.c:61
uint32_t ULONG
Definition: typedefs.h:59
struct _SID_AND_ATTRIBUTES * PSID_AND_ATTRIBUTES
Definition: security.c:130
#define TOKEN_QUERY
Definition: setypes.h:940
@ TokenUser
Definition: setypes.h:978
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by _Success_(), RtlOpenCurrentUser(), and RtlpGetRegistryHandle().

◆ RtlOpenCurrentUser()

NTSTATUS NTAPI RtlOpenCurrentUser ( IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE  KeyHandle 
)

Definition at line 702 of file registry.c.

704{
706 UNICODE_STRING KeyPath;
709
710 /* Get the user key */
712 if (NT_SUCCESS(Status))
713 {
714 /* Initialize the attributes and open it */
716 &KeyPath,
718 NULL,
719 NULL);
721
722 /* Free the path and return success if it worked */
723 RtlFreeUnicodeString(&KeyPath);
724 if (NT_SUCCESS(Status)) return STATUS_SUCCESS;
725 }
726
727 /* It didn't work, so use the default key */
730 &KeyPath,
732 NULL,
733 NULL);
735
736 /* Return status */
737 return Status;
738}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RTL_REGISTRY_USER
Definition: nt_native.h:166
NTSTATUS NTAPI RtlFormatCurrentUserKeyPath(OUT PUNICODE_STRING KeyPath)
Definition: registry.c:745
PCWSTR RtlpRegPaths[RTL_REGISTRY_MAXIMUM]
Definition: registry.c:25
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664

◆ RtlpCallQueryRegistryRoutine()

NTSTATUS NTAPI RtlpCallQueryRegistryRoutine ( IN PRTL_QUERY_REGISTRY_TABLE  QueryTable,
IN PKEY_VALUE_FULL_INFORMATION  KeyValueInfo,
IN OUT PULONG  InfoSize,
IN PVOID  Context,
IN PVOID  Environment 
)

Definition at line 127 of file registry.c.

132{
133 ULONG InfoLength;
134 SIZE_T Length, SpareLength, c;
136 PCHAR SpareData, DataEnd;
137 ULONG Type;
138 PWCHAR Name, p, ValueEnd;
139 PVOID Data;
141 BOOLEAN FoundExpander = FALSE;
143
144 /* Setup defaults */
145 InfoLength = *InfoSize;
146 *InfoSize = 0;
147
148 /* Check if there's no data */
149 if (KeyValueInfo->DataOffset == MAXULONG)
150 {
151 /* Return proper status code */
154 }
155
156 /* Setup spare data pointers */
157 SpareData = (PCHAR)KeyValueInfo;
158 SpareLength = InfoLength;
159 DataEnd = SpareData + SpareLength;
160
161 /* Check if there's no value or data */
162 if ((KeyValueInfo->Type == REG_NONE) ||
163 (!(KeyValueInfo->DataLength) &&
164 (KeyValueInfo->Type == QueryTable->DefaultType)))
165 {
166 /* Check if there's no value */
168 {
169 /* Return proper status code */
172 }
173
174 /* We can setup a default value... capture the defaults */
179 if (!Length)
180 {
181 /* No default length given, try to calculate it */
182 p = Data;
183 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
184 {
185 /* This is a string, count the characters */
186 while (*p++);
188 }
189 else if (Type == REG_MULTI_SZ)
190 {
191 /* This is a multi-string, calculate all characters */
192 while (*p) while (*p++);
194 }
195 }
196 }
197 else
198 {
199 /* Check if we have length */
200 if (KeyValueInfo->DataLength)
201 {
202 /* Increase the spare data */
203 SpareData += KeyValueInfo->DataOffset +
204 KeyValueInfo->DataLength;
205 }
206 else
207 {
208 /* Otherwise, the spare data only has the name data */
210 KeyValueInfo->NameLength;
211 }
212
213 /* Align the pointer and get new size of spare data */
214 SpareData = (PVOID)(((ULONG_PTR)SpareData + 7) & ~7);
215 SpareLength = DataEnd - SpareData;
216
217 /* Check if we have space to copy the data */
218 RequiredLength = KeyValueInfo->NameLength + sizeof(UNICODE_NULL);
219 if ((SpareData > DataEnd) || (SpareLength < RequiredLength))
220 {
221 /* Fail and return the missing length */
222 *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) + RequiredLength;
224 }
225
226 /* Check if this isn't a direct return */
228 {
229 /* Copy the data and null-terminate it */
230 Name = (PWCHAR)SpareData;
231 RtlCopyMemory(Name, KeyValueInfo->Name, KeyValueInfo->NameLength);
232 Name[KeyValueInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
233
234 /* Update the spare data information */
235 SpareData += RequiredLength;
236 SpareData = (PVOID)(((ULONG_PTR)SpareData + 7) & ~7);
237 SpareLength = DataEnd - SpareData;
238 }
239 else
240 {
241 /* Just return the name */
243 }
244
245 /* Capture key data */
246 Type = KeyValueInfo->Type;
247 Data = (PVOID)((ULONG_PTR)KeyValueInfo + KeyValueInfo->DataOffset);
248 Length = KeyValueInfo->DataLength;
249 }
250
251 /* Check if we're expanding */
253 {
254 /* Check if it's a multi-string */
255 if (Type == REG_MULTI_SZ)
256 {
257 /* Prepare defaults */
259 /* Skip the last two UNICODE_NULL chars (the terminating null string) */
260 ValueEnd = (PWSTR)((ULONG_PTR)Data + Length - 2 * sizeof(UNICODE_NULL));
261 p = Data;
262
263 /* Loop all strings */
264 while (p < ValueEnd)
265 {
266 /* Go to the next string */
267 while (*p++);
268
269 /* Get the length and check if this is direct */
272 {
273 /* Do the query */
275 Data,
276 (ULONG)Length,
280 sizeof(UNICODE_STRING));
281 }
282 else
283 {
284 /* Call the custom routine */
286 REG_SZ,
287 Data,
288 (ULONG)Length,
289 Context,
291 }
292
293 /* Normalize status */
295 if (!NT_SUCCESS(Status)) break;
296
297 /* Update data pointer */
298 Data = p;
299 }
300
301 /* Return */
302 return Status;
303 }
304
305 /* Check if this is an expand string */
306 if ((Type == REG_EXPAND_SZ) && (Length >= sizeof(WCHAR)))
307 {
308 /* Try to find the expander */
309 c = Length - sizeof(UNICODE_NULL);
310 p = (PWCHAR)Data;
311 while (c)
312 {
313 /* Check if this is one */
314 if (*p == L'%')
315 {
316 /* Yup! */
317 FoundExpander = TRUE;
318 break;
319 }
320
321 /* Continue in the buffer */
322 p++;
323 c -= sizeof(WCHAR);
324 }
325
326 /* So check if we have one */
327 if (FoundExpander)
328 {
329 /* Setup the source string */
330 RtlInitEmptyUnicodeString(&Source, Data, (USHORT)Length);
331 Source.Length = Source.MaximumLength - sizeof(UNICODE_NULL);
332
333 /* Setup the destination string */
334 RtlInitEmptyUnicodeString(&Destination, (PWCHAR)SpareData, 0);
335
336 /* Check if we're out of space */
337 if (SpareLength <= 0)
338 {
339 /* Then we don't have any space in our string */
341 }
342 else if (SpareLength <= MAXUSHORT)
343 {
344 /* This is the good case, where we fit into a string */
345 Destination.MaximumLength = (USHORT)SpareLength;
346 Destination.Buffer[SpareLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
347 }
348 else
349 {
350 /* We can't fit into a string, so truncate */
353 }
354
355 /* Expand the strings and set our type as one string */
357 &Source,
360 Type = REG_SZ;
361
362 /* Check for success */
363 if (NT_SUCCESS(Status))
364 {
365 /* Set the value name and length to our string */
368 }
369 else
370 {
371 /* Check if our buffer is too small */
373 {
374 /* Set the required missing length */
375 *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) +
377
378 /* Notify debugger */
379 DPRINT1("RTL: Expand variables for %wZ failed - "
380 "Status == %lx Size %x > %x <%x>\n",
381 &Source,
382 Status,
383 *InfoSize,
384 InfoLength,
386 }
387 else
388 {
389 /* Notify debugger */
390 DPRINT1("RTL: Expand variables for %wZ failed - "
391 "Status == %lx\n",
392 &Source,
393 Status);
394 }
395
396 /* Return the status */
397 return Status;
398 }
399 }
400 }
401 }
402
403 /* Check if this is a direct query */
405 {
406 /* Return the data */
408 Data,
409 (ULONG)Length,
411 }
412 else
413 {
414 /* Call the query routine */
416 Type,
417 Data,
418 (ULONG)Length,
419 Context,
421 }
422
423 /* Normalize and return status */
425}
unsigned char BOOLEAN
Type
Definition: Type.h:7
#define DPRINT1
Definition: precomp.h:8
#define ULONG_PTR
Definition: config.h:101
struct _UNICODE_STRING UNICODE_STRING
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
NTSYSAPI NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PCWSTR, const UNICODE_STRING *, UNICODE_STRING *, ULONG *)
#define c
Definition: ke_i.h:80
#define REG_SZ
Definition: layer.c:22
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4211
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3051
#define RTL_QUERY_REGISTRY_NOEXPAND
Definition: nt_native.h:139
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define REG_NONE
Definition: nt_native.h:1495
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define UNICODE_NULL
NTSTATUS NTAPI RtlpQueryRegistryDirect(IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Buffer)
Definition: registry.c:39
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
#define MAXULONG
Definition: typedefs.h:251
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:30
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by RtlQueryRegistryValues().

◆ RtlpCloseRegistryHandle()

FORCEINLINE VOID RtlpCloseRegistryHandle ( _In_ ULONG  RelativeTo,
_In_ HANDLE  KeyHandle 
)

Definition at line 567 of file registry.c.

570{
571 /* Did the caller pass a key handle? */
572 if (!(RelativeTo & RTL_REGISTRY_HANDLE))
573 {
574 /* We opened the key in RtlpGetRegistryHandle, so close it now */
576 }
577}
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168

Referenced by RtlCreateRegistryKey(), RtlDeleteRegistryValue(), RtlQueryRegistryValues(), and RtlWriteRegistryValue().

◆ RtlpGetRegistryHandle()

NTSTATUS NTAPI RtlpGetRegistryHandle ( IN ULONG  RelativeTo,
IN PCWSTR  Path,
IN BOOLEAN  Create,
IN PHANDLE  KeyHandle 
)

Definition at line 459 of file registry.c.

463{
464 UNICODE_STRING KeyPath, KeyName;
465 WCHAR KeyBuffer[MAX_PATH];
468
469 /* Check if we just want the handle */
470 if (RelativeTo & RTL_REGISTRY_HANDLE)
471 {
473 return STATUS_SUCCESS;
474 }
475
476 /* Check for optional flag */
477 if (RelativeTo & RTL_REGISTRY_OPTIONAL)
478 {
479 /* Mask it out */
480 RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
481 }
482
483 /* Fail on invalid parameter */
484 if (RelativeTo >= RTL_REGISTRY_MAXIMUM) return STATUS_INVALID_PARAMETER;
485
486 /* Initialize the key name */
487 RtlInitEmptyUnicodeString(&KeyName, KeyBuffer, sizeof(KeyBuffer));
488
489 /* Check if we have to lookup a path to prefix */
490 if (RelativeTo != RTL_REGISTRY_ABSOLUTE)
491 {
492 /* Check if we need the current user key */
493 if (RelativeTo == RTL_REGISTRY_USER)
494 {
495 /* Get the user key path */
497
498 /* Check if it worked */
499 if (NT_SUCCESS(Status))
500 {
501 /* Append the user key path */
503
504 /* Free the user key path */
505 RtlFreeUnicodeString (&KeyPath);
506 }
507 else
508 {
509 /* It didn't work so fall back to the default user key */
511 }
512 }
513 else
514 {
515 /* Get one of the prefixes */
517 RtlpRegPaths[RelativeTo]);
518 }
519
520 /* Check for failure, otherwise, append the path separator */
521 if (!NT_SUCCESS(Status)) return Status;
523 if (!NT_SUCCESS(Status)) return Status;
524 }
525
526 if (Path != NULL)
527 {
528 /* And now append the path */
529 if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE) Path++; // HACK!
531 if (!NT_SUCCESS(Status)) return Status;
532 }
533
534 /* Initialize the object attributes */
536 &KeyName,
538 NULL,
539 NULL);
540
541 /* Check if we want to create it */
542 if (Create)
543 {
544 /* Create the key with write privileges */
545 Status = ZwCreateKey(KeyHandle,
548 0,
549 NULL,
550 0,
551 NULL);
552 }
553 else
554 {
555 /* Otherwise, just open it with read access */
556 Status = ZwOpenKey(KeyHandle,
559 }
560
561 /* Return status */
562 return Status;
563}
@ Create
Definition: registry.c:563
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_REGISTRY_MAXIMUM
Definition: nt_native.h:167
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
#define GENERIC_WRITE
Definition: nt_native.h:90
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
PVOID HANDLE
Definition: typedefs.h:73
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705

Referenced by RtlCheckRegistryKey(), RtlCreateRegistryKey(), RtlDeleteRegistryValue(), RtlQueryRegistryValues(), and RtlWriteRegistryValue().

◆ RtlpNtCreateKey()

NTSTATUS NTAPI RtlpNtCreateKey ( OUT HANDLE  KeyHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN ULONG  TitleIndex,
IN PUNICODE_STRING  Class,
OUT PULONG  Disposition 
)

Definition at line 818 of file registry.c.

824{
825 /* Check if we have object attributes */
827 {
828 /* Mask out the unsupported flags */
829 ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
830 }
831
832 /* Create the key */
833 return ZwCreateKey(KeyHandle,
836 0,
837 NULL,
838 0,
840}
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
#define OBJ_PERMANENT
Definition: winternl.h:226
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56

◆ RtlpNtEnumerateSubKey()

NTSTATUS NTAPI RtlpNtEnumerateSubKey ( IN HANDLE  KeyHandle,
OUT PUNICODE_STRING  SubKeyName,
IN ULONG  Index,
IN ULONG  Unused 
)

Definition at line 847 of file registry.c.

851{
856
857 /* Check if we have a name */
858 if (SubKeyName->MaximumLength)
859 {
860 /* Allocate a buffer for it */
861 BufferLength = SubKeyName->MaximumLength +
862 sizeof(KEY_BASIC_INFORMATION);
863 KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
864 if (!KeyInfo) return STATUS_NO_MEMORY;
865 }
866
867 /* Enumerate the key */
868 Status = ZwEnumerateKey(KeyHandle,
869 Index,
871 KeyInfo,
874 if (NT_SUCCESS(Status) && (KeyInfo != NULL))
875 {
876 /* Check if the name fits */
877 if (KeyInfo->NameLength <= SubKeyName->MaximumLength)
878 {
879 /* Set the length */
880 SubKeyName->Length = (USHORT)KeyInfo->NameLength;
881
882 /* Copy it */
884 KeyInfo->Name,
885 SubKeyName->Length);
886 }
887 else
888 {
889 /* Otherwise, we ran out of buffer space */
891 }
892 }
893
894 /* Free the buffer and return status */
895 if (KeyInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
896 return Status;
897}
_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:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4725
@ KeyBasicInformation
Definition: nt_native.h:1134
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777

◆ RtlpNtMakeTemporaryKey()

NTSTATUS NTAPI RtlpNtMakeTemporaryKey ( IN HANDLE  KeyHandle)

Definition at line 904 of file registry.c.

905{
906 /* This just deletes the key */
907 return ZwDeleteKey(KeyHandle);
908}

◆ RtlpNtOpenKey()

NTSTATUS NTAPI RtlpNtOpenKey ( OUT HANDLE  KeyHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN ULONG  Unused 
)

Definition at line 915 of file registry.c.

919{
920 /* Check if we have object attributes */
922 {
923 /* Mask out the unsupported flags */
924 ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
925 }
926
927 /* Open the key */
928 return ZwOpenKey(KeyHandle, DesiredAccess, ObjectAttributes);
929}

◆ RtlpNtQueryValueKey()

NTSTATUS NTAPI RtlpNtQueryValueKey ( IN HANDLE  KeyHandle,
OUT PULONG Type  OPTIONAL,
OUT PVOID Data  OPTIONAL,
IN OUT PULONG DataLength  OPTIONAL,
IN ULONG  Unused 
)

Definition at line 936 of file registry.c.

941{
946
947 /* Clear the value name */
948 RtlInitEmptyUnicodeString(&ValueName, NULL, 0);
949
950 /* Check if we were already given a length */
952
953 /* Add the size of the structure */
955
956 /* Allocate memory for the value */
957 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
958 if (!ValueInfo) return STATUS_NO_MEMORY;
959
960 /* Query the value */
961 Status = ZwQueryValueKey(KeyHandle,
962 &ValueName,
964 ValueInfo,
966 &BufferLength);
968 {
969 /* Return the length and type */
970 if (DataLength) *DataLength = ValueInfo->DataLength;
971 if (Type) *Type = ValueInfo->Type;
972 }
973
974 /* Check if the caller wanted data back, and we got it */
975 if ((NT_SUCCESS(Status)) && (Data))
976 {
977 /* Copy it */
978 RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
979 }
980
981 /* Free the memory and return status */
982 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
983 return Status;
984}
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
@ KeyValuePartialInformation
Definition: nt_native.h:1185

Referenced by InitFunctionPtrs(), LsapGetObjectAttribute(), and RtlInitializeRXact().

◆ RtlpNtSetValueKey()

NTSTATUS NTAPI RtlpNtSetValueKey ( IN HANDLE  KeyHandle,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataLength 
)

Definition at line 991 of file registry.c.

995{
997
998 /* Set the value */
999 RtlInitEmptyUnicodeString(&ValueName, NULL, 0);
1000 return ZwSetValueKey(KeyHandle,
1001 &ValueName,
1002 0,
1003 Type,
1004 Data,
1005 DataLength);
1006}

◆ RtlpQueryRegistryDirect()

NTSTATUS NTAPI RtlpQueryRegistryDirect ( IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Buffer 
)

Definition at line 39 of file registry.c.

43{
44 USHORT ActualLength;
45 PUNICODE_STRING ReturnString = Buffer;
47 ULONG RealLength;
48
49 /* Check if this is a string */
50 if ((ValueType == REG_SZ) ||
53 {
54 /* Normalize the length */
56 ActualLength = MAXUSHORT;
57 else
58 ActualLength = (USHORT)ValueLength;
59
60 /* Check if the return string has been allocated */
61 if (!ReturnString->Buffer)
62 {
63 /* Allocate it */
64 ReturnString->Buffer = RtlpAllocateStringMemory(ActualLength, TAG_RTLREGISTRY);
65 if (!ReturnString->Buffer) return STATUS_NO_MEMORY;
66 ReturnString->MaximumLength = ActualLength;
67 }
68 else if (ActualLength > ReturnString->MaximumLength)
69 {
70 /* The string the caller allocated is too small */
72 }
73
74 /* Copy the data */
75 RtlCopyMemory(ReturnString->Buffer, ValueData, ActualLength);
76 ReturnString->Length = ActualLength - sizeof(UNICODE_NULL);
77 }
78 else if (ValueLength <= sizeof(ULONG))
79 {
80 /* Check if we can just copy the data */
81 if ((Buffer != ValueData) && (ValueLength))
82 {
83 /* Copy it */
85 }
86 }
87 else
88 {
89 /* Check if the length is negative */
90 if ((LONG)*Length < 0)
91 {
92 /* Get the real length and copy the buffer */
93 RealLength = -(LONG)*Length;
94 if (RealLength < ValueLength) return STATUS_BUFFER_TOO_SMALL;
96 }
97 else
98 {
99 if (ValueType != REG_BINARY)
100 {
101 /* Check if there's space for the length and type, plus data */
102 if (*Length < (2 * sizeof(ULONG) + ValueLength))
103 {
104 /* Nope, fail */
106 }
107
108 /* Return the data */
109 *Length++ = ValueLength;
110 *Length++ = ValueType;
112 }
113 else
114 {
115 /* Return the REG_BINARY data */
117 }
118 }
119 }
120
121 /* All done */
122 return STATUS_SUCCESS;
123}
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
#define REG_BINARY
Definition: nt_native.h:1499
long LONG
Definition: pedump.c:60
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275

Referenced by RtlpCallQueryRegistryRoutine().

◆ RtlQueryRegistryValues()

NTSTATUS NTAPI RtlQueryRegistryValues ( IN ULONG  RelativeTo,
IN PCWSTR  Path,
IN PRTL_QUERY_REGISTRY_TABLE  QueryTable,
IN PVOID  Context,
IN PVOID Environment  OPTIONAL 
)

Definition at line 1013 of file registry.c.

1018{
1020 PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL;
1021 HANDLE KeyHandle, CurrentKey;
1022 SIZE_T BufferSize, InfoSize;
1023 UNICODE_STRING KeyPath, KeyValueName;
1025 ULONG i, Value;
1027
1028 /* Get the registry handle */
1030 if (!NT_SUCCESS(Status)) return Status;
1031
1032 /* Initialize the path */
1033 RtlInitUnicodeString(&KeyPath,
1034 (RelativeTo & RTL_REGISTRY_HANDLE) ? NULL : Path);
1035
1036 /* Allocate a query buffer */
1038 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize, NULL, 0, &Status);
1039 if (!KeyValueInfo)
1040 {
1041 /* Close the handle if we have one and fail */
1043 return Status;
1044 }
1045
1046 /* Set defaults */
1047 KeyValueInfo->DataOffset = 0;
1048 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1049 CurrentKey = KeyHandle;
1050
1051 /* Loop the query table */
1052 while ((QueryTable->QueryRoutine) ||
1055 {
1056 /* Check if the request is invalid */
1058 (!(QueryTable->Name) ||
1061 {
1062 /* Fail */
1064 break;
1065 }
1066
1067 /* Check if we want a specific key */
1070 {
1071 /* Check if we're working with another handle */
1072 if (CurrentKey != KeyHandle)
1073 {
1074 /* Close our current key and use the top */
1075 NtClose(CurrentKey);
1076 CurrentKey = KeyHandle;
1077 }
1078 }
1079
1080 /* Check if we're querying the subkey */
1082 {
1083 /* Make sure we have a name */
1084 if (!QueryTable->Name)
1085 {
1086 /* Fail */
1088 }
1089 else
1090 {
1091 /* Initialize the name */
1093
1094 /* Get the key handle */
1096 &KeyPath,
1099 KeyHandle,
1100 NULL);
1101 Status = ZwOpenKey(&CurrentKey,
1104 if (NT_SUCCESS(Status))
1105 {
1106 /* If we have a query routine, go enumerate values */
1107 if (QueryTable->QueryRoutine) goto ProcessValues;
1108 }
1109 }
1110 }
1111 else if (QueryTable->Name)
1112 {
1113 /* Initialize the path */
1114 RtlInitUnicodeString(&KeyValueName, QueryTable->Name);
1115
1116 /* Start query loop */
1117 i = 0;
1118 while (TRUE)
1119 {
1120 /* Make sure we didn't retry too many times */
1121 if (i++ > 4)
1122 {
1123 /* Fail */
1124 DPRINT1("RtlQueryRegistryValues: Miscomputed buffer size "
1125 "at line %d\n", __LINE__);
1126 break;
1127 }
1128
1129 /* Query key information */
1130 Status = ZwQueryValueKey(CurrentKey,
1131 &KeyValueName,
1133 KeyValueInfo,
1134 (ULONG)InfoSize,
1135 &ResultLength);
1137 {
1138 /* Normalize status code */
1140 }
1141
1142 /* Check for failure */
1143 if (!NT_SUCCESS(Status))
1144 {
1145 /* Check if we didn't find it */
1147 {
1148 /* Setup a default */
1149 KeyValueInfo->Type = REG_NONE;
1150 KeyValueInfo->DataLength = 0;
1151 ResultLength = (ULONG)InfoSize;
1152
1153 /* Call the query routine */
1155 KeyValueInfo,
1156 &ResultLength,
1157 Context,
1158 Environment);
1159 }
1160
1161 /* Check for buffer being too small */
1163 {
1164 /* Increase allocation size */
1166 sizeof(ULONG_PTR) +
1167 sizeof(UNICODE_NULL);
1168 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1169 KeyValueInfo,
1170 BufferSize,
1171 &Status);
1172 if (!KeyValueInfo) break;
1173
1174 /* Update the data */
1175 KeyValueInfo->DataOffset = 0;
1176 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1177 continue;
1178 }
1179 }
1180 else
1181 {
1182 /* Check if this is a multi-string */
1183 if (KeyValueInfo->Type == REG_MULTI_SZ)
1184 {
1185 /* Add a null-char */
1186 ((PWCHAR)KeyValueInfo)[ResultLength / sizeof(WCHAR)] = UNICODE_NULL;
1187 KeyValueInfo->DataLength += sizeof(UNICODE_NULL);
1188 }
1189
1190 /* Call the query routine */
1191 ResultLength = (ULONG)InfoSize;
1193 KeyValueInfo,
1194 &ResultLength,
1195 Context,
1196 Environment);
1197
1198 /* Check for buffer being too small */
1200 {
1201 /* Increase allocation size */
1203 sizeof(ULONG_PTR) +
1204 sizeof(UNICODE_NULL);
1205 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1206 KeyValueInfo,
1207 BufferSize,
1208 &Status);
1209 if (!KeyValueInfo) break;
1210
1211 /* Update the data */
1212 KeyValueInfo->DataOffset = 0;
1213 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1214 continue;
1215 }
1216
1217 /* Check if we need to delete the key */
1218 if ((NT_SUCCESS(Status)) &&
1220 {
1221 /* Delete it */
1222 ZwDeleteValueKey(CurrentKey, &KeyValueName);
1223 }
1224 }
1225
1226 /* We're done, break out */
1227 break;
1228 }
1229 }
1231 {
1232 /* Just call the query routine */
1234 REG_NONE,
1235 NULL,
1236 0,
1237 Context,
1239 }
1240 else
1241 {
1242ProcessValues:
1243 /* Loop every value */
1244 i = Value = 0;
1245 while (TRUE)
1246 {
1247 /* Enumerate the keys */
1248 Status = ZwEnumerateValueKey(CurrentKey,
1249 Value,
1251 KeyValueInfo,
1252 (ULONG)InfoSize,
1253 &ResultLength);
1255 {
1256 /* Normalize the status */
1258 }
1259
1260 /* Check if we found all the entries */
1262 {
1263 /* Check if this was the first entry and caller needs it */
1264 if (!(Value) &&
1266 {
1267 /* Fail */
1269 }
1270 else
1271 {
1272 /* Otherwise, it's ok */
1274 }
1275 break;
1276 }
1277
1278 /* Check if enumeration worked */
1279 if (NT_SUCCESS(Status))
1280 {
1281 /* Call the query routine */
1282 ResultLength = (ULONG)InfoSize;
1284 KeyValueInfo,
1285 &ResultLength,
1286 Context,
1287 Environment);
1288 }
1289
1290 /* Check if the query failed */
1292 {
1293 /* Increase allocation size */
1295 sizeof(ULONG_PTR) +
1296 sizeof(UNICODE_NULL);
1297 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1298 KeyValueInfo,
1299 BufferSize,
1300 &Status);
1301 if (!KeyValueInfo) break;
1302
1303 /* Update the data */
1304 KeyValueInfo->DataOffset = 0;
1305 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1306
1307 /* Try the value again unless it's been too many times */
1308 if (i++ <= 4) continue;
1309 break;
1310 }
1311
1312 /* Break out if we failed */
1313 if (!NT_SUCCESS(Status)) break;
1314
1315 /* Reset the number of retries and check if we need to delete */
1316 i = 0;
1318 {
1319 /* Build the name */
1320 RtlInitEmptyUnicodeString(&KeyValueName,
1321 KeyValueInfo->Name,
1322 (USHORT)KeyValueInfo->NameLength);
1323 KeyValueName.Length = KeyValueName.MaximumLength;
1324
1325 /* Delete the key */
1326 Status = ZwDeleteValueKey(CurrentKey, &KeyValueName);
1327 if (NT_SUCCESS(Status)) Value--;
1328 }
1329
1330 /* Go to the next value */
1331 Value++;
1332 }
1333 }
1334
1335 /* Check if we failed anywhere along the road */
1336 if (!NT_SUCCESS(Status)) break;
1337
1338 /* Continue */
1339 QueryTable++;
1340 }
1341
1342 /* Check if we need to close our handle */
1344 if ((CurrentKey) && (CurrentKey != KeyHandle)) ZwClose(CurrentKey);
1345
1346 /* Free our buffer and return status */
1347 RtlpAllocDeallocQueryBuffer(NULL, KeyValueInfo, BufferSize, NULL);
1348 return Status;
1349}
#define BufferSize
Definition: mmc.h:75
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
@ KeyValueFullInformation
Definition: nt_native.h:1184
#define RTL_QUERY_REGISTRY_TOPKEY
Definition: nt_native.h:129
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define RTL_QUERY_REGISTRY_DELETE
Definition: nt_native.h:153
#define RTL_QUERY_REGISTRY_NOVALUE
Definition: nt_native.h:135
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
NTSTATUS NTAPI RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PKEY_VALUE_FULL_INFORMATION KeyValueInfo, IN OUT PULONG InfoSize, IN PVOID Context, IN PVOID Environment)
Definition: registry.c:127
SIZE_T RtlpAllocDeallocQueryBufferSize
Definition: libsupp.c:19
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

◆ RtlWriteRegistryValue()

NTSTATUS NTAPI RtlWriteRegistryValue ( IN ULONG  RelativeTo,
IN PCWSTR  Path,
IN PCWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength 
)

Definition at line 664 of file registry.c.

670{
675
676 /* Call the helper */
677 Status = RtlpGetRegistryHandle(RelativeTo,
678 Path,
679 TRUE,
680 &KeyHandle);
681 if (!NT_SUCCESS(Status)) return Status;
682
683 /* Initialize the key name and set it */
685 Status = ZwSetValueKey(KeyHandle,
686 &Name,
687 0,
688 ValueType,
689 ValueData,
691
692 /* Close the handle and return status */
694 return Status;
695}

Variable Documentation

◆ RtlpAllocDeallocQueryBufferSize

SIZE_T RtlpAllocDeallocQueryBufferSize
extern

Definition at line 19 of file libsupp.c.

Referenced by RtlQueryRegistryValues().

◆ RtlpRegPaths

Initial value:
=
{
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services",
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control",
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion",
L"\\Registry\\Machine\\Hardware\\DeviceMap",
L"\\Registry\\User\\.Default",
}

Definition at line 25 of file registry.c.

Referenced by RtlOpenCurrentUser(), and RtlpGetRegistryHandle().