ReactOS 0.4.15-dev-6067-g0b695a6
hkcr.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/reg/hkcr.c
5 * PURPOSE: Registry functions - HKEY_CLASSES_ROOT abstraction
6 * PROGRAMMER: Jerôme Gardou (jerome.gardou@reactos.org)
7 */
8
9#include <advapi32.h>
10
11#include <ndk/cmfuncs.h>
12#include <pseh/pseh2.h>
13
14#include "reg.h"
15
17
18static const UNICODE_STRING HKLM_ClassesPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Classes");
19
20static
21LONG
23{
24 UNICODE_STRING InfoName;
25 PKEY_NAME_INFORMATION NameInformation;
26 ULONG InfoLength;
28
29 /* Get info length */
30 InfoLength = 0;
31 Status = NtQueryKey(hKey, KeyNameInformation, NULL, 0, &InfoLength);
33 {
34 ERR("NtQueryKey returned unexpected Status: 0x%08x\n", Status);
36 }
37
38 /* Get it for real */
39 NameInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, InfoLength);
40 if (NameInformation == NULL)
41 {
42 ERR("Failed to allocate %lu bytes\n", InfoLength);
44 }
45
46 Status = NtQueryKey(hKey, KeyNameInformation, NameInformation, InfoLength, &InfoLength);
47 if (!NT_SUCCESS(Status))
48 {
49 RtlFreeHeap(RtlGetProcessHeap(), 0, NameInformation);
50 ERR("NtQueryKey failed: 0x%08x\n", Status);
52 }
53
54 /* Make it a proper UNICODE_STRING */
55 InfoName.Length = NameInformation->NameLength;
56 InfoName.MaximumLength = NameInformation->NameLength;
57 InfoName.Buffer = NameInformation->Name;
58
60 if (!NT_SUCCESS(Status))
61 {
62 RtlFreeHeap(RtlGetProcessHeap(), 0, NameInformation);
63 ERR("RtlDuplicateUnicodeString failed: 0x%08x\n", Status);
65 }
66
67 RtlFreeHeap(RtlGetProcessHeap(), 0, NameInformation);
68
69 return ERROR_SUCCESS;
70}
71
72static
73LONG
76 _Out_ REGSAM* RegSam)
77{
79 OBJECT_BASIC_INFORMATION ObjectInfo;
80
81 Status = NtQueryObject(hKey, ObjectBasicInformation, &ObjectInfo, sizeof(ObjectInfo), NULL);
82 if (!NT_SUCCESS(Status))
83 {
84 ERR("NtQueryObject failed, Status %x08x\n", Status);
86 }
87
88 *RegSam = ObjectInfo.GrantedAccess;
89 return ERROR_SUCCESS;
90}
91
92/*
93 * Gets a HKLM key from an HKCU key.
94 */
95static
96LONG
99 _Out_ HKEY* MachineKey,
100 _In_ BOOL MustCreate)
101{
105 REGSAM SamDesired;
106
107 /* Get the key name */
110 return ErrorCode;
111
112 /* See if we really need a conversion */
114 {
116 *MachineKey = hKey;
117 return ERROR_SUCCESS;
118 }
119
120 SubKeyName = KeyName.Buffer + 15; /* 15 == wcslen(L"\\Registry\\User\\") */
121 /* Skip the user token */
122 while (*SubKeyName++ != L'\\')
123 {
124 if (!*SubKeyName)
125 {
126 ERR("Key name %S is invalid!\n", KeyName.Buffer);
128 }
129 }
130
131 /* Use the same access mask than the original key */
132 ErrorCode = GetKeySam(hKey, &SamDesired);
134 {
136 return ErrorCode;
137 }
138
139 if (MustCreate)
140 {
144 0,
145 NULL,
146 0,
147 SamDesired,
148 NULL,
149 MachineKey,
150 NULL);
151 }
152 else
153 {
154 /* Open the key. */
158 0,
159 SamDesired,
160 MachineKey);
161 }
162
164
165 return ErrorCode;
166}
167
168/* Get the HKCU key (if it exists) from an HKCR key */
169static
170LONG
172 _In_ HKEY hKey,
173 _Out_ HKEY* PreferredKey)
174{
178 REGSAM SamDesired;
179
180 /* Get the key name */
183 return ErrorCode;
184
185 /* See if we really need a conversion */
187 {
189 *PreferredKey = hKey;
190 return ERROR_SUCCESS;
191 }
192
193 /* 18 == wcslen(L"\\Registry\\Machine\\") */
194 SubKeyName = KeyName.Buffer + 18;
195
196 /* Use the same access mask than the original key */
197 ErrorCode = GetKeySam(hKey, &SamDesired);
199 {
201 return ErrorCode;
202 }
203
204 /* Open the key. */
208 0,
209 SamDesired,
210 PreferredKey);
211
213
214 return ErrorCode;
215}
216
217/* HKCR version of RegCreateKeyExW. */
218LONG
219WINAPI
221 _In_ HKEY hKey,
222 _In_ LPCWSTR lpSubKey,
224 _In_opt_ LPWSTR lpClass,
226 _In_ REGSAM samDesired,
227 _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
228 _Out_ PHKEY phkResult,
229 _Out_opt_ LPDWORD lpdwDisposition)
230{
232 HKEY QueriedKey, TestKey;
233
235
236 /* Remove the HKCR flag while we're working */
237 hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
238
239 ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey);
240
242 {
243 /* The current key doesn't exist on HKCU side, so we can only create it in HKLM */
245 hKey,
246 lpSubKey,
247 Reserved,
248 lpClass,
249 dwOptions,
250 samDesired,
251 lpSecurityAttributes,
252 phkResult,
253 lpdwDisposition);
255 MakeHKCRKey(phkResult);
256 return ErrorCode;
257 }
258
260 {
261 /* Somehow we failed for another reason (maybe deleted key or whatever) */
262 return ErrorCode;
263 }
264
265 /* See if the subkey already exists in HKCU. */
266 ErrorCode = RegOpenKeyExW(QueriedKey, lpSubKey, 0, READ_CONTROL, &TestKey);
268 {
270 {
271 /* Great. Close the test one and do the real create operation */
272 RegCloseKey(TestKey);
274 QueriedKey,
275 lpSubKey,
276 Reserved,
277 lpClass,
278 dwOptions,
279 samDesired,
280 lpSecurityAttributes,
281 phkResult,
282 lpdwDisposition);
284 MakeHKCRKey(phkResult);
285 }
286 if (QueriedKey != hKey)
287 RegCloseKey(QueriedKey);
288
289 return ERROR_SUCCESS;
290 }
291
292 if (QueriedKey != hKey)
293 RegCloseKey(QueriedKey);
294
295 /* So we must do the create operation in HKLM, creating the missing parent keys if needed. */
296 ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, TRUE);
298 return ErrorCode;
299
300 /* Do the key creation */
302 QueriedKey,
303 lpSubKey,
304 Reserved,
305 lpClass,
306 dwOptions,
307 samDesired,
308 lpSecurityAttributes,
309 phkResult,
310 lpdwDisposition);
311
312 if (QueriedKey != hKey)
313 RegCloseKey(QueriedKey);
314
316 MakeHKCRKey(phkResult);
317
318 return ErrorCode;
319}
320
321/* Same as RegOpenKeyExW, but for HKEY_CLASSES_ROOT subkeys */
322LONG
323WINAPI
325 _In_ HKEY hKey,
326 _In_ LPCWSTR lpSubKey,
327 _In_ DWORD ulOptions,
328 _In_ REGSAM samDesired,
329 _In_ PHKEY phkResult)
330{
331 HKEY QueriedKey;
333
335
336 /* Remove the HKCR flag while we're working */
337 hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
338
339 ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey);
340
342 {
343 /* The key doesn't exist on HKCU side, no chance for a subkey */
344 ErrorCode = RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
346 MakeHKCRKey(phkResult);
347 return ErrorCode;
348 }
349
351 {
352 /* Somehow we failed for another reason (maybe deleted key or whatever) */
353 return ErrorCode;
354 }
355
356 /* Try on the HKCU side */
357 ErrorCode = RegOpenKeyExW(QueriedKey, lpSubKey, ulOptions, samDesired, phkResult);
359 MakeHKCRKey(phkResult);
360
361 /* Close it if we must */
362 if (QueriedKey != hKey)
363 {
364 RegCloseKey(QueriedKey);
365 }
366
367 /* Anything else than ERROR_FILE_NOT_FOUND means that we found it, even if it is with failures. */
369 return ErrorCode;
370
371 /* If we're here, we must open from HKLM key. */
372 ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE);
374 {
375 /* Maybe the key doesn't exist in the HKLM view */
376 return ErrorCode;
377 }
378
379 ErrorCode = RegOpenKeyExW(QueriedKey, lpSubKey, ulOptions, samDesired, phkResult);
381 MakeHKCRKey(phkResult);
382
383 /* Close it if we must */
384 if (QueriedKey != hKey)
385 {
386 RegCloseKey(QueriedKey);
387 }
388
389 return ErrorCode;
390}
391
392/* HKCR version of RegDeleteKeyExW */
393LONG
394WINAPI
396 _In_ HKEY hKey,
397 _In_ LPCWSTR lpSubKey,
398 _In_ REGSAM RegSam,
400{
401 HKEY QueriedKey;
403
405
406 /* Remove the HKCR flag while we're working */
407 hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
408
409 ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey);
410
412 {
413 /* The key doesn't exist on HKCU side, no chance for a subkey */
414 return RegDeleteKeyExW(hKey, lpSubKey, RegSam, Reserved);
415 }
416
418 {
419 /* Somehow we failed for another reason (maybe deleted key or whatever) */
420 return ErrorCode;
421 }
422
423 ErrorCode = RegDeleteKeyExW(QueriedKey, lpSubKey, RegSam, Reserved);
424
425 /* Close it if we must */
426 if (QueriedKey != hKey)
427 {
428 /* The original key is on the machine view */
429 RegCloseKey(QueriedKey);
430 }
431
432 /* Anything else than ERROR_FILE_NOT_FOUND means that we found it, even if it is with failures. */
434 return ErrorCode;
435
436 /* If we're here, we must open from HKLM key. */
437 ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE);
439 {
440 /* Maybe the key doesn't exist in the HKLM view */
441 return ErrorCode;
442 }
443
444 ErrorCode = RegDeleteKeyExW(QueriedKey, lpSubKey, RegSam, Reserved);
445
446 /* Close it if we must */
447 if (QueriedKey != hKey)
448 {
449 RegCloseKey(QueriedKey);
450 }
451
452 return ErrorCode;
453}
454
455/* HKCR version of RegQueryValueExW */
456LONG
457WINAPI
459 _In_ HKEY hKey,
465{
466 HKEY QueriedKey;
468
470
471 /* Remove the HKCR flag while we're working */
472 hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
473
474 ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey);
475
477 {
478 /* The key doesn't exist on HKCU side, no chance for a value in it */
480 }
481
483 {
484 /* Somehow we failed for another reason (maybe deleted key or whatever) */
485 return ErrorCode;
486 }
487
489
490 /* Close it if we must */
491 if (QueriedKey != hKey)
492 {
493 /* The original key is on the machine view */
494 RegCloseKey(QueriedKey);
495 }
496
497 /* Anything else than ERROR_FILE_NOT_FOUND means that we found it, even if it is with failures. */
499 return ErrorCode;
500
501 /* If we're here, we must open from HKLM key. */
502 ErrorCode = GetFallbackHKCRKey(hKey, &QueriedKey, FALSE);
504 {
505 /* Maybe the key doesn't exist in the HKLM view */
506 return ErrorCode;
507 }
508
510
511 /* Close it if we must */
512 if (QueriedKey != hKey)
513 {
514 RegCloseKey(QueriedKey);
515 }
516
517 return ErrorCode;
518}
519
520/* HKCR version of RegSetValueExW */
521LONG
522WINAPI
524 _In_ HKEY hKey,
530{
531 HKEY QueriedKey;
533
535
536 /* Remove the HKCR flag while we're working */
537 hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
538
539 ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey);
540
542 {
543 /* The key doesn't exist on HKCU side, no chance to put a value in it */
545 }
546
548 {
549 /* Somehow we failed for another reason (maybe deleted key or whatever) */
550 return ErrorCode;
551 }
552
553 /* Check if the value already exists in the preferred key */
554 ErrorCode = RegQueryValueExW(QueriedKey, Name, NULL, NULL, NULL, NULL);
556 {
558 {
559 /* Yes, so we have the right to modify it */
561 }
562 if (QueriedKey != hKey)
563 RegCloseKey(QueriedKey);
564 return ErrorCode;
565 }
566 if (QueriedKey != hKey)
567 RegCloseKey(QueriedKey);
568
569 /* So we must set the value in the HKLM version */
570 ErrorCode = GetPreferredHKCRKey(hKey, &QueriedKey);
572 {
573 /* No choice: put this in HKCU */
575 }
576 else if (ErrorCode != ERROR_SUCCESS)
577 {
578 return ErrorCode;
579 }
580
582
583 if (QueriedKey != hKey)
584 RegCloseKey(QueriedKey);
585
586 return ErrorCode;
587}
588
589/* HKCR version of RegEnumKeyExW */
590LONG
591WINAPI
593 _In_ HKEY hKey,
594 _In_ DWORD dwIndex,
596 _Inout_ LPDWORD lpcbName,
597 _Reserved_ LPDWORD lpReserved,
598 _Out_opt_ LPWSTR lpClass,
599 _Inout_opt_ LPDWORD lpcbClass,
600 _Out_opt_ PFILETIME lpftLastWriteTime)
601{
602 HKEY PreferredKey, FallbackKey;
603 DWORD NumPreferredSubKeys;
604 DWORD MaxFallbackSubKeyLen;
605 DWORD FallbackIndex;
606 WCHAR* FallbackSubKeyName = NULL;
608
610
611 /* Remove the HKCR flag while we're working */
612 hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
613
614 /* Get the preferred key */
615 ErrorCode = GetPreferredHKCRKey(hKey, &PreferredKey);
617 {
619 {
620 /* Only the HKLM key exists */
621 return RegEnumKeyExW(
622 hKey,
623 dwIndex,
624 lpName,
625 lpcbName,
626 lpReserved,
627 lpClass,
628 lpcbClass,
629 lpftLastWriteTime);
630 }
631 return ErrorCode;
632 }
633
634 /* Get the fallback key */
635 ErrorCode = GetFallbackHKCRKey(hKey, &FallbackKey, FALSE);
637 {
638 if (PreferredKey != hKey)
639 RegCloseKey(PreferredKey);
641 {
642 /* Only the HKCU key exists */
643 return RegEnumKeyExW(
644 hKey,
645 dwIndex,
646 lpName,
647 lpcbName,
648 lpReserved,
649 lpClass,
650 lpcbClass,
651 lpftLastWriteTime);
652 }
653 return ErrorCode;
654 }
655
656 /* Get some info on the HKCU side */
658 PreferredKey,
659 NULL,
660 NULL,
661 NULL,
662 &NumPreferredSubKeys,
663 NULL,
664 NULL,
665 NULL,
666 NULL,
667 NULL,
668 NULL,
669 NULL);
671 goto Exit;
672
673 if (dwIndex < NumPreferredSubKeys)
674 {
675 /* HKCU side takes precedence */
677 PreferredKey,
678 dwIndex,
679 lpName,
680 lpcbName,
681 lpReserved,
682 lpClass,
683 lpcbClass,
684 lpftLastWriteTime);
685 goto Exit;
686 }
687
688 /* Here it gets tricky. We must enumerate the values from the HKLM side,
689 * without reporting those which are present on the HKCU side */
690
691 /* Squash out the indices from HKCU */
692 dwIndex -= NumPreferredSubKeys;
693
694 /* Get some info */
696 FallbackKey,
697 NULL,
698 NULL,
699 NULL,
700 NULL,
701 &MaxFallbackSubKeyLen,
702 NULL,
703 NULL,
704 NULL,
705 NULL,
706 NULL,
707 NULL);
709 {
710 ERR("Could not query info of key %p (Err: %d)\n", FallbackKey, ErrorCode);
711 goto Exit;
712 }
713
714 MaxFallbackSubKeyLen++;
715 TRACE("Maxfallbacksubkeylen: %d\n", MaxFallbackSubKeyLen);
716
717 /* Allocate our buffer */
718 FallbackSubKeyName = RtlAllocateHeap(
719 RtlGetProcessHeap(), 0, MaxFallbackSubKeyLen * sizeof(WCHAR));
720 if (!FallbackSubKeyName)
721 {
723 goto Exit;
724 }
725
726 /* We must begin at the very first subkey of the fallback key,
727 * and then see if we meet keys that already are in the preferred key.
728 * In that case, we must bump dwIndex, as otherwise we would enumerate a key we already
729 * saw in a previous call.
730 */
731 FallbackIndex = 0;
732 while (TRUE)
733 {
734 HKEY PreferredSubKey;
735 DWORD FallbackSubkeyLen = MaxFallbackSubKeyLen;
736
737 /* Try enumerating */
739 FallbackKey,
740 FallbackIndex,
741 FallbackSubKeyName,
742 &FallbackSubkeyLen,
743 NULL,
744 NULL,
745 NULL,
746 NULL);
748 {
750 ERR("Returning %d.\n", ErrorCode);
751 goto Exit;
752 }
753 FallbackSubKeyName[FallbackSubkeyLen] = L'\0';
754
755 /* See if there is such a value on HKCU side */
757 PreferredKey,
758 FallbackSubKeyName,
759 0,
761 &PreferredSubKey);
762
764 {
765 RegCloseKey(PreferredSubKey);
766 /* So we already enumerated it on HKCU side. */
767 dwIndex++;
768 }
770 {
771 ERR("Got error %d while querying for %s on HKCU side.\n", ErrorCode, FallbackSubKeyName);
772 goto Exit;
773 }
774
775 /* See if we caught up */
776 if (FallbackIndex == dwIndex)
777 break;
778
779 FallbackIndex++;
780 }
781
782 /* We can finally enumerate on the fallback side */
784 FallbackKey,
785 dwIndex,
786 lpName,
787 lpcbName,
788 lpReserved,
789 lpClass,
790 lpcbClass,
791 lpftLastWriteTime);
792
793Exit:
794 if (PreferredKey != hKey)
795 RegCloseKey(PreferredKey);
796 if (FallbackKey != hKey)
797 RegCloseKey(FallbackKey);
798 if (FallbackSubKeyName)
799 RtlFreeHeap(RtlGetProcessHeap(), 0, FallbackSubKeyName);
800
801 return ErrorCode;
802}
803
804/* HKCR version of RegEnumValueW */
805LONG
806WINAPI
808 _In_ HKEY hKey,
809 _In_ DWORD dwIndex,
811 _Inout_ PDWORD lpcbName,
812 _Reserved_ PDWORD lpReserved,
813 _Out_opt_ PDWORD lpdwType,
814 _Out_opt_ LPBYTE lpData,
815 _Inout_opt_ PDWORD lpcbData)
816{
817 HKEY PreferredKey, FallbackKey;
818 DWORD NumPreferredValues;
819 DWORD MaxFallbackValueNameLen;
820 DWORD FallbackIndex;
821 WCHAR* FallbackValueName = NULL;
823
825
826 /* Remove the HKCR flag while we're working */
827 hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
828
829 /* Get the preferred key */
830 ErrorCode = GetPreferredHKCRKey(hKey, &PreferredKey);
832 {
834 {
835 /* Only the HKLM key exists */
836 return RegEnumValueW(
837 hKey,
838 dwIndex,
839 lpName,
840 lpcbName,
841 lpReserved,
842 lpdwType,
843 lpData,
844 lpcbData);
845 }
846 return ErrorCode;
847 }
848
849 /* Get the fallback key */
850 ErrorCode = GetFallbackHKCRKey(hKey, &FallbackKey, FALSE);
852 {
853 if (PreferredKey != hKey)
854 RegCloseKey(PreferredKey);
856 {
857 /* Only the HKCU key exists */
858 return RegEnumValueW(
859 hKey,
860 dwIndex,
861 lpName,
862 lpcbName,
863 lpReserved,
864 lpdwType,
865 lpData,
866 lpcbData);
867 }
868 return ErrorCode;
869 }
870
871 /* Get some info on the HKCU side */
873 PreferredKey,
874 NULL,
875 NULL,
876 NULL,
877 NULL,
878 NULL,
879 NULL,
880 &NumPreferredValues,
881 NULL,
882 NULL,
883 NULL,
884 NULL);
886 goto Exit;
887
888 if (dwIndex < NumPreferredValues)
889 {
890 /* HKCU side takes precedence */
891 return RegEnumValueW(
892 PreferredKey,
893 dwIndex,
894 lpName,
895 lpcbName,
896 lpReserved,
897 lpdwType,
898 lpData,
899 lpcbData);
900 goto Exit;
901 }
902
903 /* Here it gets tricky. We must enumerate the values from the HKLM side,
904 * without reporting those which are present on the HKCU side */
905
906 /* Squash out the indices from HKCU */
907 dwIndex -= NumPreferredValues;
908
909 /* Get some info */
911 FallbackKey,
912 NULL,
913 NULL,
914 NULL,
915 NULL,
916 NULL,
917 NULL,
918 NULL,
919 &MaxFallbackValueNameLen,
920 NULL,
921 NULL,
922 NULL);
924 {
925 ERR("Could not query info of key %p (Err: %d)\n", FallbackKey, ErrorCode);
926 goto Exit;
927 }
928
929 MaxFallbackValueNameLen++;
930 TRACE("Maxfallbacksubkeylen: %d\n", MaxFallbackValueNameLen);
931
932 /* Allocate our buffer */
933 FallbackValueName = RtlAllocateHeap(
934 RtlGetProcessHeap(), 0, MaxFallbackValueNameLen * sizeof(WCHAR));
935 if (!FallbackValueName)
936 {
938 goto Exit;
939 }
940
941 /* We must begin at the very first subkey of the fallback key,
942 * and then see if we meet keys that already are in the preferred key.
943 * In that case, we must bump dwIndex, as otherwise we would enumerate a key we already
944 * saw in a previous call.
945 */
946 FallbackIndex = 0;
947 while (TRUE)
948 {
949 DWORD FallbackValueNameLen = MaxFallbackValueNameLen;
950
951 /* Try enumerating */
953 FallbackKey,
954 FallbackIndex,
955 FallbackValueName,
956 &FallbackValueNameLen,
957 NULL,
958 NULL,
959 NULL,
960 NULL);
962 {
964 ERR("Returning %d.\n", ErrorCode);
965 goto Exit;
966 }
967 FallbackValueName[FallbackValueNameLen] = L'\0';
968
969 /* See if there is such a value on HKCU side */
971 PreferredKey,
972 FallbackValueName,
973 NULL,
974 NULL,
975 NULL,
976 NULL);
977
979 {
980 /* So we already enumerated it on HKCU side. */
981 dwIndex++;
982 }
984 {
985 ERR("Got error %d while querying for %s on HKCU side.\n", ErrorCode, FallbackValueName);
986 goto Exit;
987 }
988
989 /* See if we caught up */
990 if (FallbackIndex == dwIndex)
991 break;
992
993 FallbackIndex++;
994 }
995
996 /* We can finally enumerate on the fallback side */
998 FallbackKey,
999 dwIndex,
1000 lpName,
1001 lpcbName,
1002 lpReserved,
1003 lpdwType,
1004 lpData,
1005 lpcbData);
1006
1007Exit:
1008 if (PreferredKey != hKey)
1009 RegCloseKey(PreferredKey);
1010 if (FallbackKey != hKey)
1011 RegCloseKey(FallbackKey);
1012 if (FallbackValueName)
1013 RtlFreeHeap(RtlGetProcessHeap(), 0, FallbackValueName);
1014
1015 return ErrorCode;
1016}
@ ObjectBasicInformation
Definition: DriverTester.h:54
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
Type
Definition: Type.h:7
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: debug.h:110
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE HKEY
Definition: registry.h:26
#define RegCloseKey(hKey)
Definition: registry.h:47
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3353
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2524
LONG WINAPI RegDeleteKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1281
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4897
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2850
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3687
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4118
FORCEINLINE BOOL IsHKCRKey(_In_ HKEY hKey)
Definition: reg.h:13
FORCEINLINE void MakeHKCRKey(_Inout_ HKEY *hKey)
Definition: reg.h:20
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
LONG WINAPI CreateHKCRKey(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: hkcr.c:220
static LONG GetFallbackHKCRKey(_In_ HKEY hKey, _Out_ HKEY *MachineKey, _In_ BOOL MustCreate)
Definition: hkcr.c:97
LONG WINAPI QueryHKCRValue(_In_ HKEY hKey, _In_ LPCWSTR Name, _In_ LPDWORD Reserved, _In_ LPDWORD Type, _In_ LPBYTE Data, _In_ LPDWORD Count)
Definition: hkcr.c:458
LONG WINAPI EnumHKCRValue(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ PDWORD lpcbName, _Reserved_ PDWORD lpReserved, _Out_opt_ PDWORD lpdwType, _Out_opt_ LPBYTE lpData, _Inout_opt_ PDWORD lpcbData)
Definition: hkcr.c:807
static LONG GetKeySam(_In_ HKEY hKey, _Out_ REGSAM *RegSam)
Definition: hkcr.c:74
LONG WINAPI SetHKCRValue(_In_ HKEY hKey, _In_ LPCWSTR Name, _In_ DWORD Reserved, _In_ DWORD Type, _In_ CONST BYTE *Data, _In_ DWORD DataSize)
Definition: hkcr.c:523
static const UNICODE_STRING HKLM_ClassesPath
Definition: hkcr.c:18
LONG WINAPI OpenHKCRKey(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _In_ PHKEY phkResult)
Definition: hkcr.c:324
static LONG GetPreferredHKCRKey(_In_ HKEY hKey, _Out_ HKEY *PreferredKey)
Definition: hkcr.c:171
LONG WINAPI DeleteHKCRKey(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ REGSAM RegSam, _In_ DWORD Reserved)
Definition: hkcr.c:395
static LONG GetKeyName(HKEY hKey, PUNICODE_STRING KeyName)
Definition: hkcr.c:22
LONG WINAPI EnumHKCRKey(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: hkcr.c:592
static int reg
Definition: i386-dis.c:1290
@ KeyNameInformation
Definition: winternl.h:831
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define ASSERT(a)
Definition: mode.c:44
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define _Out_opt_
Definition: ms_sal.h:346
#define _Inout_
Definition: ms_sal.h:378
#define _Inout_opt_
Definition: ms_sal.h:379
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define _Reserved_
Definition: ms_sal.h:295
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4725
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
int Count
Definition: noreturn.cpp:7
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define READ_CONTROL
Definition: nt_native.h:58
NTSTATUS NTAPI NtQueryKey(IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:632
#define L(x)
Definition: ntvdm.h:50
#define CONST
Definition: pedump.c:81
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwOptions
Definition: solitaire.cpp:24
ACCESS_MASK GrantedAccess
Definition: winternl.h:1251
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_In_ LPCSTR lpName
Definition: winbase.h:2776
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define WINAPI
Definition: msvc.h:6
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RegCreateKeyEx
Definition: winreg.h:501
ACCESS_MASK REGSAM
Definition: winreg.h:69
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193