2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Rtl registry functions
5 * FILE: lib/rtl/registry.c
11 * - finish RtlQueryRegistryValues()
12 * - support RTL_QUERY_REGISTRY_DELETE
15 /* INCLUDES *****************************************************************/
22 #define TAG_RTLREGISTRY TAG('R', 't', 'l', 'R')
24 /* FUNCTIONS ***************************************************************/
27 RtlpGetRegistryHandle(ULONG RelativeTo
,
32 UNICODE_STRING KeyPath
;
33 UNICODE_STRING KeyName
;
34 WCHAR KeyBuffer
[MAX_PATH
];
35 OBJECT_ATTRIBUTES ObjectAttributes
;
38 DPRINT("RtlpGetRegistryHandle()\n");
40 if (RelativeTo
& RTL_REGISTRY_HANDLE
)
42 Status
= ZwDuplicateObject(NtCurrentProcess(),
48 DUPLICATE_SAME_ACCESS
);
50 if(!NT_SUCCESS(Status
))
52 DPRINT("ZwDuplicateObject() failed! Status: 0x%x\n", Status
);
59 if (RelativeTo
& RTL_REGISTRY_OPTIONAL
)
60 RelativeTo
&= ~RTL_REGISTRY_OPTIONAL
;
62 if (RelativeTo
>= RTL_REGISTRY_MAXIMUM
)
64 DPRINT("Invalid relative flag, parameter invalid!\n");
65 return(STATUS_INVALID_PARAMETER
);
69 KeyName
.MaximumLength
= sizeof(KeyBuffer
);
70 KeyName
.Buffer
= KeyBuffer
;
75 case RTL_REGISTRY_ABSOLUTE
:
76 /* nothing to prefix! */
79 case RTL_REGISTRY_SERVICES
:
80 RtlAppendUnicodeToString(&KeyName
,
81 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
84 case RTL_REGISTRY_CONTROL
:
85 RtlAppendUnicodeToString(&KeyName
,
86 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
89 case RTL_REGISTRY_WINDOWS_NT
:
90 RtlAppendUnicodeToString(&KeyName
,
91 L
"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");
94 case RTL_REGISTRY_DEVICEMAP
:
95 RtlAppendUnicodeToString(&KeyName
,
96 L
"\\Registry\\Machine\\Hardware\\DeviceMap\\");
99 case RTL_REGISTRY_USER
:
100 Status
= RtlFormatCurrentUserKeyPath (&KeyPath
);
101 if (!NT_SUCCESS(Status
))
103 RtlAppendUnicodeStringToString (&KeyName
,
105 RtlFreeUnicodeString (&KeyPath
);
106 RtlAppendUnicodeToString (&KeyName
,
111 if (Path
[0] == L
'\\' && RelativeTo
!= RTL_REGISTRY_ABSOLUTE
)
115 RtlAppendUnicodeToString(&KeyName
,
118 DPRINT("KeyName %wZ\n", &KeyName
);
120 InitializeObjectAttributes(&ObjectAttributes
,
122 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
128 Status
= ZwCreateKey(KeyHandle
,
138 Status
= ZwOpenKey(KeyHandle
,
144 if(!NT_SUCCESS(Status
))
146 DPRINT("%s failed! Status: 0x%x\n", (Create
? "ZwCreateKey" : "ZwOpenKey"), Status
);
158 RtlCheckRegistryKey(IN ULONG RelativeTo
,
166 Status
= RtlpGetRegistryHandle(RelativeTo
,
170 if (!NT_SUCCESS(Status
))
175 return(STATUS_SUCCESS
);
183 RtlCreateRegistryKey(IN ULONG RelativeTo
,
191 Status
= RtlpGetRegistryHandle(RelativeTo
,
195 if (!NT_SUCCESS(Status
))
200 return(STATUS_SUCCESS
);
208 RtlDeleteRegistryValue(IN ULONG RelativeTo
,
218 Status
= RtlpGetRegistryHandle(RelativeTo
,
222 if (!NT_SUCCESS(Status
))
225 RtlInitUnicodeString(&Name
,
228 Status
= ZwDeleteValueKey(KeyHandle
,
241 RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath
)
245 PSID_AND_ATTRIBUTES SidBuffer
;
247 UNICODE_STRING SidString
;
252 DPRINT ("RtlFormatCurrentUserKeyPath() called\n");
254 Status
= ZwOpenThreadToken (NtCurrentThread (),
258 if (!NT_SUCCESS (Status
))
260 if (Status
!= STATUS_NO_TOKEN
)
262 DPRINT1 ("ZwOpenThreadToken() failed (Status %lx)\n", Status
);
266 Status
= ZwOpenProcessToken (NtCurrentProcess (),
269 if (!NT_SUCCESS (Status
))
271 DPRINT1 ("ZwOpenProcessToken() failed (Status %lx)\n", Status
);
276 SidBuffer
= (PSID_AND_ATTRIBUTES
)Buffer
;
277 Status
= ZwQueryInformationToken (TokenHandle
,
282 ZwClose (TokenHandle
);
283 if (!NT_SUCCESS(Status
))
285 DPRINT1 ("ZwQueryInformationToken() failed (Status %lx)\n", Status
);
289 Status
= RtlConvertSidToUnicodeString (&SidString
,
292 if (!NT_SUCCESS(Status
))
294 DPRINT1 ("RtlConvertSidToUnicodeString() failed (Status %lx)\n", Status
);
298 DPRINT ("SidString: '%wZ'\n", &SidString
);
300 Length
= SidString
.Length
+ sizeof(L
"\\Registry\\User\\");
301 DPRINT ("Length: %lu\n", Length
);
304 KeyPath
->MaximumLength
= Length
;
305 KeyPath
->Buffer
= RtlpAllocateStringMemory(KeyPath
->MaximumLength
, TAG_USTR
);
306 if (KeyPath
->Buffer
== NULL
)
308 DPRINT1 ("RtlpAllocateMemory() failed\n");
309 RtlFreeUnicodeString (&SidString
);
310 return STATUS_NO_TOKEN
;
313 RtlAppendUnicodeToString (KeyPath
,
314 L
"\\Registry\\User\\");
315 RtlAppendUnicodeStringToString (KeyPath
,
317 RtlFreeUnicodeString (&SidString
);
319 return STATUS_SUCCESS
;
327 RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess
,
328 OUT PHANDLE KeyHandle
)
330 OBJECT_ATTRIBUTES ObjectAttributes
;
331 UNICODE_STRING KeyPath
;
336 Status
= RtlFormatCurrentUserKeyPath(&KeyPath
);
337 if (NT_SUCCESS(Status
))
339 InitializeObjectAttributes(&ObjectAttributes
,
341 OBJ_CASE_INSENSITIVE
,
344 Status
= ZwOpenKey(KeyHandle
,
347 RtlFreeUnicodeString(&KeyPath
);
348 if (NT_SUCCESS(Status
))
350 return STATUS_SUCCESS
;
354 RtlInitUnicodeString (&KeyPath
,
355 L
"\\Registry\\User\\.Default");
356 InitializeObjectAttributes(&ObjectAttributes
,
358 OBJ_CASE_INSENSITIVE
,
361 Status
= ZwOpenKey(KeyHandle
,
373 RtlQueryRegistryValues(IN ULONG RelativeTo
,
375 IN PRTL_QUERY_REGISTRY_TABLE QueryTable
,
377 IN PVOID Environment OPTIONAL
)
380 HANDLE BaseKeyHandle
;
381 HANDLE CurrentKeyHandle
;
382 PRTL_QUERY_REGISTRY_TABLE QueryEntry
;
383 OBJECT_ATTRIBUTES ObjectAttributes
;
384 UNICODE_STRING KeyName
;
385 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
386 PKEY_VALUE_FULL_INFORMATION FullValueInfo
;
395 UNICODE_STRING EnvValue
;
396 UNICODE_STRING EnvExpandedValue
;
400 DPRINT("RtlQueryRegistryValues() called\n");
402 Status
= RtlpGetRegistryHandle(RelativeTo
,
406 if (!NT_SUCCESS(Status
))
408 DPRINT("RtlpGetRegistryHandle() failed (Status %lx)\n", Status
);
412 CurrentKeyHandle
= BaseKeyHandle
;
413 QueryEntry
= QueryTable
;
414 while ((QueryEntry
->QueryRoutine
!= NULL
) ||
415 (QueryEntry
->Name
!= NULL
))
417 if (((QueryEntry
->Flags
& (RTL_QUERY_REGISTRY_SUBKEY
| RTL_QUERY_REGISTRY_TOPKEY
)) != 0) &&
418 (BaseKeyHandle
!= CurrentKeyHandle
))
420 ZwClose(CurrentKeyHandle
);
421 CurrentKeyHandle
= BaseKeyHandle
;
424 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_SUBKEY
)
426 DPRINT("Open new subkey: %S\n", QueryEntry
->Name
);
428 RtlInitUnicodeString(&KeyName
,
430 InitializeObjectAttributes(&ObjectAttributes
,
432 OBJ_CASE_INSENSITIVE
,
435 Status
= ZwOpenKey(&CurrentKeyHandle
,
438 if (!NT_SUCCESS(Status
))
441 else if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DIRECT
)
443 DPRINT("Query value directly: %S\n", QueryEntry
->Name
);
445 RtlInitUnicodeString(&KeyName
,
448 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + 4096;
449 ValueInfo
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
450 if (ValueInfo
== NULL
)
452 Status
= STATUS_NO_MEMORY
;
456 Status
= ZwQueryValueKey(CurrentKeyHandle
,
458 KeyValuePartialInformation
,
462 if (!NT_SUCCESS(Status
))
464 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
)
466 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
467 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
471 if (QueryEntry
->DefaultType
== REG_SZ
)
473 PUNICODE_STRING ValueString
;
474 PUNICODE_STRING SourceString
;
476 SourceString
= (PUNICODE_STRING
)QueryEntry
->DefaultData
;
477 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
478 if (ValueString
->Buffer
== NULL
)
480 ValueString
->Length
= SourceString
->Length
;
481 ValueString
->MaximumLength
= SourceString
->MaximumLength
;
482 ValueString
->Buffer
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
483 if (!ValueString
->Buffer
)
485 ValueString
->Buffer
[0] = 0;
486 memcpy(ValueString
->Buffer
,
487 SourceString
->Buffer
,
488 SourceString
->MaximumLength
);
492 ValueString
->Length
= min(SourceString
->Length
,
493 ValueString
->MaximumLength
- sizeof(WCHAR
));
494 memcpy(ValueString
->Buffer
,
495 SourceString
->Buffer
,
496 ValueString
->Length
);
497 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
502 memcpy(QueryEntry
->EntryContext
,
503 QueryEntry
->DefaultData
,
504 QueryEntry
->DefaultLength
);
506 Status
= STATUS_SUCCESS
;
510 if ((ValueInfo
->Type
== REG_SZ
) ||
511 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
512 (ValueInfo
->Type
== REG_EXPAND_SZ
&& (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
)))
514 PUNICODE_STRING ValueString
;
516 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
517 if (ValueString
->Buffer
== NULL
)
519 ValueString
->MaximumLength
= ValueInfo
->DataLength
;
520 ValueString
->Buffer
= RtlpAllocateMemory(ValueString
->MaximumLength
, TAG_RTLREGISTRY
);
521 if (ValueString
->Buffer
== NULL
)
523 Status
= STATUS_INSUFFICIENT_RESOURCES
;
526 ValueString
->Buffer
[0] = 0;
528 ValueString
->Length
= min(ValueInfo
->DataLength
,
529 ValueString
->MaximumLength
) - sizeof(WCHAR
);
530 memcpy(ValueString
->Buffer
,
532 ValueString
->Length
);
533 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
535 else if (ValueInfo
->Type
== REG_EXPAND_SZ
)
537 PUNICODE_STRING ValueString
;
539 DPRINT("Expand REG_EXPAND_SZ type\n");
541 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
543 ExpandBuffer
= RtlpAllocateMemory(ValueInfo
->DataLength
* 2, TAG_RTLREGISTRY
);
544 if (ExpandBuffer
== NULL
)
546 Status
= STATUS_NO_MEMORY
;
550 RtlInitUnicodeString(&EnvValue
,
551 (PWSTR
)ValueInfo
->Data
);
552 EnvExpandedValue
.Length
= 0;
553 EnvExpandedValue
.MaximumLength
= ValueInfo
->DataLength
* 2;
554 EnvExpandedValue
.Buffer
= ExpandBuffer
;
557 RtlExpandEnvironmentStrings_U(Environment
,
562 if (ValueString
->Buffer
== NULL
)
564 ValueString
->MaximumLength
= EnvExpandedValue
.Length
+ sizeof(WCHAR
);
565 ValueString
->Length
= EnvExpandedValue
.Length
;
566 ValueString
->Buffer
= RtlpAllocateMemory(ValueString
->MaximumLength
, TAG_RTLREGISTRY
);
567 if (ValueString
->Buffer
== NULL
)
569 Status
= STATUS_INSUFFICIENT_RESOURCES
;
575 ValueString
->Length
= min(EnvExpandedValue
.Length
,
576 ValueString
->MaximumLength
- sizeof(WCHAR
));
579 memcpy(ValueString
->Buffer
,
580 EnvExpandedValue
.Buffer
,
581 ValueString
->Length
);
582 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
584 RtlpFreeMemory(ExpandBuffer
, TAG_RTLREGISTRY
);
588 memcpy(QueryEntry
->EntryContext
,
590 ValueInfo
->DataLength
);
594 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DELETE
)
596 DPRINT1("FIXME: Delete value: %S\n", QueryEntry
->Name
);
600 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
604 DPRINT("Query value via query routine: %S\n", QueryEntry
->Name
);
605 if (QueryEntry
->Name
!= NULL
)
607 RtlInitUnicodeString(&KeyName
,
610 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + 4096;
611 ValueInfo
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
612 if (ValueInfo
== NULL
)
614 Status
= STATUS_NO_MEMORY
;
618 Status
= ZwQueryValueKey(CurrentKeyHandle
,
620 KeyValuePartialInformation
,
624 if (!NT_SUCCESS(Status
))
626 if (!(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
))
628 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
629 QueryEntry
->DefaultType
,
630 QueryEntry
->DefaultData
,
631 QueryEntry
->DefaultLength
,
633 QueryEntry
->EntryContext
);
636 else if ((ValueInfo
->Type
== REG_MULTI_SZ
) &&
637 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
639 DPRINT("Expand REG_MULTI_SZ type\n");
640 StringPtr
= (PWSTR
)ValueInfo
->Data
;
641 while (*StringPtr
!= 0)
643 StringLen
= (wcslen(StringPtr
) + 1) * sizeof(WCHAR
);
644 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
649 QueryEntry
->EntryContext
);
650 if(!NT_SUCCESS(Status
))
652 StringPtr
= (PWSTR
)((PUCHAR
)StringPtr
+ StringLen
);
655 else if ((ValueInfo
->Type
== REG_EXPAND_SZ
) &&
656 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
658 DPRINT("Expand REG_EXPAND_SZ type\n");
660 ExpandBuffer
= RtlpAllocateMemory(ValueInfo
->DataLength
* 2, TAG_RTLREGISTRY
);
661 if (ExpandBuffer
== NULL
)
663 Status
= STATUS_NO_MEMORY
;
667 RtlInitUnicodeString(&EnvValue
,
668 (PWSTR
)ValueInfo
->Data
);
669 EnvExpandedValue
.Length
= 0;
670 EnvExpandedValue
.MaximumLength
= ValueInfo
->DataLength
* 2 * sizeof(WCHAR
);
671 EnvExpandedValue
.Buffer
= ExpandBuffer
;
674 RtlExpandEnvironmentStrings_U(Environment
,
679 StringLen
= (wcslen(ExpandBuffer
) + 1) * sizeof(WCHAR
);
680 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
685 QueryEntry
->EntryContext
);
687 RtlpFreeMemory(ExpandBuffer
, TAG_RTLREGISTRY
);
691 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
694 ValueInfo
->DataLength
,
696 QueryEntry
->EntryContext
);
699 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DELETE
)
701 DPRINT1("FIXME: Delete value: %S\n", QueryEntry
->Name
);
705 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
706 if (!NT_SUCCESS(Status
))
709 else if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOVALUE
)
711 DPRINT("Simple callback\n");
712 Status
= QueryEntry
->QueryRoutine(NULL
,
717 QueryEntry
->EntryContext
);
718 if (!NT_SUCCESS(Status
))
723 DPRINT("Enumerate values\n");
725 BufferSize
= sizeof(KEY_VALUE_FULL_INFORMATION
) + 4096;
726 FullValueInfo
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
727 if (FullValueInfo
== NULL
)
729 Status
= STATUS_NO_MEMORY
;
732 ValueNameSize
= 256 * sizeof(WCHAR
);
733 ValueName
= RtlpAllocateMemory(ValueNameSize
, TAG_RTLREGISTRY
);
734 if (ValueName
== NULL
)
736 Status
= STATUS_NO_MEMORY
;
742 Status
= ZwEnumerateValueKey(CurrentKeyHandle
,
744 KeyValueFullInformation
,
748 if (!NT_SUCCESS(Status
))
750 if ((Status
== STATUS_NO_MORE_ENTRIES
) &&
752 (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
))
754 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
756 else if (Status
== STATUS_NO_MORE_ENTRIES
)
758 Status
= STATUS_SUCCESS
;
763 if (FullValueInfo
->NameLength
> ValueNameSize
- sizeof(WCHAR
))
765 /* Should not happen, because the name length is limited to 255 characters */
766 RtlpFreeMemory(ValueName
, TAG_RTLREGISTRY
);
767 ValueNameSize
= FullValueInfo
->NameLength
+ sizeof(WCHAR
);
768 ValueName
= RtlpAllocateMemory(ValueNameSize
, TAG_RTLREGISTRY
);
769 if (ValueName
== NULL
)
771 Status
= STATUS_NO_MEMORY
;
778 FullValueInfo
->NameLength
);
779 ValueName
[FullValueInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
781 DPRINT("FullValueInfo->Type: %lu\n", FullValueInfo
->Type
);
782 if ((FullValueInfo
->Type
== REG_MULTI_SZ
) &&
783 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
785 DPRINT("Expand REG_MULTI_SZ type\n");
786 StringPtr
= (PWSTR
)((ULONG_PTR
)FullValueInfo
+ FullValueInfo
->DataOffset
);
787 while (*StringPtr
!= 0)
789 StringLen
= (wcslen(StringPtr
) + 1) * sizeof(WCHAR
);
790 Status
= QueryEntry
->QueryRoutine(ValueName
,
795 QueryEntry
->EntryContext
);
796 if(!NT_SUCCESS(Status
))
798 StringPtr
= (PWSTR
)((PUCHAR
)StringPtr
+ StringLen
);
801 else if ((FullValueInfo
->Type
== REG_EXPAND_SZ
) &&
802 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
804 DPRINT("Expand REG_EXPAND_SZ type\n");
806 StringPtr
= (PWSTR
)((ULONG_PTR
)FullValueInfo
+ FullValueInfo
->DataOffset
);
807 ExpandBuffer
= RtlpAllocateMemory(FullValueInfo
->DataLength
* 2, TAG_RTLREGISTRY
);
808 if (ExpandBuffer
== NULL
)
810 Status
= STATUS_NO_MEMORY
;
814 RtlInitUnicodeString(&EnvValue
,
816 EnvExpandedValue
.Length
= 0;
817 EnvExpandedValue
.MaximumLength
= FullValueInfo
->DataLength
* 2;
818 EnvExpandedValue
.Buffer
= ExpandBuffer
;
821 RtlExpandEnvironmentStrings_U(Environment
,
826 StringLen
= (wcslen(ExpandBuffer
) + 1) * sizeof(WCHAR
);
827 Status
= QueryEntry
->QueryRoutine(ValueName
,
832 QueryEntry
->EntryContext
);
834 RtlpFreeMemory(ExpandBuffer
, TAG_RTLREGISTRY
);
838 Status
= QueryEntry
->QueryRoutine(ValueName
,
840 (PVOID
)((ULONG_PTR
)FullValueInfo
+ FullValueInfo
->DataOffset
),
841 FullValueInfo
->DataLength
,
843 QueryEntry
->EntryContext
);
846 if (!NT_SUCCESS(Status
))
849 /* FIXME: How will these be deleted? */
854 RtlpFreeMemory(FullValueInfo
, TAG_RTLREGISTRY
);
855 RtlpFreeMemory(ValueName
, TAG_RTLREGISTRY
);
856 if (!NT_SUCCESS(Status
))
864 if (CurrentKeyHandle
!= BaseKeyHandle
)
865 ZwClose(CurrentKeyHandle
);
867 ZwClose(BaseKeyHandle
);
877 RtlWriteRegistryValue(IN ULONG RelativeTo
,
882 IN ULONG ValueLength
)
890 Status
= RtlpGetRegistryHandle(RelativeTo
,
894 if (!NT_SUCCESS(Status
))
896 DPRINT("RtlpGetRegistryHandle() failed! Status: 0x%x\n", Status
);
900 RtlInitUnicodeString(&Name
,
903 Status
= ZwSetValueKey(KeyHandle
,
909 if (!NT_SUCCESS(Status
))
911 DPRINT1("ZwSetValueKey() failed! Status: 0x%x\n", Status
);
924 RtlpNtCreateKey(OUT HANDLE KeyHandle
,
925 IN ACCESS_MASK DesiredAccess
,
926 IN POBJECT_ATTRIBUTES ObjectAttributes
,
928 OUT PULONG Disposition
,
931 if (ObjectAttributes
!= NULL
)
932 ObjectAttributes
->Attributes
&= ~(OBJ_PERMANENT
| OBJ_EXCLUSIVE
);
934 return(ZwCreateKey(KeyHandle
,
948 RtlpNtEnumerateSubKey(IN HANDLE KeyHandle
,
949 OUT PUNICODE_STRING SubKeyName
,
953 PKEY_BASIC_INFORMATION KeyInfo
= NULL
;
954 ULONG BufferLength
= 0;
955 ULONG ReturnedLength
;
958 if (SubKeyName
->MaximumLength
!= 0)
960 BufferLength
= SubKeyName
->MaximumLength
+
961 sizeof(KEY_BASIC_INFORMATION
);
962 KeyInfo
= RtlpAllocateMemory(BufferLength
, TAG_RTLREGISTRY
);
964 return(STATUS_NO_MEMORY
);
967 Status
= ZwEnumerateKey(KeyHandle
,
973 if (NT_SUCCESS(Status
))
975 if (KeyInfo
->NameLength
+ sizeof(WCHAR
) <= SubKeyName
->MaximumLength
)
977 memmove(SubKeyName
->Buffer
,
979 KeyInfo
->NameLength
);
980 SubKeyName
->Buffer
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
981 SubKeyName
->Length
= KeyInfo
->NameLength
;
985 Status
= STATUS_BUFFER_OVERFLOW
;
991 RtlpFreeMemory(KeyInfo
, TAG_RTLREGISTRY
);
1002 RtlpNtMakeTemporaryKey(IN HANDLE KeyHandle
)
1004 return(ZwDeleteKey(KeyHandle
));
1012 RtlpNtOpenKey(OUT HANDLE KeyHandle
,
1013 IN ACCESS_MASK DesiredAccess
,
1014 IN POBJECT_ATTRIBUTES ObjectAttributes
,
1017 if (ObjectAttributes
!= NULL
)
1018 ObjectAttributes
->Attributes
&= ~(OBJ_PERMANENT
| OBJ_EXCLUSIVE
);
1020 return(ZwOpenKey(KeyHandle
,
1030 RtlpNtQueryValueKey(IN HANDLE KeyHandle
,
1031 OUT PULONG Type OPTIONAL
,
1032 OUT PVOID Data OPTIONAL
,
1033 IN OUT PULONG DataLength OPTIONAL
,
1036 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
1037 UNICODE_STRING ValueName
;
1039 ULONG ReturnedLength
;
1042 RtlInitUnicodeString(&ValueName
,
1045 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
1046 if (DataLength
!= NULL
)
1047 BufferLength
= *DataLength
;
1049 ValueInfo
= RtlpAllocateMemory(BufferLength
, TAG_RTLREGISTRY
);
1050 if (ValueInfo
== NULL
)
1051 return(STATUS_NO_MEMORY
);
1053 Status
= ZwQueryValueKey(KeyHandle
,
1055 KeyValuePartialInformation
,
1059 if (NT_SUCCESS(Status
))
1061 if (DataLength
!= NULL
)
1062 *DataLength
= ValueInfo
->DataLength
;
1065 *Type
= ValueInfo
->Type
;
1071 ValueInfo
->DataLength
);
1075 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
1085 RtlpNtSetValueKey(IN HANDLE KeyHandle
,
1088 IN ULONG DataLength
)
1090 UNICODE_STRING ValueName
;
1092 RtlInitUnicodeString(&ValueName
,
1094 return(ZwSetValueKey(KeyHandle
,