2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmapi.c
5 * PURPOSE: Configuration Manager - Internal Registry APIs
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 BOOLEAN CmBootAcceptFirstTime
= TRUE
;
16 BOOLEAN CmFirstTime
= TRUE
;
18 /* FUNCTIONS *****************************************************************/
22 NtCreateKey(OUT PHANDLE KeyHandle
,
23 IN ACCESS_MASK DesiredAccess
,
24 IN POBJECT_ATTRIBUTES ObjectAttributes
,
26 IN PUNICODE_STRING Class
,
27 IN ULONG CreateOptions
,
28 OUT PULONG Disposition
)
31 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
32 CM_PARSE_CONTEXT ParseContext
= {0};
35 DPRINT("NtCreateKey(OB 0x%wZ)\n", ObjectAttributes
->ObjectName
);
37 /* Setup the parse context */
38 ParseContext
.CreateOperation
= TRUE
;
39 ParseContext
.CreateOptions
= CreateOptions
;
40 if (Class
) ParseContext
.Class
= *Class
;
43 Status
= ObOpenObjectByName(ObjectAttributes
,
50 if (NT_SUCCESS(Status
)) *KeyHandle
= Handle
;
52 /* Return data to user */
53 if (Disposition
) *Disposition
= ParseContext
.Disposition
;
59 NtOpenKey(OUT PHANDLE KeyHandle
,
60 IN ACCESS_MASK DesiredAccess
,
61 IN POBJECT_ATTRIBUTES ObjectAttributes
)
63 CM_PARSE_CONTEXT ParseContext
= {0};
67 DPRINT("NtOpenKey(OB 0x%wZ)\n", ObjectAttributes
->ObjectName
);
69 /* Just let the object manager handle this */
70 Status
= ObOpenObjectByName(ObjectAttributes
,
77 if (NT_SUCCESS(Status
)) *KeyHandle
= Handle
;
86 NtDeleteKey(IN HANDLE KeyHandle
)
88 PCM_KEY_BODY KeyObject
;
90 REG_DELETE_KEY_INFORMATION DeleteKeyInfo
;
91 REG_POST_OPERATION_INFORMATION PostOperationInfo
;
93 DPRINT("NtDeleteKey(KH 0x%p)\n", KeyHandle
);
95 /* Verify that the handle is valid and is a registry key */
96 Status
= ObReferenceObjectByHandle(KeyHandle
,
102 if (!NT_SUCCESS(Status
)) return Status
;
104 /* Setup the callback */
105 PostOperationInfo
.Object
= (PVOID
)KeyObject
;
106 DeleteKeyInfo
.Object
= (PVOID
)KeyObject
;
107 Status
= CmiCallRegisteredCallbacks(RegNtPreDeleteKey
, &DeleteKeyInfo
);
108 if (NT_SUCCESS(Status
))
110 /* Check if we are read-only */
111 if ((KeyObject
->KeyControlBlock
->ExtFlags
& CM_KCB_READ_ONLY_KEY
) ||
112 (KeyObject
->KeyControlBlock
->ParentKcb
->ExtFlags
& CM_KCB_READ_ONLY_KEY
))
115 Status
= STATUS_ACCESS_DENIED
;
119 /* Call the internal API */
120 Status
= CmDeleteKey(KeyObject
);
123 /* Do post callback */
124 PostOperationInfo
.Status
= Status
;
125 CmiCallRegisteredCallbacks(RegNtPostDeleteKey
, &PostOperationInfo
);
128 /* Dereference the object */
129 ObDereferenceObject(KeyObject
);
135 NtEnumerateKey(IN HANDLE KeyHandle
,
137 IN KEY_INFORMATION_CLASS KeyInformationClass
,
138 OUT PVOID KeyInformation
,
140 OUT PULONG ResultLength
)
143 PCM_KEY_BODY KeyObject
;
144 REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo
;
145 REG_POST_OPERATION_INFORMATION PostOperationInfo
;
147 DPRINT("NtEnumerateKey() KH 0x%x, Index 0x%x, KIC %d, Length %d\n",
148 KeyHandle
, Index
, KeyInformationClass
, Length
);
150 /* Reject classes we don't know about */
151 if ((KeyInformationClass
!= KeyBasicInformation
) &&
152 (KeyInformationClass
!= KeyNodeInformation
) &&
153 (KeyInformationClass
!= KeyFullInformation
))
156 return STATUS_INVALID_PARAMETER
;
159 /* Verify that the handle is valid and is a registry key */
160 Status
= ObReferenceObjectByHandle(KeyHandle
,
161 KEY_ENUMERATE_SUB_KEYS
,
166 if (!NT_SUCCESS(Status
)) return Status
;
168 /* Setup the callback */
169 PostOperationInfo
.Object
= (PVOID
)KeyObject
;
170 EnumerateKeyInfo
.Object
= (PVOID
)KeyObject
;
171 EnumerateKeyInfo
.Index
= Index
;
172 EnumerateKeyInfo
.KeyInformationClass
= KeyInformationClass
;
173 EnumerateKeyInfo
.Length
= Length
;
174 EnumerateKeyInfo
.ResultLength
= ResultLength
;
176 /* Do the callback */
177 Status
= CmiCallRegisteredCallbacks(RegNtPreEnumerateKey
, &EnumerateKeyInfo
);
178 if (NT_SUCCESS(Status
))
180 /* Call the internal API */
181 Status
= CmEnumerateKey(KeyObject
->KeyControlBlock
,
188 /* Do the post callback */
189 PostOperationInfo
.Status
= Status
;
190 CmiCallRegisteredCallbacks(RegNtPostEnumerateKey
, &PostOperationInfo
);
193 /* Dereference and return status */
194 ObDereferenceObject(KeyObject
);
200 NtEnumerateValueKey(IN HANDLE KeyHandle
,
202 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
,
203 OUT PVOID KeyValueInformation
,
205 OUT PULONG ResultLength
)
208 PCM_KEY_BODY KeyObject
;
209 REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo
;
210 REG_POST_OPERATION_INFORMATION PostOperationInfo
;
212 DPRINT("NtEnumerateValueKey() KH 0x%x, Index 0x%x, KVIC %d, Length %d\n",
213 KeyHandle
, Index
, KeyValueInformationClass
, Length
);
215 /* Reject classes we don't know about */
216 if ((KeyValueInformationClass
!= KeyValueBasicInformation
) &&
217 (KeyValueInformationClass
!= KeyValueFullInformation
) &&
218 (KeyValueInformationClass
!= KeyValuePartialInformation
))
221 return STATUS_INVALID_PARAMETER
;
224 /* Verify that the handle is valid and is a registry key */
225 Status
= ObReferenceObjectByHandle(KeyHandle
,
231 if (!NT_SUCCESS(Status
)) return Status
;
233 /* Setup the callback */
234 PostOperationInfo
.Object
= (PVOID
)KeyObject
;
235 EnumerateValueKeyInfo
.Object
= (PVOID
)KeyObject
;
236 EnumerateValueKeyInfo
.Index
= Index
;
237 EnumerateValueKeyInfo
.KeyValueInformationClass
= KeyValueInformationClass
;
238 EnumerateValueKeyInfo
.KeyValueInformation
= KeyValueInformation
;
239 EnumerateValueKeyInfo
.Length
= Length
;
240 EnumerateValueKeyInfo
.ResultLength
= ResultLength
;
242 /* Do the callback */
243 Status
= CmiCallRegisteredCallbacks(RegNtPreEnumerateValueKey
,
244 &EnumerateValueKeyInfo
);
245 if (NT_SUCCESS(Status
))
247 /* Call the internal API */
248 Status
= CmEnumerateValueKey(KeyObject
->KeyControlBlock
,
250 KeyValueInformationClass
,
255 /* Do the post callback */
256 PostOperationInfo
.Status
= Status
;
257 CmiCallRegisteredCallbacks(RegNtPostEnumerateValueKey
, &PostOperationInfo
);
260 ObDereferenceObject(KeyObject
);
266 NtQueryKey(IN HANDLE KeyHandle
,
267 IN KEY_INFORMATION_CLASS KeyInformationClass
,
268 OUT PVOID KeyInformation
,
270 OUT PULONG ResultLength
)
273 PCM_KEY_BODY KeyObject
;
274 REG_QUERY_KEY_INFORMATION QueryKeyInfo
;
275 REG_POST_OPERATION_INFORMATION PostOperationInfo
;
276 OBJECT_HANDLE_INFORMATION HandleInfo
;
278 DPRINT("NtQueryKey() KH 0x%x, KIC %d, Length %d\n",
279 KeyHandle
, KeyInformationClass
, Length
);
281 /* Reject invalid classes */
282 if ((KeyInformationClass
!= KeyBasicInformation
) &&
283 (KeyInformationClass
!= KeyNodeInformation
) &&
284 (KeyInformationClass
!= KeyFullInformation
) &&
285 (KeyInformationClass
!= KeyNameInformation
) &&
286 (KeyInformationClass
!= KeyCachedInformation
) &&
287 (KeyInformationClass
!= KeyFlagsInformation
))
290 return STATUS_INVALID_PARAMETER
;
293 /* Check if just the name is required */
294 if (KeyInformationClass
== KeyNameInformation
)
296 /* Ignore access level */
297 Status
= ObReferenceObjectByHandle(KeyHandle
,
303 if (NT_SUCCESS(Status
))
305 /* At least a single bit of access is required */
306 if (!HandleInfo
.GrantedAccess
)
309 ObDereferenceObject(KeyObject
);
310 Status
= STATUS_ACCESS_DENIED
;
316 /* Get a reference */
317 Status
= ObReferenceObjectByHandle(KeyHandle
,
325 /* Quit on failure */
326 if (!NT_SUCCESS(Status
)) return Status
;
328 /* Setup the callback */
329 PostOperationInfo
.Object
= (PVOID
)KeyObject
;
330 QueryKeyInfo
.Object
= (PVOID
)KeyObject
;
331 QueryKeyInfo
.KeyInformationClass
= KeyInformationClass
;
332 QueryKeyInfo
.KeyInformation
= KeyInformation
;
333 QueryKeyInfo
.Length
= Length
;
334 QueryKeyInfo
.ResultLength
= ResultLength
;
336 /* Do the callback */
337 Status
= CmiCallRegisteredCallbacks(RegNtPreQueryKey
, &QueryKeyInfo
);
338 if (NT_SUCCESS(Status
))
340 /* Call the internal API */
341 Status
= CmQueryKey(KeyObject
->KeyControlBlock
,
347 /* Do the post callback */
348 PostOperationInfo
.Status
= Status
;
349 CmiCallRegisteredCallbacks(RegNtPostQueryKey
, &PostOperationInfo
);
352 /* Dereference and return status */
353 ObDereferenceObject(KeyObject
);
359 NtQueryValueKey(IN HANDLE KeyHandle
,
360 IN PUNICODE_STRING ValueName
,
361 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
,
362 OUT PVOID KeyValueInformation
,
364 OUT PULONG ResultLength
)
367 PCM_KEY_BODY KeyObject
;
368 REG_QUERY_VALUE_KEY_INFORMATION QueryValueKeyInfo
;
369 REG_POST_OPERATION_INFORMATION PostOperationInfo
;
370 UNICODE_STRING ValueNameCopy
= *ValueName
;
372 DPRINT("NtQueryValueKey() KH 0x%x, VN '%wZ', KVIC %d, Length %d\n",
373 KeyHandle
, ValueName
, KeyValueInformationClass
, Length
);
375 /* Verify that the handle is valid and is a registry key */
376 Status
= ObReferenceObjectByHandle(KeyHandle
,
382 if (!NT_SUCCESS(Status
)) return Status
;
384 /* Make sure the name is aligned properly */
385 if ((ValueNameCopy
.Length
& (sizeof(WCHAR
) - 1)))
387 /* It isn't, so we'll fail */
388 ObDereferenceObject(KeyObject
);
389 return STATUS_INVALID_PARAMETER
;
393 /* Ignore any null characters at the end */
394 while ((ValueNameCopy
.Length
) &&
395 !(ValueNameCopy
.Buffer
[ValueNameCopy
.Length
/ sizeof(WCHAR
) - 1]))
398 ValueNameCopy
.Length
-= sizeof(WCHAR
);
402 /* Setup the callback */
403 PostOperationInfo
.Object
= (PVOID
)KeyObject
;
404 QueryValueKeyInfo
.Object
= (PVOID
)KeyObject
;
405 QueryValueKeyInfo
.ValueName
= &ValueNameCopy
;
406 QueryValueKeyInfo
.KeyValueInformationClass
= KeyValueInformationClass
;
407 QueryValueKeyInfo
.Length
= Length
;
408 QueryValueKeyInfo
.ResultLength
= ResultLength
;
410 /* Do the callback */
411 Status
= CmiCallRegisteredCallbacks(RegNtPreQueryValueKey
, &QueryValueKeyInfo
);
412 if (NT_SUCCESS(Status
))
414 /* Call the internal API */
415 Status
= CmQueryValueKey(KeyObject
->KeyControlBlock
,
417 KeyValueInformationClass
,
422 /* Do the post callback */
423 PostOperationInfo
.Status
= Status
;
424 CmiCallRegisteredCallbacks(RegNtPostQueryValueKey
, &PostOperationInfo
);
427 /* Dereference and return status */
428 ObDereferenceObject(KeyObject
);
434 NtSetValueKey(IN HANDLE KeyHandle
,
435 IN PUNICODE_STRING ValueName
,
442 PCM_KEY_BODY KeyObject
;
443 REG_SET_VALUE_KEY_INFORMATION SetValueKeyInfo
;
444 REG_POST_OPERATION_INFORMATION PostOperationInfo
;
445 UNICODE_STRING ValueNameCopy
= *ValueName
;
447 DPRINT("NtSetValueKey() KH 0x%x, VN '%wZ', TI %x, T %d, DS %d\n",
448 KeyHandle
, ValueName
, TitleIndex
, Type
, DataSize
);
450 /* Verify that the handle is valid and is a registry key */
451 Status
= ObReferenceObjectByHandle(KeyHandle
,
457 if (!NT_SUCCESS(Status
)) return Status
;
459 /* Make sure the name is aligned, not too long, and the data under 4GB */
460 if ( (ValueNameCopy
.Length
> 32767) ||
461 ((ValueNameCopy
.Length
& (sizeof(WCHAR
) - 1))) ||
462 (DataSize
> 0x80000000))
465 ObDereferenceObject(KeyObject
);
466 return STATUS_INVALID_PARAMETER
;
469 /* Ignore any null characters at the end */
470 while ((ValueNameCopy
.Length
) &&
471 !(ValueNameCopy
.Buffer
[ValueNameCopy
.Length
/ sizeof(WCHAR
) - 1]))
474 ValueNameCopy
.Length
-= sizeof(WCHAR
);
477 /* Don't touch read-only keys */
478 if (KeyObject
->KeyControlBlock
->ExtFlags
& CM_KCB_READ_ONLY_KEY
)
481 ObDereferenceObject(KeyObject
);
482 return STATUS_ACCESS_DENIED
;
486 PostOperationInfo
.Object
= (PVOID
)KeyObject
;
487 SetValueKeyInfo
.Object
= (PVOID
)KeyObject
;
488 SetValueKeyInfo
.ValueName
= ValueName
;
489 SetValueKeyInfo
.TitleIndex
= TitleIndex
;
490 SetValueKeyInfo
.Type
= Type
;
491 SetValueKeyInfo
.Data
= Data
;
492 SetValueKeyInfo
.DataSize
= DataSize
;
494 /* Do the callback */
495 Status
= CmiCallRegisteredCallbacks(RegNtPreSetValueKey
, &SetValueKeyInfo
);
496 if (NT_SUCCESS(Status
))
498 /* Call the internal API */
499 Status
= CmSetValueKey(KeyObject
->KeyControlBlock
,
506 /* Do the post-callback */
507 PostOperationInfo
.Status
= Status
;
508 CmiCallRegisteredCallbacks(RegNtPostSetValueKey
, &PostOperationInfo
);
510 /* Dereference and return status */
511 ObDereferenceObject(KeyObject
);
517 NtDeleteValueKey(IN HANDLE KeyHandle
,
518 IN PUNICODE_STRING ValueName
)
520 PCM_KEY_BODY KeyObject
;
522 REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo
;
523 REG_POST_OPERATION_INFORMATION PostOperationInfo
;
524 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
525 UNICODE_STRING ValueNameCopy
= *ValueName
;
528 /* Verify that the handle is valid and is a registry key */
529 Status
= ObReferenceObjectByHandle(KeyHandle
,
535 if (!NT_SUCCESS(Status
)) return Status
;
537 /* Don't touch read-only keys */
538 if (KeyObject
->KeyControlBlock
->ExtFlags
& CM_KCB_READ_ONLY_KEY
)
541 ObDereferenceObject(KeyObject
);
542 return STATUS_ACCESS_DENIED
;
545 /* Make sure the name is aligned properly */
546 if ((ValueNameCopy
.Length
& (sizeof(WCHAR
) - 1)))
548 /* It isn't, so we'll fail */
549 ObDereferenceObject(KeyObject
);
550 return STATUS_INVALID_PARAMETER
;
553 /* Do the callback */
554 DeleteValueKeyInfo
.Object
= (PVOID
)KeyObject
;
555 DeleteValueKeyInfo
.ValueName
= ValueName
;
556 Status
= CmiCallRegisteredCallbacks(RegNtPreDeleteValueKey
,
557 &DeleteValueKeyInfo
);
558 if (NT_SUCCESS(Status
))
560 /* Call the internal API */
561 Status
= CmDeleteValueKey(KeyObject
->KeyControlBlock
, ValueNameCopy
);
563 /* Do the post callback */
564 PostOperationInfo
.Object
= (PVOID
)KeyObject
;
565 PostOperationInfo
.Status
= Status
;
566 CmiCallRegisteredCallbacks(RegNtPostDeleteValueKey
,
570 /* Dereference the key body */
571 ObDereferenceObject(KeyObject
);
577 NtFlushKey(IN HANDLE KeyHandle
)
580 PCM_KEY_BODY KeyObject
;
583 /* Get the key object */
584 Status
= ObReferenceObjectByHandle(KeyHandle
,
590 if (!NT_SUCCESS(Status
)) return Status
;
592 /* Lock the registry */
596 CmpAcquireKcbLockShared(KeyObject
->KeyControlBlock
);
598 /* Make sure KCB isn't deleted */
599 if (KeyObject
->KeyControlBlock
->Delete
)
602 Status
= STATUS_KEY_DELETED
;
606 /* Call the internal API */
607 Status
= CmFlushKey(KeyObject
->KeyControlBlock
, FALSE
);
610 /* Release the locks */
611 CmpReleaseKcbLock(KeyObject
->KeyControlBlock
);
614 /* Dereference the object and return status */
615 ObDereferenceObject(KeyObject
);
621 NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes
,
622 IN POBJECT_ATTRIBUTES FileObjectAttributes
)
624 /* Call the newer API */
625 return NtLoadKey2(KeyObjectAttributes
, FileObjectAttributes
, 0);
630 NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes
,
631 IN POBJECT_ATTRIBUTES FileObjectAttributes
,
634 /* Call the newer API */
635 return NtLoadKeyEx(KeyObjectAttributes
, FileObjectAttributes
, Flags
, NULL
);
640 NtLoadKeyEx(IN POBJECT_ATTRIBUTES TargetKey
,
641 IN POBJECT_ATTRIBUTES SourceFile
,
643 IN HANDLE TrustClassKey
)
646 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
647 PCM_KEY_BODY KeyBody
= NULL
;
651 if (Flags
& ~REG_NO_LAZY_FLUSH
) return STATUS_INVALID_PARAMETER
;
653 /* Validate privilege */
654 if (!SeSinglePrivilegeCheck(SeRestorePrivilege
, PreviousMode
))
657 DPRINT1("Restore Privilege missing!\n");
658 return STATUS_PRIVILEGE_NOT_HELD
;
662 KeEnterCriticalRegion();
664 /* Check if we have a trust class */
668 Status
= ObReferenceObjectByHandle(TrustClassKey
,
676 /* Call the internal API */
677 Status
= CmLoadKey(TargetKey
, SourceFile
, Flags
, KeyBody
);
679 /* Dereference the trust key, if any */
680 if (KeyBody
) ObDereferenceObject(KeyBody
);
682 /* Bring back APCs */
683 KeLeaveCriticalRegion();
691 NtNotifyChangeKey(IN HANDLE KeyHandle
,
693 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
694 IN PVOID ApcContext OPTIONAL
,
695 OUT PIO_STATUS_BLOCK IoStatusBlock
,
696 IN ULONG CompletionFilter
,
697 IN BOOLEAN WatchTree
,
700 IN BOOLEAN Asynchronous
)
702 /* Call the newer API */
703 return NtNotifyChangeMultipleKeys(KeyHandle
,
719 NtInitializeRegistry(IN USHORT Flag
)
722 NTSTATUS Status
= STATUS_SUCCESS
;
725 /* Always do this as kernel mode */
726 if (KeGetPreviousMode() == UserMode
) return ZwInitializeRegistry(Flag
);
729 if (Flag
> CM_BOOT_FLAG_MAX
) return STATUS_INVALID_PARAMETER
;
731 /* Check if boot was accepted */
732 if ((Flag
>= CM_BOOT_FLAG_ACCEPTED
) && (Flag
<= CM_BOOT_FLAG_MAX
))
734 /* Only allow once */
735 if (!CmBootAcceptFirstTime
) return STATUS_ACCESS_DENIED
;
736 CmBootAcceptFirstTime
= FALSE
;
738 /* Get the control set accepted */
739 Flag
-= CM_BOOT_FLAG_ACCEPTED
;
742 /* FIXME: Save the last known good boot */
743 //Status = CmpSaveBootControlSet(Flag);
748 /* Enable lazy flush */
749 CmpHoldLazyFlush
= FALSE
;
754 /* Otherwise, invalid boot */
755 return STATUS_INVALID_PARAMETER
;
758 /* Check if this was a setup boot */
759 SetupBoot
= (Flag
== CM_BOOT_FLAG_SETUP
? TRUE
: FALSE
);
761 /* Make sure we're only called once */
762 if (!CmFirstTime
) return STATUS_ACCESS_DENIED
;
765 /* Acquire registry lock */
766 //CmpLockRegistryExclusive();
768 /* Initialize the hives and lazy flusher */
769 CmpCmdInit(SetupBoot
);
771 /* FIXME: Save version data */
772 //CmpSetVersionData();
774 /* Release the registry lock */
775 //CmpUnlockRegistry();
776 return STATUS_SUCCESS
;
781 NtCompactKeys(IN ULONG Count
,
785 return STATUS_NOT_IMPLEMENTED
;
790 NtCompressKey(IN HANDLE Key
)
793 return STATUS_NOT_IMPLEMENTED
;
798 NtLockProductActivationKeys(IN PULONG pPrivateVer
,
802 return STATUS_NOT_IMPLEMENTED
;
807 NtLockRegistryKey(IN HANDLE KeyHandle
)
810 return STATUS_NOT_IMPLEMENTED
;
815 NtNotifyChangeMultipleKeys(IN HANDLE MasterKeyHandle
,
817 IN POBJECT_ATTRIBUTES SlaveObjects
,
819 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
820 IN PVOID ApcContext OPTIONAL
,
821 OUT PIO_STATUS_BLOCK IoStatusBlock
,
822 IN ULONG CompletionFilter
,
823 IN BOOLEAN WatchTree
,
826 IN BOOLEAN Asynchronous
)
829 return STATUS_NOT_IMPLEMENTED
;
834 NtQueryMultipleValueKey(IN HANDLE KeyHandle
,
835 IN OUT PKEY_VALUE_ENTRY ValueList
,
836 IN ULONG NumberOfValues
,
838 IN OUT PULONG Length
,
839 OUT PULONG ReturnLength
)
842 return STATUS_NOT_IMPLEMENTED
;
847 NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey
,
848 IN ULONG HandleCount
)
851 return STATUS_NOT_IMPLEMENTED
;
856 NtQueryOpenSubKeysEx(IN POBJECT_ATTRIBUTES TargetKey
,
857 IN ULONG BufferLength
,
859 IN PULONG RequiredSize
)
862 return STATUS_NOT_IMPLEMENTED
;
867 NtRenameKey(IN HANDLE KeyHandle
,
868 IN PUNICODE_STRING ReplacementName
)
871 return STATUS_NOT_IMPLEMENTED
;
876 NtReplaceKey(IN POBJECT_ATTRIBUTES ObjectAttributes
,
878 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes
)
881 return STATUS_NOT_IMPLEMENTED
;
886 NtRestoreKey(IN HANDLE KeyHandle
,
887 IN HANDLE FileHandle
,
888 IN ULONG RestoreFlags
)
891 return STATUS_NOT_IMPLEMENTED
;
896 NtSaveKey(IN HANDLE KeyHandle
,
897 IN HANDLE FileHandle
)
900 return STATUS_NOT_IMPLEMENTED
;
905 NtSaveKeyEx(IN HANDLE KeyHandle
,
906 IN HANDLE FileHandle
,
910 return STATUS_NOT_IMPLEMENTED
;
915 NtSaveMergedKeys(IN HANDLE HighPrecedenceKeyHandle
,
916 IN HANDLE LowPrecedenceKeyHandle
,
917 IN HANDLE FileHandle
)
920 return STATUS_NOT_IMPLEMENTED
;
925 NtSetInformationKey(IN HANDLE KeyHandle
,
926 IN KEY_SET_INFORMATION_CLASS KeyInformationClass
,
927 IN PVOID KeyInformation
,
928 IN ULONG KeyInformationLength
)
931 return STATUS_NOT_IMPLEMENTED
;
936 NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes
)
939 return STATUS_NOT_IMPLEMENTED
;
944 NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey
,
948 return STATUS_NOT_IMPLEMENTED
;
953 NtUnloadKeyEx(IN POBJECT_ATTRIBUTES TargetKey
,
957 return STATUS_NOT_IMPLEMENTED
;