ReactOS  0.4.14-dev-342-gdc047f9
registry.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * PURPOSE: Rtl registry functions
5  * FILE: lib/rtl/registry.c
6  * PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
7  * Eric Kohl
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include <rtl.h>
13 
14 #include <ndk/cmfuncs.h>
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 #define TAG_RTLREGISTRY 'vrqR'
20 
22 
23 /* DATA **********************************************************************/
24 
26 {
27  NULL,
28  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services",
29  L"\\Registry\\Machine\\System\\CurrentControlSet\\Control",
30  L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion",
31  L"\\Registry\\Machine\\Hardware\\DeviceMap",
32  L"\\Registry\\User\\.Default",
33 };
34 
35 /* PRIVATE FUNCTIONS *********************************************************/
36 
38 NTAPI
42  IN PVOID Buffer)
43 {
44  USHORT ActualLength;
45  PUNICODE_STRING ReturnString = Buffer;
47  ULONG RealLength;
48 
49  /* Check if this is a string */
50  if ((ValueType == REG_SZ) ||
51  (ValueType == REG_EXPAND_SZ) ||
53  {
54  /* Normalize the length */
55  if (ValueLength > MAXUSHORT)
56  ActualLength = MAXUSHORT;
57  else
58  ActualLength = (USHORT)ValueLength;
59 
60  /* Check if the return string has been allocated */
61  if (!ReturnString->Buffer)
62  {
63  /* Allocate it */
64  ReturnString->Buffer = RtlpAllocateMemory(ActualLength, TAG_RTLREGISTRY);
65  if (!ReturnString->Buffer) return STATUS_NO_MEMORY;
66  ReturnString->MaximumLength = ActualLength;
67  }
68  else if (ActualLength > ReturnString->MaximumLength)
69  {
70  /* The string the caller allocated is too small */
72  }
73 
74  /* Copy the data */
75  RtlCopyMemory(ReturnString->Buffer, ValueData, ActualLength);
76  ReturnString->Length = ActualLength - sizeof(UNICODE_NULL);
77  }
78  else if (ValueLength <= sizeof(ULONG))
79  {
80  /* Check if we can just copy the data */
81  if ((Buffer != ValueData) && (ValueLength))
82  {
83  /* Copy it */
85  }
86  }
87  else
88  {
89  /* Check if the length is negative */
90  if ((LONG)*Length < 0)
91  {
92  /* Get the real length and copy the buffer */
93  RealLength = -(LONG)*Length;
94  if (RealLength < ValueLength) return STATUS_BUFFER_TOO_SMALL;
96  }
97  else
98  {
99  if (ValueType != REG_BINARY)
100  {
101  /* Check if there's space for the length and type, plus data */
102  if (*Length < (2 * sizeof(ULONG) + ValueLength))
103  {
104  /* Nope, fail */
106  }
107 
108  /* Return the data */
109  *Length++ = ValueLength;
110  *Length++ = ValueType;
112  }
113  else
114  {
115  /* Return the REG_BINARY data */
117  }
118  }
119  }
120 
121  /* All done */
122  return STATUS_SUCCESS;
123 }
124 
125 NTSTATUS
126 NTAPI
128  IN PKEY_VALUE_FULL_INFORMATION KeyValueInfo,
129  IN OUT PULONG InfoSize,
130  IN PVOID Context,
132 {
133  ULONG InfoLength;
134  SIZE_T Length, SpareLength, c;
136  PCHAR SpareData, DataEnd;
137  ULONG Type;
138  PWCHAR Name, p, ValueEnd;
139  PVOID Data;
141  BOOLEAN FoundExpander = FALSE;
143 
144  /* Setup defaults */
145  InfoLength = *InfoSize;
146  *InfoSize = 0;
147 
148  /* Check if there's no data */
149  if (KeyValueInfo->DataOffset == MAXULONG)
150  {
151  /* Return proper status code */
154  }
155 
156  /* Setup spare data pointers */
157  SpareData = (PCHAR)KeyValueInfo;
158  SpareLength = InfoLength;
159  DataEnd = SpareData + SpareLength;
160 
161  /* Check if there's no value or data */
162  if ((KeyValueInfo->Type == REG_NONE) ||
163  (!(KeyValueInfo->DataLength) &&
164  (KeyValueInfo->Type == QueryTable->DefaultType)))
165  {
166  /* Check if there's no value */
168  {
169  /* Return proper status code */
172  }
173 
174  /* We can setup a default value... capture the defaults */
179  if (!Length)
180  {
181  /* No default length given, try to calculate it */
182  p = Data;
183  if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
184  {
185  /* This is a string, count the characters */
186  while (*p++);
188  }
189  else if (Type == REG_MULTI_SZ)
190  {
191  /* This is a multi-string, calculate all characters */
192  while (*p) while (*p++);
193  Length = (ULONG_PTR)p - (ULONG_PTR)Data + sizeof(UNICODE_NULL);
194  }
195  }
196  }
197  else
198  {
199  /* Check if this isn't a direct return */
201  {
202  /* Check if we have length */
203  if (KeyValueInfo->DataLength)
204  {
205  /* Increase the spare data */
206  SpareData += KeyValueInfo->DataOffset +
207  KeyValueInfo->DataLength;
208  }
209  else
210  {
211  /* Otherwise, the spare data only has the name data */
213  KeyValueInfo->NameLength;
214  }
215 
216  /* Align the pointer and get new size of spare data */
217  SpareData = (PVOID)(((ULONG_PTR)SpareData + 7) & ~7);
218  SpareLength = DataEnd - SpareData;
219 
220  /* Check if we have space to copy the data */
221  RequiredLength = KeyValueInfo->NameLength + sizeof(UNICODE_NULL);
222  if ((SpareData > DataEnd) || (SpareLength < RequiredLength))
223  {
224  /* Fail and return the missing length */
225  *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) + RequiredLength;
227  }
228 
229  /* Copy the data and null-terminate it */
230  Name = (PWCHAR)SpareData;
231  RtlCopyMemory(Name, KeyValueInfo->Name, KeyValueInfo->NameLength);
232  Name[KeyValueInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
233 
234  /* Update the spare data information */
235  SpareData += RequiredLength;
236  SpareData = (PVOID)(((ULONG_PTR)SpareData + 7) & ~7);
237  SpareLength = DataEnd - SpareData;
238  }
239  else
240  {
241  /* Just return the name */
243  }
244 
245  /* Capture key data */
246  Type = KeyValueInfo->Type;
247  Data = (PVOID)((ULONG_PTR)KeyValueInfo + KeyValueInfo->DataOffset);
248  Length = KeyValueInfo->DataLength;
249  }
250 
251  /* Check if we're expanding */
253  {
254  /* Check if it's a multi-string */
255  if (Type == REG_MULTI_SZ)
256  {
257  /* Prepare defaults */
259  /* Skip the last two UNICODE_NULL chars (the terminating null string) */
260  ValueEnd = (PWSTR)((ULONG_PTR)Data + Length - 2 * sizeof(UNICODE_NULL));
261  p = Data;
262 
263  /* Loop all strings */
264  while (p < ValueEnd)
265  {
266  /* Go to the next string */
267  while (*p++);
268 
269  /* Get the length and check if this is direct */
272  {
273  /* Do the query */
275  Data,
276  (ULONG)Length,
280  sizeof(UNICODE_STRING));
281  }
282  else
283  {
284  /* Call the custom routine */
286  REG_SZ,
287  Data,
288  (ULONG)Length,
289  Context,
291  }
292 
293  /* Normalize status */
295  if (!NT_SUCCESS(Status)) break;
296 
297  /* Update data pointer */
298  Data = p;
299  }
300 
301  /* Return */
302  return Status;
303  }
304 
305  /* Check if this is an expand string */
306  if ((Type == REG_EXPAND_SZ) && (Length >= sizeof(WCHAR)))
307  {
308  /* Try to find the expander */
309  c = Length - sizeof(UNICODE_NULL);
310  p = (PWCHAR)Data;
311  while (c)
312  {
313  /* Check if this is one */
314  if (*p == L'%')
315  {
316  /* Yup! */
317  FoundExpander = TRUE;
318  break;
319  }
320 
321  /* Continue in the buffer */
322  p++;
323  c -= sizeof(WCHAR);
324  }
325 
326  /* So check if we have one */
327  if (FoundExpander)
328  {
329  /* Setup the source string */
330  RtlInitEmptyUnicodeString(&Source, Data, (USHORT)Length);
331  Source.Length = Source.MaximumLength - sizeof(UNICODE_NULL);
332 
333  /* Setup the desination string */
334  RtlInitEmptyUnicodeString(&Destination, (PWCHAR)SpareData, 0);
335 
336  /* Check if we're out of space */
337  if (SpareLength <= 0)
338  {
339  /* Then we don't have any space in our string */
341  }
342  else if (SpareLength <= MAXUSHORT)
343  {
344  /* This is the good case, where we fit into a string */
345  Destination.MaximumLength = (USHORT)SpareLength;
346  Destination.Buffer[SpareLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
347  }
348  else
349  {
350  /* We can't fit into a string, so truncate */
352  Destination.Buffer[MAXUSHORT / sizeof(WCHAR) - 1] = UNICODE_NULL;
353  }
354 
355  /* Expand the strings and set our type as one string */
357  &Source,
358  &Destination,
359  &RequiredLength);
360  Type = REG_SZ;
361 
362  /* Check for success */
363  if (NT_SUCCESS(Status))
364  {
365  /* Set the value name and length to our string */
368  }
369  else
370  {
371  /* Check if our buffer is too small */
373  {
374  /* Set the required missing length */
375  *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) +
377 
378  /* Notify debugger */
379  DPRINT1("RTL: Expand variables for %wZ failed - "
380  "Status == %lx Size %x > %x <%x>\n",
381  &Source,
382  Status,
383  *InfoSize,
384  InfoLength,
386  }
387  else
388  {
389  /* Notify debugger */
390  DPRINT1("RTL: Expand variables for %wZ failed - "
391  "Status == %lx\n",
392  &Source,
393  Status);
394  }
395 
396  /* Return the status */
397  return Status;
398  }
399  }
400  }
401  }
402 
403  /* Check if this is a direct query */
405  {
406  /* Return the data */
408  Data,
409  (ULONG)Length,
411  }
412  else
413  {
414  /* Call the query routine */
416  Type,
417  Data,
418  (ULONG)Length,
419  Context,
421  }
422 
423  /* Normalize and return status */
425 }
426 
427 _Success_(return!=NULL || BufferSize==0)
429 PVOID
430 NTAPI
431 RtlpAllocDeallocQueryBuffer(
433  _In_opt_ __drv_freesMem(Mem) PVOID OldBuffer,
434  _In_ SIZE_T OldBufferSize,
436 {
437  PVOID Buffer = NULL;
438 
439  /* Assume success */
440  if (Status) *Status = STATUS_SUCCESS;
441 
442  /* Free the old buffer */
443  if (OldBuffer) RtlpFreeMemory(OldBuffer, TAG_RTLREGISTRY);
444 
445  /* Check if we need to allocate a new one */
446  if (BufferSize)
447  {
448  /* Allocate */
450  if (!(Buffer) && (Status)) *Status = STATUS_NO_MEMORY;
451  }
452 
453  /* Return the pointer */
454  return Buffer;
455 }
456 
457 NTSTATUS
458 NTAPI
460  IN PCWSTR Path,
461  IN BOOLEAN Create,
463 {
464  UNICODE_STRING KeyPath, KeyName;
465  WCHAR KeyBuffer[MAX_PATH];
468 
469  /* Check if we just want the handle */
470  if (RelativeTo & RTL_REGISTRY_HANDLE)
471  {
472  *KeyHandle = (HANDLE)Path;
473  return STATUS_SUCCESS;
474  }
475 
476  /* Check for optional flag */
477  if (RelativeTo & RTL_REGISTRY_OPTIONAL)
478  {
479  /* Mask it out */
480  RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
481  }
482 
483  /* Fail on invalid parameter */
484  if (RelativeTo >= RTL_REGISTRY_MAXIMUM) return STATUS_INVALID_PARAMETER;
485 
486  /* Initialize the key name */
487  RtlInitEmptyUnicodeString(&KeyName, KeyBuffer, sizeof(KeyBuffer));
488 
489  /* Check if we have to lookup a path to prefix */
490  if (RelativeTo != RTL_REGISTRY_ABSOLUTE)
491  {
492  /* Check if we need the current user key */
493  if (RelativeTo == RTL_REGISTRY_USER)
494  {
495  /* Get the user key path */
497 
498  /* Check if it worked */
499  if (NT_SUCCESS(Status))
500  {
501  /* Append the user key path */
503 
504  /* Free the user key path */
505  RtlFreeUnicodeString (&KeyPath);
506  }
507  else
508  {
509  /* It didn't work so fall back to the default user key */
511  }
512  }
513  else
514  {
515  /* Get one of the prefixes */
517  RtlpRegPaths[RelativeTo]);
518  }
519 
520  /* Check for failure, otherwise, append the path separator */
521  if (!NT_SUCCESS(Status)) return Status;
523  if (!NT_SUCCESS(Status)) return Status;
524  }
525 
526  /* And now append the path */
527  if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE) Path++; // HACK!
529  if (!NT_SUCCESS(Status)) return Status;
530 
531  /* Initialize the object attributes */
533  &KeyName,
535  NULL,
536  NULL);
537 
538  /* Check if we want to create it */
539  if (Create)
540  {
541  /* Create the key with write privileges */
542  Status = ZwCreateKey(KeyHandle,
545  0,
546  NULL,
547  0,
548  NULL);
549  }
550  else
551  {
552  /* Otherwise, just open it with read access */
553  Status = ZwOpenKey(KeyHandle,
556  }
557 
558  /* Return status */
559  return Status;
560 }
561 
563 VOID
565  _In_ ULONG RelativeTo,
567 {
568  /* Did the caller pass a key handle? */
569  if (!(RelativeTo & RTL_REGISTRY_HANDLE))
570  {
571  /* We opened the key in RtlpGetRegistryHandle, so close it now */
573  }
574 }
575 
576 /* PUBLIC FUNCTIONS **********************************************************/
577 
578 /*
579  * @implemented
580  */
581 NTSTATUS
582 NTAPI
584  IN PWSTR Path)
585 {
588  PAGED_CODE_RTL();
589 
590  /* Call the helper */
591  Status = RtlpGetRegistryHandle(RelativeTo,
592  Path,
593  FALSE,
594  &KeyHandle);
595  if (!NT_SUCCESS(Status)) return Status;
596 
597  /* Close the handle even for RTL_REGISTRY_HANDLE */
599  return STATUS_SUCCESS;
600 }
601 
602 /*
603  * @implemented
604  */
605 NTSTATUS
606 NTAPI
608  IN PWSTR Path)
609 {
612  PAGED_CODE_RTL();
613 
614  /* Call the helper */
615  Status = RtlpGetRegistryHandle(RelativeTo,
616  Path,
617  TRUE,
618  &KeyHandle);
619  if (!NT_SUCCESS(Status)) return Status;
620 
621  /* All went well, close the handle and return status */
622  RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
623  return STATUS_SUCCESS;
624 }
625 
626 /*
627  * @implemented
628  */
629 NTSTATUS
630 NTAPI
632  IN PCWSTR Path,
634 {
638  PAGED_CODE_RTL();
639 
640  /* Call the helper */
641  Status = RtlpGetRegistryHandle(RelativeTo,
642  Path,
643  TRUE,
644  &KeyHandle);
645  if (!NT_SUCCESS(Status)) return Status;
646 
647  /* Initialize the key name and delete it */
649  Status = ZwDeleteValueKey(KeyHandle, &Name);
650 
651  /* Close the handle and return status */
652  RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
653  return Status;
654 }
655 
656 /*
657  * @implemented
658  */
659 NTSTATUS
660 NTAPI
662  IN PCWSTR Path,
667 {
671  PAGED_CODE_RTL();
672 
673  /* Call the helper */
674  Status = RtlpGetRegistryHandle(RelativeTo,
675  Path,
676  TRUE,
677  &KeyHandle);
678  if (!NT_SUCCESS(Status)) return Status;
679 
680  /* Initialize the key name and set it */
682  Status = ZwSetValueKey(KeyHandle,
683  &Name,
684  0,
685  ValueType,
686  ValueData,
687  ValueLength);
688 
689  /* Close the handle and return status */
690  RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
691  return Status;
692 }
693 
694 /*
695  * @implemented
696  */
697 NTSTATUS
698 NTAPI
701 {
703  UNICODE_STRING KeyPath;
705  PAGED_CODE_RTL();
706 
707  /* Get the user key */
709  if (NT_SUCCESS(Status))
710  {
711  /* Initialize the attributes and open it */
713  &KeyPath,
715  NULL,
716  NULL);
718 
719  /* Free the path and return success if it worked */
720  RtlFreeUnicodeString(&KeyPath);
721  if (NT_SUCCESS(Status)) return STATUS_SUCCESS;
722  }
723 
724  /* It didn't work, so use the default key */
727  &KeyPath,
729  NULL,
730  NULL);
732 
733  /* Return status */
734  return Status;
735 }
736 
737 /*
738  * @implemented
739  */
740 NTSTATUS
741 NTAPI
743 {
745  UCHAR Buffer[256];
746  PSID_AND_ATTRIBUTES SidBuffer;
747  ULONG Length;
748  UNICODE_STRING SidString;
750  PAGED_CODE_RTL();
751 
752  /* Open the thread token */
754  TOKEN_QUERY,
755  TRUE,
757  &TokenHandle);
758  if (!NT_SUCCESS(Status))
759  {
760  /* We failed, is it because we don't have a thread token? */
761  if (Status != STATUS_NO_TOKEN) return Status;
762 
763  /* It is, so use the process token */
765  TOKEN_QUERY,
767  &TokenHandle);
768  if (!NT_SUCCESS(Status)) return Status;
769  }
770 
771  /* Now query the token information */
772  SidBuffer = (PSID_AND_ATTRIBUTES)Buffer;
773  Status = ZwQueryInformationToken(TokenHandle,
774  TokenUser,
775  (PVOID)SidBuffer,
776  sizeof(Buffer),
777  &Length);
778 
779  /* Close the handle and handle failure */
781  if (!NT_SUCCESS(Status)) return Status;
782 
783  /* Convert the SID */
784  Status = RtlConvertSidToUnicodeString(&SidString, SidBuffer[0].Sid, TRUE);
785  if (!NT_SUCCESS(Status)) return Status;
786 
787  /* Add the length of the prefix */
788  Length = SidString.Length + sizeof(L"\\REGISTRY\\USER\\");
789 
790  /* Initialize a string */
791  RtlInitEmptyUnicodeString(KeyPath,
793  (USHORT)Length);
794  if (!KeyPath->Buffer)
795  {
796  /* Free the string and fail */
797  RtlFreeUnicodeString(&SidString);
798  return STATUS_NO_MEMORY;
799  }
800 
801  /* Append the prefix and SID */
802  RtlAppendUnicodeToString(KeyPath, L"\\REGISTRY\\USER\\");
803  RtlAppendUnicodeStringToString(KeyPath, &SidString);
804 
805  /* Free the temporary string and return success */
806  RtlFreeUnicodeString(&SidString);
807  return STATUS_SUCCESS;
808 }
809 
810 /*
811  * @implemented
812  */
813 NTSTATUS
814 NTAPI
821 {
822  /* Check if we have object attributes */
823  if (ObjectAttributes)
824  {
825  /* Mask out the unsupported flags */
826  ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
827  }
828 
829  /* Create the key */
830  return ZwCreateKey(KeyHandle,
833  0,
834  NULL,
835  0,
836  Disposition);
837 }
838 
839 /*
840  * @implemented
841  */
842 NTSTATUS
843 NTAPI
846  IN ULONG Index,
847  IN ULONG Unused)
848 {
849  PKEY_BASIC_INFORMATION KeyInfo = NULL;
850  ULONG BufferLength = 0;
853 
854  /* Check if we have a name */
855  if (SubKeyName->MaximumLength)
856  {
857  /* Allocate a buffer for it */
858  BufferLength = SubKeyName->MaximumLength +
859  sizeof(KEY_BASIC_INFORMATION);
860  KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
861  if (!KeyInfo) return STATUS_NO_MEMORY;
862  }
863 
864  /* Enumerate the key */
865  Status = ZwEnumerateKey(KeyHandle,
866  Index,
868  KeyInfo,
869  BufferLength,
870  &ReturnedLength);
871  if (NT_SUCCESS(Status) && (KeyInfo != NULL))
872  {
873  /* Check if the name fits */
874  if (KeyInfo->NameLength <= SubKeyName->MaximumLength)
875  {
876  /* Set the length */
877  SubKeyName->Length = (USHORT)KeyInfo->NameLength;
878 
879  /* Copy it */
880  RtlMoveMemory(SubKeyName->Buffer,
881  KeyInfo->Name,
882  SubKeyName->Length);
883  }
884  else
885  {
886  /* Otherwise, we ran out of buffer space */
888  }
889  }
890 
891  /* Free the buffer and return status */
892  if (KeyInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
893  return Status;
894 }
895 
896 /*
897  * @implemented
898  */
899 NTSTATUS
900 NTAPI
902 {
903  /* This just deletes the key */
904  return ZwDeleteKey(KeyHandle);
905 }
906 
907 /*
908  * @implemented
909  */
910 NTSTATUS
911 NTAPI
915  IN ULONG Unused)
916 {
917  /* Check if we have object attributes */
918  if (ObjectAttributes)
919  {
920  /* Mask out the unsupported flags */
921  ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
922  }
923 
924  /* Open the key */
925  return ZwOpenKey(KeyHandle, DesiredAccess, ObjectAttributes);
926 }
927 
928 /*
929  * @implemented
930  */
931 NTSTATUS
932 NTAPI
937  IN ULONG Unused)
938 {
941  ULONG BufferLength = 0;
943 
944  /* Clear the value name */
945  RtlInitEmptyUnicodeString(&ValueName, NULL, 0);
946 
947  /* Check if we were already given a length */
949 
950  /* Add the size of the structure */
952 
953  /* Allocate memory for the value */
954  ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
955  if (!ValueInfo) return STATUS_NO_MEMORY;
956 
957  /* Query the value */
958  Status = ZwQueryValueKey(KeyHandle,
959  &ValueName,
961  ValueInfo,
962  BufferLength,
963  &BufferLength);
965  {
966  /* Return the length and type */
967  if (DataLength) *DataLength = ValueInfo->DataLength;
968  if (Type) *Type = ValueInfo->Type;
969  }
970 
971  /* Check if the caller wanted data back, and we got it */
972  if ((NT_SUCCESS(Status)) && (Data))
973  {
974  /* Copy it */
975  RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
976  }
977 
978  /* Free the memory and return status */
979  RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
980  return Status;
981 }
982 
983 /*
984  * @implemented
985  */
986 NTSTATUS
987 NTAPI
989  IN ULONG Type,
990  IN PVOID Data,
992 {
994 
995  /* Set the value */
996  RtlInitEmptyUnicodeString(&ValueName, NULL, 0);
997  return ZwSetValueKey(KeyHandle,
998  &ValueName,
999  0,
1000  Type,
1001  Data,
1002  DataLength);
1003 }
1004 
1005 /*
1006  * @implemented
1007  */
1008 NTSTATUS
1009 NTAPI
1011  IN PCWSTR Path,
1013  IN PVOID Context,
1015 {
1016  NTSTATUS Status;
1017  PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL;
1018  HANDLE KeyHandle, CurrentKey;
1019  SIZE_T BufferSize, InfoSize;
1020  UNICODE_STRING KeyPath, KeyValueName;
1022  ULONG i, Value;
1024 
1025  /* Get the registry handle */
1026  Status = RtlpGetRegistryHandle(RelativeTo, Path, FALSE, &KeyHandle);
1027  if (!NT_SUCCESS(Status)) return Status;
1028 
1029  /* Initialize the path */
1030  RtlInitUnicodeString(&KeyPath,
1031  (RelativeTo & RTL_REGISTRY_HANDLE) ? NULL : Path);
1032 
1033  /* Allocate a query buffer */
1035  KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize, NULL, 0, &Status);
1036  if (!KeyValueInfo)
1037  {
1038  /* Close the handle if we have one and fail */
1039  RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
1040  return Status;
1041  }
1042 
1043  /* Set defaults */
1044  KeyValueInfo->DataOffset = 0;
1045  InfoSize = BufferSize - sizeof(UNICODE_NULL);
1046  CurrentKey = KeyHandle;
1047 
1048  /* Loop the query table */
1049  while ((QueryTable->QueryRoutine) ||
1052  {
1053  /* Check if the request is invalid */
1055  (!(QueryTable->Name) ||
1058  {
1059  /* Fail */
1061  break;
1062  }
1063 
1064  /* Check if we want a specific key */
1067  {
1068  /* Check if we're working with another handle */
1069  if (CurrentKey != KeyHandle)
1070  {
1071  /* Close our current key and use the top */
1072  NtClose(CurrentKey);
1073  CurrentKey = KeyHandle;
1074  }
1075  }
1076 
1077  /* Check if we're querying the subkey */
1079  {
1080  /* Make sure we have a name */
1081  if (!QueryTable->Name)
1082  {
1083  /* Fail */
1085  }
1086  else
1087  {
1088  /* Initialize the name */
1089  RtlInitUnicodeString(&KeyPath, QueryTable->Name);
1090 
1091  /* Get the key handle */
1093  &KeyPath,
1096  KeyHandle,
1097  NULL);
1098  Status = ZwOpenKey(&CurrentKey,
1100  &ObjectAttributes);
1101  if (NT_SUCCESS(Status))
1102  {
1103  /* If we have a query routine, go enumerate values */
1104  if (QueryTable->QueryRoutine) goto ProcessValues;
1105  }
1106  }
1107  }
1108  else if (QueryTable->Name)
1109  {
1110  /* Initialize the path */
1111  RtlInitUnicodeString(&KeyValueName, QueryTable->Name);
1112 
1113  /* Start query loop */
1114  i = 0;
1115  while (TRUE)
1116  {
1117  /* Make sure we didn't retry too many times */
1118  if (i++ > 4)
1119  {
1120  /* Fail */
1121  DPRINT1("RtlQueryRegistryValues: Miscomputed buffer size "
1122  "at line %d\n", __LINE__);
1123  break;
1124  }
1125 
1126  /* Query key information */
1127  Status = ZwQueryValueKey(CurrentKey,
1128  &KeyValueName,
1130  KeyValueInfo,
1131  (ULONG)InfoSize,
1132  &ResultLength);
1134  {
1135  /* Normalize status code */
1137  }
1138 
1139  /* Check for failure */
1140  if (!NT_SUCCESS(Status))
1141  {
1142  /* Check if we didn't find it */
1144  {
1145  /* Setup a default */
1146  KeyValueInfo->Type = REG_NONE;
1147  KeyValueInfo->DataLength = 0;
1148  ResultLength = (ULONG)InfoSize;
1149 
1150  /* Call the query routine */
1152  KeyValueInfo,
1153  &ResultLength,
1154  Context,
1155  Environment);
1156  }
1157 
1158  /* Check for buffer being too small */
1160  {
1161  /* Increase allocation size */
1163  sizeof(ULONG_PTR) +
1164  sizeof(UNICODE_NULL);
1165  KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1166  KeyValueInfo,
1167  BufferSize,
1168  &Status);
1169  if (!KeyValueInfo) break;
1170 
1171  /* Update the data */
1172  KeyValueInfo->DataOffset = 0;
1173  InfoSize = BufferSize - sizeof(UNICODE_NULL);
1174  continue;
1175  }
1176  }
1177  else
1178  {
1179  /* Check if this is a multi-string */
1180  if (KeyValueInfo->Type == REG_MULTI_SZ)
1181  {
1182  /* Add a null-char */
1183  ((PWCHAR)KeyValueInfo)[ResultLength / sizeof(WCHAR)] = UNICODE_NULL;
1184  KeyValueInfo->DataLength += sizeof(UNICODE_NULL);
1185  }
1186 
1187  /* Call the query routine */
1188  ResultLength = (ULONG)InfoSize;
1190  KeyValueInfo,
1191  &ResultLength,
1192  Context,
1193  Environment);
1194 
1195  /* Check for buffer being too small */
1197  {
1198  /* Increase allocation size */
1200  sizeof(ULONG_PTR) +
1201  sizeof(UNICODE_NULL);
1202  KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1203  KeyValueInfo,
1204  BufferSize,
1205  &Status);
1206  if (!KeyValueInfo) break;
1207 
1208  /* Update the data */
1209  KeyValueInfo->DataOffset = 0;
1210  InfoSize = BufferSize - sizeof(UNICODE_NULL);
1211  continue;
1212  }
1213 
1214  /* Check if we need to delete the key */
1215  if ((NT_SUCCESS(Status)) &&
1217  {
1218  /* Delete it */
1219  ZwDeleteValueKey(CurrentKey, &KeyValueName);
1220  }
1221  }
1222 
1223  /* We're done, break out */
1224  break;
1225  }
1226  }
1228  {
1229  /* Just call the query routine */
1231  REG_NONE,
1232  NULL,
1233  0,
1234  Context,
1236  }
1237  else
1238  {
1239 ProcessValues:
1240  /* Loop every value */
1241  i = Value = 0;
1242  while (TRUE)
1243  {
1244  /* Enumerate the keys */
1245  Status = ZwEnumerateValueKey(CurrentKey,
1246  Value,
1248  KeyValueInfo,
1249  (ULONG)InfoSize,
1250  &ResultLength);
1252  {
1253  /* Normalize the status */
1255  }
1256 
1257  /* Check if we found all the entries */
1259  {
1260  /* Check if this was the first entry and caller needs it */
1261  if (!(Value) &&
1263  {
1264  /* Fail */
1266  }
1267  else
1268  {
1269  /* Otherwise, it's ok */
1271  }
1272  break;
1273  }
1274 
1275  /* Check if enumeration worked */
1276  if (NT_SUCCESS(Status))
1277  {
1278  /* Call the query routine */
1279  ResultLength = (ULONG)InfoSize;
1281  KeyValueInfo,
1282  &ResultLength,
1283  Context,
1284  Environment);
1285  }
1286 
1287  /* Check if the query failed */
1289  {
1290  /* Increase allocation size */
1292  sizeof(ULONG_PTR) +
1293  sizeof(UNICODE_NULL);
1294  KeyValueInfo = RtlpAllocDeallocQueryBuffer(&BufferSize,
1295  KeyValueInfo,
1296  BufferSize,
1297  &Status);
1298  if (!KeyValueInfo) break;
1299 
1300  /* Update the data */
1301  KeyValueInfo->DataOffset = 0;
1302  InfoSize = BufferSize - sizeof(UNICODE_NULL);
1303 
1304  /* Try the value again unless it's been too many times */
1305  if (i++ <= 4) continue;
1306  break;
1307  }
1308 
1309  /* Break out if we failed */
1310  if (!NT_SUCCESS(Status)) break;
1311 
1312  /* Reset the number of retries and check if we need to delete */
1313  i = 0;
1315  {
1316  /* Build the name */
1317  RtlInitEmptyUnicodeString(&KeyValueName,
1318  KeyValueInfo->Name,
1319  (USHORT)KeyValueInfo->NameLength);
1320  KeyValueName.Length = KeyValueName.MaximumLength;
1321 
1322  /* Delete the key */
1323  Status = ZwDeleteValueKey(CurrentKey, &KeyValueName);
1324  if (NT_SUCCESS(Status)) Value--;
1325  }
1326 
1327  /* Go to the next value */
1328  Value++;
1329  }
1330  }
1331 
1332  /* Check if we failed anywhere along the road */
1333  if (!NT_SUCCESS(Status)) break;
1334 
1335  /* Continue */
1336  QueryTable++;
1337  }
1338 
1339  /* Check if we need to close our handle */
1340  if (KeyHandle) RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
1341  if ((CurrentKey) && (CurrentKey != KeyHandle)) ZwClose(CurrentKey);
1342 
1343  /* Free our buffer and return status */
1344  RtlpAllocDeallocQueryBuffer(NULL, KeyValueInfo, BufferSize, NULL);
1345  return Status;
1346 }
1347 
1348 /* EOF */
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
signed char * PCHAR
Definition: retypes.h:7
* PNTSTATUS
Definition: strlen.c:14
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
_Must_inspect_result_ typedef _In_ PVOID Unused
Definition: iotypes.h:1129
const uint16_t * PCWSTR
Definition: typedefs.h:55
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:45
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define RTL_QUERY_REGISTRY_NOVALUE
Definition: nt_native.h:135
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG TitleIndex
Definition: reg.c:130
static LONG(WINAPI *pRegCopyTreeA)(HKEY
Type
Definition: Type.h:6
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS NTAPI RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle)
Definition: registry.c:699
NTSTATUS NTAPI RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PKEY_VALUE_FULL_INFORMATION KeyValueInfo, IN OUT PULONG InfoSize, IN PVOID Context, IN PVOID Environment)
Definition: registry.c:127
#define REG_BINARY
Definition: nt_native.h:1496
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
_In_ BOOLEAN Create
Definition: pstypes.h:511
#define RTL_QUERY_REGISTRY_TOPKEY
Definition: nt_native.h:129
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSYSAPI NTSTATUS NTAPI ZwOpenProcessTokenEx(_In_ HANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
#define NtCurrentThread()
#define RTL_QUERY_REGISTRY_NOEXPAND
Definition: nt_native.h:139
#define OBJ_PERMANENT
Definition: winternl.h:226
static PVOID
Definition: registry.c:44
#define RtlpAllocateStringMemory
Definition: rtlp.h:140
VOID NTAPI RtlpFreeMemory(_In_ PVOID Mem, _In_ ULONG Tag)
Definition: rtlcompat.c:45
uint16_t * PWCHAR
Definition: typedefs.h:54
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
NTSYSAPI NTSTATUS NTAPI ZwOpenThreadTokenEx(_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
#define RTL_REGISTRY_USER
Definition: nt_native.h:166
_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
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define RTL_QUERY_REGISTRY_DELETE
Definition: nt_native.h:153
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
PVOID NTAPI RtlpAllocateMemory(_In_ ULONG Bytes, _In_ ULONG Tag)
Definition: rtlcompat.c:34
long LONG
Definition: pedump.c:60
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define GENERIC_WRITE
Definition: nt_native.h:90
struct NameRec_ * Name
Definition: cdprocs.h:464
NTSTATUS NTAPI RtlpNtMakeTemporaryKey(IN HANDLE KeyHandle)
Definition: registry.c:901
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
#define FORCEINLINE
Definition: ntbasedef.h:221
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1104
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
Definition: bufpool.h:45
NTSTATUS NTAPI RtlpQueryRegistryDirect(IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Buffer)
Definition: registry.c:39
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
_Success_(return!=NULL||BufferSize==0)
Definition: registry.c:427
NTSTATUS NTAPI RtlpNtOpenKey(OUT HANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG Unused)
Definition: registry.c:912
SIZE_T RtlpAllocDeallocQueryBufferSize
Definition: libsupp.c:17
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define PCHAR
Definition: match.c:90
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
NTSYSAPI NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PCWSTR, const UNICODE_STRING *, UNICODE_STRING *, ULONG *)
NTSTATUS NTAPI RtlFormatCurrentUserKeyPath(OUT PUNICODE_STRING KeyPath)
Definition: registry.c:742
FORCEINLINE VOID RtlpCloseRegistryHandle(_In_ ULONG RelativeTo, _In_ HANDLE KeyHandle)
Definition: registry.c:564
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define _Out_opt_
Definition: no_sal2.h:339
struct _SID_AND_ATTRIBUTES * PSID_AND_ATTRIBUTES
Definition: security.c:129
#define __drv_allocatesMem(kind)
Definition: driverspecs.h:239
#define TOKEN_QUERY
Definition: setypes.h:874
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
const GLubyte * c
Definition: glext.h:8905
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
#define BufferSize
Definition: classpnp.h:419
PVOID HANDLE
Definition: typedefs.h:71
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2891
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define STATUS_NO_TOKEN
Definition: ntstatus.h:346
NTSYSAPI NTSTATUS NTAPI RtlConvertSidToUnicodeString(OUT PUNICODE_STRING DestinationString, IN PVOID Sid, IN BOOLEAN AllocateDestinationString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTATUS NTAPI RtlpNtEnumerateSubKey(IN HANDLE KeyHandle, OUT PUNICODE_STRING SubKeyName, IN ULONG Index, IN ULONG Unused)
Definition: registry.c:844
unsigned char UCHAR
Definition: xmlstorage.h:181
PCWSTR RtlpRegPaths[RTL_REGISTRY_MAXIMUM]
Definition: registry.c:25
NTSTATUS NTAPI RtlpNtQueryValueKey(IN HANDLE KeyHandle, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL, IN ULONG Unused)
Definition: registry.c:933
static const WCHAR L[]
Definition: oid.c:1250
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
#define GENERIC_READ
Definition: compat.h:124
NTSTATUS NTAPI RtlWriteRegistryValue(IN ULONG RelativeTo, IN PCWSTR Path, IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength)
Definition: registry.c:661
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define TAG_USTR
Definition: libsupp.c:111
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
NTSTATUS NTAPI RtlpGetRegistryHandle(IN ULONG RelativeTo, IN PCWSTR Path, IN BOOLEAN Create, IN PHANDLE KeyHandle)
Definition: registry.c:459
NTSTATUS NTAPI RtlQueryRegistryValues(IN ULONG RelativeTo, IN PCWSTR Path, IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PVOID Context, IN PVOID Environment OPTIONAL)
Definition: registry.c:1010
PRTL_UNICODE_STRING_BUFFER Path
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI RtlpNtCreateKey(OUT HANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class, OUT PULONG Disposition)
Definition: registry.c:815
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
NTSTATUS NTAPI RtlpNtSetValueKey(IN HANDLE KeyHandle, IN ULONG Type, IN PVOID Data, IN ULONG DataLength)
Definition: registry.c:988
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
_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
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
#define _On_failure_(annos)
Definition: no_sal2.h:322
#define _When_(expr, annos)
Definition: no_sal2.h:639
#define __drv_freesMem(kind)
Definition: driverspecs.h:254
#define _Post_satisfies_(a)
Definition: btrfs_drv.h:195
#define MAXUSHORT
Definition: typedefs.h:81
struct _UNICODE_STRING UNICODE_STRING
#define DPRINT1
Definition: precomp.h:8
#define TAG_RTLREGISTRY
Definition: registry.c:19
NTSTATUS NTAPI RtlCheckRegistryKey(IN ULONG RelativeTo, IN PWSTR Path)
Definition: registry.c:583
#define OUT
Definition: typedefs.h:39
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RTL_REGISTRY_MAXIMUM
Definition: nt_native.h:167
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define REG_NONE
Definition: nt_native.h:1492
GLfloat GLfloat p
Definition: glext.h:8902
NTSTATUS NTAPI RtlCreateRegistryKey(IN ULONG RelativeTo, IN PWSTR Path)
Definition: registry.c:607
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSTATUS NTAPI RtlDeleteRegistryValue(IN ULONG RelativeTo, IN PCWSTR Path, IN PCWSTR ValueName)
Definition: registry.c:631
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68