3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Rtl registry functions
6 * FILE: lib/rtl/registry.c
14 * - finish RtlQueryRegistryValues()
15 * - support RTL_QUERY_REGISTRY_DELETE
18 /* INCLUDES ****************************************************************/
26 #define TAG_RTLREGISTRY TAG('R', 't', 'l', 'R')
29 /* FUNCTIONS ***************************************************************/
32 RtlpGetRegistryHandle(ULONG RelativeTo
,
37 UNICODE_STRING KeyPath
;
38 UNICODE_STRING KeyName
;
39 WCHAR KeyBuffer
[MAX_PATH
];
40 OBJECT_ATTRIBUTES ObjectAttributes
;
43 DPRINT("RtlpGetRegistryHandle()\n");
45 if (RelativeTo
& RTL_REGISTRY_HANDLE
)
47 Status
= ZwDuplicateObject(NtCurrentProcess(),
53 DUPLICATE_SAME_ACCESS
);
55 if(!NT_SUCCESS(Status
))
57 DPRINT("ZwDuplicateObject() failed! Status: 0x%x\n", Status
);
64 if (RelativeTo
& RTL_REGISTRY_OPTIONAL
)
65 RelativeTo
&= ~RTL_REGISTRY_OPTIONAL
;
67 if (RelativeTo
>= RTL_REGISTRY_MAXIMUM
)
69 DPRINT("Invalid relative flag, parameter invalid!\n");
70 return(STATUS_INVALID_PARAMETER
);
74 KeyName
.MaximumLength
= sizeof(KeyBuffer
);
75 KeyName
.Buffer
= KeyBuffer
;
80 case RTL_REGISTRY_ABSOLUTE
:
81 /* nothing to prefix! */
84 case RTL_REGISTRY_SERVICES
:
85 RtlAppendUnicodeToString(&KeyName
,
86 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
89 case RTL_REGISTRY_CONTROL
:
90 RtlAppendUnicodeToString(&KeyName
,
91 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
94 case RTL_REGISTRY_WINDOWS_NT
:
95 RtlAppendUnicodeToString(&KeyName
,
96 L
"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");
99 case RTL_REGISTRY_DEVICEMAP
:
100 RtlAppendUnicodeToString(&KeyName
,
101 L
"\\Registry\\Machine\\Hardware\\DeviceMap\\");
104 case RTL_REGISTRY_USER
:
105 Status
= RtlFormatCurrentUserKeyPath (&KeyPath
);
106 if (!NT_SUCCESS(Status
))
108 RtlAppendUnicodeStringToString (&KeyName
,
110 RtlFreeUnicodeString (&KeyPath
);
111 RtlAppendUnicodeToString (&KeyName
,
116 if (Path
[0] == L
'\\' && RelativeTo
!= RTL_REGISTRY_ABSOLUTE
)
120 RtlAppendUnicodeToString(&KeyName
,
123 DPRINT("KeyName %wZ\n", &KeyName
);
125 InitializeObjectAttributes(&ObjectAttributes
,
127 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
133 Status
= ZwCreateKey(KeyHandle
,
143 Status
= ZwOpenKey(KeyHandle
,
149 if(!NT_SUCCESS(Status
))
151 DPRINT("%s failed! Status: 0x%x\n", (Create
? "ZwCreateKey" : "ZwOpenKey"), Status
);
163 RtlCheckRegistryKey(IN ULONG RelativeTo
,
171 Status
= RtlpGetRegistryHandle(RelativeTo
,
175 if (!NT_SUCCESS(Status
))
180 return(STATUS_SUCCESS
);
188 RtlCreateRegistryKey(IN ULONG RelativeTo
,
196 Status
= RtlpGetRegistryHandle(RelativeTo
,
200 if (!NT_SUCCESS(Status
))
205 return(STATUS_SUCCESS
);
213 RtlDeleteRegistryValue(IN ULONG RelativeTo
,
223 Status
= RtlpGetRegistryHandle(RelativeTo
,
227 if (!NT_SUCCESS(Status
))
230 RtlInitUnicodeString(&Name
,
233 Status
= ZwDeleteValueKey(KeyHandle
,
246 RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath
)
250 PSID_AND_ATTRIBUTES SidBuffer
;
252 UNICODE_STRING SidString
;
257 DPRINT ("RtlFormatCurrentUserKeyPath() called\n");
259 Status
= ZwOpenThreadToken (NtCurrentThread (),
263 if (!NT_SUCCESS (Status
))
265 if (Status
!= STATUS_NO_TOKEN
)
267 DPRINT1 ("ZwOpenThreadToken() failed (Status %lx)\n", Status
);
271 Status
= ZwOpenProcessToken (NtCurrentProcess (),
274 if (!NT_SUCCESS (Status
))
276 DPRINT1 ("ZwOpenProcessToken() failed (Status %lx)\n", Status
);
281 SidBuffer
= (PSID_AND_ATTRIBUTES
)Buffer
;
282 Status
= ZwQueryInformationToken (TokenHandle
,
287 ZwClose (TokenHandle
);
288 if (!NT_SUCCESS(Status
))
290 DPRINT1 ("ZwQueryInformationToken() failed (Status %lx)\n", Status
);
294 Status
= RtlConvertSidToUnicodeString (&SidString
,
297 if (!NT_SUCCESS(Status
))
299 DPRINT1 ("RtlConvertSidToUnicodeString() failed (Status %lx)\n", Status
);
303 DPRINT ("SidString: '%wZ'\n", &SidString
);
305 Length
= SidString
.Length
+ sizeof(L
"\\Registry\\User\\");
306 DPRINT ("Length: %lu\n", Length
);
309 KeyPath
->MaximumLength
= Length
;
310 KeyPath
->Buffer
= RtlpAllocateStringMemory(KeyPath
->MaximumLength
, TAG_USTR
);
311 if (KeyPath
->Buffer
== NULL
)
313 DPRINT1 ("RtlpAllocateMemory() failed\n");
314 RtlFreeUnicodeString (&SidString
);
315 return STATUS_NO_TOKEN
;
318 RtlAppendUnicodeToString (KeyPath
,
319 L
"\\Registry\\User\\");
320 RtlAppendUnicodeStringToString (KeyPath
,
322 RtlFreeUnicodeString (&SidString
);
324 return STATUS_SUCCESS
;
332 RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess
,
333 OUT PHANDLE KeyHandle
)
335 OBJECT_ATTRIBUTES ObjectAttributes
;
336 UNICODE_STRING KeyPath
;
341 Status
= RtlFormatCurrentUserKeyPath(&KeyPath
);
342 if (NT_SUCCESS(Status
))
344 InitializeObjectAttributes(&ObjectAttributes
,
346 OBJ_CASE_INSENSITIVE
,
349 Status
= ZwOpenKey(KeyHandle
,
352 RtlFreeUnicodeString(&KeyPath
);
353 if (NT_SUCCESS(Status
))
355 return STATUS_SUCCESS
;
359 RtlInitUnicodeString (&KeyPath
,
360 L
"\\Registry\\User\\.Default");
361 InitializeObjectAttributes(&ObjectAttributes
,
363 OBJ_CASE_INSENSITIVE
,
366 Status
= ZwOpenKey(KeyHandle
,
378 RtlQueryRegistryValues(IN ULONG RelativeTo
,
380 IN PRTL_QUERY_REGISTRY_TABLE QueryTable
,
382 IN PVOID Environment OPTIONAL
)
385 HANDLE BaseKeyHandle
;
386 HANDLE CurrentKeyHandle
;
387 PRTL_QUERY_REGISTRY_TABLE QueryEntry
;
388 OBJECT_ATTRIBUTES ObjectAttributes
;
389 UNICODE_STRING KeyName
;
390 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
391 PKEY_VALUE_FULL_INFORMATION FullValueInfo
;
400 UNICODE_STRING EnvValue
;
401 UNICODE_STRING EnvExpandedValue
;
405 DPRINT("RtlQueryRegistryValues() called\n");
407 Status
= RtlpGetRegistryHandle(RelativeTo
,
411 if (!NT_SUCCESS(Status
))
413 DPRINT("RtlpGetRegistryHandle() failed (Status %lx)\n", Status
);
417 CurrentKeyHandle
= BaseKeyHandle
;
418 QueryEntry
= QueryTable
;
419 while ((QueryEntry
->QueryRoutine
!= NULL
) ||
420 (QueryEntry
->Name
!= NULL
))
422 if (((QueryEntry
->Flags
& (RTL_QUERY_REGISTRY_SUBKEY
| RTL_QUERY_REGISTRY_TOPKEY
)) != 0) &&
423 (BaseKeyHandle
!= CurrentKeyHandle
))
425 ZwClose(CurrentKeyHandle
);
426 CurrentKeyHandle
= BaseKeyHandle
;
429 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_SUBKEY
)
431 DPRINT("Open new subkey: %S\n", QueryEntry
->Name
);
433 RtlInitUnicodeString(&KeyName
,
435 InitializeObjectAttributes(&ObjectAttributes
,
437 OBJ_CASE_INSENSITIVE
,
440 Status
= ZwOpenKey(&CurrentKeyHandle
,
443 if (!NT_SUCCESS(Status
))
446 else if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DIRECT
)
448 DPRINT("Query value directly: %S\n", QueryEntry
->Name
);
450 RtlInitUnicodeString(&KeyName
,
453 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + 4096;
454 ValueInfo
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
455 if (ValueInfo
== NULL
)
457 Status
= STATUS_NO_MEMORY
;
461 Status
= ZwQueryValueKey(CurrentKeyHandle
,
463 KeyValuePartialInformation
,
467 if (!NT_SUCCESS(Status
))
469 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
)
471 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
472 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
476 if (QueryEntry
->DefaultType
== REG_SZ
)
478 PUNICODE_STRING ValueString
;
479 PUNICODE_STRING SourceString
;
481 SourceString
= (PUNICODE_STRING
)QueryEntry
->DefaultData
;
482 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
483 if (ValueString
->Buffer
== NULL
)
485 ValueString
->Length
= SourceString
->Length
;
486 ValueString
->MaximumLength
= SourceString
->MaximumLength
;
487 ValueString
->Buffer
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
488 if (!ValueString
->Buffer
)
490 ValueString
->Buffer
[0] = 0;
491 memcpy(ValueString
->Buffer
,
492 SourceString
->Buffer
,
493 SourceString
->MaximumLength
);
497 ValueString
->Length
= min(SourceString
->Length
,
498 ValueString
->MaximumLength
- sizeof(WCHAR
));
499 memcpy(ValueString
->Buffer
,
500 SourceString
->Buffer
,
501 ValueString
->Length
);
502 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
507 memcpy(QueryEntry
->EntryContext
,
508 QueryEntry
->DefaultData
,
509 QueryEntry
->DefaultLength
);
511 Status
= STATUS_SUCCESS
;
515 if ((ValueInfo
->Type
== REG_SZ
) ||
516 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
517 (ValueInfo
->Type
== REG_EXPAND_SZ
&& (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
)))
519 PUNICODE_STRING ValueString
;
521 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
522 if (ValueString
->Buffer
== NULL
)
524 ValueString
->MaximumLength
= ValueInfo
->DataLength
;
525 ValueString
->Buffer
= RtlpAllocateMemory(ValueString
->MaximumLength
, TAG_RTLREGISTRY
);
526 if (ValueString
->Buffer
== NULL
)
528 Status
= STATUS_INSUFFICIENT_RESOURCES
;
531 ValueString
->Buffer
[0] = 0;
533 ValueString
->Length
= min(ValueInfo
->DataLength
,
534 ValueString
->MaximumLength
) - sizeof(WCHAR
);
535 memcpy(ValueString
->Buffer
,
537 ValueString
->Length
);
538 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
540 else if (ValueInfo
->Type
== REG_EXPAND_SZ
)
542 PUNICODE_STRING ValueString
;
544 DPRINT("Expand REG_EXPAND_SZ type\n");
546 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
548 ExpandBuffer
= RtlpAllocateMemory(ValueInfo
->DataLength
* 2, TAG_RTLREGISTRY
);
549 if (ExpandBuffer
== NULL
)
551 Status
= STATUS_NO_MEMORY
;
555 RtlInitUnicodeString(&EnvValue
,
556 (PWSTR
)ValueInfo
->Data
);
557 EnvExpandedValue
.Length
= 0;
558 EnvExpandedValue
.MaximumLength
= ValueInfo
->DataLength
* 2;
559 EnvExpandedValue
.Buffer
= ExpandBuffer
;
562 RtlExpandEnvironmentStrings_U(Environment
,
567 if (ValueString
->Buffer
== NULL
)
569 ValueString
->MaximumLength
= EnvExpandedValue
.Length
+ sizeof(WCHAR
);
570 ValueString
->Length
= EnvExpandedValue
.Length
;
571 ValueString
->Buffer
= RtlpAllocateMemory(ValueString
->MaximumLength
, TAG_RTLREGISTRY
);
572 if (ValueString
->Buffer
== NULL
)
574 Status
= STATUS_INSUFFICIENT_RESOURCES
;
580 ValueString
->Length
= min(EnvExpandedValue
.Length
,
581 ValueString
->MaximumLength
- sizeof(WCHAR
));
584 memcpy(ValueString
->Buffer
,
585 EnvExpandedValue
.Buffer
,
586 ValueString
->Length
);
587 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
589 RtlpFreeMemory(ExpandBuffer
, TAG_RTLREGISTRY
);
593 memcpy(QueryEntry
->EntryContext
,
595 ValueInfo
->DataLength
);
599 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DELETE
)
601 DPRINT1("FIXME: Delete value: %S\n", QueryEntry
->Name
);
605 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
609 DPRINT("Query value via query routine: %S\n", QueryEntry
->Name
);
610 if (QueryEntry
->Name
!= NULL
)
612 RtlInitUnicodeString(&KeyName
,
615 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + 4096;
616 ValueInfo
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
617 if (ValueInfo
== NULL
)
619 Status
= STATUS_NO_MEMORY
;
623 Status
= ZwQueryValueKey(CurrentKeyHandle
,
625 KeyValuePartialInformation
,
629 if (!NT_SUCCESS(Status
))
631 if (!(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
))
633 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
634 QueryEntry
->DefaultType
,
635 QueryEntry
->DefaultData
,
636 QueryEntry
->DefaultLength
,
638 QueryEntry
->EntryContext
);
641 else if ((ValueInfo
->Type
== REG_MULTI_SZ
) &&
642 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
644 DPRINT("Expand REG_MULTI_SZ type\n");
645 StringPtr
= (PWSTR
)ValueInfo
->Data
;
646 while (*StringPtr
!= 0)
648 StringLen
= (wcslen(StringPtr
) + 1) * sizeof(WCHAR
);
649 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
654 QueryEntry
->EntryContext
);
655 if(!NT_SUCCESS(Status
))
657 StringPtr
= (PWSTR
)((PUCHAR
)StringPtr
+ StringLen
);
660 else if ((ValueInfo
->Type
== REG_EXPAND_SZ
) &&
661 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
663 DPRINT("Expand REG_EXPAND_SZ type\n");
665 ExpandBuffer
= RtlpAllocateMemory(ValueInfo
->DataLength
* 2, TAG_RTLREGISTRY
);
666 if (ExpandBuffer
== NULL
)
668 Status
= STATUS_NO_MEMORY
;
672 RtlInitUnicodeString(&EnvValue
,
673 (PWSTR
)ValueInfo
->Data
);
674 EnvExpandedValue
.Length
= 0;
675 EnvExpandedValue
.MaximumLength
= ValueInfo
->DataLength
* 2 * sizeof(WCHAR
);
676 EnvExpandedValue
.Buffer
= ExpandBuffer
;
679 RtlExpandEnvironmentStrings_U(Environment
,
684 StringLen
= (wcslen(ExpandBuffer
) + 1) * sizeof(WCHAR
);
685 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
690 QueryEntry
->EntryContext
);
692 RtlpFreeMemory(ExpandBuffer
, TAG_RTLREGISTRY
);
696 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
699 ValueInfo
->DataLength
,
701 QueryEntry
->EntryContext
);
704 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DELETE
)
706 DPRINT1("FIXME: Delete value: %S\n", QueryEntry
->Name
);
710 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
711 if (!NT_SUCCESS(Status
))
714 else if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOVALUE
)
716 DPRINT("Simple callback\n");
717 Status
= QueryEntry
->QueryRoutine(NULL
,
722 QueryEntry
->EntryContext
);
723 if (!NT_SUCCESS(Status
))
728 DPRINT("Enumerate values\n");
730 BufferSize
= sizeof(KEY_VALUE_FULL_INFORMATION
) + 4096;
731 FullValueInfo
= RtlpAllocateMemory(BufferSize
, TAG_RTLREGISTRY
);
732 if (FullValueInfo
== NULL
)
734 Status
= STATUS_NO_MEMORY
;
737 ValueNameSize
= 256 * sizeof(WCHAR
);
738 ValueName
= RtlpAllocateMemory(ValueNameSize
, TAG_RTLREGISTRY
);
739 if (ValueName
== NULL
)
741 Status
= STATUS_NO_MEMORY
;
747 Status
= ZwEnumerateValueKey(CurrentKeyHandle
,
749 KeyValueFullInformation
,
753 if (!NT_SUCCESS(Status
))
755 if ((Status
== STATUS_NO_MORE_ENTRIES
) &&
757 (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
))
759 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
761 else if (Status
== STATUS_NO_MORE_ENTRIES
)
763 Status
= STATUS_SUCCESS
;
768 if (FullValueInfo
->NameLength
> ValueNameSize
- sizeof(WCHAR
))
770 /* Should not happen, because the name length is limited to 255 characters */
771 RtlpFreeMemory(ValueName
, TAG_RTLREGISTRY
);
772 ValueNameSize
= FullValueInfo
->NameLength
+ sizeof(WCHAR
);
773 ValueName
= RtlpAllocateMemory(ValueNameSize
, TAG_RTLREGISTRY
);
774 if (ValueName
== NULL
)
776 Status
= STATUS_NO_MEMORY
;
783 FullValueInfo
->NameLength
);
784 ValueName
[FullValueInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
786 DPRINT("FullValueInfo->Type: %lu\n", FullValueInfo
->Type
);
787 if ((FullValueInfo
->Type
== REG_MULTI_SZ
) &&
788 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
790 DPRINT("Expand REG_MULTI_SZ type\n");
791 StringPtr
= (PWSTR
)((ULONG_PTR
)FullValueInfo
+ FullValueInfo
->DataOffset
);
792 while (*StringPtr
!= 0)
794 StringLen
= (wcslen(StringPtr
) + 1) * sizeof(WCHAR
);
795 Status
= QueryEntry
->QueryRoutine(ValueName
,
800 QueryEntry
->EntryContext
);
801 if(!NT_SUCCESS(Status
))
803 StringPtr
= (PWSTR
)((PUCHAR
)StringPtr
+ StringLen
);
806 else if ((FullValueInfo
->Type
== REG_EXPAND_SZ
) &&
807 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
809 DPRINT("Expand REG_EXPAND_SZ type\n");
811 StringPtr
= (PWSTR
)((ULONG_PTR
)FullValueInfo
+ FullValueInfo
->DataOffset
);
812 ExpandBuffer
= RtlpAllocateMemory(FullValueInfo
->DataLength
* 2, TAG_RTLREGISTRY
);
813 if (ExpandBuffer
== NULL
)
815 Status
= STATUS_NO_MEMORY
;
819 RtlInitUnicodeString(&EnvValue
,
821 EnvExpandedValue
.Length
= 0;
822 EnvExpandedValue
.MaximumLength
= FullValueInfo
->DataLength
* 2;
823 EnvExpandedValue
.Buffer
= ExpandBuffer
;
826 RtlExpandEnvironmentStrings_U(Environment
,
831 StringLen
= (wcslen(ExpandBuffer
) + 1) * sizeof(WCHAR
);
832 Status
= QueryEntry
->QueryRoutine(ValueName
,
837 QueryEntry
->EntryContext
);
839 RtlpFreeMemory(ExpandBuffer
, TAG_RTLREGISTRY
);
843 Status
= QueryEntry
->QueryRoutine(ValueName
,
845 (PVOID
)((ULONG_PTR
)FullValueInfo
+ FullValueInfo
->DataOffset
),
846 FullValueInfo
->DataLength
,
848 QueryEntry
->EntryContext
);
851 if (!NT_SUCCESS(Status
))
854 /* FIXME: How will these be deleted? */
859 RtlpFreeMemory(FullValueInfo
, TAG_RTLREGISTRY
);
860 RtlpFreeMemory(ValueName
, TAG_RTLREGISTRY
);
861 if (!NT_SUCCESS(Status
))
869 if (CurrentKeyHandle
!= BaseKeyHandle
)
870 ZwClose(CurrentKeyHandle
);
872 ZwClose(BaseKeyHandle
);
882 RtlWriteRegistryValue(IN ULONG RelativeTo
,
887 IN ULONG ValueLength
)
895 Status
= RtlpGetRegistryHandle(RelativeTo
,
899 if (!NT_SUCCESS(Status
))
901 DPRINT("RtlpGetRegistryHandle() failed! Status: 0x%x\n", Status
);
905 RtlInitUnicodeString(&Name
,
908 Status
= ZwSetValueKey(KeyHandle
,
914 if (!NT_SUCCESS(Status
))
916 DPRINT1("ZwSetValueKey() failed! Status: 0x%x\n", Status
);
929 RtlpNtCreateKey(OUT HANDLE KeyHandle
,
930 IN ACCESS_MASK DesiredAccess
,
931 IN POBJECT_ATTRIBUTES ObjectAttributes
,
933 OUT PULONG Disposition
,
936 if (ObjectAttributes
!= NULL
)
937 ObjectAttributes
->Attributes
&= ~(OBJ_PERMANENT
| OBJ_EXCLUSIVE
);
939 return(ZwCreateKey(KeyHandle
,
953 RtlpNtEnumerateSubKey(IN HANDLE KeyHandle
,
954 OUT PUNICODE_STRING SubKeyName
,
958 PKEY_BASIC_INFORMATION KeyInfo
= NULL
;
959 ULONG BufferLength
= 0;
960 ULONG ReturnedLength
;
963 if (SubKeyName
->MaximumLength
!= 0)
965 BufferLength
= SubKeyName
->MaximumLength
+
966 sizeof(KEY_BASIC_INFORMATION
);
967 KeyInfo
= RtlpAllocateMemory(BufferLength
, TAG_RTLREGISTRY
);
969 return(STATUS_NO_MEMORY
);
972 Status
= ZwEnumerateKey(KeyHandle
,
978 if (NT_SUCCESS(Status
))
980 if (KeyInfo
->NameLength
+ sizeof(WCHAR
) <= SubKeyName
->MaximumLength
)
982 memmove(SubKeyName
->Buffer
,
984 KeyInfo
->NameLength
);
985 SubKeyName
->Buffer
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
986 SubKeyName
->Length
= KeyInfo
->NameLength
;
990 Status
= STATUS_BUFFER_OVERFLOW
;
996 RtlpFreeMemory(KeyInfo
, TAG_RTLREGISTRY
);
1007 RtlpNtMakeTemporaryKey(IN HANDLE KeyHandle
)
1009 return(ZwDeleteKey(KeyHandle
));
1017 RtlpNtOpenKey(OUT HANDLE KeyHandle
,
1018 IN ACCESS_MASK DesiredAccess
,
1019 IN POBJECT_ATTRIBUTES ObjectAttributes
,
1022 if (ObjectAttributes
!= NULL
)
1023 ObjectAttributes
->Attributes
&= ~(OBJ_PERMANENT
| OBJ_EXCLUSIVE
);
1025 return(ZwOpenKey(KeyHandle
,
1035 RtlpNtQueryValueKey(IN HANDLE KeyHandle
,
1036 OUT PULONG Type OPTIONAL
,
1037 OUT PVOID Data OPTIONAL
,
1038 IN OUT PULONG DataLength OPTIONAL
,
1041 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
1042 UNICODE_STRING ValueName
;
1044 ULONG ReturnedLength
;
1047 RtlInitUnicodeString(&ValueName
,
1050 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
1051 if (DataLength
!= NULL
)
1052 BufferLength
= *DataLength
;
1054 ValueInfo
= RtlpAllocateMemory(BufferLength
, TAG_RTLREGISTRY
);
1055 if (ValueInfo
== NULL
)
1056 return(STATUS_NO_MEMORY
);
1058 Status
= ZwQueryValueKey(KeyHandle
,
1060 KeyValuePartialInformation
,
1064 if (NT_SUCCESS(Status
))
1066 if (DataLength
!= NULL
)
1067 *DataLength
= ValueInfo
->DataLength
;
1070 *Type
= ValueInfo
->Type
;
1076 ValueInfo
->DataLength
);
1080 RtlpFreeMemory(ValueInfo
, TAG_RTLREGISTRY
);
1090 RtlpNtSetValueKey(IN HANDLE KeyHandle
,
1093 IN ULONG DataLength
)
1095 UNICODE_STRING ValueName
;
1097 RtlInitUnicodeString(&ValueName
,
1099 return(ZwSetValueKey(KeyHandle
,