ReactOS  0.4.15-dev-321-g2d9b385
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  {
893  PVOID DataCopy = NULL;
894 
895  _SEH2_TRY
896  {
898  }
900  {
902  }
903  _SEH2_END;
904 
905  if (!NT_SUCCESS(Status))
906  {
907  /* Dereference and return status */
908  ObDereferenceObject(KeyObject);
909  return Status;
910  }
911 
913  if (!DataCopy)
914  {
915  /* Dereference and return status */
916  ObDereferenceObject(KeyObject);
918  }
919 
920  _SEH2_TRY
921  {
922  RtlCopyMemory(DataCopy, Data, DataSize);
923  }
925  {
927  }
928  _SEH2_END;
929 
930  if (!NT_SUCCESS(Status))
931  {
932  /* Dereference and return status */
933  ExFreePoolWithTag(DataCopy, TAG_CM);
934  ObDereferenceObject(KeyObject);
935  return Status;
936  }
937 
938  Data = DataCopy;
939  }
940 
941  /* Capture the string */
943  if (!NT_SUCCESS(Status))
944  goto Quit;
945 
946  DPRINT("NtSetValueKey() KH 0x%p, VN '%wZ', TI %x, T %lu, DS %lu\n",
947  KeyHandle, &ValueNameCopy, TitleIndex, Type, DataSize);
948 
949  /* Make sure the name is aligned, not too long, and the data under 4GB */
950  if ( (ValueNameCopy.Length > 32767) ||
951  ((ValueNameCopy.Length & (sizeof(WCHAR) - 1))) ||
952  (DataSize > 0x80000000))
953  {
954  /* Fail */
956  goto Quit;
957  }
958 
959  /* Ignore any null characters at the end */
960  while ((ValueNameCopy.Length) &&
961  !(ValueNameCopy.Buffer[ValueNameCopy.Length / sizeof(WCHAR) - 1]))
962  {
963  /* Skip it */
964  ValueNameCopy.Length -= sizeof(WCHAR);
965  }
966 
967  /* Don't touch read-only keys */
968  if (KeyObject->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY)
969  {
970  /* Fail */
972  goto Quit;
973  }
974 
975  /* Setup callback */
976  PostOperationInfo.Object = (PVOID)KeyObject;
977  SetValueKeyInfo.Object = (PVOID)KeyObject;
978  SetValueKeyInfo.ValueName = &ValueNameCopy;
979  SetValueKeyInfo.TitleIndex = TitleIndex;
980  SetValueKeyInfo.Type = Type;
981  SetValueKeyInfo.Data = Data;
982  SetValueKeyInfo.DataSize = DataSize;
983 
984  /* Do the callback */
986  if (NT_SUCCESS(Status))
987  {
988  /* Call the internal API */
989  Status = CmSetValueKey(KeyObject->KeyControlBlock,
990  &ValueNameCopy,
991  Type,
992  Data,
993  DataSize);
994 
995  /* Do the post-callback */
996  PostOperationInfo.Status = Status;
998  }
999 
1000 Quit:
1001  if (ValueNameCopy.Buffer)
1002  ReleaseCapturedUnicodeString(&ValueNameCopy, PreviousMode);
1003 
1004  if ((PreviousMode != KernelMode) && Data)
1006 
1007  /* Dereference and return status */
1008  ObDereferenceObject(KeyObject);
1009  return Status;
1010 }
1011 
1012 NTSTATUS
1013 NTAPI
1016 {
1017  NTSTATUS Status;
1018  PCM_KEY_BODY KeyObject;
1019  REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo;
1020  REG_POST_OPERATION_INFORMATION PostOperationInfo;
1022  UNICODE_STRING ValueNameCopy;
1023 
1024  PAGED_CODE();
1025 
1026  /* Verify that the handle is valid and is a registry key */
1028  KEY_SET_VALUE,
1030  PreviousMode,
1031  (PVOID*)&KeyObject,
1032  NULL);
1033  if (!NT_SUCCESS(Status))
1034  return Status;
1035 
1036  /* Capture the string */
1038  if (!NT_SUCCESS(Status))
1039  goto Quit;
1040 
1041  /* Make sure the name is aligned properly */
1042  if ((ValueNameCopy.Length & (sizeof(WCHAR) - 1)))
1043  {
1044  /* It isn't, so we'll fail */
1046  goto Quit;
1047  }
1048 
1049  /* Don't touch read-only keys */
1050  if (KeyObject->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY)
1051  {
1052  /* Fail */
1054  goto Quit;
1055  }
1056 
1057  /* Do the callback */
1058  DeleteValueKeyInfo.Object = (PVOID)KeyObject;
1059  DeleteValueKeyInfo.ValueName = ValueName;
1061  &DeleteValueKeyInfo);
1062  if (NT_SUCCESS(Status))
1063  {
1064  /* Call the internal API */
1065  Status = CmDeleteValueKey(KeyObject->KeyControlBlock, ValueNameCopy);
1066 
1067  /* Do the post callback */
1068  PostOperationInfo.Object = (PVOID)KeyObject;
1069  PostOperationInfo.Status = Status;
1071  &PostOperationInfo);
1072  }
1073 
1074 Quit:
1075  if (ValueNameCopy.Buffer)
1076  ReleaseCapturedUnicodeString(&ValueNameCopy, PreviousMode);
1077 
1078  /* Dereference and return status */
1079  ObDereferenceObject(KeyObject);
1080  return Status;
1081 }
1082 
1083 NTSTATUS
1084 NTAPI
1086 {
1087  NTSTATUS Status;
1088  PCM_KEY_BODY KeyObject;
1089  PAGED_CODE();
1090 
1091  /* Get the key object */
1093  0,
1096  (PVOID*)&KeyObject,
1097  NULL);
1098  if (!NT_SUCCESS(Status)) return Status;
1099 
1100  /* Lock the registry */
1101  CmpLockRegistry();
1102 
1103  /* Lock the KCB */
1104  CmpAcquireKcbLockShared(KeyObject->KeyControlBlock);
1105 
1106  /* Make sure KCB isn't deleted */
1107  if (KeyObject->KeyControlBlock->Delete)
1108  {
1109  /* Fail */
1111  }
1112  else
1113  {
1114  /* Call the internal API */
1115  Status = CmFlushKey(KeyObject->KeyControlBlock, FALSE);
1116  }
1117 
1118  /* Release the locks */
1119  CmpReleaseKcbLock(KeyObject->KeyControlBlock);
1121 
1122  /* Dereference the object and return status */
1123  ObDereferenceObject(KeyObject);
1124  return Status;
1125 }
1126 
1127 NTSTATUS
1128 NTAPI
1129 NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
1130  IN POBJECT_ATTRIBUTES FileObjectAttributes)
1131 {
1132  /* Call the newer API */
1133  return NtLoadKeyEx(KeyObjectAttributes, FileObjectAttributes, 0, NULL);
1134 }
1135 
1136 NTSTATUS
1137 NTAPI
1138 NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
1139  IN POBJECT_ATTRIBUTES FileObjectAttributes,
1140  IN ULONG Flags)
1141 {
1142  /* Call the newer API */
1143  return NtLoadKeyEx(KeyObjectAttributes, FileObjectAttributes, Flags, NULL);
1144 }
1145 
1146 NTSTATUS
1147 NTAPI
1149  IN POBJECT_ATTRIBUTES SourceFile,
1150  IN ULONG Flags,
1151  IN HANDLE TrustClassKey)
1152 {
1153  NTSTATUS Status;
1155  OBJECT_ATTRIBUTES CapturedTargetKey;
1156  OBJECT_ATTRIBUTES CapturedSourceFile;
1157  UNICODE_STRING TargetKeyName, SourceFileName;
1158  HANDLE KmTargetKeyRootDir = NULL, KmSourceFileRootDir = NULL;
1159  PCM_KEY_BODY KeyBody = NULL;
1160 
1161  PAGED_CODE();
1162 
1163  /* Validate flags */
1164  if (Flags & ~REG_NO_LAZY_FLUSH)
1165  return STATUS_INVALID_PARAMETER;
1166 
1167  /* Validate privilege */
1169  {
1170  DPRINT1("Restore Privilege missing!\n");
1172  }
1173 
1174  /* Block APCs */
1176 
1177  /* Check for user-mode caller */
1178  if (PreviousMode != KernelMode)
1179  {
1180  /* Prepare to probe parameters */
1181  _SEH2_TRY
1182  {
1183  /* Probe target key */
1184  ProbeForRead(TargetKey,
1185  sizeof(OBJECT_ATTRIBUTES),
1186  sizeof(ULONG));
1187 
1188  /* Probe source file */
1189  ProbeForRead(SourceFile,
1190  sizeof(OBJECT_ATTRIBUTES),
1191  sizeof(ULONG));
1192  }
1194  {
1195  /* Return the exception code */
1197  _SEH2_YIELD(goto Quit);
1198  }
1199  _SEH2_END;
1200  }
1201 
1202  /* Probe and capture the target key attributes, including the security */
1203  Status = ProbeAndCaptureObjectAttributes(&CapturedTargetKey,
1204  &TargetKeyName,
1205  PreviousMode,
1206  TargetKey,
1207  TRUE);
1208  if (!NT_SUCCESS(Status))
1209  goto Quit;
1210 
1211  /*
1212  * Probe and capture the source file attributes, but not the security.
1213  * A proper security context is built by CmLoadKey().
1214  */
1215  Status = ProbeAndCaptureObjectAttributes(&CapturedSourceFile,
1216  &SourceFileName,
1217  PreviousMode,
1218  SourceFile,
1219  FALSE);
1220  if (!NT_SUCCESS(Status))
1221  {
1222  ReleaseCapturedObjectAttributes(&CapturedTargetKey, PreviousMode);
1223  goto Quit;
1224  }
1225 
1226  /* Make sure the target key root directory handle is a kernel handle */
1229  KEY_READ,
1230  PreviousMode,
1231  &KmTargetKeyRootDir);
1232  if (!NT_SUCCESS(Status))
1233  goto Cleanup;
1234  CapturedTargetKey.RootDirectory = KmTargetKeyRootDir;
1235  CapturedTargetKey.Attributes |= OBJ_KERNEL_HANDLE;
1236 
1237  /* Make sure the source file root directory handle is a kernel handle */
1240  FILE_TRAVERSE,
1241  PreviousMode,
1242  &KmSourceFileRootDir);
1243  if (!NT_SUCCESS(Status))
1244  goto Cleanup;
1245  CapturedSourceFile.RootDirectory = KmSourceFileRootDir;
1246  CapturedSourceFile.Attributes |= OBJ_KERNEL_HANDLE;
1247 
1248  /* Check if we have a trust class */
1249  if (TrustClassKey)
1250  {
1251  /* Reference it */
1252  Status = ObReferenceObjectByHandle(TrustClassKey,
1253  0,
1255  PreviousMode,
1256  (PVOID*)&KeyBody,
1257  NULL);
1258  }
1259 
1260  /* Call the internal API */
1261  Status = CmLoadKey(&CapturedTargetKey,
1262  &CapturedSourceFile,
1263  Flags,
1264  KeyBody);
1265 
1266  /* Dereference the trust key, if any */
1267  if (KeyBody) ObDereferenceObject(KeyBody);
1268 
1269 Cleanup:
1270  /* Close the local kernel handles */
1271  if (KmSourceFileRootDir)
1272  ObCloseHandle(KmSourceFileRootDir, KernelMode);
1273  if (KmTargetKeyRootDir)
1274  ObCloseHandle(KmTargetKeyRootDir, KernelMode);
1275 
1276  /* Release the captured object attributes */
1277  ReleaseCapturedObjectAttributes(&CapturedSourceFile, PreviousMode);
1278  ReleaseCapturedObjectAttributes(&CapturedTargetKey, PreviousMode);
1279 
1280 Quit:
1281  /* Bring back APCs */
1283 
1284  /* Return status */
1285  return Status;
1286 }
1287 
1288 NTSTATUS
1289 NTAPI
1291  IN HANDLE Event,
1297  OUT PVOID Buffer,
1298  IN ULONG Length,
1300 {
1301  /* Call the newer API */
1303  0,
1304  NULL,
1305  Event,
1306  ApcRoutine,
1307  ApcContext,
1308  IoStatusBlock,
1310  WatchTree,
1311  Buffer,
1312  Length,
1313  Asynchronous);
1314 }
1315 
1316 NTSTATUS
1317 NTAPI
1319 {
1320  BOOLEAN SetupBoot;
1322  PAGED_CODE();
1323 
1324  /* Always do this as kernel mode */
1325  if (KeGetPreviousMode() == UserMode)
1326  return ZwInitializeRegistry(Flag);
1327 
1328  /* Enough of the system has booted by now */
1329  Ki386PerfEnd();
1330 
1331  /* Validate flag */
1333 
1334  /* Check if boot was accepted */
1336  {
1337  /* Only allow once */
1340 
1341  /* Get the control set accepted */
1343  if (Flag)
1344  {
1345  /* Save the last known good boot */
1347 
1348  /* Notify HAL */
1349  HalEndOfBoot();
1350 
1351  /* Enable lazy flush */
1353  CmpLazyFlush();
1354  return Status;
1355  }
1356 
1357  /* Otherwise, invalid boot */
1358  return STATUS_INVALID_PARAMETER;
1359  }
1360 
1361  /* Check if this was a setup boot */
1362  SetupBoot = (Flag == CM_BOOT_FLAG_SETUP ? TRUE : FALSE);
1363 
1364  /* Make sure we're only called once */
1365  if (!CmFirstTime) return STATUS_ACCESS_DENIED;
1366  CmFirstTime = FALSE;
1367 
1368  /* Lock the registry exclusively */
1370 
1371  /* Initialize the hives and lazy flusher */
1372  CmpCmdInit(SetupBoot);
1373 
1374  /* Save version data */
1376 
1377  /* Release the registry lock */
1379  return STATUS_SUCCESS;
1380 }
1381 
1382 NTSTATUS
1383 NTAPI
1385  IN PHANDLE KeyArray)
1386 {
1387  UNIMPLEMENTED;
1388  return STATUS_NOT_IMPLEMENTED;
1389 }
1390 
1391 NTSTATUS
1392 NTAPI
1394 {
1395  UNIMPLEMENTED;
1396  return STATUS_NOT_IMPLEMENTED;
1397 }
1398 
1399 // FIXME: different for different windows versions!
1400 #define PRODUCT_ACTIVATION_VERSION 7749
1401 
1402 NTSTATUS
1403 NTAPI
1405  IN PULONG pSafeMode)
1406 {
1408 
1410  _SEH2_TRY
1411  {
1412  /* Check if the caller asked for the version */
1413  if (pPrivateVer != NULL)
1414  {
1415  /* For user mode, probe it */
1416  if (PreviousMode != KernelMode)
1417  {
1418  ProbeForWriteUlong(pPrivateVer);
1419  }
1420 
1421  /* Return the expected version */
1422  *pPrivateVer = PRODUCT_ACTIVATION_VERSION;
1423  }
1424 
1425  /* Check if the caller asked for safe mode mode state */
1426  if (pSafeMode != NULL)
1427  {
1428  /* For user mode, probe it */
1429  if (PreviousMode != KernelMode)
1430  {
1431  ProbeForWriteUlong(pSafeMode);
1432  }
1433 
1434  /* Return the safe boot mode state */
1435  *pSafeMode = InitSafeBootMode;
1436  }
1437  }
1439  {
1441  }
1442  _SEH2_END;
1443 
1444  return STATUS_SUCCESS;
1445 }
1446 
1447 NTSTATUS
1448 NTAPI
1450 {
1451  UNIMPLEMENTED;
1452  return STATUS_NOT_IMPLEMENTED;
1453 }
1454 
1455 NTSTATUS
1456 NTAPI
1458  IN ULONG Count,
1459  IN POBJECT_ATTRIBUTES SlaveObjects,
1460  IN HANDLE Event,
1466  OUT PVOID Buffer,
1467  IN ULONG Length,
1469 {
1471  return STATUS_NOT_IMPLEMENTED;
1472 }
1473 
1474 NTSTATUS
1475 NTAPI
1477  IN OUT PKEY_VALUE_ENTRY ValueList,
1478  IN ULONG NumberOfValues,
1479  OUT PVOID Buffer,
1480  IN OUT PULONG Length,
1482 {
1483  UNIMPLEMENTED;
1484  return STATUS_NOT_IMPLEMENTED;
1485 }
1486 
1487 NTSTATUS
1488 NTAPI
1490  OUT PULONG HandleCount)
1491 {
1493  PCM_KEY_BODY KeyBody = NULL;
1494  HANDLE KeyHandle;
1495  NTSTATUS Status;
1496  ULONG SubKeys;
1497 
1498  DPRINT("NtQueryOpenSubKeys()\n");
1499 
1500  PAGED_CODE();
1501 
1502  /* Get the processor mode */
1504 
1505  /* Check for user-mode caller */
1506  if (PreviousMode != KernelMode)
1507  {
1508  /* Prepare to probe parameters */
1509  _SEH2_TRY
1510  {
1511  /* Probe target key */
1512  ProbeForRead(TargetKey,
1513  sizeof(OBJECT_ATTRIBUTES),
1514  sizeof(ULONG));
1515 
1516  /* Probe handle count */
1517  ProbeForWriteUlong(HandleCount);
1518  }
1520  {
1521  /* Return the exception code */
1523  }
1524  _SEH2_END;
1525  }
1526 
1527  /* Open a handle to the key */
1528  Status = ObOpenObjectByName(TargetKey,
1530  PreviousMode,
1531  NULL,
1532  KEY_READ,
1533  NULL,
1534  &KeyHandle);
1535  if (NT_SUCCESS(Status))
1536  {
1537  /* Reference the key object */
1539  KEY_READ,
1541  PreviousMode,
1542  (PVOID*)&KeyBody,
1543  NULL);
1544 
1545  /* Close the handle */
1546  NtClose(KeyHandle);
1547  }
1548 
1549  /* Fail, if the key object could not be referenced */
1550  if (!NT_SUCCESS(Status))
1551  return Status;
1552 
1553  /* Lock the registry exclusively */
1555 
1556  /* Fail, if we did not open a hive root key */
1557  if (KeyBody->KeyControlBlock->KeyCell !=
1558  KeyBody->KeyControlBlock->KeyHive->BaseBlock->RootCell)
1559  {
1560  DPRINT("Error: Key is not a hive root key!\n");
1562  ObDereferenceObject(KeyBody);
1563  return STATUS_INVALID_PARAMETER;
1564  }
1565 
1566  /* Call the internal API */
1567  SubKeys = CmpEnumerateOpenSubKeys(KeyBody->KeyControlBlock,
1568  FALSE, FALSE);
1569 
1570  /* Unlock the registry */
1572 
1573  /* Dereference the key object */
1574  ObDereferenceObject(KeyBody);
1575 
1576  /* Write back the result */
1577  _SEH2_TRY
1578  {
1579  *HandleCount = SubKeys;
1580  }
1582  {
1584  }
1585  _SEH2_END;
1586 
1587  DPRINT("Done.\n");
1588 
1589  return Status;
1590 }
1591 
1592 NTSTATUS
1593 NTAPI
1596  IN PVOID Buffer,
1598 {
1599  UNIMPLEMENTED;
1600  return STATUS_NOT_IMPLEMENTED;
1601 }
1602 
1603 NTSTATUS
1604 NTAPI
1606  IN PUNICODE_STRING ReplacementName)
1607 {
1608  UNIMPLEMENTED;
1609  return STATUS_NOT_IMPLEMENTED;
1610 }
1611 
1612 NTSTATUS
1613 NTAPI
1615  IN HANDLE Key,
1616  IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
1617 {
1618  UNIMPLEMENTED;
1619  return STATUS_NOT_IMPLEMENTED;
1620 }
1621 
1622 NTSTATUS
1623 NTAPI
1626  IN ULONG RestoreFlags)
1627 {
1628  UNIMPLEMENTED;
1629  return STATUS_NOT_IMPLEMENTED;
1630 }
1631 
1632 NTSTATUS
1633 NTAPI
1636 {
1637  /* Call the extended API */
1639 }
1640 
1641 NTSTATUS
1642 NTAPI
1645  IN ULONG Flags)
1646 {
1647  NTSTATUS Status;
1648  HANDLE KmFileHandle = NULL;
1649  PCM_KEY_BODY KeyObject;
1651 
1652  PAGED_CODE();
1653 
1654  DPRINT("NtSaveKeyEx(0x%p, 0x%p, %lu)\n", KeyHandle, FileHandle, Flags);
1655 
1656  /* Verify the flags */
1657  if ((Flags != REG_STANDARD_FORMAT)
1658  && (Flags != REG_LATEST_FORMAT)
1659  && (Flags != REG_NO_COMPRESSION))
1660  {
1661  /* Only one of these values can be specified */
1662  return STATUS_INVALID_PARAMETER;
1663  }
1664 
1665  /* Validate privilege */
1667  {
1669  }
1670 
1671  /* Make sure the target file handle is a kernel handle */
1675  PreviousMode,
1676  &KmFileHandle);
1677  if (!NT_SUCCESS(Status))
1678  goto Quit;
1679 
1680  /* Verify that the handle is valid and is a registry key */
1682  KEY_READ,
1684  PreviousMode,
1685  (PVOID*)&KeyObject,
1686  NULL);
1687  if (!NT_SUCCESS(Status))
1688  goto Quit;
1689 
1690  /* Call the internal API */
1691  Status = CmSaveKey(KeyObject->KeyControlBlock, KmFileHandle, Flags);
1692 
1693  /* Dereference the registry key */
1694  ObDereferenceObject(KeyObject);
1695 
1696 Quit:
1697  /* Close the local kernel handle */
1698  if (KmFileHandle)
1699  ObCloseHandle(KmFileHandle, KernelMode);
1700 
1701  return Status;
1702 }
1703 
1704 NTSTATUS
1705 NTAPI
1706 NtSaveMergedKeys(IN HANDLE HighPrecedenceKeyHandle,
1707  IN HANDLE LowPrecedenceKeyHandle,
1709 {
1710  NTSTATUS Status;
1712  HANDLE KmFileHandle = NULL;
1713  PCM_KEY_BODY HighPrecedenceKeyObject = NULL;
1714  PCM_KEY_BODY LowPrecedenceKeyObject = NULL;
1715 
1716  PAGED_CODE();
1717 
1718  DPRINT("NtSaveMergedKeys(0x%p, 0x%p, 0x%p)\n",
1719  HighPrecedenceKeyHandle, LowPrecedenceKeyHandle, FileHandle);
1720 
1722 
1723  /* Validate privilege */
1725  {
1727  }
1728 
1729  /* Make sure the target file handle is a kernel handle */
1733  PreviousMode,
1734  &KmFileHandle);
1735  if (!NT_SUCCESS(Status))
1736  goto Quit;
1737 
1738  /* Verify that the handles are valid and are registry keys */
1739  Status = ObReferenceObjectByHandle(HighPrecedenceKeyHandle,
1740  KEY_READ,
1742  PreviousMode,
1743  (PVOID*)&HighPrecedenceKeyObject,
1744  NULL);
1745  if (!NT_SUCCESS(Status))
1746  goto Quit;
1747 
1748  Status = ObReferenceObjectByHandle(LowPrecedenceKeyHandle,
1749  KEY_READ,
1751  PreviousMode,
1752  (PVOID*)&LowPrecedenceKeyObject,
1753  NULL);
1754  if (!NT_SUCCESS(Status))
1755  goto Quit;
1756 
1757  /* Call the internal API */
1758  Status = CmSaveMergedKeys(HighPrecedenceKeyObject->KeyControlBlock,
1759  LowPrecedenceKeyObject->KeyControlBlock,
1760  KmFileHandle);
1761 
1762 Quit:
1763  /* Dereference the opened key objects */
1764  if (LowPrecedenceKeyObject)
1765  ObDereferenceObject(LowPrecedenceKeyObject);
1766  if (HighPrecedenceKeyObject)
1767  ObDereferenceObject(HighPrecedenceKeyObject);
1768 
1769  /* Close the local kernel handle */
1770  if (KmFileHandle)
1771  ObCloseHandle(KmFileHandle, KernelMode);
1772 
1773  return Status;
1774 }
1775 
1776 NTSTATUS
1777 NTAPI
1780  IN PVOID KeyInformation,
1781  IN ULONG KeyInformationLength)
1782 {
1783  UNIMPLEMENTED;
1784  return STATUS_NOT_IMPLEMENTED;
1785 }
1786 
1787 NTSTATUS
1788 NTAPI
1789 NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
1790 {
1791  return NtUnloadKey2(KeyObjectAttributes, 0);
1792 }
1793 
1794 NTSTATUS
1795 NTAPI
1797  IN ULONG Flags)
1798 {
1799  NTSTATUS Status;
1800  OBJECT_ATTRIBUTES CapturedTargetKey;
1802  HANDLE KmTargetKeyRootDir = NULL;
1803  CM_PARSE_CONTEXT ParseContext = {0};
1805  PCM_KEY_BODY KeyBody = NULL;
1806  ULONG ParentConv = 0, ChildConv = 0;
1807  HANDLE Handle;
1808 
1809  PAGED_CODE();
1810 
1811  /* Validate privilege */
1813  {
1814  DPRINT1("Restore Privilege missing!\n");
1816  }
1817 
1818  /* Check for user-mode caller */
1819  if (PreviousMode != KernelMode)
1820  {
1821  /* Prepare to probe parameters */
1822  _SEH2_TRY
1823  {
1824  /* Probe object attributes */
1825  ProbeForRead(TargetKey,
1826  sizeof(OBJECT_ATTRIBUTES),
1827  sizeof(ULONG));
1828 
1829  CapturedTargetKey = *TargetKey;
1830 
1831  /* Probe the string */
1832  ObjectName = ProbeForReadUnicodeString(CapturedTargetKey.ObjectName);
1833  ProbeForRead(ObjectName.Buffer,
1834  ObjectName.Length,
1835  sizeof(WCHAR));
1836 
1837  CapturedTargetKey.ObjectName = &ObjectName;
1838  }
1840  {
1841  /* Return the exception code */
1843  }
1844  _SEH2_END;
1845  }
1846  else
1847  {
1848  /* Save the target attributes directly */
1849  CapturedTargetKey = *TargetKey;
1850  }
1851 
1852  /* Make sure the target key root directory handle is a kernel handle */
1855  KEY_WRITE,
1856  PreviousMode,
1857  &KmTargetKeyRootDir);
1858  if (!NT_SUCCESS(Status))
1859  return Status;
1860  CapturedTargetKey.RootDirectory = KmTargetKeyRootDir;
1861  CapturedTargetKey.Attributes |= OBJ_KERNEL_HANDLE;
1862 
1863  /* Setup the parse context */
1864  ParseContext.CreateOperation = TRUE;
1866 
1867  /* Do the create */
1868  /* Open a local handle to the key */
1869  Status = ObOpenObjectByName(&CapturedTargetKey,
1871  KernelMode,
1872  NULL,
1873  KEY_WRITE,
1874  &ParseContext,
1875  &Handle);
1876  if (NT_SUCCESS(Status))
1877  {
1878  /* Reference the key object */
1880  KEY_WRITE,
1882  KernelMode,
1883  (PVOID*)&KeyBody,
1884  NULL);
1885 
1886  /* Close the handle */
1888  }
1889 
1890  /* Close the local kernel handle */
1891  if (KmTargetKeyRootDir)
1892  ObCloseHandle(KmTargetKeyRootDir, KernelMode);
1893 
1894  /* Return if a failure was encountered */
1895  if (!NT_SUCCESS(Status))
1896  return Status;
1897 
1898  /* Acquire the lock depending on flags */
1899  if (Flags == REG_FORCE_UNLOAD)
1900  {
1901  /* Lock registry exclusively */
1903  }
1904  else
1905  {
1906  /* Lock registry */
1907  CmpLockRegistry();
1908 
1909  /* Acquire the hive loading lock */
1911 
1912  /* Lock parent and child */
1913  if (KeyBody->KeyControlBlock->ParentKcb)
1914  ParentConv = KeyBody->KeyControlBlock->ParentKcb->ConvKey;
1915  else
1916  ParentConv = KeyBody->KeyControlBlock->ConvKey;
1917 
1918  ChildConv = KeyBody->KeyControlBlock->ConvKey;
1919 
1920  CmpAcquireTwoKcbLocksExclusiveByKey(ChildConv, ParentConv);
1921  }
1922 
1923  /* Check if it's being deleted already */
1924  if (KeyBody->KeyControlBlock->Delete)
1925  {
1926  /* Return appropriate status */
1928  goto Quit;
1929  }
1930 
1931  /* Check if it's a read-only key */
1932  if (KeyBody->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY)
1933  {
1934  /* Return appropriate status */
1936  goto Quit;
1937  }
1938 
1939  /* Call the internal API. Note that CmUnloadKey() unlocks the registry only on success. */
1940  Status = CmUnloadKey(KeyBody->KeyControlBlock, Flags);
1941 
1942  /* Check if we failed, but really need to succeed */
1944  {
1945  /* TODO: We should perform another attempt here */
1946  _SEH2_TRY
1947  {
1948  DPRINT1("NtUnloadKey2(%wZ): We want to force-unload the hive but couldn't unload it: Retrying is UNIMPLEMENTED!\n", TargetKey->ObjectName);
1949  }
1951  {
1952  }
1953  _SEH2_END;
1954  }
1955 
1956  /* If CmUnloadKey() failed we need to unlock registry ourselves */
1957  if (!NT_SUCCESS(Status))
1958  {
1959  if (Flags != REG_FORCE_UNLOAD)
1960  {
1961  /* Release the KCB locks */
1962  CmpReleaseTwoKcbLockByKey(ChildConv, ParentConv);
1963 
1964  /* Release the hive loading lock */
1966  }
1967 
1968  /* Unlock the registry */
1970  }
1971 
1972 Quit:
1973  /* Dereference the key */
1974  ObDereferenceObject(KeyBody);
1975 
1976  /* Return status */
1977  return Status;
1978 }
1979 
1980 NTSTATUS
1981 NTAPI
1983  IN HANDLE Event)
1984 {
1985  UNIMPLEMENTED;
1986  return STATUS_NOT_IMPLEMENTED;
1987 }
1988 
1989 /* 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:39
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSTATUS NTAPI NtCompressKey(IN HANDLE Key)
Definition: ntapi.c:1393
ObjectType
Definition: metafile.c:80
#define PRODUCT_ACTIVATION_VERSION
Definition: ntapi.c:1400
KEY_INFORMATION_CLASS KeyInformationClass
Definition: cmtypes.h:767
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:39
Definition: cmtypes.h:858
_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:1796
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:160
NTSTATUS NTAPI NtUnloadKeyEx(IN POBJECT_ATTRIBUTES TargetKey, IN HANDLE Event)
Definition: ntapi.c:1982
#define KeGetPreviousMode()
Definition: ketypes.h:1107
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:3066
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:62
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:1634
NTSTATUS NTAPI NtRestoreKey(IN HANDLE KeyHandle, IN HANDLE FileHandle, IN ULONG RestoreFlags)
Definition: ntapi.c:1624
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:1457
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:485
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
NTSTATUS NTAPI NtLockProductActivationKeys(IN PULONG pPrivateVer, IN PULONG pSafeMode)
Definition: ntapi.c:1404
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 _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:486
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS NTAPI NtLockRegistryKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1449
KEY_INFORMATION_CLASS KeyInformationClass
Definition: cmtypes.h:744
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:779
NTSTATUS NTAPI NtSetInformationKey(IN HANDLE KeyHandle, IN KEY_SET_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG KeyInformationLength)
Definition: ntapi.c:1778
_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:1148
NTSTATUS NTAPI NtInitializeRegistry(IN USHORT Flag)
Definition: ntapi.c:1318
_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:1138
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:1489
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:1476
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:1129
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:230
NTSTATUS NTAPI NtReplaceKey(IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE Key, IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
Definition: ntapi.c:1614
#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:239
_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:1290
NTSTATUS Status
Definition: cmtypes.h:860
UNICODE_STRING Class
Definition: cm.h:484
#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:1789
#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:1594
_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:161
#define REG_NO_COMPRESSION
Definition: cmtypes.h:99
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#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:454
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:1605
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:1643
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1085
_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:1706
#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:713
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI NtCompactKeys(IN ULONG Count, IN PHANDLE KeyArray)
Definition: ntapi.c:1384
_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:40
ULONG InitSafeBootMode
Definition: init.c:69
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:756
#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:115
#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:859
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:93
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
#define CM_BOOT_FLAG_SETUP
Definition: cmtypes.h:159
return STATUS_SUCCESS
Definition: btrfs.c:3014
VOID NTAPI CmpCmdInit(IN BOOLEAN SetupBoot)
Definition: cmlazy.c:234
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
BOOLEAN CreateOperation
Definition: cm.h:490
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 PAGED_CODE()
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68