ReactOS  0.4.13-dev-249-gcba1a2f
ntapi.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/config/ntapi.c
5  * PURPOSE: Configuration Manager - Internal Registry APIs
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Eric Kohl
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include "ntoskrnl.h"
13 #define NDEBUG
14 #include "debug.h"
15 
18 extern ULONG InitSafeBootMode;
19 
20 
21 /* PRIVATE FUNCTIONS *********************************************************/
22 
23 /*
24  * Adapted from ntoskrnl/include/internal/ob_x.h:ObpReleaseObjectCreateInformation()
25  */
26 VOID
28  _In_ POBJECT_ATTRIBUTES CapturedObjectAttributes,
30 {
31  /* Check if we have a security descriptor */
32  if (CapturedObjectAttributes->SecurityDescriptor)
33  {
34  /* Release it */
35  SeReleaseSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor,
36  AccessMode,
37  TRUE);
38  CapturedObjectAttributes->SecurityDescriptor = NULL;
39  }
40 
41  /* Check if we have an object name */
42  if (CapturedObjectAttributes->ObjectName)
43  {
44  /* Release it */
45  ReleaseCapturedUnicodeString(CapturedObjectAttributes->ObjectName, AccessMode);
46  }
47 }
48 
49 /*
50  * Adapted from ntoskrnl/ob/oblife.c:ObpCaptureObjectCreateInformation()
51  */
54  _Out_ POBJECT_ATTRIBUTES CapturedObjectAttributes,
58  _In_ BOOLEAN CaptureSecurity)
59 {
62  // PSECURITY_QUALITY_OF_SERVICE SecurityQos;
63  PUNICODE_STRING LocalObjectName = NULL;
64 
65  /* Zero out the Capture Data */
66  RtlZeroMemory(CapturedObjectAttributes, sizeof(*CapturedObjectAttributes));
67 
68  /* SEH everything here for protection */
69  _SEH2_TRY
70  {
71  /* Check if we got attributes */
72  if (ObjectAttributes)
73  {
74  /* Check if we're in user mode */
75  if (AccessMode != KernelMode)
76  {
77  /* Probe the attributes */
79  sizeof(OBJECT_ATTRIBUTES),
80  sizeof(ULONG));
81  }
82 
83  /* Validate the Size and Attributes */
84  if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
85  (ObjectAttributes->Attributes & ~OBJ_VALID_KERNEL_ATTRIBUTES)) // Understood as all the possible valid attributes
86  {
87  /* Invalid combination, fail */
89  }
90 
91  /* Set some Create Info and do not allow user-mode kernel handles */
92  CapturedObjectAttributes->Length = sizeof(OBJECT_ATTRIBUTES);
93  CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
94  CapturedObjectAttributes->Attributes = ObpValidateAttributes(ObjectAttributes->Attributes, AccessMode);
95  LocalObjectName = ObjectAttributes->ObjectName;
96  SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
97  // SecurityQos = ObjectAttributes->SecurityQualityOfService;
98 
99  /* Check if we have a security descriptor */
100  if (CaptureSecurity && SecurityDescriptor)
101  {
102  /*
103  * Capture it.
104  * Note: This has an implicit memory barrier due
105  * to the function call, so cleanup is safe here.
106  */
108  AccessMode,
109  NonPagedPool,
110  TRUE,
111  &CapturedObjectAttributes->
113  if (!NT_SUCCESS(Status))
114  {
115  /* Capture failed, quit */
116  CapturedObjectAttributes->SecurityDescriptor = NULL;
117  _SEH2_YIELD(return Status);
118  }
119  }
120  else
121  {
122  CapturedObjectAttributes->SecurityDescriptor = NULL;
123  }
124 
125 #if 0
126 // We don't use the QoS!
127 
128  /* Check if we have QoS */
129  if (SecurityQos)
130  {
131  /* Check if we came from user mode */
132  if (AccessMode != KernelMode)
133  {
134  /* Validate the QoS */
135  ProbeForRead(SecurityQos,
137  sizeof(ULONG));
138  }
139 
140  /* Save Info */
141  CapturedObjectAttributes->SecurityQualityOfService = *SecurityQos;
142  CapturedObjectAttributes->SecurityQos =
143  &CapturedObjectAttributes->SecurityQualityOfService;
144  }
145 #else
146  CapturedObjectAttributes->SecurityQualityOfService = NULL;
147 #endif
148  }
149  else
150  {
151  /* We don't have a name */
152  LocalObjectName = NULL;
153  }
154  }
156  {
157  /* Cleanup and return the exception code */
158  ReleaseCapturedObjectAttributes(CapturedObjectAttributes, AccessMode);
160  }
161  _SEH2_END;
162 
163  /* Now check if the Object Attributes had an Object Name */
164  if (LocalObjectName)
165  {
167  }
168  else
169  {
170  /* Clear the string */
171  RtlInitEmptyUnicodeString(ObjectName, NULL, 0);
172 
173  /* It cannot have specified a Root Directory */
174  if (CapturedObjectAttributes->RootDirectory)
175  {
177  }
178  }
179 
180  /* Set the caputured object attributes name pointer to the one the user gave to us */
181  CapturedObjectAttributes->ObjectName = ObjectName;
182 
183  /* Cleanup if we failed */
184  if (!NT_SUCCESS(Status))
185  {
186  ReleaseCapturedObjectAttributes(CapturedObjectAttributes, AccessMode);
187  }
188 
189  /* Return status to caller */
190  return Status;
191 }
192 
193 static
194 NTSTATUS
201 {
203  PVOID Object;
204 
205  *KernelHandle = NULL;
206 
207  /* NULL handle is valid */
208  if (SourceHandle == NULL)
209  return STATUS_SUCCESS;
210 
211  /* Get the object pointer */
214  ObjectType,
215  AccessMode,
216  &Object,
217  NULL);
218  if (!NT_SUCCESS(Status))
219  return Status;
220 
221  /* Create a kernel handle from the pointer */
224  NULL,
226  ObjectType,
227  KernelMode,
228  KernelHandle);
229 
230  /* Dereference the object */
232  return Status;
233 }
234 
235 
236 /* FUNCTIONS *****************************************************************/
237 
238 NTSTATUS
239 NTAPI
247 {
250  CM_PARSE_CONTEXT ParseContext = {0};
251  HANDLE Handle;
252  PAGED_CODE();
253 
254  DPRINT("NtCreateKey(Path: %wZ, Root %x, Access: %x, CreateOptions %x)\n",
255  ObjectAttributes->ObjectName, ObjectAttributes->RootDirectory,
257 
258  /* Ignore the WOW64 flag, it's not valid in the kernel */
260 
261  /* Check for user-mode caller */
262  if (PreviousMode != KernelMode)
263  {
264  /* Prepare to probe parameters */
265  _SEH2_TRY
266  {
267  /* Check if we have a class */
268  if (Class)
269  {
270  /* Probe it */
271  ParseContext.Class = ProbeForReadUnicodeString(Class);
272  ProbeForRead(ParseContext.Class.Buffer,
273  ParseContext.Class.Length,
274  sizeof(WCHAR));
275  }
276 
277  /* Probe the key handle */
279  *KeyHandle = NULL;
280 
281  /* Probe object attributes */
283  sizeof(OBJECT_ATTRIBUTES),
284  sizeof(ULONG));
285 
286  if (Disposition)
288  }
290  {
291  /* Return the exception code */
293  }
294  _SEH2_END;
295  }
296  else
297  {
298  /* Save the class directly */
299  if (Class) ParseContext.Class = *Class;
300  }
301 
302  /* Setup the parse context */
303  ParseContext.CreateOperation = TRUE;
304  ParseContext.CreateOptions = CreateOptions;
305 
306  /* Do the create */
309  PreviousMode,
310  NULL,
312  &ParseContext,
313  &Handle);
314 
315  _SEH2_TRY
316  {
317  /* Return data to user */
319  if (Disposition) *Disposition = ParseContext.Disposition;
320  }
322  {
323  /* Get the status */
325  }
326  _SEH2_END;
327 
328  DPRINT("Returning handle %x, Status %x.\n", Handle, Status);
329 
330  /* Return status */
331  return Status;
332 }
333 
334 NTSTATUS
335 NTAPI
339 {
340  CM_PARSE_CONTEXT ParseContext = {0};
341  HANDLE Handle;
344  PAGED_CODE();
345  DPRINT("NtOpenKey(Path: %wZ, Root %x, Access: %x)\n",
346  ObjectAttributes->ObjectName, ObjectAttributes->RootDirectory, DesiredAccess);
347 
348  /* Ignore the WOW64 flag, it's not valid in the kernel */
350 
351  /* Check for user-mode caller */
352  if (PreviousMode != KernelMode)
353  {
354  /* Prepare to probe parameters */
355  _SEH2_TRY
356  {
357  /* Probe the key handle */
359  *KeyHandle = NULL;
360 
361  /* Probe object attributes */
363  sizeof(OBJECT_ATTRIBUTES),
364  sizeof(ULONG));
365  }
367  {
368  /* Return the exception code */
370  }
371  _SEH2_END;
372  }
373 
374  /* Just let the object manager handle this */
377  PreviousMode,
378  NULL,
380  &ParseContext,
381  &Handle);
382 
383  /* Only do this if we succeeded */
384  if (NT_SUCCESS(Status))
385  {
386  _SEH2_TRY
387  {
388  /* Return the handle to caller */
389  *KeyHandle = Handle;
390  }
392  {
393  /* Get the status */
395  }
396  _SEH2_END;
397  }
398 
399  DPRINT("Returning handle %x, Status %x.\n", Handle, Status);
400 
401  /* Return status */
402  return Status;
403 }
404 
405 
406 NTSTATUS
407 NTAPI
409 {
410  PCM_KEY_BODY KeyObject;
412  REG_DELETE_KEY_INFORMATION DeleteKeyInfo;
413  REG_POST_OPERATION_INFORMATION PostOperationInfo;
414  PAGED_CODE();
415  DPRINT("NtDeleteKey(KH 0x%p)\n", KeyHandle);
416 
417  /* Verify that the handle is valid and is a registry key */
419  DELETE,
422  (PVOID*)&KeyObject,
423  NULL);
424  if (!NT_SUCCESS(Status)) return Status;
425 
426  /* Setup the callback */
427  PostOperationInfo.Object = (PVOID)KeyObject;
428  DeleteKeyInfo.Object = (PVOID)KeyObject;
430  if (NT_SUCCESS(Status))
431  {
432  /* Check if we are read-only */
433  if ((KeyObject->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY) ||
434  (KeyObject->KeyControlBlock->ParentKcb->ExtFlags & CM_KCB_READ_ONLY_KEY))
435  {
436  /* Fail */
438  }
439  else
440  {
441  /* Call the internal API */
442  Status = CmDeleteKey(KeyObject);
443  }
444 
445  /* Do post callback */
446  PostOperationInfo.Status = Status;
447  CmiCallRegisteredCallbacks(RegNtPostDeleteKey, &PostOperationInfo);
448  }
449 
450  /* Dereference and return status */
451  ObDereferenceObject(KeyObject);
452  return Status;
453 }
454 
455 NTSTATUS
456 NTAPI
458  IN ULONG Index,
460  OUT PVOID KeyInformation,
461  IN ULONG Length,
463 {
466  PCM_KEY_BODY KeyObject;
467  REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
468  REG_POST_OPERATION_INFORMATION PostOperationInfo;
469  PAGED_CODE();
470  DPRINT("NtEnumerateKey() KH 0x%p, Index 0x%x, KIC %d, Length %lu\n",
472 
473  /* Reject classes we don't know about */
477  {
478  /* Fail */
480  }
481 
482  /* Verify that the handle is valid and is a registry key */
486  PreviousMode,
487  (PVOID*)&KeyObject,
488  NULL);
489  if (!NT_SUCCESS(Status)) return Status;
490 
491  if (PreviousMode != KernelMode)
492  {
493  _SEH2_TRY
494  {
496  ProbeForWrite(KeyInformation,
497  Length,
498  sizeof(ULONG));
499  }
501  {
502  /* Dereference and return status */
503  ObDereferenceObject(KeyObject);
505  }
506  _SEH2_END;
507  }
508 
509  /* Setup the callback */
510  PostOperationInfo.Object = (PVOID)KeyObject;
511  EnumerateKeyInfo.Object = (PVOID)KeyObject;
512  EnumerateKeyInfo.Index = Index;
513  EnumerateKeyInfo.KeyInformationClass = KeyInformationClass;
514  EnumerateKeyInfo.Length = Length;
515  EnumerateKeyInfo.ResultLength = ResultLength;
516 
517  /* Do the callback */
519  if (NT_SUCCESS(Status))
520  {
521  /* Call the internal API */
522  Status = CmEnumerateKey(KeyObject->KeyControlBlock,
523  Index,
525  KeyInformation,
526  Length,
527  ResultLength);
528 
529  /* Do the post callback */
530  PostOperationInfo.Status = Status;
532  }
533 
534  /* Dereference and return status */
535  ObDereferenceObject(KeyObject);
536  DPRINT("Returning status %x.\n", Status);
537  return Status;
538 }
539 
540 NTSTATUS
541 NTAPI
543  IN ULONG Index,
545  OUT PVOID KeyValueInformation,
546  IN ULONG Length,
548 {
551  PCM_KEY_BODY KeyObject;
552  REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo;
553  REG_POST_OPERATION_INFORMATION PostOperationInfo;
554 
555  PAGED_CODE();
556 
557  DPRINT("NtEnumerateValueKey() KH 0x%p, Index 0x%x, KVIC %d, Length %lu\n",
559 
560  /* Reject classes we don't know about */
566  {
567  /* Fail */
569  }
570 
571  /* Verify that the handle is valid and is a registry key */
575  PreviousMode,
576  (PVOID*)&KeyObject,
577  NULL);
578  if (!NT_SUCCESS(Status)) return Status;
579 
580  if (PreviousMode != KernelMode)
581  {
582  _SEH2_TRY
583  {
585  ProbeForWrite(KeyValueInformation,
586  Length,
587  sizeof(ULONG));
588  }
590  {
591  /* Dereference and return status */
592  ObDereferenceObject(KeyObject);
594  }
595  _SEH2_END;
596  }
597 
598  /* Setup the callback */
599  PostOperationInfo.Object = (PVOID)KeyObject;
600  EnumerateValueKeyInfo.Object = (PVOID)KeyObject;
601  EnumerateValueKeyInfo.Index = Index;
602  EnumerateValueKeyInfo.KeyValueInformationClass = KeyValueInformationClass;
603  EnumerateValueKeyInfo.KeyValueInformation = KeyValueInformation;
604  EnumerateValueKeyInfo.Length = Length;
605  EnumerateValueKeyInfo.ResultLength = ResultLength;
606 
607  /* Do the callback */
609  &EnumerateValueKeyInfo);
610  if (NT_SUCCESS(Status))
611  {
612  /* Call the internal API */
613  Status = CmEnumerateValueKey(KeyObject->KeyControlBlock,
614  Index,
616  KeyValueInformation,
617  Length,
618  ResultLength);
619 
620  /* Do the post callback */
621  PostOperationInfo.Status = Status;
623  }
624 
625  /* Dereference and return status */
626  ObDereferenceObject(KeyObject);
627  return Status;
628 }
629 
630 NTSTATUS
631 NTAPI
634  OUT PVOID KeyInformation,
635  IN ULONG Length,
637 {
640  PCM_KEY_BODY KeyObject;
641  REG_QUERY_KEY_INFORMATION QueryKeyInfo;
642  REG_POST_OPERATION_INFORMATION PostOperationInfo;
643  OBJECT_HANDLE_INFORMATION HandleInfo;
644  PAGED_CODE();
645  DPRINT("NtQueryKey() KH 0x%p, KIC %d, Length %lu\n",
647 
648  /* Reject invalid classes */
655  {
656  /* Fail */
658  }
659 
660  /* Check if just the name is required */
662  {
663  /* Ignore access level */
665  0,
667  PreviousMode,
668  (PVOID*)&KeyObject,
669  &HandleInfo);
670  if (NT_SUCCESS(Status))
671  {
672  /* At least a single bit of access is required */
673  if (!HandleInfo.GrantedAccess)
674  {
675  /* No such luck */
676  ObDereferenceObject(KeyObject);
678  }
679  }
680  }
681  else
682  {
683  /* Get a reference */
687  PreviousMode,
688  (PVOID*)&KeyObject,
689  NULL);
690  }
691 
692  /* Quit on failure */
693  if (!NT_SUCCESS(Status)) return Status;
694 
695  if (PreviousMode != KernelMode)
696  {
697  _SEH2_TRY
698  {
700  ProbeForWrite(KeyInformation,
701  Length,
702  sizeof(ULONG));
703  }
705  {
706  /* Dereference and return status */
707  ObDereferenceObject(KeyObject);
709  }
710  _SEH2_END;
711  }
712 
713  /* Setup the callback */
714  PostOperationInfo.Object = (PVOID)KeyObject;
715  QueryKeyInfo.Object = (PVOID)KeyObject;
717  QueryKeyInfo.KeyInformation = KeyInformation;
718  QueryKeyInfo.Length = Length;
719  QueryKeyInfo.ResultLength = ResultLength;
720 
721  /* Do the callback */
723  if (NT_SUCCESS(Status))
724  {
725  /* Call the internal API */
726  Status = CmQueryKey(KeyObject->KeyControlBlock,
728  KeyInformation,
729  Length,
730  ResultLength);
731 
732  /* Do the post callback */
733  PostOperationInfo.Status = Status;
734  CmiCallRegisteredCallbacks(RegNtPostQueryKey, &PostOperationInfo);
735  }
736 
737  /* Dereference and return status */
738  ObDereferenceObject(KeyObject);
739  return Status;
740 }
741 
742 NTSTATUS
743 NTAPI
747  OUT PVOID KeyValueInformation,
748  IN ULONG Length,
750 {
753  PCM_KEY_BODY KeyObject;
754  REG_QUERY_VALUE_KEY_INFORMATION QueryValueKeyInfo;
755  REG_POST_OPERATION_INFORMATION PostOperationInfo;
756  UNICODE_STRING ValueNameCopy;
757 
758  PAGED_CODE();
759 
760  DPRINT("NtQueryValueKey() KH 0x%p, VN '%wZ', KVIC %d, Length %lu\n",
762 
763  /* Reject classes we don't know about */
769  {
770  /* Fail */
772  }
773 
774  /* Verify that the handle is valid and is a registry key */
778  PreviousMode,
779  (PVOID*)&KeyObject,
780  NULL);
781  if (!NT_SUCCESS(Status))
782  return Status;
783 
784  if (PreviousMode != KernelMode)
785  {
786  _SEH2_TRY
787  {
789  ProbeForWrite(KeyValueInformation,
790  Length,
791  sizeof(ULONG));
792  }
794  {
795  /* Dereference and return status */
796  ObDereferenceObject(KeyObject);
798  }
799  _SEH2_END;
800  }
801 
802  /* Capture the string */
804  if (!NT_SUCCESS(Status))
805  goto Quit;
806 
807  /* Make sure the name is aligned properly */
808  if ((ValueNameCopy.Length & (sizeof(WCHAR) - 1)))
809  {
810  /* It isn't, so we'll fail */
812  goto Quit;
813  }
814 
815  /* Ignore any null characters at the end */
816  while ((ValueNameCopy.Length) &&
817  !(ValueNameCopy.Buffer[ValueNameCopy.Length / sizeof(WCHAR) - 1]))
818  {
819  /* Skip it */
820  ValueNameCopy.Length -= sizeof(WCHAR);
821  }
822 
823  /* Setup the callback */
824  PostOperationInfo.Object = (PVOID)KeyObject;
825  QueryValueKeyInfo.Object = (PVOID)KeyObject;
826  QueryValueKeyInfo.ValueName = &ValueNameCopy;
828  QueryValueKeyInfo.Length = Length;
829  QueryValueKeyInfo.ResultLength = ResultLength;
830 
831  /* Do the callback */
833  if (NT_SUCCESS(Status))
834  {
835  /* Call the internal API */
836  Status = CmQueryValueKey(KeyObject->KeyControlBlock,
837  ValueNameCopy,
839  KeyValueInformation,
840  Length,
841  ResultLength);
842 
843  /* Do the post callback */
844  PostOperationInfo.Status = Status;
846  }
847 
848 Quit:
849  if (ValueNameCopy.Buffer)
851 
852  /* Dereference and return status */
853  ObDereferenceObject(KeyObject);
854  return Status;
855 }
856 
857 NTSTATUS
858 NTAPI
862  IN ULONG Type,
863  IN PVOID Data,
864  IN ULONG DataSize)
865 {
868  PCM_KEY_BODY KeyObject;
869  REG_SET_VALUE_KEY_INFORMATION SetValueKeyInfo;
870  REG_POST_OPERATION_INFORMATION PostOperationInfo;
871  UNICODE_STRING ValueNameCopy;
872 
873  PAGED_CODE();
874 
876 
877  /* Verify that the handle is valid and is a registry key */
881  PreviousMode,
882  (PVOID*)&KeyObject,
883  NULL);
884  if (!NT_SUCCESS(Status))
885  return Status;
886 
887  if (!DataSize)
888  Data = NULL;
889 
890  /* Probe and copy the data */
891  if ((PreviousMode != KernelMode) && (DataSize != 0))
892  {
894  if (!DataCopy)
895  {
896  /* Dereference and return status */
897  ObDereferenceObject(KeyObject);
899  }
900  _SEH2_TRY
901  {
903  RtlCopyMemory(DataCopy, Data, DataSize);
904  }
906  {
908  }
909  _SEH2_END;
910 
911  if (!NT_SUCCESS(Status))
912  {
913  /* Dereference and return status */
914  ExFreePoolWithTag(DataCopy, TAG_CM);
915  ObDereferenceObject(KeyObject);
916  return Status;
917  }
918  Data = DataCopy;
919  }
920 
921  /* Capture the string */
923  if (!NT_SUCCESS(Status))
924  goto Quit;
925 
926  DPRINT("NtSetValueKey() KH 0x%p, VN '%wZ', TI %x, T %lu, DS %lu\n",
927  KeyHandle, &ValueNameCopy, TitleIndex, Type, DataSize);
928 
929  /* Make sure the name is aligned, not too long, and the data under 4GB */
930  if ( (ValueNameCopy.Length > 32767) ||
931  ((ValueNameCopy.Length & (sizeof(WCHAR) - 1))) ||
932  (DataSize > 0x80000000))
933  {
934  /* Fail */
936  goto Quit;
937  }
938 
939  /* Ignore any null characters at the end */
940  while ((ValueNameCopy.Length) &&
941  !(ValueNameCopy.Buffer[ValueNameCopy.Length / sizeof(WCHAR) - 1]))
942  {
943  /* Skip it */
944  ValueNameCopy.Length -= sizeof(WCHAR);
945  }
946 
947  /* Don't touch read-only keys */
948  if (KeyObject->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY)
949  {
950  /* Fail */
952  goto Quit;
953  }
954 
955  /* Setup callback */
956  PostOperationInfo.Object = (PVOID)KeyObject;
957  SetValueKeyInfo.Object = (PVOID)KeyObject;
958  SetValueKeyInfo.ValueName = &ValueNameCopy;
959  SetValueKeyInfo.TitleIndex = TitleIndex;
960  SetValueKeyInfo.Type = Type;
961  SetValueKeyInfo.Data = Data;
962  SetValueKeyInfo.DataSize = DataSize;
963 
964  /* Do the callback */
966  if (NT_SUCCESS(Status))
967  {
968  /* Call the internal API */
969  Status = CmSetValueKey(KeyObject->KeyControlBlock,
970  &ValueNameCopy,
971  Type,
972  Data,
973  DataSize);
974 
975  /* Do the post-callback */
976  PostOperationInfo.Status = Status;
978  }
979 
980 Quit:
981  if (ValueNameCopy.Buffer)
983 
984  if ((PreviousMode != KernelMode) && Data)
986 
987  /* Dereference and return status */
988  ObDereferenceObject(KeyObject);
989  return Status;
990 }
991 
992 NTSTATUS
993 NTAPI
996 {
998  PCM_KEY_BODY KeyObject;
999  REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo;
1000  REG_POST_OPERATION_INFORMATION PostOperationInfo;
1002  UNICODE_STRING ValueNameCopy;
1003 
1004  PAGED_CODE();
1005 
1006  /* Verify that the handle is valid and is a registry key */
1008  KEY_SET_VALUE,
1010  PreviousMode,
1011  (PVOID*)&KeyObject,
1012  NULL);
1013  if (!NT_SUCCESS(Status))
1014  return Status;
1015 
1016  /* Capture the string */
1018  if (!NT_SUCCESS(Status))
1019  goto Quit;
1020 
1021  /* Make sure the name is aligned properly */
1022  if ((ValueNameCopy.Length & (sizeof(WCHAR) - 1)))
1023  {
1024  /* It isn't, so we'll fail */
1026  goto Quit;
1027  }
1028 
1029  /* Don't touch read-only keys */
1030  if (KeyObject->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY)
1031  {
1032  /* Fail */
1034  goto Quit;
1035  }
1036 
1037  /* Do the callback */
1038  DeleteValueKeyInfo.Object = (PVOID)KeyObject;
1039  DeleteValueKeyInfo.ValueName = ValueName;
1041  &DeleteValueKeyInfo);
1042  if (NT_SUCCESS(Status))
1043  {
1044  /* Call the internal API */
1045  Status = CmDeleteValueKey(KeyObject->KeyControlBlock, ValueNameCopy);
1046 
1047  /* Do the post callback */
1048  PostOperationInfo.Object = (PVOID)KeyObject;
1049  PostOperationInfo.Status = Status;
1051  &PostOperationInfo);
1052  }
1053 
1054 Quit:
1055  if (ValueNameCopy.Buffer)
1056  ReleaseCapturedUnicodeString(&ValueNameCopy, PreviousMode);
1057 
1058  /* Dereference and return status */
1059  ObDereferenceObject(KeyObject);
1060  return Status;
1061 }
1062 
1063 NTSTATUS
1064 NTAPI
1066 {
1067  NTSTATUS Status;
1068  PCM_KEY_BODY KeyObject;
1069  PAGED_CODE();
1070 
1071  /* Get the key object */
1073  0,
1076  (PVOID*)&KeyObject,
1077  NULL);
1078  if (!NT_SUCCESS(Status)) return Status;
1079 
1080  /* Lock the registry */
1081  CmpLockRegistry();
1082 
1083  /* Lock the KCB */
1084  CmpAcquireKcbLockShared(KeyObject->KeyControlBlock);
1085 
1086  /* Make sure KCB isn't deleted */
1087  if (KeyObject->KeyControlBlock->Delete)
1088  {
1089  /* Fail */
1091  }
1092  else
1093  {
1094  /* Call the internal API */
1095  Status = CmFlushKey(KeyObject->KeyControlBlock, FALSE);
1096  }
1097 
1098  /* Release the locks */
1099  CmpReleaseKcbLock(KeyObject->KeyControlBlock);
1101 
1102  /* Dereference the object and return status */
1103  ObDereferenceObject(KeyObject);
1104  return Status;
1105 }
1106 
1107 NTSTATUS
1108 NTAPI
1109 NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
1110  IN POBJECT_ATTRIBUTES FileObjectAttributes)
1111 {
1112  /* Call the newer API */
1113  return NtLoadKeyEx(KeyObjectAttributes, FileObjectAttributes, 0, NULL);
1114 }
1115 
1116 NTSTATUS
1117 NTAPI
1118 NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
1119  IN POBJECT_ATTRIBUTES FileObjectAttributes,
1120  IN ULONG Flags)
1121 {
1122  /* Call the newer API */
1123  return NtLoadKeyEx(KeyObjectAttributes, FileObjectAttributes, Flags, NULL);
1124 }
1125 
1126 NTSTATUS
1127 NTAPI
1129  IN POBJECT_ATTRIBUTES SourceFile,
1130  IN ULONG Flags,
1131  IN HANDLE TrustClassKey)
1132 {
1133  NTSTATUS Status;
1135  OBJECT_ATTRIBUTES CapturedTargetKey;
1136  OBJECT_ATTRIBUTES CapturedSourceFile;
1137  UNICODE_STRING TargetKeyName, SourceFileName;
1138  HANDLE KmTargetKeyRootDir = NULL, KmSourceFileRootDir = NULL;
1139  PCM_KEY_BODY KeyBody = NULL;
1140 
1141  PAGED_CODE();
1142 
1143  /* Validate flags */
1144  if (Flags & ~REG_NO_LAZY_FLUSH)
1145  return STATUS_INVALID_PARAMETER;
1146 
1147  /* Validate privilege */
1149  {
1150  DPRINT1("Restore Privilege missing!\n");
1152  }
1153 
1154  /* Block APCs */
1156 
1157  /* Check for user-mode caller */
1158  if (PreviousMode != KernelMode)
1159  {
1160  /* Prepare to probe parameters */
1161  _SEH2_TRY
1162  {
1163  /* Probe target key */
1164  ProbeForRead(TargetKey,
1165  sizeof(OBJECT_ATTRIBUTES),
1166  sizeof(ULONG));
1167 
1168  /* Probe source file */
1169  ProbeForRead(SourceFile,
1170  sizeof(OBJECT_ATTRIBUTES),
1171  sizeof(ULONG));
1172  }
1174  {
1175  /* Return the exception code */
1177  _SEH2_YIELD(goto Quit);
1178  }
1179  _SEH2_END;
1180  }
1181 
1182  /* Probe and capture the target key attributes, including the security */
1183  Status = ProbeAndCaptureObjectAttributes(&CapturedTargetKey,
1184  &TargetKeyName,
1185  PreviousMode,
1186  TargetKey,
1187  TRUE);
1188  if (!NT_SUCCESS(Status))
1189  goto Quit;
1190 
1191  /*
1192  * Probe and capture the source file attributes, but not the security.
1193  * A proper security context is built by CmLoadKey().
1194  */
1195  Status = ProbeAndCaptureObjectAttributes(&CapturedSourceFile,
1196  &SourceFileName,
1197  PreviousMode,
1198  SourceFile,
1199  FALSE);
1200  if (!NT_SUCCESS(Status))
1201  {
1202  ReleaseCapturedObjectAttributes(&CapturedTargetKey, PreviousMode);
1203  goto Quit;
1204  }
1205 
1206  /* Make sure the target key root directory handle is a kernel handle */
1209  KEY_READ,
1210  PreviousMode,
1211  &KmTargetKeyRootDir);
1212  if (!NT_SUCCESS(Status))
1213  goto Cleanup;
1214  CapturedTargetKey.RootDirectory = KmTargetKeyRootDir;
1215  CapturedTargetKey.Attributes |= OBJ_KERNEL_HANDLE;
1216 
1217  /* Make sure the source file root directory handle is a kernel handle */
1220  FILE_TRAVERSE,
1221  PreviousMode,
1222  &KmSourceFileRootDir);
1223  if (!NT_SUCCESS(Status))
1224  goto Cleanup;
1225  CapturedSourceFile.RootDirectory = KmSourceFileRootDir;
1226  CapturedSourceFile.Attributes |= OBJ_KERNEL_HANDLE;
1227 
1228  /* Check if we have a trust class */
1229  if (TrustClassKey)
1230  {
1231  /* Reference it */
1232  Status = ObReferenceObjectByHandle(TrustClassKey,
1233  0,
1235  PreviousMode,
1236  (PVOID*)&KeyBody,
1237  NULL);
1238  }
1239 
1240  /* Call the internal API */
1241  Status = CmLoadKey(&CapturedTargetKey,
1242  &CapturedSourceFile,
1243  Flags,
1244  KeyBody);
1245 
1246  /* Dereference the trust key, if any */
1247  if (KeyBody) ObDereferenceObject(KeyBody);
1248 
1249 Cleanup:
1250  /* Close the local kernel handles */
1251  if (KmSourceFileRootDir)
1252  ObCloseHandle(KmSourceFileRootDir, KernelMode);
1253  if (KmTargetKeyRootDir)
1254  ObCloseHandle(KmTargetKeyRootDir, KernelMode);
1255 
1256  /* Release the captured object attributes */
1257  ReleaseCapturedObjectAttributes(&CapturedSourceFile, PreviousMode);
1258  ReleaseCapturedObjectAttributes(&CapturedTargetKey, PreviousMode);
1259 
1260 Quit:
1261  /* Bring back APCs */
1263 
1264  /* Return status */
1265  return Status;
1266 }
1267 
1268 NTSTATUS
1269 NTAPI
1271  IN HANDLE Event,
1277  OUT PVOID Buffer,
1278  IN ULONG Length,
1280 {
1281  /* Call the newer API */
1283  0,
1284  NULL,
1285  Event,
1286  ApcRoutine,
1287  ApcContext,
1288  IoStatusBlock,
1290  WatchTree,
1291  Buffer,
1292  Length,
1293  Asynchronous);
1294 }
1295 
1296 NTSTATUS
1297 NTAPI
1299 {
1300  BOOLEAN SetupBoot;
1302  PAGED_CODE();
1303 
1304  /* Always do this as kernel mode */
1305  if (KeGetPreviousMode() == UserMode)
1306  return ZwInitializeRegistry(Flag);
1307 
1308  /* Enough of the system has booted by now */
1309  Ki386PerfEnd();
1310 
1311  /* Validate flag */
1313 
1314  /* Check if boot was accepted */
1316  {
1317  /* Only allow once */
1320 
1321  /* Get the control set accepted */
1323  if (Flag)
1324  {
1325  /* Save the last known good boot */
1327 
1328  /* Notify HAL */
1329  HalEndOfBoot();
1330 
1331  /* Enable lazy flush */
1333  CmpLazyFlush();
1334  return Status;
1335  }
1336 
1337  /* Otherwise, invalid boot */
1338  return STATUS_INVALID_PARAMETER;
1339  }
1340 
1341  /* Check if this was a setup boot */
1342  SetupBoot = (Flag == CM_BOOT_FLAG_SETUP ? TRUE : FALSE);
1343 
1344  /* Make sure we're only called once */
1345  if (!CmFirstTime) return STATUS_ACCESS_DENIED;
1346  CmFirstTime = FALSE;
1347 
1348  /* Lock the registry exclusively */
1350 
1351  /* Initialize the hives and lazy flusher */
1352  CmpCmdInit(SetupBoot);
1353 
1354  /* Save version data */
1356 
1357  /* Release the registry lock */
1359  return STATUS_SUCCESS;
1360 }
1361 
1362 NTSTATUS
1363 NTAPI
1365  IN PHANDLE KeyArray)
1366 {
1367  UNIMPLEMENTED;
1368  return STATUS_NOT_IMPLEMENTED;
1369 }
1370 
1371 NTSTATUS
1372 NTAPI
1374 {
1375  UNIMPLEMENTED;
1376  return STATUS_NOT_IMPLEMENTED;
1377 }
1378 
1379 // FIXME: different for different windows versions!
1380 #define PRODUCT_ACTIVATION_VERSION 7749
1381 
1382 NTSTATUS
1383 NTAPI
1385  IN PULONG pSafeMode)
1386 {
1388 
1390  _SEH2_TRY
1391  {
1392  /* Check if the caller asked for the version */
1393  if (pPrivateVer != NULL)
1394  {
1395  /* For user mode, probe it */
1396  if (PreviousMode != KernelMode)
1397  {
1398  ProbeForRead(pPrivateVer, sizeof(ULONG), sizeof(ULONG));
1399  }
1400 
1401  /* Return the expected version */
1402  *pPrivateVer = PRODUCT_ACTIVATION_VERSION;
1403  }
1404 
1405  /* Check if the caller asked for safe mode mode state */
1406  if (pSafeMode != NULL)
1407  {
1408  /* For user mode, probe it */
1409  if (PreviousMode != KernelMode)
1410  {
1411  ProbeForRead(pSafeMode, sizeof(ULONG), sizeof(ULONG));
1412  }
1413 
1414  /* Return the safe boot mode state */
1415  *pSafeMode = InitSafeBootMode;
1416  }
1417  }
1419  {
1421  }
1422  _SEH2_END;
1423 
1424  return STATUS_SUCCESS;
1425 }
1426 
1427 NTSTATUS
1428 NTAPI
1430 {
1431  UNIMPLEMENTED;
1432  return STATUS_NOT_IMPLEMENTED;
1433 }
1434 
1435 NTSTATUS
1436 NTAPI
1438  IN ULONG Count,
1439  IN POBJECT_ATTRIBUTES SlaveObjects,
1440  IN HANDLE Event,
1446  OUT PVOID Buffer,
1447  IN ULONG Length,
1449 {
1451  return STATUS_NOT_IMPLEMENTED;
1452 }
1453 
1454 NTSTATUS
1455 NTAPI
1457  IN OUT PKEY_VALUE_ENTRY ValueList,
1458  IN ULONG NumberOfValues,
1459  OUT PVOID Buffer,
1460  IN OUT PULONG Length,
1462 {
1463  UNIMPLEMENTED;
1464  return STATUS_NOT_IMPLEMENTED;
1465 }
1466 
1467 NTSTATUS
1468 NTAPI
1470  OUT PULONG HandleCount)
1471 {
1473  PCM_KEY_BODY KeyBody = NULL;
1474  HANDLE KeyHandle;
1475  NTSTATUS Status;
1476 
1477  DPRINT("NtQueryOpenSubKeys()\n");
1478 
1479  PAGED_CODE();
1480 
1481  /* Get the processor mode */
1483 
1484  /* Check for user-mode caller */
1485  if (PreviousMode != KernelMode)
1486  {
1487  /* Prepare to probe parameters */
1488  _SEH2_TRY
1489  {
1490  /* Probe target key */
1491  ProbeForRead(TargetKey,
1492  sizeof(OBJECT_ATTRIBUTES),
1493  sizeof(ULONG));
1494 
1495  /* Probe handle count */
1496  ProbeForWriteUlong(HandleCount);
1497  }
1499  {
1500  /* Return the exception code */
1502  }
1503  _SEH2_END;
1504  }
1505 
1506  /* Open a handle to the key */
1507  Status = ObOpenObjectByName(TargetKey,
1509  PreviousMode,
1510  NULL,
1511  KEY_READ,
1512  NULL,
1513  &KeyHandle);
1514  if (NT_SUCCESS(Status))
1515  {
1516  /* Reference the key object */
1518  KEY_READ,
1520  PreviousMode,
1521  (PVOID*)&KeyBody,
1522  NULL);
1523 
1524  /* Close the handle */
1525  NtClose(KeyHandle);
1526  }
1527 
1528  /* Fail, if the key object could not be referenced */
1529  if (!NT_SUCCESS(Status))
1530  return Status;
1531 
1532  /* Lock the registry exclusively */
1534 
1535  /* Fail, if we did not open a hive root key */
1536  if (KeyBody->KeyControlBlock->KeyCell !=
1537  KeyBody->KeyControlBlock->KeyHive->BaseBlock->RootCell)
1538  {
1539  DPRINT("Error: Key is not a hive root key!\n");
1541  ObDereferenceObject(KeyBody);
1542  return STATUS_INVALID_PARAMETER;
1543  }
1544 
1545  /* Call the internal API */
1546  *HandleCount = CmpEnumerateOpenSubKeys(KeyBody->KeyControlBlock,
1547  FALSE, FALSE);
1548 
1549  /* Unlock the registry */
1551 
1552  /* Dereference the key object */
1553  ObDereferenceObject(KeyBody);
1554 
1555  DPRINT("Done.\n");
1556 
1557  return Status;
1558 }
1559 
1560 NTSTATUS
1561 NTAPI
1564  IN PVOID Buffer,
1566 {
1567  UNIMPLEMENTED;
1568  return STATUS_NOT_IMPLEMENTED;
1569 }
1570 
1571 NTSTATUS
1572 NTAPI
1574  IN PUNICODE_STRING ReplacementName)
1575 {
1576  UNIMPLEMENTED;
1577  return STATUS_NOT_IMPLEMENTED;
1578 }
1579 
1580 NTSTATUS
1581 NTAPI
1583  IN HANDLE Key,
1584  IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
1585 {
1586  UNIMPLEMENTED;
1587  return STATUS_NOT_IMPLEMENTED;
1588 }
1589 
1590 NTSTATUS
1591 NTAPI
1594  IN ULONG RestoreFlags)
1595 {
1596  UNIMPLEMENTED;
1597  return STATUS_NOT_IMPLEMENTED;
1598 }
1599 
1600 NTSTATUS
1601 NTAPI
1604 {
1605  /* Call the extended API */
1607 }
1608 
1609 NTSTATUS
1610 NTAPI
1613  IN ULONG Flags)
1614 {
1615  NTSTATUS Status;
1616  HANDLE KmFileHandle = NULL;
1617  PCM_KEY_BODY KeyObject;
1619 
1620  PAGED_CODE();
1621 
1622  DPRINT("NtSaveKeyEx(0x%p, 0x%p, %lu)\n", KeyHandle, FileHandle, Flags);
1623 
1624  /* Verify the flags */
1625  if ((Flags != REG_STANDARD_FORMAT)
1626  && (Flags != REG_LATEST_FORMAT)
1627  && (Flags != REG_NO_COMPRESSION))
1628  {
1629  /* Only one of these values can be specified */
1630  return STATUS_INVALID_PARAMETER;
1631  }
1632 
1633  /* Validate privilege */
1635  {
1637  }
1638 
1639  /* Make sure the target file handle is a kernel handle */
1643  PreviousMode,
1644  &KmFileHandle);
1645  if (!NT_SUCCESS(Status))
1646  goto Quit;
1647 
1648  /* Verify that the handle is valid and is a registry key */
1650  KEY_READ,
1652  PreviousMode,
1653  (PVOID*)&KeyObject,
1654  NULL);
1655  if (!NT_SUCCESS(Status))
1656  goto Quit;
1657 
1658  /* Call the internal API */
1659  Status = CmSaveKey(KeyObject->KeyControlBlock, KmFileHandle, Flags);
1660 
1661  /* Dereference the registry key */
1662  ObDereferenceObject(KeyObject);
1663 
1664 Quit:
1665  /* Close the local kernel handle */
1666  if (KmFileHandle)
1667  ObCloseHandle(KmFileHandle, KernelMode);
1668 
1669  return Status;
1670 }
1671 
1672 NTSTATUS
1673 NTAPI
1674 NtSaveMergedKeys(IN HANDLE HighPrecedenceKeyHandle,
1675  IN HANDLE LowPrecedenceKeyHandle,
1677 {
1678  NTSTATUS Status;
1680  HANDLE KmFileHandle = NULL;
1681  PCM_KEY_BODY HighPrecedenceKeyObject = NULL;
1682  PCM_KEY_BODY LowPrecedenceKeyObject = NULL;
1683 
1684  PAGED_CODE();
1685 
1686  DPRINT("NtSaveMergedKeys(0x%p, 0x%p, 0x%p)\n",
1687  HighPrecedenceKeyHandle, LowPrecedenceKeyHandle, FileHandle);
1688 
1690 
1691  /* Validate privilege */
1693  {
1695  }
1696 
1697  /* Make sure the target file handle is a kernel handle */
1701  PreviousMode,
1702  &KmFileHandle);
1703  if (!NT_SUCCESS(Status))
1704  goto Quit;
1705 
1706  /* Verify that the handles are valid and are registry keys */
1707  Status = ObReferenceObjectByHandle(HighPrecedenceKeyHandle,
1708  KEY_READ,
1710  PreviousMode,
1711  (PVOID*)&HighPrecedenceKeyObject,
1712  NULL);
1713  if (!NT_SUCCESS(Status))
1714  goto Quit;
1715 
1716  Status = ObReferenceObjectByHandle(LowPrecedenceKeyHandle,
1717  KEY_READ,
1719  PreviousMode,
1720  (PVOID*)&LowPrecedenceKeyObject,
1721  NULL);
1722  if (!NT_SUCCESS(Status))
1723  goto Quit;
1724 
1725  /* Call the internal API */
1726  Status = CmSaveMergedKeys(HighPrecedenceKeyObject->KeyControlBlock,
1727  LowPrecedenceKeyObject->KeyControlBlock,
1728  KmFileHandle);
1729 
1730 Quit:
1731  /* Dereference the opened key objects */
1732  if (LowPrecedenceKeyObject)
1733  ObDereferenceObject(LowPrecedenceKeyObject);
1734  if (HighPrecedenceKeyObject)
1735  ObDereferenceObject(HighPrecedenceKeyObject);
1736 
1737  /* Close the local kernel handle */
1738  if (KmFileHandle)
1739  ObCloseHandle(KmFileHandle, KernelMode);
1740 
1741  return Status;
1742 }
1743 
1744 NTSTATUS
1745 NTAPI
1748  IN PVOID KeyInformation,
1749  IN ULONG KeyInformationLength)
1750 {
1751  UNIMPLEMENTED;
1752  return STATUS_NOT_IMPLEMENTED;
1753 }
1754 
1755 NTSTATUS
1756 NTAPI
1757 NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
1758 {
1759  return NtUnloadKey2(KeyObjectAttributes, 0);
1760 }
1761 
1762 NTSTATUS
1763 NTAPI
1765  IN ULONG Flags)
1766 {
1767  NTSTATUS Status;
1768  OBJECT_ATTRIBUTES CapturedTargetKey;
1770  HANDLE KmTargetKeyRootDir = NULL;
1771  CM_PARSE_CONTEXT ParseContext = {0};
1773  PCM_KEY_BODY KeyBody = NULL;
1774  ULONG ParentConv = 0, ChildConv = 0;
1775  HANDLE Handle;
1776 
1777  PAGED_CODE();
1778 
1779  /* Validate privilege */
1781  {
1782  DPRINT1("Restore Privilege missing!\n");
1784  }
1785 
1786  /* Check for user-mode caller */
1787  if (PreviousMode != KernelMode)
1788  {
1789  /* Prepare to probe parameters */
1790  _SEH2_TRY
1791  {
1792  /* Probe object attributes */
1793  ProbeForRead(TargetKey,
1794  sizeof(OBJECT_ATTRIBUTES),
1795  sizeof(ULONG));
1796 
1797  CapturedTargetKey = *TargetKey;
1798 
1799  /* Probe the string */
1800  ObjectName = ProbeForReadUnicodeString(CapturedTargetKey.ObjectName);
1801  ProbeForRead(ObjectName.Buffer,
1802  ObjectName.Length,
1803  sizeof(WCHAR));
1804 
1805  CapturedTargetKey.ObjectName = &ObjectName;
1806  }
1808  {
1809  /* Return the exception code */
1811  }
1812  _SEH2_END;
1813  }
1814  else
1815  {
1816  /* Save the target attributes directly */
1817  CapturedTargetKey = *TargetKey;
1818  }
1819 
1820  /* Make sure the target key root directory handle is a kernel handle */
1823  KEY_WRITE,
1824  PreviousMode,
1825  &KmTargetKeyRootDir);
1826  if (!NT_SUCCESS(Status))
1827  return Status;
1828  CapturedTargetKey.RootDirectory = KmTargetKeyRootDir;
1829  CapturedTargetKey.Attributes |= OBJ_KERNEL_HANDLE;
1830 
1831  /* Setup the parse context */
1832  ParseContext.CreateOperation = TRUE;
1834 
1835  /* Do the create */
1836  /* Open a local handle to the key */
1837  Status = ObOpenObjectByName(&CapturedTargetKey,
1839  KernelMode,
1840  NULL,
1841  KEY_WRITE,
1842  &ParseContext,
1843  &Handle);
1844  if (NT_SUCCESS(Status))
1845  {
1846  /* Reference the key object */
1848  KEY_WRITE,
1850  KernelMode,
1851  (PVOID*)&KeyBody,
1852  NULL);
1853 
1854  /* Close the handle */
1856  }
1857 
1858  /* Close the local kernel handle */
1859  if (KmTargetKeyRootDir)
1860  ObCloseHandle(KmTargetKeyRootDir, KernelMode);
1861 
1862  /* Return if a failure was encountered */
1863  if (!NT_SUCCESS(Status))
1864  return Status;
1865 
1866  /* Acquire the lock depending on flags */
1867  if (Flags == REG_FORCE_UNLOAD)
1868  {
1869  /* Lock registry exclusively */
1871  }
1872  else
1873  {
1874  /* Lock registry */
1875  CmpLockRegistry();
1876 
1877  /* Acquire the hive loading lock */
1879 
1880  /* Lock parent and child */
1881  if (KeyBody->KeyControlBlock->ParentKcb)
1882  ParentConv = KeyBody->KeyControlBlock->ParentKcb->ConvKey;
1883  else
1884  ParentConv = KeyBody->KeyControlBlock->ConvKey;
1885 
1886  ChildConv = KeyBody->KeyControlBlock->ConvKey;
1887 
1888  CmpAcquireTwoKcbLocksExclusiveByKey(ChildConv, ParentConv);
1889  }
1890 
1891  /* Check if it's being deleted already */
1892  if (KeyBody->KeyControlBlock->Delete)
1893  {
1894  /* Return appropriate status */
1896  goto Quit;
1897  }
1898 
1899  /* Check if it's a read-only key */
1900  if (KeyBody->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY)
1901  {
1902  /* Return appropriate status */
1904  goto Quit;
1905  }
1906 
1907  /* Call the internal API. Note that CmUnloadKey() unlocks the registry only on success. */
1908  Status = CmUnloadKey(KeyBody->KeyControlBlock, Flags);
1909 
1910  /* Check if we failed, but really need to succeed */
1912  {
1913  /* TODO: We should perform another attempt here */
1914  _SEH2_TRY
1915  {
1916  DPRINT1("NtUnloadKey2(%wZ): We want to force-unload the hive but couldn't unload it: Retrying is UNIMPLEMENTED!\n", TargetKey->ObjectName);
1917  }
1919  {
1920  }
1921  _SEH2_END;
1922  }
1923 
1924  /* If CmUnloadKey() failed we need to unlock registry ourselves */
1925  if (!NT_SUCCESS(Status))
1926  {
1927  if (Flags != REG_FORCE_UNLOAD)
1928  {
1929  /* Release the KCB locks */
1930  CmpReleaseTwoKcbLockByKey(ChildConv, ParentConv);
1931 
1932  /* Release the hive loading lock */
1934  }
1935 
1936  /* Unlock the registry */
1938  }
1939 
1940 Quit:
1941  /* Dereference the key */
1942  ObDereferenceObject(KeyBody);
1943 
1944  /* Return status */
1945  return Status;
1946 }
1947 
1948 NTSTATUS
1949 NTAPI
1951  IN HANDLE Event)
1952 {
1953  UNIMPLEMENTED;
1954  return STATUS_NOT_IMPLEMENTED;
1955 }
1956 
1957 /* EOF */
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2529
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
static const WCHAR Class[]
Definition: cfgmgr.c:31
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define UNIMPLEMENTED_ONCE
Definition: debug.h:138
NTSTATUS NTAPI NtCompressKey(IN HANDLE Key)
Definition: ntapi.c:1373
ObjectType
Definition: metafile.c:80
#define PRODUCT_ACTIVATION_VERSION
Definition: ntapi.c:1380
KEY_INFORMATION_CLASS KeyInformationClass
Definition: cmtypes.h:765
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1022
#define IN
Definition: typedefs.h:38
Definition: cmtypes.h:856
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:719
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
NTSTATUS NTAPI NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey, IN ULONG Flags)
Definition: ntapi.c:1764
NTSTATUS NTAPI CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey, IN POBJECT_ATTRIBUTES SourceFile, IN ULONG Flags, IN PCM_KEY_BODY KeyBody)
Definition: cmapi.c:2004
NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:744
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN ExclusiveLock)
Definition: cmapi.c:1938
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG TitleIndex
Definition: reg.c:130
#define REG_STANDARD_FORMAT
Definition: cmtypes.h:97
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
#define KEY_WOW64_RES
Definition: cmtypes.h:47
Type
Definition: Type.h:6
#define KEY_SET_VALUE
Definition: nt_native.h:1017
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_In_ ULONG _In_ KEY_INFORMATION_CLASS KeyInformationClass
Definition: zwfuncs.h:166
enum _KEY_INFORMATION_CLASS KEY_INFORMATION_CLASS
HANDLE KernelHandle
Definition: legacy.c:24
const LUID SeBackupPrivilege
Definition: priv.c:38
#define KEY_READ
Definition: nt_native.h:1023
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
Definition: cmapi.c:1192
NTSTATUS NTAPI CmSaveKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN HANDLE FileHandle, IN ULONG Flags)
Definition: cmapi.c:2637
ULONG NTAPI CmpEnumerateOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb, IN BOOLEAN RemoveEmptyCacheEntries, IN BOOLEAN DereferenceOpenedEntries)
Definition: cmapi.c:2327
#define CM_BOOT_FLAG_ACCEPTED
Definition: cmtypes.h:153
NTSTATUS NTAPI NtUnloadKeyEx(IN POBJECT_ATTRIBUTES TargetKey, IN HANDLE Event)
Definition: ntapi.c:1950
#define KeGetPreviousMode()
Definition: ketypes.h:1081
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN UNICODE_STRING ValueName)
Definition: cmapi.c:916
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN WatchTree
Definition: fltkernel.h:2239
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2982
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
BOOLEAN CmpHoldLazyFlush
Definition: cmlazy.c:24
#define CM_KCB_READ_ONLY_KEY
Definition: cm.h:61
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2739
NTSTATUS NTAPI NtSaveKey(IN HANDLE KeyHandle, IN HANDLE FileHandle)
Definition: ntapi.c:1602
NTSTATUS NTAPI NtRestoreKey(IN HANDLE KeyHandle, IN HANDLE FileHandle, IN ULONG RestoreFlags)
Definition: ntapi.c:1592
NTSTATUS NTAPI NtNotifyChangeMultipleKeys(IN HANDLE MasterKeyHandle, IN ULONG Count, IN POBJECT_ATTRIBUTES SlaveObjects, IN HANDLE Event, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG CompletionFilter, IN BOOLEAN WatchTree, OUT PVOID Buffer, IN ULONG Length, IN BOOLEAN Asynchronous)
Definition: ntapi.c:1437
NTSTATUS NTAPI NtQueryKey(IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:632
ULONG CreateOptions
Definition: cm.h:484
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:994
NTSTATUS NTAPI NtLockProductActivationKeys(IN PULONG pPrivateVer, IN PULONG pSafeMode)
Definition: ntapi.c:1384
VOID NTAPI CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2050
NTSTATUS NTAPI CmpSaveBootControlSet(IN USHORT ControlSet)
Definition: cmcontrl.c:268
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
VOID ReleaseCapturedObjectAttributes(_In_ POBJECT_ATTRIBUTES CapturedObjectAttributes, _In_ KPROCESSOR_MODE AccessMode)
Definition: ntapi.c:27
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define PAGED_CODE()
Definition: video.h:57
#define _In_opt_
Definition: no_sal2.h:213
NTSTATUS NTAPI SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, IN KPROCESSOR_MODE CurrentMode, IN BOOLEAN CaptureIfKernelMode)
Definition: sd.c:766
_SEH2_TRY
Definition: create.c:4250
#define FILE_TRAVERSE
Definition: nt_native.h:643
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
ULONG Disposition
Definition: cm.h:485
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS NTAPI NtLockRegistryKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1429
KEY_INFORMATION_CLASS KeyInformationClass
Definition: cmtypes.h:742
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
_In_ SYSTEM_POWER_STATE _In_ ULONG _In_ BOOLEAN Asynchronous
Definition: ntpoapi.h:303
ACCESS_MASK GrantedAccess
Definition: iotypes.h:158
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmtypes.h:777
NTSTATUS NTAPI NtSetInformationKey(IN HANDLE KeyHandle, IN KEY_SET_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG KeyInformationLength)
Definition: ntapi.c:1746
_In_ ULONG BufferLength
Definition: usbdlib.h:225
NTSTATUS NTAPI NtLoadKeyEx(IN POBJECT_ATTRIBUTES TargetKey, IN POBJECT_ATTRIBUTES SourceFile, IN ULONG Flags, IN HANDLE TrustClassKey)
Definition: ntapi.c:1128
NTSTATUS NTAPI NtInitializeRegistry(IN USHORT Flag)
Definition: ntapi.c:1298
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
enum _KEY_SET_INFORMATION_CLASS KEY_SET_INFORMATION_CLASS
NTSTATUS NTAPI NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes, IN ULONG Flags)
Definition: ntapi.c:1118
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1238
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSTATUS ProbeAndCaptureObjectAttributes(_Out_ POBJECT_ATTRIBUTES CapturedObjectAttributes, _Out_ PUNICODE_STRING ObjectName, _In_ KPROCESSOR_MODE AccessMode, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN CaptureSecurity)
Definition: ntapi.c:53
unsigned char BOOLEAN
NTSTATUS NTAPI NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey, OUT PULONG HandleCount)
Definition: ntapi.c:1469
smooth NULL
Definition: ftsmooth.c:416
#define _Out_
Definition: no_sal2.h:323
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI CmpLockRegistryExclusive(VOID)
Definition: cmsysini.c:1894
NTSTATUS NTAPI NtQueryMultipleValueKey(IN HANDLE KeyHandle, IN OUT PKEY_VALUE_ENTRY ValueList, IN ULONG NumberOfValues, OUT PVOID Buffer, IN OUT PULONG Length, OUT PULONG ReturnLength)
Definition: ntapi.c:1456
Definition: bufpool.h:45
#define HalEndOfBoot
Definition: haltypes.h:296
FORCEINLINE VOID Ki386PerfEnd(VOID)
Definition: ke.h:893
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
#define OBJ_VALID_KERNEL_ATTRIBUTES
Definition: obtypes.h:92
void * PVOID
Definition: retypes.h:9
NTSTATUS NTAPI CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PUNICODE_STRING ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataLength)
Definition: cmapi.c:644
#define FILE_WRITE_DATA
Definition: nt_native.h:631
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
struct _OBJECT_ATTRIBUTES OBJECT_ATTRIBUTES
static NTSTATUS CmpConvertHandleToKernelHandle(_In_ HANDLE SourceHandle, _In_opt_ POBJECT_TYPE ObjectType, _In_ ACCESS_MASK DesiredAccess, _In_ KPROCESSOR_MODE AccessMode, _Out_ PHANDLE KernelHandle)
Definition: ntapi.c:195
NTSTATUS NTAPI NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes)
Definition: ntapi.c:1109
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:229
NTSTATUS NTAPI NtReplaceKey(IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE Key, IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
Definition: ntapi.c:1582
#define KEY_WRITE
Definition: nt_native.h:1031
_In_ HANDLE Handle
Definition: extypes.h:390
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:228
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
NTSTATUS NTAPI NtNotifyChangeKey(IN HANDLE KeyHandle, IN HANDLE Event, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG CompletionFilter, IN BOOLEAN WatchTree, OUT PVOID Buffer, IN ULONG Length, IN BOOLEAN Asynchronous)
Definition: ntapi.c:1270
NTSTATUS Status
Definition: cmtypes.h:858
UNICODE_STRING Class
Definition: cm.h:483
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
const LUID SeRestorePrivilege
Definition: priv.c:39
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
Definition: xml2sdb.h:79
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS NTAPI CmQueryKey(_In_ PCM_KEY_CONTROL_BLOCK Kcb, _In_ KEY_INFORMATION_CLASS KeyInformationClass, _Out_opt_ PVOID KeyInformation, _In_ ULONG Length, _Out_ PULONG ResultLength)
Definition: cmapi.c:1615
NTSTATUS NTAPI NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
Definition: ntapi.c:1757
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
NTSTATUS NTAPI NtQueryOpenSubKeysEx(IN POBJECT_ATTRIBUTES TargetKey, IN ULONG BufferLength, IN PVOID Buffer, IN PULONG RequiredSize)
Definition: ntapi.c:1562
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define REG_OPTION_BACKUP_RESTORE
Definition: nt_native.h:1066
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI CmSaveMergedKeys(IN PCM_KEY_CONTROL_BLOCK HighKcb, IN PCM_KEY_CONTROL_BLOCK LowKcb, IN HANDLE FileHandle)
Definition: cmapi.c:2706
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
static IUnknown Object
Definition: main.c:512
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define CM_BOOT_FLAG_MAX
Definition: cmtypes.h:154
#define REG_NO_COMPRESSION
Definition: cmtypes.h:99
#define STATUS_CANNOT_DELETE
Definition: shellext.h:66
#define TAG_CM
Definition: cmlib.h:203
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
BOOLEAN CmFirstTime
Definition: ntapi.c:17
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
NTSYSAPI NTSTATUS NTAPI ZwInitializeRegistry(_In_ USHORT Flag)
#define REG_LATEST_FORMAT
Definition: cmtypes.h:98
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
NTSTATUS NTAPI NtEnumerateValueKey(IN HANDLE KeyHandle, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:542
#define REG_NO_LAZY_FLUSH
Definition: nt_native.h:1093
static const WCHAR Cleanup[]
Definition: register.c:80
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
EX_PUSH_LOCK CmpLoadHiveLock
Definition: cmdata.c:39
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Flags)
Definition: cmapi.c:2194
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
FORCEINLINE ULONG ObpValidateAttributes(IN ULONG Attributes, IN KPROCESSOR_MODE PreviousMode)
Definition: ob_x.h:22
#define _In_
Definition: no_sal2.h:204
#define REG_FORCE_UNLOAD
NTSTATUS NTAPI NtRenameKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ReplacementName)
Definition: ntapi.c:1573
NTSTATUS NTAPI CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN UNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
Definition: cmapi.c:1075
_SEH2_END
Definition: create.c:4424
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:351
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI NtSaveKeyEx(IN HANDLE KeyHandle, IN HANDLE FileHandle, IN ULONG Flags)
Definition: ntapi.c:1611
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1065
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
NTSTATUS NTAPI NtSaveMergedKeys(IN HANDLE HighPrecedenceKeyHandle, IN HANDLE LowPrecedenceKeyHandle, IN HANDLE FileHandle)
Definition: ntapi.c:1674
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
PUNICODE_STRING ValueName
Definition: cmtypes.h:711
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI NtCompactKeys(IN ULONG Count, IN PHANDLE KeyArray)
Definition: ntapi.c:1364
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG CompletionFilter
Definition: fltkernel.h:2239
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
ULONG InitSafeBootMode
Definition: init.c:68
Definition: nt_native.h:1172
PUNICODE_STRING ObjectName
Definition: umtypes.h:185
HANDLE RootDirectory
Definition: umtypes.h:184
unsigned int ULONG
Definition: retypes.h:1
KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmtypes.h:754
#define CmpKeyObjectType
Definition: ObTypes.c:132
BOOLEAN CmBootAcceptFirstTime
Definition: ntapi.c:16
NTSTATUS NTAPI NtEnumerateKey(IN HANDLE KeyHandle, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:457
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2)
Definition: cmhook.c:59
NTSTATUS NTAPI CmDeleteKey(IN PCM_KEY_BODY KeyBody)
Definition: cmapi.c:1824
VOID NTAPI CmpLazyFlush(VOID)
Definition: cmlazy.c:158
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
NTSTATUS NTAPI SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, IN KPROCESSOR_MODE CurrentMode, IN POOL_TYPE PoolType, IN BOOLEAN CaptureIfKernel, OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
Definition: sd.c:434
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID NTAPI CmpSetVersionData(VOID)
Definition: cmsysini.c:2116
NTSTATUS NTAPI CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG Length, IN PULONG ResultLength)
Definition: cmapi.c:1735
PVOID Object
Definition: cmtypes.h:857
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:93
#define CM_BOOT_FLAG_SETUP
Definition: cmtypes.h:152
return STATUS_SUCCESS
Definition: btrfs.c:2745
VOID NTAPI CmpCmdInit(IN BOOLEAN SetupBoot)
Definition: cmlazy.c:234
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
BOOLEAN CreateOperation
Definition: cm.h:489
ULONG ACCESS_MASK
Definition: nt_native.h:40
VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2021
NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
enum _KEY_VALUE_INFORMATION_CLASS KEY_VALUE_INFORMATION_CLASS
Definition: reg.c:135
#define DELETE
Definition: nt_native.h:57
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68