ReactOS 0.4.16-dev-91-g764881a
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 NULL
Definition: types.h:112
Status
Definition: gdiplustypes.h:25
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
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 583 of file registry.c.

585{
589
590 /* Call the helper */
591 Status = RtlpGetRegistryHandle(RelativeTo,
592 Path,
593 FALSE,
594 &KeyHandle);
595 if (!NT_SUCCESS(Status)) return Status;
596
597 /* Close the handle even for RTL_REGISTRY_HANDLE */
599 return STATUS_SUCCESS;
600}
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 607 of file registry.c.

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

Referenced by IntCreateNewRegistryPath().

◆ RtlDeleteRegistryValue()

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

Definition at line 631 of file registry.c.

634{
639
640 /* Call the helper */
641 Status = RtlpGetRegistryHandle(RelativeTo,
642 Path,
643 TRUE,
644 &KeyHandle);
645 if (!NT_SUCCESS(Status)) return Status;
646
647 /* Initialize the key name and delete it */
650
651 /* Close the handle and return status */
653 return Status;
654}
struct NameRec_ * Name
Definition: cdprocs.h:460
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 742 of file registry.c.

743{
745 UCHAR Buffer[256];
746 PSID_AND_ATTRIBUTES SidBuffer;
748 UNICODE_STRING SidString;
751
752 /* Open the thread token */
755 TRUE,
757 &TokenHandle);
758 if (!NT_SUCCESS(Status))
759 {
760 /* We failed, is it because we don't have a thread token? */
761 if (Status != STATUS_NO_TOKEN) return Status;
762
763 /* It is, so use the process token */
767 &TokenHandle);
768 if (!NT_SUCCESS(Status)) return Status;
769 }
770
771 /* Now query the token information */
772 SidBuffer = (PSID_AND_ATTRIBUTES)Buffer;
773 Status = ZwQueryInformationToken(TokenHandle,
774 TokenUser,
775 (PVOID)SidBuffer,
776 sizeof(Buffer),
777 &Length);
778
779 /* Close the handle and handle failure */
781 if (!NT_SUCCESS(Status)) return Status;
782
783 /* Convert the SID */
784 Status = RtlConvertSidToUnicodeString(&SidString, SidBuffer[0].Sid, TRUE);
785 if (!NT_SUCCESS(Status)) return Status;
786
787 /* Add the length of the prefix */
788 Length = SidString.Length + sizeof(L"\\REGISTRY\\USER\\");
789
790 /* Initialize a string */
791 RtlInitEmptyUnicodeString(KeyPath,
793 (USHORT)Length);
794 if (!KeyPath->Buffer)
795 {
796 /* Free the string and fail */
797 RtlFreeUnicodeString(&SidString);
798 return STATUS_NO_MEMORY;
799 }
800
801 /* Append the prefix and SID */
802 RtlAppendUnicodeToString(KeyPath, L"\\REGISTRY\\USER\\");
803 RtlAppendUnicodeStringToString(KeyPath, &SidString);
804
805 /* Free the temporary string and return success */
806 RtlFreeUnicodeString(&SidString);
807 return STATUS_SUCCESS;
808}
#define TAG_USTR
Definition: libsupp.c:997
#define RtlpAllocateStringMemory(Bytes, Tag)
Definition: libsupp.c:1000
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:726
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:1145
NTSYSAPI NTSTATUS NTAPI ZwOpenProcessTokenEx(_In_ HANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NtCurrentProcess()
Definition: nt_native.h:1657
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:360
#define L(x)
Definition: ntvdm.h:50
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:928
@ TokenUser
Definition: setypes.h:966
unsigned char UCHAR
Definition: xmlstorage.h:181
#define NtCurrentThread()

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

◆ RtlOpenCurrentUser()

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

Definition at line 699 of file registry.c.

701{
703 UNICODE_STRING KeyPath;
706
707 /* Get the user key */
709 if (NT_SUCCESS(Status))
710 {
711 /* Initialize the attributes and open it */
713 &KeyPath,
715 NULL,
716 NULL);
718
719 /* Free the path and return success if it worked */
720 RtlFreeUnicodeString(&KeyPath);
721 if (NT_SUCCESS(Status)) return STATUS_SUCCESS;
722 }
723
724 /* It didn't work, so use the default key */
727 &KeyPath,
729 NULL,
730 NULL);
732
733 /* Return status */
734 return Status;
735}
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:742
PCWSTR RtlpRegPaths[RTL_REGISTRY_MAXIMUM]
Definition: registry.c:25
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658

◆ 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:4220
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3016
#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:1501
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#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 564 of file registry.c.

567{
568 /* Did the caller pass a key handle? */
569 if (!(RelativeTo & RTL_REGISTRY_HANDLE))
570 {
571 /* We opened the key in RtlpGetRegistryHandle, so close it now */
573 }
574}
#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 /* And now append the path */
527 if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE) Path++; // HACK!
529 if (!NT_SUCCESS(Status)) return Status;
530
531 /* Initialize the object attributes */
533 &KeyName,
535 NULL,
536 NULL);
537
538 /* Check if we want to create it */
539 if (Create)
540 {
541 /* Create the key with write privileges */
542 Status = ZwCreateKey(KeyHandle,
545 0,
546 NULL,
547 0,
548 NULL);
549 }
550 else
551 {
552 /* Otherwise, just open it with read access */
553 Status = ZwOpenKey(KeyHandle,
556 }
557
558 /* Return status */
559 return Status;
560}
@ 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:2699

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 815 of file registry.c.

821{
822 /* Check if we have object attributes */
824 {
825 /* Mask out the unsupported flags */
826 ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
827 }
828
829 /* Create the key */
830 return ZwCreateKey(KeyHandle,
833 0,
834 NULL,
835 0,
837}
#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 844 of file registry.c.

848{
853
854 /* Check if we have a name */
855 if (SubKeyName->MaximumLength)
856 {
857 /* Allocate a buffer for it */
858 BufferLength = SubKeyName->MaximumLength +
859 sizeof(KEY_BASIC_INFORMATION);
860 KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
861 if (!KeyInfo) return STATUS_NO_MEMORY;
862 }
863
864 /* Enumerate the key */
865 Status = ZwEnumerateKey(KeyHandle,
866 Index,
868 KeyInfo,
871 if (NT_SUCCESS(Status) && (KeyInfo != NULL))
872 {
873 /* Check if the name fits */
874 if (KeyInfo->NameLength <= SubKeyName->MaximumLength)
875 {
876 /* Set the length */
877 SubKeyName->Length = (USHORT)KeyInfo->NameLength;
878
879 /* Copy it */
881 KeyInfo->Name,
882 SubKeyName->Length);
883 }
884 else
885 {
886 /* Otherwise, we ran out of buffer space */
888 }
889 }
890
891 /* Free the buffer and return status */
892 if (KeyInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
893 return Status;
894}
_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
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4725
@ KeyBasicInformation
Definition: nt_native.h:1131
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:3771

◆ RtlpNtMakeTemporaryKey()

NTSTATUS NTAPI RtlpNtMakeTemporaryKey ( IN HANDLE  KeyHandle)

Definition at line 901 of file registry.c.

902{
903 /* This just deletes the key */
904 return ZwDeleteKey(KeyHandle);
905}

◆ RtlpNtOpenKey()

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

Definition at line 912 of file registry.c.

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

Referenced by LsapIsDatabaseInstalled(), and LsapOpenServiceKey().

◆ 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 933 of file registry.c.

938{
943
944 /* Clear the value name */
945 RtlInitEmptyUnicodeString(&ValueName, NULL, 0);
946
947 /* Check if we were already given a length */
949
950 /* Add the size of the structure */
952
953 /* Allocate memory for the value */
954 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
955 if (!ValueInfo) return STATUS_NO_MEMORY;
956
957 /* Query the value */
958 Status = ZwQueryValueKey(KeyHandle,
959 &ValueName,
961 ValueInfo,
963 &BufferLength);
965 {
966 /* Return the length and type */
967 if (DataLength) *DataLength = ValueInfo->DataLength;
968 if (Type) *Type = ValueInfo->Type;
969 }
970
971 /* Check if the caller wanted data back, and we got it */
972 if ((NT_SUCCESS(Status)) && (Data))
973 {
974 /* Copy it */
975 RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
976 }
977
978 /* Free the memory and return status */
979 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
980 return Status;
981}
_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:1182

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 988 of file registry.c.

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

Referenced by LsapSetObjectAttribute().

◆ 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:1496
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 1010 of file registry.c.

1015{
1017 PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL;
1018 HANDLE KeyHandle, CurrentKey;
1019 SIZE_T BufferSize, InfoSize;
1020 UNICODE_STRING KeyPath, KeyValueName;
1022 ULONG i, Value;
1024
1025 /* Get the registry handle */
1027 if (!NT_SUCCESS(Status)) return Status;
1028
1029 /* Initialize the path */
1030 RtlInitUnicodeString(&KeyPath,
1031 (RelativeTo & RTL_REGISTRY_HANDLE) ? NULL : Path);
1032
1033 /* Allocate a query buffer */
1035 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize, NULL, 0, &Status);
1036 if (!KeyValueInfo)
1037 {
1038 /* Close the handle if we have one and fail */
1040 return Status;
1041 }
1042
1043 /* Set defaults */
1044 KeyValueInfo->DataOffset = 0;
1045 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1046 CurrentKey = KeyHandle;
1047
1048 /* Loop the query table */
1049 while ((QueryTable->QueryRoutine) ||
1052 {
1053 /* Check if the request is invalid */
1055 (!(QueryTable->Name) ||
1058 {
1059 /* Fail */
1061 break;
1062 }
1063
1064 /* Check if we want a specific key */
1067 {
1068 /* Check if we're working with another handle */
1069 if (CurrentKey != KeyHandle)
1070 {
1071 /* Close our current key and use the top */
1072 NtClose(CurrentKey);
1073 CurrentKey = KeyHandle;
1074 }
1075 }
1076
1077 /* Check if we're querying the subkey */
1079 {
1080 /* Make sure we have a name */
1081 if (!QueryTable->Name)
1082 {
1083 /* Fail */
1085 }
1086 else
1087 {
1088 /* Initialize the name */
1090
1091 /* Get the key handle */
1093 &KeyPath,
1096 KeyHandle,
1097 NULL);
1098 Status = ZwOpenKey(&CurrentKey,
1101 if (NT_SUCCESS(Status))
1102 {
1103 /* If we have a query routine, go enumerate values */
1104 if (QueryTable->QueryRoutine) goto ProcessValues;
1105 }
1106 }
1107 }
1108 else if (QueryTable->Name)
1109 {
1110 /* Initialize the path */
1111 RtlInitUnicodeString(&KeyValueName, QueryTable->Name);
1112
1113 /* Start query loop */
1114 i = 0;
1115 while (TRUE)
1116 {
1117 /* Make sure we didn't retry too many times */
1118 if (i++ > 4)
1119 {
1120 /* Fail */
1121 DPRINT1("RtlQueryRegistryValues: Miscomputed buffer size "
1122 "at line %d\n", __LINE__);
1123 break;
1124 }
1125
1126 /* Query key information */
1127 Status = ZwQueryValueKey(CurrentKey,
1128 &KeyValueName,
1130 KeyValueInfo,
1131 (ULONG)InfoSize,
1132 &ResultLength);
1134 {
1135 /* Normalize status code */
1137 }
1138
1139 /* Check for failure */
1140 if (!NT_SUCCESS(Status))
1141 {
1142 /* Check if we didn't find it */
1144 {
1145 /* Setup a default */
1146 KeyValueInfo->Type = REG_NONE;
1147 KeyValueInfo->DataLength = 0;
1148 ResultLength = (ULONG)InfoSize;
1149
1150 /* Call the query routine */
1152 KeyValueInfo,
1153 &ResultLength,
1154 Context,
1155 Environment);
1156 }
1157
1158 /* Check for buffer being too small */
1160 {
1161 /* Increase allocation size */
1163 sizeof(ULONG_PTR) +
1164 sizeof(UNICODE_NULL);
1165 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1166 KeyValueInfo,
1167 BufferSize,
1168 &Status);
1169 if (!KeyValueInfo) break;
1170
1171 /* Update the data */
1172 KeyValueInfo->DataOffset = 0;
1173 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1174 continue;
1175 }
1176 }
1177 else
1178 {
1179 /* Check if this is a multi-string */
1180 if (KeyValueInfo->Type == REG_MULTI_SZ)
1181 {
1182 /* Add a null-char */
1183 ((PWCHAR)KeyValueInfo)[ResultLength / sizeof(WCHAR)] = UNICODE_NULL;
1184 KeyValueInfo->DataLength += sizeof(UNICODE_NULL);
1185 }
1186
1187 /* Call the query routine */
1188 ResultLength = (ULONG)InfoSize;
1190 KeyValueInfo,
1191 &ResultLength,
1192 Context,
1193 Environment);
1194
1195 /* Check for buffer being too small */
1197 {
1198 /* Increase allocation size */
1200 sizeof(ULONG_PTR) +
1201 sizeof(UNICODE_NULL);
1202 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1203 KeyValueInfo,
1204 BufferSize,
1205 &Status);
1206 if (!KeyValueInfo) break;
1207
1208 /* Update the data */
1209 KeyValueInfo->DataOffset = 0;
1210 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1211 continue;
1212 }
1213
1214 /* Check if we need to delete the key */
1215 if ((NT_SUCCESS(Status)) &&
1217 {
1218 /* Delete it */
1219 ZwDeleteValueKey(CurrentKey, &KeyValueName);
1220 }
1221 }
1222
1223 /* We're done, break out */
1224 break;
1225 }
1226 }
1228 {
1229 /* Just call the query routine */
1231 REG_NONE,
1232 NULL,
1233 0,
1234 Context,
1236 }
1237 else
1238 {
1239ProcessValues:
1240 /* Loop every value */
1241 i = Value = 0;
1242 while (TRUE)
1243 {
1244 /* Enumerate the keys */
1245 Status = ZwEnumerateValueKey(CurrentKey,
1246 Value,
1248 KeyValueInfo,
1249 (ULONG)InfoSize,
1250 &ResultLength);
1252 {
1253 /* Normalize the status */
1255 }
1256
1257 /* Check if we found all the entries */
1259 {
1260 /* Check if this was the first entry and caller needs it */
1261 if (!(Value) &&
1263 {
1264 /* Fail */
1266 }
1267 else
1268 {
1269 /* Otherwise, it's ok */
1271 }
1272 break;
1273 }
1274
1275 /* Check if enumeration worked */
1276 if (NT_SUCCESS(Status))
1277 {
1278 /* Call the query routine */
1279 ResultLength = (ULONG)InfoSize;
1281 KeyValueInfo,
1282 &ResultLength,
1283 Context,
1284 Environment);
1285 }
1286
1287 /* Check if the query failed */
1289 {
1290 /* Increase allocation size */
1292 sizeof(ULONG_PTR) +
1293 sizeof(UNICODE_NULL);
1294 KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1295 KeyValueInfo,
1296 BufferSize,
1297 &Status);
1298 if (!KeyValueInfo) break;
1299
1300 /* Update the data */
1301 KeyValueInfo->DataOffset = 0;
1302 InfoSize = BufferSize - sizeof(UNICODE_NULL);
1303
1304 /* Try the value again unless it's been too many times */
1305 if (i++ <= 4) continue;
1306 break;
1307 }
1308
1309 /* Break out if we failed */
1310 if (!NT_SUCCESS(Status)) break;
1311
1312 /* Reset the number of retries and check if we need to delete */
1313 i = 0;
1315 {
1316 /* Build the name */
1317 RtlInitEmptyUnicodeString(&KeyValueName,
1318 KeyValueInfo->Name,
1319 (USHORT)KeyValueInfo->NameLength);
1320 KeyValueName.Length = KeyValueName.MaximumLength;
1321
1322 /* Delete the key */
1323 Status = ZwDeleteValueKey(CurrentKey, &KeyValueName);
1324 if (NT_SUCCESS(Status)) Value--;
1325 }
1326
1327 /* Go to the next value */
1328 Value++;
1329 }
1330 }
1331
1332 /* Check if we failed anywhere along the road */
1333 if (!NT_SUCCESS(Status)) break;
1334
1335 /* Continue */
1336 QueryTable++;
1337 }
1338
1339 /* Check if we need to close our handle */
1341 if ((CurrentKey) && (CurrentKey != KeyHandle)) ZwClose(CurrentKey);
1342
1343 /* Free our buffer and return status */
1344 RtlpAllocDeallocQueryBuffer(NULL, KeyValueInfo, BufferSize, NULL);
1345 return Status;
1346}
#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:1181
#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:205
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:3776
_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 661 of file registry.c.

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

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().