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 ****************************************************************/
27 /* FUNCTIONS ***************************************************************/
30 RtlpGetRegistryHandle(ULONG RelativeTo
,
35 UNICODE_STRING KeyPath
;
36 UNICODE_STRING KeyName
;
37 WCHAR KeyBuffer
[MAX_PATH
];
38 OBJECT_ATTRIBUTES ObjectAttributes
;
41 DPRINT("RtlpGetRegistryHandle()\n");
43 if (RelativeTo
& RTL_REGISTRY_HANDLE
)
45 Status
= ZwDuplicateObject(NtCurrentProcess(),
51 DUPLICATE_SAME_ACCESS
);
53 if(!NT_SUCCESS(Status
))
55 DPRINT("ZwDuplicateObject() failed! Status: 0x%x\n", Status
);
62 if (RelativeTo
& RTL_REGISTRY_OPTIONAL
)
63 RelativeTo
&= ~RTL_REGISTRY_OPTIONAL
;
65 if (RelativeTo
>= RTL_REGISTRY_MAXIMUM
)
67 DPRINT("Invalid relative flag, parameter invalid!\n");
68 return(STATUS_INVALID_PARAMETER
);
72 KeyName
.MaximumLength
= sizeof(KeyBuffer
);
73 KeyName
.Buffer
= KeyBuffer
;
78 case RTL_REGISTRY_ABSOLUTE
:
79 /* nothing to prefix! */
82 case RTL_REGISTRY_SERVICES
:
83 RtlAppendUnicodeToString(&KeyName
,
84 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
87 case RTL_REGISTRY_CONTROL
:
88 RtlAppendUnicodeToString(&KeyName
,
89 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
92 case RTL_REGISTRY_WINDOWS_NT
:
93 RtlAppendUnicodeToString(&KeyName
,
94 L
"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");
97 case RTL_REGISTRY_DEVICEMAP
:
98 RtlAppendUnicodeToString(&KeyName
,
99 L
"\\Registry\\Machine\\Hardware\\DeviceMap\\");
102 case RTL_REGISTRY_USER
:
103 Status
= RtlFormatCurrentUserKeyPath (&KeyPath
);
104 if (!NT_SUCCESS(Status
))
106 RtlAppendUnicodeStringToString (&KeyName
,
108 RtlFreeUnicodeString (&KeyPath
);
109 RtlAppendUnicodeToString (&KeyName
,
114 if (Path
[0] == L
'\\' && RelativeTo
!= RTL_REGISTRY_ABSOLUTE
)
118 RtlAppendUnicodeToString(&KeyName
,
121 DPRINT("KeyName %wZ\n", &KeyName
);
123 InitializeObjectAttributes(&ObjectAttributes
,
125 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
131 Status
= ZwCreateKey(KeyHandle
,
141 Status
= ZwOpenKey(KeyHandle
,
147 if(!NT_SUCCESS(Status
))
149 DPRINT("%s failed! Status: 0x%x\n", (Create
? "ZwCreateKey" : "ZwOpenKey"), Status
);
161 RtlCheckRegistryKey(IN ULONG RelativeTo
,
169 Status
= RtlpGetRegistryHandle(RelativeTo
,
173 if (!NT_SUCCESS(Status
))
178 return(STATUS_SUCCESS
);
186 RtlCreateRegistryKey(IN ULONG RelativeTo
,
194 Status
= RtlpGetRegistryHandle(RelativeTo
,
198 if (!NT_SUCCESS(Status
))
203 return(STATUS_SUCCESS
);
211 RtlDeleteRegistryValue(IN ULONG RelativeTo
,
221 Status
= RtlpGetRegistryHandle(RelativeTo
,
225 if (!NT_SUCCESS(Status
))
228 RtlInitUnicodeString(&Name
,
231 Status
= ZwDeleteValueKey(KeyHandle
,
244 RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath
)
248 PSID_AND_ATTRIBUTES SidBuffer
;
250 UNICODE_STRING SidString
;
255 DPRINT ("RtlFormatCurrentUserKeyPath() called\n");
257 Status
= ZwOpenThreadToken (NtCurrentThread (),
261 if (!NT_SUCCESS (Status
))
263 if (Status
!= STATUS_NO_TOKEN
)
265 DPRINT1 ("ZwOpenThreadToken() failed (Status %lx)\n", Status
);
269 Status
= ZwOpenProcessToken (NtCurrentProcess (),
272 if (!NT_SUCCESS (Status
))
274 DPRINT1 ("ZwOpenProcessToken() failed (Status %lx)\n", Status
);
279 SidBuffer
= (PSID_AND_ATTRIBUTES
)Buffer
;
280 Status
= ZwQueryInformationToken (TokenHandle
,
285 ZwClose (TokenHandle
);
286 if (!NT_SUCCESS(Status
))
288 DPRINT1 ("ZwQueryInformationToken() failed (Status %lx)\n", Status
);
292 Status
= RtlConvertSidToUnicodeString (&SidString
,
295 if (!NT_SUCCESS(Status
))
297 DPRINT1 ("RtlConvertSidToUnicodeString() failed (Status %lx)\n", Status
);
301 DPRINT ("SidString: '%wZ'\n", &SidString
);
303 Length
= SidString
.Length
+ sizeof(L
"\\Registry\\User\\");
304 DPRINT ("Length: %lu\n", Length
);
307 KeyPath
->MaximumLength
= Length
;
308 KeyPath
->Buffer
= ExAllocatePool (PagedPool
,
309 KeyPath
->MaximumLength
);
310 if (KeyPath
->Buffer
== NULL
)
312 DPRINT1 ("ExAllocatePool() failed\n");
313 RtlFreeUnicodeString (&SidString
);
314 return STATUS_NO_TOKEN
;
317 RtlAppendUnicodeToString (KeyPath
,
318 L
"\\Registry\\User\\");
319 RtlAppendUnicodeStringToString (KeyPath
,
321 RtlFreeUnicodeString (&SidString
);
323 return STATUS_SUCCESS
;
331 RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess
,
332 OUT PHANDLE KeyHandle
)
334 OBJECT_ATTRIBUTES ObjectAttributes
;
335 UNICODE_STRING KeyPath
;
340 Status
= RtlFormatCurrentUserKeyPath(&KeyPath
);
341 if (NT_SUCCESS(Status
))
343 InitializeObjectAttributes(&ObjectAttributes
,
345 OBJ_CASE_INSENSITIVE
,
348 Status
= ZwOpenKey(KeyHandle
,
351 RtlFreeUnicodeString(&KeyPath
);
352 if (NT_SUCCESS(Status
))
354 return STATUS_SUCCESS
;
358 RtlInitUnicodeString (&KeyPath
,
359 L
"\\Registry\\User\\.Default");
360 InitializeObjectAttributes(&ObjectAttributes
,
362 OBJ_CASE_INSENSITIVE
,
365 Status
= ZwOpenKey(KeyHandle
,
377 RtlQueryRegistryValues(IN ULONG RelativeTo
,
379 IN PRTL_QUERY_REGISTRY_TABLE QueryTable
,
381 IN PVOID Environment OPTIONAL
)
384 HANDLE BaseKeyHandle
;
385 HANDLE CurrentKeyHandle
;
386 PRTL_QUERY_REGISTRY_TABLE QueryEntry
;
387 OBJECT_ATTRIBUTES ObjectAttributes
;
388 UNICODE_STRING KeyName
;
389 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
390 PKEY_VALUE_FULL_INFORMATION FullValueInfo
;
399 UNICODE_STRING EnvValue
;
400 UNICODE_STRING EnvExpandedValue
;
404 DPRINT("RtlQueryRegistryValues() called\n");
406 Status
= RtlpGetRegistryHandle(RelativeTo
,
410 if (!NT_SUCCESS(Status
))
412 DPRINT("RtlpGetRegistryHandle() failed (Status %lx)\n", Status
);
416 CurrentKeyHandle
= BaseKeyHandle
;
417 QueryEntry
= QueryTable
;
418 while ((QueryEntry
->QueryRoutine
!= NULL
) ||
419 (QueryEntry
->Name
!= NULL
))
421 if (((QueryEntry
->Flags
& (RTL_QUERY_REGISTRY_SUBKEY
| RTL_QUERY_REGISTRY_TOPKEY
)) != 0) &&
422 (BaseKeyHandle
!= CurrentKeyHandle
))
424 ZwClose(CurrentKeyHandle
);
425 CurrentKeyHandle
= BaseKeyHandle
;
428 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_SUBKEY
)
430 DPRINT("Open new subkey: %S\n", QueryEntry
->Name
);
432 RtlInitUnicodeString(&KeyName
,
434 InitializeObjectAttributes(&ObjectAttributes
,
436 OBJ_CASE_INSENSITIVE
,
439 Status
= ZwOpenKey(&CurrentKeyHandle
,
442 if (!NT_SUCCESS(Status
))
445 else if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DIRECT
)
447 DPRINT("Query value directly: %S\n", QueryEntry
->Name
);
449 RtlInitUnicodeString(&KeyName
,
452 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + 4096;
453 ValueInfo
= ExAllocatePool(PagedPool
, BufferSize
);
454 if (ValueInfo
== NULL
)
456 Status
= STATUS_NO_MEMORY
;
460 Status
= ZwQueryValueKey(CurrentKeyHandle
,
462 KeyValuePartialInformation
,
466 if (!NT_SUCCESS(Status
))
468 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
)
470 ExFreePool(ValueInfo
);
471 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
475 if (QueryEntry
->DefaultType
== REG_SZ
)
477 PUNICODE_STRING ValueString
;
478 PUNICODE_STRING SourceString
;
480 SourceString
= (PUNICODE_STRING
)QueryEntry
->DefaultData
;
481 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
482 if (ValueString
->Buffer
== NULL
)
484 ValueString
->Length
= SourceString
->Length
;
485 ValueString
->MaximumLength
= SourceString
->MaximumLength
;
486 ValueString
->Buffer
= ExAllocatePool(PagedPool
, BufferSize
);
487 if (!ValueString
->Buffer
)
489 ValueString
->Buffer
[0] = 0;
490 memcpy(ValueString
->Buffer
,
491 SourceString
->Buffer
,
492 SourceString
->MaximumLength
);
496 ValueString
->Length
= min(SourceString
->Length
,
497 ValueString
->MaximumLength
- sizeof(WCHAR
));
498 memcpy(ValueString
->Buffer
,
499 SourceString
->Buffer
,
500 ValueString
->Length
);
501 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
506 memcpy(QueryEntry
->EntryContext
,
507 QueryEntry
->DefaultData
,
508 QueryEntry
->DefaultLength
);
510 Status
= STATUS_SUCCESS
;
514 if ((ValueInfo
->Type
== REG_SZ
) ||
515 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
516 (ValueInfo
->Type
== REG_EXPAND_SZ
&& (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
)))
518 PUNICODE_STRING ValueString
;
520 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
521 if (ValueString
->Buffer
== NULL
)
523 ValueString
->MaximumLength
= ValueInfo
->DataLength
;
524 ValueString
->Buffer
= ExAllocatePool(PagedPool
, ValueString
->MaximumLength
);
525 if (ValueString
->Buffer
== NULL
)
527 Status
= STATUS_INSUFFICIENT_RESOURCES
;
530 ValueString
->Buffer
[0] = 0;
532 ValueString
->Length
= min(ValueInfo
->DataLength
,
533 ValueString
->MaximumLength
) - sizeof(WCHAR
);
534 memcpy(ValueString
->Buffer
,
536 ValueString
->Length
);
537 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
539 else if (ValueInfo
->Type
== REG_EXPAND_SZ
)
541 PUNICODE_STRING ValueString
;
543 DPRINT("Expand REG_EXPAND_SZ type\n");
545 ValueString
= (PUNICODE_STRING
)QueryEntry
->EntryContext
;
547 ExpandBuffer
= ExAllocatePool(PagedPool
, ValueInfo
->DataLength
* 2);
548 if (ExpandBuffer
== NULL
)
550 Status
= STATUS_NO_MEMORY
;
554 RtlInitUnicodeString(&EnvValue
,
555 (PWSTR
)ValueInfo
->Data
);
556 EnvExpandedValue
.Length
= 0;
557 EnvExpandedValue
.MaximumLength
= ValueInfo
->DataLength
* 2;
558 EnvExpandedValue
.Buffer
= ExpandBuffer
;
561 RtlExpandEnvironmentStrings_U(Environment
,
566 if (ValueString
->Buffer
== NULL
)
568 ValueString
->MaximumLength
= EnvExpandedValue
.Length
+ sizeof(WCHAR
);
569 ValueString
->Length
= EnvExpandedValue
.Length
;
570 ValueString
->Buffer
= ExAllocatePool(PagedPool
, ValueString
->MaximumLength
);
571 if (ValueString
->Buffer
== NULL
)
573 Status
= STATUS_INSUFFICIENT_RESOURCES
;
579 ValueString
->Length
= min(EnvExpandedValue
.Length
,
580 ValueString
->MaximumLength
- sizeof(WCHAR
));
583 memcpy(ValueString
->Buffer
,
584 EnvExpandedValue
.Buffer
,
585 ValueString
->Length
);
586 ((PWSTR
)ValueString
->Buffer
)[ValueString
->Length
/ sizeof(WCHAR
)] = 0;
588 ExFreePool(ExpandBuffer
);
592 memcpy(QueryEntry
->EntryContext
,
594 ValueInfo
->DataLength
);
598 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DELETE
)
600 DPRINT1("FIXME: Delete value: %S\n", QueryEntry
->Name
);
604 ExFreePool(ValueInfo
);
608 DPRINT("Query value via query routine: %S\n", QueryEntry
->Name
);
609 if (QueryEntry
->Name
!= NULL
)
611 RtlInitUnicodeString(&KeyName
,
614 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + 4096;
615 ValueInfo
= ExAllocatePool(PagedPool
, BufferSize
);
616 if (ValueInfo
== NULL
)
618 Status
= STATUS_NO_MEMORY
;
622 Status
= ZwQueryValueKey(CurrentKeyHandle
,
624 KeyValuePartialInformation
,
628 if (!NT_SUCCESS(Status
))
630 if (!(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
))
632 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
633 QueryEntry
->DefaultType
,
634 QueryEntry
->DefaultData
,
635 QueryEntry
->DefaultLength
,
637 QueryEntry
->EntryContext
);
640 else if ((ValueInfo
->Type
== REG_MULTI_SZ
) &&
641 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
643 DPRINT("Expand REG_MULTI_SZ type\n");
644 StringPtr
= (PWSTR
)ValueInfo
->Data
;
645 while (*StringPtr
!= 0)
647 StringLen
= (wcslen(StringPtr
) + 1) * sizeof(WCHAR
);
648 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
653 QueryEntry
->EntryContext
);
654 if(!NT_SUCCESS(Status
))
656 StringPtr
= (PWSTR
)((PUCHAR
)StringPtr
+ StringLen
);
659 else if ((ValueInfo
->Type
== REG_EXPAND_SZ
) &&
660 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
662 DPRINT("Expand REG_EXPAND_SZ type\n");
664 ExpandBuffer
= ExAllocatePool(PagedPool
, ValueInfo
->DataLength
* 2);
665 if (ExpandBuffer
== NULL
)
667 Status
= STATUS_NO_MEMORY
;
671 RtlInitUnicodeString(&EnvValue
,
672 (PWSTR
)ValueInfo
->Data
);
673 EnvExpandedValue
.Length
= 0;
674 EnvExpandedValue
.MaximumLength
= ValueInfo
->DataLength
* 2 * sizeof(WCHAR
);
675 EnvExpandedValue
.Buffer
= ExpandBuffer
;
678 RtlExpandEnvironmentStrings_U(Environment
,
683 StringLen
= (wcslen(ExpandBuffer
) + 1) * sizeof(WCHAR
);
684 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
689 QueryEntry
->EntryContext
);
691 ExFreePool(ExpandBuffer
);
695 Status
= QueryEntry
->QueryRoutine(QueryEntry
->Name
,
698 ValueInfo
->DataLength
,
700 QueryEntry
->EntryContext
);
703 if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_DELETE
)
705 DPRINT1("FIXME: Delete value: %S\n", QueryEntry
->Name
);
709 ExFreePool(ValueInfo
);
710 if (!NT_SUCCESS(Status
))
713 else if (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOVALUE
)
715 DPRINT("Simple callback\n");
716 Status
= QueryEntry
->QueryRoutine(NULL
,
721 QueryEntry
->EntryContext
);
722 if (!NT_SUCCESS(Status
))
727 DPRINT("Enumerate values\n");
729 BufferSize
= sizeof(KEY_VALUE_FULL_INFORMATION
) + 4096;
730 FullValueInfo
= ExAllocatePool(PagedPool
, BufferSize
);
731 if (FullValueInfo
== NULL
)
733 Status
= STATUS_NO_MEMORY
;
736 ValueNameSize
= 256 * sizeof(WCHAR
);
737 ValueName
= ExAllocatePool(PagedPool
, ValueNameSize
);
738 if (ValueName
== NULL
)
740 Status
= STATUS_NO_MEMORY
;
746 Status
= ZwEnumerateValueKey(CurrentKeyHandle
,
748 KeyValueFullInformation
,
752 if (!NT_SUCCESS(Status
))
754 if ((Status
== STATUS_NO_MORE_ENTRIES
) &&
756 (QueryEntry
->Flags
& RTL_QUERY_REGISTRY_REQUIRED
))
758 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
760 else if (Status
== STATUS_NO_MORE_ENTRIES
)
762 Status
= STATUS_SUCCESS
;
767 if (FullValueInfo
->NameLength
> ValueNameSize
- sizeof(WCHAR
))
769 /* Should not happen, because the name length is limited to 255 characters */
770 ExFreePool(ValueName
);
771 ValueNameSize
= FullValueInfo
->NameLength
+ sizeof(WCHAR
);
772 ValueName
= ExAllocatePool(PagedPool
, ValueNameSize
);
773 if (ValueName
== NULL
)
775 Status
= STATUS_NO_MEMORY
;
782 FullValueInfo
->NameLength
);
783 ValueName
[FullValueInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
785 DPRINT("FullValueInfo->Type: %lu\n", FullValueInfo
->Type
);
786 if ((FullValueInfo
->Type
== REG_MULTI_SZ
) &&
787 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
789 DPRINT("Expand REG_MULTI_SZ type\n");
790 StringPtr
= (PWSTR
)((PVOID
)FullValueInfo
+ FullValueInfo
->DataOffset
);
791 while (*StringPtr
!= 0)
793 StringLen
= (wcslen(StringPtr
) + 1) * sizeof(WCHAR
);
794 Status
= QueryEntry
->QueryRoutine(ValueName
,
799 QueryEntry
->EntryContext
);
800 if(!NT_SUCCESS(Status
))
802 StringPtr
= (PWSTR
)((PUCHAR
)StringPtr
+ StringLen
);
805 else if ((FullValueInfo
->Type
== REG_EXPAND_SZ
) &&
806 !(QueryEntry
->Flags
& RTL_QUERY_REGISTRY_NOEXPAND
))
808 DPRINT("Expand REG_EXPAND_SZ type\n");
810 StringPtr
= (PWSTR
)((PVOID
)FullValueInfo
+ FullValueInfo
->DataOffset
);
811 ExpandBuffer
= ExAllocatePool(PagedPool
, FullValueInfo
->DataLength
* 2);
812 if (ExpandBuffer
== NULL
)
814 Status
= STATUS_NO_MEMORY
;
818 RtlInitUnicodeString(&EnvValue
,
820 EnvExpandedValue
.Length
= 0;
821 EnvExpandedValue
.MaximumLength
= FullValueInfo
->DataLength
* 2;
822 EnvExpandedValue
.Buffer
= ExpandBuffer
;
825 RtlExpandEnvironmentStrings_U(Environment
,
830 StringLen
= (wcslen(ExpandBuffer
) + 1) * sizeof(WCHAR
);
831 Status
= QueryEntry
->QueryRoutine(ValueName
,
836 QueryEntry
->EntryContext
);
838 ExFreePool(ExpandBuffer
);
842 Status
= QueryEntry
->QueryRoutine(ValueName
,
844 (PVOID
)FullValueInfo
+ FullValueInfo
->DataOffset
,
845 FullValueInfo
->DataLength
,
847 QueryEntry
->EntryContext
);
850 if (!NT_SUCCESS(Status
))
853 /* FIXME: How will these be deleted? */
858 ExFreePool(FullValueInfo
);
859 ExFreePool(ValueName
);
860 if (!NT_SUCCESS(Status
))
868 if (CurrentKeyHandle
!= BaseKeyHandle
)
869 ZwClose(CurrentKeyHandle
);
871 ZwClose(BaseKeyHandle
);
881 RtlWriteRegistryValue(IN ULONG RelativeTo
,
886 IN ULONG ValueLength
)
894 Status
= RtlpGetRegistryHandle(RelativeTo
,
898 if (!NT_SUCCESS(Status
))
900 DPRINT("RtlpGetRegistryHandle() failed! Status: 0x%x\n", Status
);
904 RtlInitUnicodeString(&Name
,
907 Status
= ZwSetValueKey(KeyHandle
,
913 if (!NT_SUCCESS(Status
))
915 DPRINT1("ZwSetValueKey() failed! Status: 0x%x\n", Status
);
928 RtlpNtCreateKey(OUT HANDLE KeyHandle
,
929 IN ACCESS_MASK DesiredAccess
,
930 IN POBJECT_ATTRIBUTES ObjectAttributes
,
932 OUT PULONG Disposition
,
935 if (ObjectAttributes
!= NULL
)
936 ObjectAttributes
->Attributes
&= ~(OBJ_PERMANENT
| OBJ_EXCLUSIVE
);
938 return(ZwCreateKey(KeyHandle
,
952 RtlpNtEnumerateSubKey(IN HANDLE KeyHandle
,
953 OUT PUNICODE_STRING SubKeyName
,
957 PKEY_BASIC_INFORMATION KeyInfo
= NULL
;
958 ULONG BufferLength
= 0;
959 ULONG ReturnedLength
;
962 if (SubKeyName
->MaximumLength
!= 0)
964 BufferLength
= SubKeyName
->MaximumLength
+
965 sizeof(KEY_BASIC_INFORMATION
);
966 KeyInfo
= ExAllocatePool(PagedPool
, BufferLength
);
968 return(STATUS_NO_MEMORY
);
971 Status
= ZwEnumerateKey(KeyHandle
,
977 if (NT_SUCCESS(Status
))
979 if (KeyInfo
->NameLength
+ sizeof(WCHAR
) <= SubKeyName
->MaximumLength
)
981 memmove(SubKeyName
->Buffer
,
983 KeyInfo
->NameLength
);
984 SubKeyName
->Buffer
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
985 SubKeyName
->Length
= KeyInfo
->NameLength
;
989 Status
= STATUS_BUFFER_OVERFLOW
;
1006 RtlpNtMakeTemporaryKey(IN HANDLE KeyHandle
)
1008 return(ZwDeleteKey(KeyHandle
));
1016 RtlpNtOpenKey(OUT HANDLE KeyHandle
,
1017 IN ACCESS_MASK DesiredAccess
,
1018 IN POBJECT_ATTRIBUTES ObjectAttributes
,
1021 if (ObjectAttributes
!= NULL
)
1022 ObjectAttributes
->Attributes
&= ~(OBJ_PERMANENT
| OBJ_EXCLUSIVE
);
1024 return(ZwOpenKey(KeyHandle
,
1034 RtlpNtQueryValueKey(IN HANDLE KeyHandle
,
1035 OUT PULONG Type OPTIONAL
,
1036 OUT PVOID Data OPTIONAL
,
1037 IN OUT PULONG DataLength OPTIONAL
,
1040 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
1041 UNICODE_STRING ValueName
;
1043 ULONG ReturnedLength
;
1046 RtlInitUnicodeString(&ValueName
,
1049 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
1050 if (DataLength
!= NULL
)
1051 BufferLength
= *DataLength
;
1053 ValueInfo
= ExAllocatePool(PagedPool
, BufferLength
);
1054 if (ValueInfo
== NULL
)
1055 return(STATUS_NO_MEMORY
);
1057 Status
= ZwQueryValueKey(KeyHandle
,
1059 KeyValuePartialInformation
,
1063 if (NT_SUCCESS(Status
))
1065 if (DataLength
!= NULL
)
1066 *DataLength
= ValueInfo
->DataLength
;
1069 *Type
= ValueInfo
->Type
;
1075 ValueInfo
->DataLength
);
1079 ExFreePool(ValueInfo
);
1089 RtlpNtSetValueKey(IN HANDLE KeyHandle
,
1092 IN ULONG DataLength
)
1094 UNICODE_STRING ValueName
;
1096 RtlInitUnicodeString(&ValueName
,
1098 return(ZwSetValueKey(KeyHandle
,