1 /* $Id: reg.c,v 1.57 2004/09/13 14:42:37 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/reg/reg.c
6 * PURPOSE: Registry functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
13 /* INCLUDES *****************************************************************/
19 /* DEFINES ******************************************************************/
21 #define MAX_DEFAULT_HANDLES 6
22 #define REG_MAX_NAME_SIZE 256
23 #define REG_MAX_DATA_SIZE 2048
25 /* GLOBALS ******************************************************************/
27 static CRITICAL_SECTION HandleTableCS
;
28 static HANDLE DefaultHandleTable
[MAX_DEFAULT_HANDLES
];
29 static HANDLE ProcessHeap
;
31 /* PROTOTYPES ***************************************************************/
33 static NTSTATUS
MapDefaultKey (PHANDLE ParentKey
, HKEY Key
);
34 static VOID
CloseDefaultKeys(VOID
);
36 static NTSTATUS
OpenClassesRootKey(PHANDLE KeyHandle
);
37 static NTSTATUS
OpenLocalMachineKey (PHANDLE KeyHandle
);
38 static NTSTATUS
OpenUsersKey (PHANDLE KeyHandle
);
39 static NTSTATUS
OpenCurrentConfigKey(PHANDLE KeyHandle
);
42 /* FUNCTIONS ****************************************************************/
44 /************************************************************************
45 * RegInitDefaultHandles
50 DPRINT("RegInitialize()\n");
52 ProcessHeap
= RtlGetProcessHeap();
53 RtlZeroMemory (DefaultHandleTable
,
54 MAX_DEFAULT_HANDLES
* sizeof(HANDLE
));
55 RtlInitializeCriticalSection (&HandleTableCS
);
61 /************************************************************************
67 DPRINT("RegCleanup()\n");
70 RtlDeleteCriticalSection (&HandleTableCS
);
77 MapDefaultKey (PHANDLE RealKey
,
82 NTSTATUS Status
= STATUS_SUCCESS
;
84 DPRINT("MapDefaultKey (Key %x)\n", Key
);
86 if (((ULONG
)Key
& 0xF0000000) != 0x80000000)
88 *RealKey
= (HANDLE
)Key
;
89 return STATUS_SUCCESS
;
92 /* Handle special cases here */
93 Index
= (ULONG
)Key
& 0x0FFFFFFF;
94 if (Index
>= MAX_DEFAULT_HANDLES
)
96 return STATUS_INVALID_PARAMETER
;
99 RtlEnterCriticalSection (&HandleTableCS
);
100 Handle
= &DefaultHandleTable
[Index
];
103 /* create/open the default handle */
106 case 0: /* HKEY_CLASSES_ROOT */
107 Status
= OpenClassesRootKey (Handle
);
110 case 1: /* HKEY_CURRENT_USER */
111 Status
= RtlOpenCurrentUser (MAXIMUM_ALLOWED
,
115 case 2: /* HKEY_LOCAL_MACHINE */
116 Status
= OpenLocalMachineKey (Handle
);
119 case 3: /* HKEY_USERS */
120 Status
= OpenUsersKey (Handle
);
123 case 4: /* HKEY_PERFORMANCE_DATA */
124 Status
= OpenPerformanceDataKey (Handle
);
127 case 5: /* HKEY_CURRENT_CONFIG */
128 Status
= OpenCurrentConfigKey (Handle
);
131 case 6: /* HKEY_DYN_DATA */
132 Status
= STATUS_NOT_IMPLEMENTED
;
136 DPRINT("MapDefaultHandle() no handle creator\n");
137 Status
= STATUS_INVALID_PARAMETER
;
140 RtlLeaveCriticalSection (&HandleTableCS
);
142 if (NT_SUCCESS(Status
))
152 CloseDefaultKeys (VOID
)
156 RtlEnterCriticalSection (&HandleTableCS
);
157 for (i
= 0; i
< MAX_DEFAULT_HANDLES
; i
++)
159 if (DefaultHandleTable
[i
] != NULL
)
161 NtClose (DefaultHandleTable
[i
]);
162 DefaultHandleTable
[i
] = NULL
;
165 RtlLeaveCriticalSection (&HandleTableCS
);
170 OpenClassesRootKey (PHANDLE KeyHandle
)
172 OBJECT_ATTRIBUTES Attributes
;
173 UNICODE_STRING KeyName
= ROS_STRING_INITIALIZER(L
"\\Registry\\Machine\\Software\\CLASSES");
175 DPRINT("OpenClassesRootKey()\n");
177 InitializeObjectAttributes (&Attributes
,
179 OBJ_CASE_INSENSITIVE
,
182 return NtOpenKey (KeyHandle
,
189 OpenLocalMachineKey (PHANDLE KeyHandle
)
191 OBJECT_ATTRIBUTES Attributes
;
192 UNICODE_STRING KeyName
= ROS_STRING_INITIALIZER(L
"\\Registry\\Machine");
195 DPRINT("OpenLocalMachineKey()\n");
197 InitializeObjectAttributes (&Attributes
,
199 OBJ_CASE_INSENSITIVE
,
202 Status
= NtOpenKey (KeyHandle
,
206 DPRINT("NtOpenKey(%wZ) => %08x\n", &KeyName
, Status
);
212 OpenUsersKey (PHANDLE KeyHandle
)
214 OBJECT_ATTRIBUTES Attributes
;
215 UNICODE_STRING KeyName
= ROS_STRING_INITIALIZER(L
"\\Registry\\User");
217 DPRINT("OpenUsersKey()\n");
219 InitializeObjectAttributes (&Attributes
,
221 OBJ_CASE_INSENSITIVE
,
224 return NtOpenKey (KeyHandle
,
231 OpenCurrentConfigKey (PHANDLE KeyHandle
)
233 OBJECT_ATTRIBUTES Attributes
;
234 UNICODE_STRING KeyName
=
235 ROS_STRING_INITIALIZER(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
237 DPRINT("OpenCurrentConfigKey()\n");
239 InitializeObjectAttributes (&Attributes
,
241 OBJ_CASE_INSENSITIVE
,
244 return NtOpenKey (KeyHandle
,
250 /************************************************************************
256 RegCloseKey (HKEY hKey
)
261 /* don't close null handle or a pseudo handle */
262 if ((!hKey
) || (((ULONG
)hKey
& 0xF0000000) == 0x80000000))
264 return ERROR_INVALID_HANDLE
;
267 Status
= NtClose (hKey
);
268 if (!NT_SUCCESS(Status
))
270 ErrorCode
= RtlNtStatusToDosError (Status
);
271 SetLastError (ErrorCode
);
275 return ERROR_SUCCESS
;
279 /************************************************************************
280 * RegConnectRegistryA
285 RegConnectRegistryA (LPCSTR lpMachineName
,
289 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
290 return ERROR_CALL_NOT_IMPLEMENTED
;
294 /************************************************************************
295 * RegConnectRegistryW
300 RegConnectRegistryW (LPCWSTR lpMachineName
,
304 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
305 return ERROR_CALL_NOT_IMPLEMENTED
;
309 /************************************************************************
312 * Create key and all necessary intermediate keys
315 CreateNestedKey(PHKEY KeyHandle
,
316 POBJECT_ATTRIBUTES ObjectAttributes
,
317 PUNICODE_STRING ClassString
,
320 DWORD
*lpdwDisposition
)
322 OBJECT_ATTRIBUTES LocalObjectAttributes
;
323 UNICODE_STRING LocalKeyName
;
326 ULONG FullNameLength
;
329 HANDLE LocalKeyHandle
;
331 Status
= NtCreateKey((PHANDLE
) KeyHandle
,
337 (PULONG
)lpdwDisposition
);
338 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes
->ObjectName
, Status
);
339 if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
342 /* Copy object attributes */
343 RtlCopyMemory (&LocalObjectAttributes
,
345 sizeof(OBJECT_ATTRIBUTES
));
346 RtlCreateUnicodeString (&LocalKeyName
,
347 ObjectAttributes
->ObjectName
->Buffer
);
348 LocalObjectAttributes
.ObjectName
= &LocalKeyName
;
349 FullNameLength
= LocalKeyName
.Length
/ sizeof(WCHAR
);
351 /* Remove the last part of the key name and try to create the key again. */
352 while (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
354 Ptr
= wcsrchr (LocalKeyName
.Buffer
, '\\');
355 if (Ptr
== NULL
|| Ptr
== LocalKeyName
.Buffer
)
357 Status
= STATUS_UNSUCCESSFUL
;
361 LocalKeyName
.Length
= wcslen (LocalKeyName
.Buffer
) * sizeof(WCHAR
);
363 Status
= NtCreateKey (&LocalKeyHandle
,
365 &LocalObjectAttributes
,
370 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName
, Status
);
373 if (!NT_SUCCESS(Status
))
375 RtlFreeUnicodeString (&LocalKeyName
);
379 /* Add removed parts of the key name and create them too. */
380 Length
= wcslen (LocalKeyName
.Buffer
);
383 NtClose (LocalKeyHandle
);
385 LocalKeyName
.Buffer
[Length
] = L
'\\';
386 Length
= wcslen (LocalKeyName
.Buffer
);
387 LocalKeyName
.Length
= Length
* sizeof(WCHAR
);
389 if (Length
== FullNameLength
)
391 Status
= NtCreateKey((PHANDLE
) KeyHandle
,
397 (PULONG
)lpdwDisposition
);
400 Status
= NtCreateKey (&LocalKeyHandle
,
402 &LocalObjectAttributes
,
407 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName
, Status
);
408 if (!NT_SUCCESS(Status
))
412 RtlFreeUnicodeString (&LocalKeyName
);
418 /************************************************************************
424 RegCreateKeyExA (HKEY hKey
,
430 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
432 LPDWORD lpdwDisposition
)
434 UNICODE_STRING SubKeyString
;
435 UNICODE_STRING ClassString
;
436 OBJECT_ATTRIBUTES Attributes
;
441 DPRINT("RegCreateKeyExA() called\n");
443 /* get the real parent key */
444 Status
= MapDefaultKey (&ParentKey
,
446 if (!NT_SUCCESS(Status
))
448 ErrorCode
= RtlNtStatusToDosError (Status
);
449 SetLastError (ErrorCode
);
452 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
456 RtlCreateUnicodeStringFromAsciiz (&ClassString
,
459 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
461 InitializeObjectAttributes (&Attributes
,
463 OBJ_CASE_INSENSITIVE
,
465 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
466 Status
= CreateNestedKey(phkResult
,
468 (lpClass
== NULL
)? NULL
: &ClassString
,
472 RtlFreeUnicodeString (&SubKeyString
);
475 RtlFreeUnicodeString (&ClassString
);
477 DPRINT("Status %x\n", Status
);
478 if (!NT_SUCCESS(Status
))
480 ErrorCode
= RtlNtStatusToDosError (Status
);
481 SetLastError (ErrorCode
);
485 return ERROR_SUCCESS
;
489 /************************************************************************
495 RegCreateKeyExW (HKEY hKey
,
501 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
503 LPDWORD lpdwDisposition
)
505 UNICODE_STRING SubKeyString
;
506 UNICODE_STRING ClassString
;
507 OBJECT_ATTRIBUTES Attributes
;
512 DPRINT("RegCreateKeyExW() called\n");
514 /* get the real parent key */
515 Status
= MapDefaultKey (&ParentKey
,
517 if (!NT_SUCCESS(Status
))
519 ErrorCode
= RtlNtStatusToDosError(Status
);
520 SetLastError (ErrorCode
);
523 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
525 RtlInitUnicodeString (&ClassString
,
527 RtlInitUnicodeString (&SubKeyString
,
529 InitializeObjectAttributes (&Attributes
,
531 OBJ_CASE_INSENSITIVE
,
533 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
534 Status
= CreateNestedKey(phkResult
,
536 (lpClass
== NULL
)? NULL
: &ClassString
,
540 DPRINT("Status %x\n", Status
);
541 if (!NT_SUCCESS(Status
))
543 ErrorCode
= RtlNtStatusToDosError (Status
);
544 SetLastError (ErrorCode
);
548 return ERROR_SUCCESS
;
552 /************************************************************************
558 RegCreateKeyA (HKEY hKey
,
562 return RegCreateKeyExA (hKey
,
574 /************************************************************************
580 RegCreateKeyW (HKEY hKey
,
584 return RegCreateKeyExW (hKey
,
596 /************************************************************************
602 RegDeleteKeyA (HKEY hKey
,
605 OBJECT_ATTRIBUTES ObjectAttributes
;
606 UNICODE_STRING SubKeyName
;
612 Status
= MapDefaultKey (&ParentKey
,
614 if (!NT_SUCCESS(Status
))
616 ErrorCode
= RtlNtStatusToDosError (Status
);
617 SetLastError (ErrorCode
);
621 RtlCreateUnicodeStringFromAsciiz (&SubKeyName
,
623 InitializeObjectAttributes(&ObjectAttributes
,
625 OBJ_CASE_INSENSITIVE
,
629 Status
= NtOpenKey (&TargetKey
,
632 RtlFreeUnicodeString (&SubKeyName
);
633 if (!NT_SUCCESS(Status
))
635 ErrorCode
= RtlNtStatusToDosError (Status
);
636 SetLastError (ErrorCode
);
640 Status
= NtDeleteKey (TargetKey
);
642 if (!NT_SUCCESS(Status
))
644 ErrorCode
= RtlNtStatusToDosError(Status
);
645 SetLastError (ErrorCode
);
649 return ERROR_SUCCESS
;
653 /************************************************************************
659 RegDeleteKeyW (HKEY hKey
,
662 OBJECT_ATTRIBUTES ObjectAttributes
;
663 UNICODE_STRING SubKeyName
;
669 Status
= MapDefaultKey (&ParentKey
,
671 if (!NT_SUCCESS(Status
))
673 ErrorCode
= RtlNtStatusToDosError (Status
);
674 SetLastError (ErrorCode
);
678 RtlInitUnicodeString (&SubKeyName
,
680 InitializeObjectAttributes (&ObjectAttributes
,
682 OBJ_CASE_INSENSITIVE
,
685 Status
= NtOpenKey (&TargetKey
,
688 if (!NT_SUCCESS(Status
))
690 ErrorCode
= RtlNtStatusToDosError (Status
);
691 SetLastError (ErrorCode
);
695 Status
= NtDeleteKey (TargetKey
);
697 if (!NT_SUCCESS(Status
))
699 ErrorCode
= RtlNtStatusToDosError (Status
);
700 SetLastError (ErrorCode
);
704 return ERROR_SUCCESS
;
708 /************************************************************************
714 RegDeleteValueA (HKEY hKey
,
717 UNICODE_STRING ValueName
;
722 Status
= MapDefaultKey (&KeyHandle
,
724 if (!NT_SUCCESS(Status
))
726 ErrorCode
= RtlNtStatusToDosError (Status
);
727 SetLastError (ErrorCode
);
731 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
733 Status
= NtDeleteValueKey (KeyHandle
,
735 RtlFreeUnicodeString (&ValueName
);
736 if (!NT_SUCCESS(Status
))
738 ErrorCode
= RtlNtStatusToDosError (Status
);
739 SetLastError (ErrorCode
);
743 return ERROR_SUCCESS
;
747 /************************************************************************
753 RegDeleteValueW (HKEY hKey
,
756 UNICODE_STRING ValueName
;
761 Status
= MapDefaultKey (&KeyHandle
,
763 if (!NT_SUCCESS(Status
))
765 ErrorCode
= RtlNtStatusToDosError (Status
);
766 SetLastError (ErrorCode
);
770 RtlInitUnicodeString (&ValueName
,
771 (LPWSTR
)lpValueName
);
773 Status
= NtDeleteValueKey (KeyHandle
,
775 if (!NT_SUCCESS(Status
))
777 ErrorCode
= RtlNtStatusToDosError (Status
);
778 SetLastError (ErrorCode
);
782 return ERROR_SUCCESS
;
786 /************************************************************************
792 RegEnumKeyA (HKEY hKey
,
800 return RegEnumKeyExA (hKey
,
811 /************************************************************************
817 RegEnumKeyW (HKEY hKey
,
825 return RegEnumKeyExW (hKey
,
836 /************************************************************************
842 RegEnumKeyExA (HKEY hKey
,
849 PFILETIME lpftLastWriteTime
)
853 KEY_NODE_INFORMATION Node
;
854 KEY_BASIC_INFORMATION Basic
;
857 UNICODE_STRING StringU
;
859 LONG ErrorCode
= ERROR_SUCCESS
;
861 DWORD ClassLength
= 0;
867 DPRINT("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
868 hKey
, dwIndex
, lpName
, *lpcbName
, lpClass
, lpcbClass
? *lpcbClass
: 0);
870 if ((lpClass
) && (!lpcbClass
))
872 SetLastError (ERROR_INVALID_PARAMETER
);
873 return ERROR_INVALID_PARAMETER
;
876 Status
= MapDefaultKey(&KeyHandle
,
878 if (!NT_SUCCESS(Status
))
880 ErrorCode
= RtlNtStatusToDosError (Status
);
881 SetLastError (ErrorCode
);
887 NameLength
= min (*lpcbName
- 1 , REG_MAX_NAME_SIZE
) * sizeof (WCHAR
);
898 ClassLength
= min (*lpcbClass
-1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
905 /* The class name should start at a dword boundary */
906 BufferSize
= ((sizeof(KEY_NODE_INFORMATION
) + NameLength
+ 3) & ~3) + ClassLength
;
910 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + NameLength
;
913 KeyInfo
= RtlAllocateHeap (ProcessHeap
,
918 SetLastError (ERROR_OUTOFMEMORY
);
919 return ERROR_OUTOFMEMORY
;
922 Status
= NtEnumerateKey (KeyHandle
,
924 lpClass
== NULL
? KeyBasicInformation
: KeyNodeInformation
,
928 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status
);
929 if (!NT_SUCCESS(Status
))
931 ErrorCode
= RtlNtStatusToDosError (Status
);
937 if (KeyInfo
->Basic
.NameLength
> NameLength
)
939 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
943 StringU
.Buffer
= KeyInfo
->Basic
.Name
;
944 StringU
.Length
= KeyInfo
->Basic
.NameLength
;
945 StringU
.MaximumLength
= KeyInfo
->Basic
.NameLength
;
950 if (KeyInfo
->Node
.NameLength
> NameLength
||
951 KeyInfo
->Node
.ClassLength
> ClassLength
)
953 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
957 StringA
.Buffer
= lpClass
;
959 StringA
.MaximumLength
= *lpcbClass
;
960 StringU
.Buffer
= (PWCHAR
)((ULONG_PTR
)KeyInfo
->Node
.Name
+ KeyInfo
->Node
.ClassOffset
);
961 StringU
.Length
= KeyInfo
->Node
.ClassLength
;
962 StringU
.MaximumLength
= KeyInfo
->Node
.ClassLength
;
963 RtlUnicodeStringToAnsiString (&StringA
, &StringU
, FALSE
);
964 lpClass
[StringA
.Length
] = 0;
965 *lpcbClass
= StringA
.Length
;
966 StringU
.Buffer
= KeyInfo
->Node
.Name
;
967 StringU
.Length
= KeyInfo
->Node
.NameLength
;
968 StringU
.MaximumLength
= KeyInfo
->Node
.NameLength
;
972 if (ErrorCode
== ERROR_SUCCESS
)
974 StringA
.Buffer
= lpName
;
976 StringA
.MaximumLength
= *lpcbName
;
977 RtlUnicodeStringToAnsiString (&StringA
, &StringU
, FALSE
);
978 lpName
[StringA
.Length
] = 0;
979 *lpcbName
= StringA
.Length
;
980 if (lpftLastWriteTime
!= NULL
)
984 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.LowPart
;
985 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.HighPart
;
989 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.LowPart
;
990 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.HighPart
;
996 DPRINT("Key Namea0 Length %d\n", StringU
.Length
);
997 DPRINT("Key Namea1 Length %d\n", NameLength
);
998 DPRINT("Key Namea Length %d\n", *lpcbName
);
999 DPRINT("Key Namea %s\n", lpName
);
1001 RtlFreeHeap (ProcessHeap
,
1005 if (ErrorCode
!= ERROR_SUCCESS
)
1007 SetLastError(ErrorCode
);
1014 /************************************************************************
1020 RegEnumKeyExW (HKEY hKey
,
1027 PFILETIME lpftLastWriteTime
)
1031 KEY_NODE_INFORMATION Node
;
1032 KEY_BASIC_INFORMATION Basic
;
1038 ULONG ClassLength
= 0;
1040 LONG ErrorCode
= ERROR_SUCCESS
;
1043 Status
= MapDefaultKey(&KeyHandle
,
1045 if (!NT_SUCCESS(Status
))
1047 ErrorCode
= RtlNtStatusToDosError (Status
);
1048 SetLastError (ErrorCode
);
1054 NameLength
= min (*lpcbName
- 1, REG_MAX_NAME_SIZE
) * sizeof (WCHAR
);
1065 ClassLength
= min (*lpcbClass
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
1072 BufferSize
= ((sizeof(KEY_NODE_INFORMATION
) + NameLength
+ 3) & ~3) + ClassLength
;
1076 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + NameLength
;
1079 KeyInfo
= RtlAllocateHeap (ProcessHeap
,
1082 if (KeyInfo
== NULL
)
1084 SetLastError (ERROR_OUTOFMEMORY
);
1085 return ERROR_OUTOFMEMORY
;
1088 Status
= NtEnumerateKey (KeyHandle
,
1090 lpClass
? KeyNodeInformation
: KeyBasicInformation
,
1094 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status
);
1095 if (!NT_SUCCESS(Status
))
1097 ErrorCode
= RtlNtStatusToDosError (Status
);
1101 if (lpClass
== NULL
)
1103 if (KeyInfo
->Basic
.NameLength
> NameLength
)
1105 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1109 RtlCopyMemory (lpName
,
1110 KeyInfo
->Basic
.Name
,
1111 KeyInfo
->Basic
.NameLength
);
1112 *lpcbName
= (DWORD
)(KeyInfo
->Basic
.NameLength
/ sizeof(WCHAR
));
1113 lpName
[*lpcbName
] = 0;
1118 if (KeyInfo
->Node
.NameLength
> NameLength
||
1119 KeyInfo
->Node
.ClassLength
> ClassLength
)
1121 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1125 RtlCopyMemory (lpName
,
1127 KeyInfo
->Node
.NameLength
);
1128 *lpcbName
= KeyInfo
->Node
.NameLength
/ sizeof(WCHAR
);
1129 lpName
[*lpcbName
] = 0;
1130 RtlCopyMemory (lpClass
,
1131 (PVOID
)((ULONG_PTR
)KeyInfo
->Node
.Name
+ KeyInfo
->Node
.ClassOffset
),
1132 KeyInfo
->Node
.ClassLength
);
1133 *lpcbClass
= (DWORD
)(KeyInfo
->Node
.ClassLength
/ sizeof(WCHAR
));
1134 lpClass
[*lpcbClass
] = 0;
1138 if (ErrorCode
== ERROR_SUCCESS
&& lpftLastWriteTime
!= NULL
)
1140 if (lpClass
== NULL
)
1142 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.LowPart
;
1143 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.HighPart
;
1147 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.LowPart
;
1148 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.HighPart
;
1153 RtlFreeHeap (ProcessHeap
,
1157 if (ErrorCode
!= ERROR_SUCCESS
)
1159 SetLastError(ErrorCode
);
1166 /************************************************************************
1172 RegEnumValueA (HKEY hKey
,
1175 LPDWORD lpcbValueName
,
1183 KEY_VALUE_FULL_INFORMATION Full
;
1184 KEY_VALUE_BASIC_INFORMATION Basic
;
1189 ULONG DataLength
= 0;
1194 UNICODE_STRING StringU
;
1195 ANSI_STRING StringA
;
1198 ErrorCode
= ERROR_SUCCESS
;
1200 Status
= MapDefaultKey (&KeyHandle
,
1202 if (!NT_SUCCESS(Status
))
1204 ErrorCode
= RtlNtStatusToDosError (Status
);
1205 SetLastError (ErrorCode
);
1209 if (*lpcbValueName
> 0)
1211 NameLength
= min (*lpcbValueName
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
1220 DataLength
= min (*lpcbData
* sizeof(WCHAR
), REG_MAX_DATA_SIZE
);
1221 BufferSize
= ((sizeof(KEY_VALUE_FULL_INFORMATION
) + NameLength
+ 3) & ~3) + DataLength
;
1225 BufferSize
= sizeof(KEY_VALUE_BASIC_INFORMATION
) + NameLength
;
1228 ValueInfo
= RtlAllocateHeap (ProcessHeap
,
1231 if (ValueInfo
== NULL
)
1233 SetLastError(ERROR_OUTOFMEMORY
);
1234 return ERROR_OUTOFMEMORY
;
1237 Status
= NtEnumerateValueKey (KeyHandle
,
1239 lpData
? KeyValueFullInformation
: KeyValueBasicInformation
,
1244 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status
);
1245 if (!NT_SUCCESS(Status
))
1247 ErrorCode
= RtlNtStatusToDosError (Status
);
1253 IsStringType
= (ValueInfo
->Full
.Type
== REG_SZ
) ||
1254 (ValueInfo
->Full
.Type
== REG_MULTI_SZ
) ||
1255 (ValueInfo
->Full
.Type
== REG_EXPAND_SZ
);
1256 if (ValueInfo
->Full
.NameLength
> NameLength
||
1257 (!IsStringType
&& ValueInfo
->Full
.DataLength
> *lpcbData
) ||
1258 ValueInfo
->Full
.DataLength
> DataLength
)
1260 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1266 StringU
.Buffer
= (PWCHAR
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->Full
.DataOffset
);
1267 StringU
.Length
= ValueInfo
->Full
.DataLength
;
1268 StringU
.MaximumLength
= DataLength
;
1269 StringA
.Buffer
= (PCHAR
)lpData
;
1271 StringA
.MaximumLength
= *lpcbData
;
1272 RtlUnicodeStringToAnsiString (&StringA
,
1275 *lpcbData
= StringA
.Length
;
1279 RtlCopyMemory (lpData
,
1280 (PVOID
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->Full
.DataOffset
),
1281 ValueInfo
->Full
.DataLength
);
1282 *lpcbData
= ValueInfo
->Full
.DataLength
;
1285 StringU
.Buffer
= ValueInfo
->Full
.Name
;
1286 StringU
.Length
= ValueInfo
->Full
.NameLength
;
1287 StringU
.MaximumLength
= NameLength
;
1292 if (ValueInfo
->Basic
.NameLength
> NameLength
)
1294 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1298 StringU
.Buffer
= ValueInfo
->Basic
.Name
;
1299 StringU
.Length
= ValueInfo
->Basic
.NameLength
;
1300 StringU
.MaximumLength
= NameLength
;
1304 if (ErrorCode
== ERROR_SUCCESS
)
1306 StringA
.Buffer
= (PCHAR
)lpValueName
;
1308 StringA
.MaximumLength
= *lpcbValueName
;
1309 RtlUnicodeStringToAnsiString (&StringA
,
1312 StringA
.Buffer
[StringA
.Length
] = 0;
1313 *lpcbValueName
= StringA
.Length
;
1316 *lpType
= lpData
? ValueInfo
->Full
.Type
: ValueInfo
->Basic
.Type
;
1321 RtlFreeHeap (ProcessHeap
,
1324 if (ErrorCode
!= ERROR_SUCCESS
)
1326 SetLastError(ErrorCode
);
1333 /************************************************************************
1339 RegEnumValueW (HKEY hKey
,
1342 LPDWORD lpcbValueName
,
1350 KEY_VALUE_FULL_INFORMATION Full
;
1351 KEY_VALUE_BASIC_INFORMATION Basic
;
1356 ULONG DataLength
= 0;
1362 ErrorCode
= ERROR_SUCCESS
;
1364 Status
= MapDefaultKey (&KeyHandle
,
1366 if (!NT_SUCCESS(Status
))
1368 ErrorCode
= RtlNtStatusToDosError (Status
);
1369 SetLastError (ErrorCode
);
1373 if (*lpcbValueName
> 0)
1375 NameLength
= min (*lpcbValueName
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
1384 DataLength
= min(*lpcbData
, REG_MAX_DATA_SIZE
);
1385 BufferSize
= ((sizeof(KEY_VALUE_FULL_INFORMATION
) + NameLength
+ 3) & ~3) + DataLength
;
1389 BufferSize
= sizeof(KEY_VALUE_BASIC_INFORMATION
) + NameLength
;
1391 ValueInfo
= RtlAllocateHeap (ProcessHeap
,
1394 if (ValueInfo
== NULL
)
1396 SetLastError (ERROR_OUTOFMEMORY
);
1397 return ERROR_OUTOFMEMORY
;
1399 Status
= NtEnumerateValueKey (KeyHandle
,
1401 lpData
? KeyValueFullInformation
: KeyValueBasicInformation
,
1406 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status
);
1407 if (!NT_SUCCESS(Status
))
1409 ErrorCode
= RtlNtStatusToDosError (Status
);
1415 if (ValueInfo
->Full
.DataLength
> DataLength
||
1416 ValueInfo
->Full
.NameLength
> NameLength
)
1418 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1422 RtlCopyMemory (lpValueName
,
1423 ValueInfo
->Full
.Name
,
1424 ValueInfo
->Full
.NameLength
);
1425 *lpcbValueName
= (DWORD
)(ValueInfo
->Full
.NameLength
/ sizeof(WCHAR
));
1426 lpValueName
[*lpcbValueName
] = 0;
1427 RtlCopyMemory (lpData
,
1428 (PVOID
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->Full
.DataOffset
),
1429 ValueInfo
->Full
.DataLength
);
1430 *lpcbData
= (DWORD
)ValueInfo
->Full
.DataLength
;
1435 if (ValueInfo
->Basic
.NameLength
> NameLength
)
1437 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1441 RtlCopyMemory (lpValueName
,
1442 ValueInfo
->Basic
.Name
,
1443 ValueInfo
->Basic
.NameLength
);
1444 *lpcbValueName
= (DWORD
)(ValueInfo
->Basic
.NameLength
/ sizeof(WCHAR
));
1445 lpValueName
[*lpcbValueName
] = 0;
1447 *lpcbData
= (DWORD
)ValueInfo
->Full
.DataLength
;
1450 if (ErrorCode
== ERROR_SUCCESS
&& lpType
!= NULL
)
1452 *lpType
= lpData
? ValueInfo
->Full
.Type
: ValueInfo
->Basic
.Type
;
1456 RtlFreeHeap (ProcessHeap
,
1460 if (ErrorCode
!= ERROR_SUCCESS
)
1462 SetLastError (ErrorCode
);
1469 /************************************************************************
1475 RegFlushKey(HKEY hKey
)
1481 if (hKey
== HKEY_PERFORMANCE_DATA
)
1483 return ERROR_SUCCESS
;
1486 Status
= MapDefaultKey (&KeyHandle
,
1488 if (!NT_SUCCESS(Status
))
1490 ErrorCode
= RtlNtStatusToDosError (Status
);
1491 SetLastError (ErrorCode
);
1495 Status
= NtFlushKey (KeyHandle
);
1496 if (!NT_SUCCESS(Status
))
1498 ErrorCode
= RtlNtStatusToDosError (Status
);
1499 SetLastError (ErrorCode
);
1503 return ERROR_SUCCESS
;
1507 /************************************************************************
1513 RegGetKeySecurity(HKEY hKey
,
1514 SECURITY_INFORMATION SecurityInformation
,
1515 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1516 LPDWORD lpcbSecurityDescriptor
)
1522 if (hKey
== HKEY_PERFORMANCE_DATA
)
1524 SetLastError(ERROR_INVALID_HANDLE
);
1525 return ERROR_INVALID_HANDLE
;
1528 Status
= MapDefaultKey(&KeyHandle
,
1530 if (!NT_SUCCESS(Status
))
1532 DPRINT("MapDefaultKey() failed (Status %lx)\n", Status
);
1533 ErrorCode
= RtlNtStatusToDosError(Status
);
1534 SetLastError(ErrorCode
);
1538 Status
= NtQuerySecurityObject(KeyHandle
,
1539 SecurityInformation
,
1540 pSecurityDescriptor
,
1541 *lpcbSecurityDescriptor
,
1542 lpcbSecurityDescriptor
);
1543 if (!NT_SUCCESS(Status
))
1545 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1546 ErrorCode
= RtlNtStatusToDosError(Status
);
1547 SetLastError(ErrorCode
);
1551 return ERROR_SUCCESS
;
1555 /************************************************************************
1561 RegLoadKeyA (HKEY hKey
,
1565 UNICODE_STRING FileName
;
1566 UNICODE_STRING KeyName
;
1569 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
1571 RtlCreateUnicodeStringFromAsciiz (&FileName
,
1574 ErrorCode
= RegLoadKeyW (hKey
,
1578 RtlFreeUnicodeString (&FileName
);
1579 RtlFreeUnicodeString (&KeyName
);
1585 /************************************************************************
1591 RegLoadKeyW (HKEY hKey
,
1595 OBJECT_ATTRIBUTES FileObjectAttributes
;
1596 OBJECT_ATTRIBUTES KeyObjectAttributes
;
1597 UNICODE_STRING FileName
;
1598 UNICODE_STRING KeyName
;
1603 if (hKey
== HKEY_PERFORMANCE_DATA
)
1605 SetLastError(ERROR_INVALID_HANDLE
);
1606 return ERROR_INVALID_HANDLE
;
1609 Status
= MapDefaultKey (&KeyHandle
,
1611 if (!NT_SUCCESS(Status
))
1613 ErrorCode
= RtlNtStatusToDosError (Status
);
1614 SetLastError (ErrorCode
);
1618 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
1623 SetLastError (ERROR_BAD_PATHNAME
);
1624 return ERROR_BAD_PATHNAME
;
1627 InitializeObjectAttributes (&FileObjectAttributes
,
1629 OBJ_CASE_INSENSITIVE
,
1633 RtlInitUnicodeString (&KeyName
,
1636 InitializeObjectAttributes (&KeyObjectAttributes
,
1638 OBJ_CASE_INSENSITIVE
,
1642 Status
= NtLoadKey (&KeyObjectAttributes
,
1643 &FileObjectAttributes
);
1645 RtlFreeUnicodeString (&FileName
);
1647 if (!NT_SUCCESS(Status
))
1649 ErrorCode
= RtlNtStatusToDosError (Status
);
1650 SetLastError (ErrorCode
);
1654 return ERROR_SUCCESS
;
1658 /************************************************************************
1659 * RegNotifyChangeKeyValue
1664 RegNotifyChangeKeyValue (HKEY hKey
,
1666 DWORD dwNotifyFilter
,
1670 IO_STATUS_BLOCK IoStatusBlock
;
1674 if (hKey
== HKEY_PERFORMANCE_DATA
)
1676 return ERROR_INVALID_HANDLE
;
1679 if (fAsynchronous
== TRUE
&& hEvent
== NULL
)
1681 return ERROR_INVALID_PARAMETER
;
1684 Status
= MapDefaultKey (&KeyHandle
,
1686 if (!NT_SUCCESS(Status
))
1688 return RtlNtStatusToDosError (Status
);
1691 /* FIXME: Remote key handles must fail */
1693 Status
= NtNotifyChangeKey (KeyHandle
,
1703 if (!NT_SUCCESS(Status
) && Status
!= STATUS_TIMEOUT
)
1705 return RtlNtStatusToDosError (Status
);
1708 return ERROR_SUCCESS
;
1712 /************************************************************************
1718 RegOpenKeyA (HKEY hKey
,
1722 OBJECT_ATTRIBUTES ObjectAttributes
;
1723 UNICODE_STRING SubKeyString
;
1728 Status
= MapDefaultKey (&KeyHandle
,
1730 if (!NT_SUCCESS(Status
))
1732 ErrorCode
= RtlNtStatusToDosError (Status
);
1733 SetLastError (ErrorCode
);
1737 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1739 InitializeObjectAttributes (&ObjectAttributes
,
1741 OBJ_CASE_INSENSITIVE
,
1744 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1747 RtlFreeUnicodeString (&SubKeyString
);
1748 if (!NT_SUCCESS(Status
))
1750 ErrorCode
= RtlNtStatusToDosError (Status
);
1751 SetLastError (ErrorCode
);
1755 return ERROR_SUCCESS
;
1759 /************************************************************************
1768 RegOpenKeyW (HKEY hKey
,
1772 OBJECT_ATTRIBUTES ObjectAttributes
;
1773 UNICODE_STRING SubKeyString
;
1778 Status
= MapDefaultKey (&KeyHandle
,
1780 if (!NT_SUCCESS(Status
))
1782 ErrorCode
= RtlNtStatusToDosError (Status
);
1783 SetLastError (ErrorCode
);
1787 RtlInitUnicodeString (&SubKeyString
,
1789 InitializeObjectAttributes (&ObjectAttributes
,
1791 OBJ_CASE_INSENSITIVE
,
1794 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1797 if (!NT_SUCCESS(Status
))
1799 ErrorCode
= RtlNtStatusToDosError (Status
);
1800 SetLastError(ErrorCode
);
1804 return ERROR_SUCCESS
;
1808 /************************************************************************
1814 RegOpenKeyExA (HKEY hKey
,
1820 OBJECT_ATTRIBUTES ObjectAttributes
;
1821 UNICODE_STRING SubKeyString
;
1826 Status
= MapDefaultKey (&KeyHandle
,
1828 if (!NT_SUCCESS(Status
))
1830 ErrorCode
= RtlNtStatusToDosError (Status
);
1831 SetLastError (ErrorCode
);
1835 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1837 InitializeObjectAttributes (&ObjectAttributes
,
1839 OBJ_CASE_INSENSITIVE
,
1842 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1845 RtlFreeUnicodeString (&SubKeyString
);
1846 if (!NT_SUCCESS(Status
))
1848 ErrorCode
= RtlNtStatusToDosError (Status
);
1849 SetLastError (ErrorCode
);
1853 return ERROR_SUCCESS
;
1857 /************************************************************************
1863 RegOpenKeyExW (HKEY hKey
,
1869 OBJECT_ATTRIBUTES ObjectAttributes
;
1870 UNICODE_STRING SubKeyString
;
1875 Status
= MapDefaultKey (&KeyHandle
,
1877 if (!NT_SUCCESS(Status
))
1879 ErrorCode
= RtlNtStatusToDosError (Status
);
1880 SetLastError (ErrorCode
);
1884 if (lpSubKey
!= NULL
)
1886 RtlInitUnicodeString (&SubKeyString
,
1891 RtlInitUnicodeString (&SubKeyString
,
1894 InitializeObjectAttributes (&ObjectAttributes
,
1896 OBJ_CASE_INSENSITIVE
,
1899 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1902 if (!NT_SUCCESS(Status
))
1904 ErrorCode
= RtlNtStatusToDosError (Status
);
1905 SetLastError (ErrorCode
);
1909 return ERROR_SUCCESS
;
1913 /************************************************************************
1919 RegQueryInfoKeyA (HKEY hKey
,
1924 LPDWORD lpcbMaxSubKeyLen
,
1925 LPDWORD lpcbMaxClassLen
,
1927 LPDWORD lpcbMaxValueNameLen
,
1928 LPDWORD lpcbMaxValueLen
,
1929 LPDWORD lpcbSecurityDescriptor
,
1930 PFILETIME lpftLastWriteTime
)
1932 WCHAR ClassName
[MAX_PATH
];
1933 UNICODE_STRING UnicodeString
;
1934 ANSI_STRING AnsiString
;
1937 RtlInitUnicodeString (&UnicodeString
,
1939 if (lpClass
!= NULL
)
1941 UnicodeString
.Buffer
= &ClassName
[0];
1942 UnicodeString
.MaximumLength
= sizeof(ClassName
);
1943 AnsiString
.MaximumLength
= *lpcbClass
;
1946 ErrorCode
= RegQueryInfoKeyW (hKey
,
1947 UnicodeString
.Buffer
,
1954 lpcbMaxValueNameLen
,
1956 lpcbSecurityDescriptor
,
1958 if ((ErrorCode
== ERROR_SUCCESS
) && (lpClass
!= NULL
))
1960 AnsiString
.Buffer
= lpClass
;
1961 AnsiString
.Length
= 0;
1962 UnicodeString
.Length
= *lpcbClass
* sizeof(WCHAR
);
1963 RtlUnicodeStringToAnsiString (&AnsiString
,
1966 *lpcbClass
= AnsiString
.Length
;
1967 lpClass
[AnsiString
.Length
] = 0;
1974 /************************************************************************
1980 RegQueryInfoKeyW (HKEY hKey
,
1985 LPDWORD lpcbMaxSubKeyLen
,
1986 LPDWORD lpcbMaxClassLen
,
1988 LPDWORD lpcbMaxValueNameLen
,
1989 LPDWORD lpcbMaxValueLen
,
1990 LPDWORD lpcbSecurityDescriptor
,
1991 PFILETIME lpftLastWriteTime
)
1993 KEY_FULL_INFORMATION FullInfoBuffer
;
1994 PKEY_FULL_INFORMATION FullInfo
;
1996 ULONG ClassLength
= 0;
1999 LONG ErrorCode
= ERROR_SUCCESS
;
2002 if ((lpClass
) && (!lpcbClass
))
2004 SetLastError(ERROR_INVALID_PARAMETER
);
2005 return ERROR_INVALID_PARAMETER
;
2008 Status
= MapDefaultKey (&KeyHandle
,
2010 if (!NT_SUCCESS(Status
))
2012 ErrorCode
= RtlNtStatusToDosError (Status
);
2013 SetLastError (ErrorCode
);
2017 if (lpClass
!= NULL
)
2021 ClassLength
= min(*lpcbClass
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
2028 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
) + ((ClassLength
+ 3) & ~3);
2029 FullInfo
= RtlAllocateHeap (ProcessHeap
,
2032 if (FullInfo
== NULL
)
2034 SetLastError (ERROR_OUTOFMEMORY
);
2035 return ERROR_OUTOFMEMORY
;
2038 FullInfo
->ClassLength
= ClassLength
;
2042 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
);
2043 FullInfo
= &FullInfoBuffer
;
2044 FullInfo
->ClassLength
= 0;
2046 FullInfo
->ClassOffset
= FIELD_OFFSET(KEY_FULL_INFORMATION
, Class
);
2048 Status
= NtQueryKey (KeyHandle
,
2053 DPRINT("NtQueryKey() returned status 0x%X\n", Status
);
2054 if (!NT_SUCCESS(Status
))
2056 if (lpClass
!= NULL
)
2058 RtlFreeHeap (ProcessHeap
,
2063 ErrorCode
= RtlNtStatusToDosError (Status
);
2064 SetLastError (ErrorCode
);
2068 DPRINT("SubKeys %d\n", FullInfo
->SubKeys
);
2069 if (lpcSubKeys
!= NULL
)
2071 *lpcSubKeys
= FullInfo
->SubKeys
;
2074 DPRINT("MaxNameLen %lu\n", FullInfo
->MaxNameLen
);
2075 if (lpcbMaxSubKeyLen
!= NULL
)
2077 *lpcbMaxSubKeyLen
= FullInfo
->MaxNameLen
/ sizeof(WCHAR
) + 1;
2080 DPRINT("MaxClassLen %lu\n", FullInfo
->MaxClassLen
);
2081 if (lpcbMaxClassLen
!= NULL
)
2083 *lpcbMaxClassLen
= FullInfo
->MaxClassLen
/ sizeof(WCHAR
) + 1;
2086 DPRINT("Values %lu\n", FullInfo
->Values
);
2087 if (lpcValues
!= NULL
)
2089 *lpcValues
= FullInfo
->Values
;
2092 DPRINT("MaxValueNameLen %lu\n", FullInfo
->MaxValueNameLen
);
2093 if (lpcbMaxValueNameLen
!= NULL
)
2095 *lpcbMaxValueNameLen
= FullInfo
->MaxValueNameLen
/ sizeof(WCHAR
) + 1;
2098 DPRINT("MaxValueDataLen %lu\n", FullInfo
->MaxValueDataLen
);
2099 if (lpcbMaxValueLen
!= NULL
)
2101 *lpcbMaxValueLen
= FullInfo
->MaxValueDataLen
;
2104 if (lpcbSecurityDescriptor
!= NULL
)
2106 Status
= NtQuerySecurityObject(KeyHandle
,
2107 OWNER_SECURITY_INFORMATION
|
2108 GROUP_SECURITY_INFORMATION
|
2109 DACL_SECURITY_INFORMATION
,
2112 lpcbSecurityDescriptor
);
2113 if (!NT_SUCCESS(Status
))
2115 if (lpClass
!= NULL
)
2117 RtlFreeHeap(ProcessHeap
,
2122 ErrorCode
= RtlNtStatusToDosError(Status
);
2123 SetLastError(ErrorCode
);
2128 if (lpftLastWriteTime
!= NULL
)
2130 lpftLastWriteTime
->dwLowDateTime
= FullInfo
->LastWriteTime
.u
.LowPart
;
2131 lpftLastWriteTime
->dwHighDateTime
= FullInfo
->LastWriteTime
.u
.HighPart
;
2134 if (lpClass
!= NULL
)
2136 if (FullInfo
->ClassLength
> ClassLength
)
2138 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
2142 RtlCopyMemory (lpClass
,
2144 FullInfo
->ClassLength
);
2145 *lpcbClass
= FullInfo
->ClassLength
/ sizeof(WCHAR
);
2146 lpClass
[*lpcbClass
] = 0;
2149 RtlFreeHeap (ProcessHeap
,
2154 if (ErrorCode
!= ERROR_SUCCESS
)
2156 SetLastError (ErrorCode
);
2163 /************************************************************************
2164 * RegQueryMultipleValuesA
2169 RegQueryMultipleValuesA (HKEY hKey
,
2176 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2177 return ERROR_CALL_NOT_IMPLEMENTED
;
2181 /************************************************************************
2182 * RegQueryMultipleValuesW
2187 RegQueryMultipleValuesW (HKEY hKey
,
2194 DWORD maxBytes
= *ldwTotsize
;
2195 LPSTR bufptr
= (LPSTR
)lpValueBuf
;
2198 if (maxBytes
>= (1024*1024))
2199 return ERROR_TRANSFER_TOO_LONG
;
2203 DPRINT ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
2204 hKey
, val_list
, num_vals
, lpValueBuf
, ldwTotsize
, *ldwTotsize
);
2206 for (i
= 0; i
< num_vals
; ++i
)
2208 val_list
[i
].ve_valuelen
= 0;
2209 ErrorCode
= RegQueryValueExW (hKey
,
2210 val_list
[i
].ve_valuename
,
2214 &val_list
[i
].ve_valuelen
);
2215 if (ErrorCode
!= ERROR_SUCCESS
)
2220 if (lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
2222 ErrorCode
= RegQueryValueExW (hKey
,
2223 val_list
[i
].ve_valuename
,
2225 &val_list
[i
].ve_type
,
2227 &val_list
[i
].ve_valuelen
);
2228 if (ErrorCode
!= ERROR_SUCCESS
)
2233 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
2235 bufptr
+= val_list
[i
].ve_valuelen
;
2238 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
2241 return (lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
) ? ERROR_SUCCESS
: ERROR_MORE_DATA
;
2245 /************************************************************************
2251 RegQueryValueExW (HKEY hKey
,
2252 LPCWSTR lpValueName
,
2258 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
2259 UNICODE_STRING ValueName
;
2261 LONG ErrorCode
= ERROR_SUCCESS
;
2265 ULONG MaxCopy
= lpcbData
!= NULL
&& lpData
!= NULL
? *lpcbData
: 0;
2267 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
2268 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
2270 Status
= MapDefaultKey (&KeyHandle
,
2272 if (!NT_SUCCESS(Status
))
2274 ErrorCode
= RtlNtStatusToDosError (Status
);
2275 SetLastError (ErrorCode
);
2279 if (lpData
!= NULL
&& lpcbData
== NULL
)
2281 SetLastError (ERROR_INVALID_PARAMETER
);
2282 return ERROR_INVALID_PARAMETER
;
2285 RtlInitUnicodeString (&ValueName
,
2287 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + MaxCopy
;
2288 ValueInfo
= RtlAllocateHeap (ProcessHeap
,
2291 if (ValueInfo
== NULL
)
2293 SetLastError(ERROR_OUTOFMEMORY
);
2294 return ERROR_OUTOFMEMORY
;
2297 Status
= NtQueryValueKey (hKey
,
2299 KeyValuePartialInformation
,
2303 DPRINT("Status 0x%X\n", Status
);
2304 if (Status
== STATUS_BUFFER_TOO_SMALL
)
2306 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
2308 ErrorCode
= lpData
? ERROR_MORE_DATA
: ERROR_SUCCESS
;
2310 else if (!NT_SUCCESS(Status
))
2312 ErrorCode
= RtlNtStatusToDosError (Status
);
2313 SetLastError (ErrorCode
);
2315 if (lpcbData
!= NULL
)
2317 ResultSize
= sizeof(*ValueInfo
) + *lpcbData
;
2323 *lpType
= ValueInfo
->Type
;
2326 if (NT_SUCCESS(Status
) && lpData
!= NULL
)
2328 RtlMoveMemory (lpData
,
2330 min(ValueInfo
->DataLength
, MaxCopy
));
2333 if ((ValueInfo
->Type
== REG_SZ
) ||
2334 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
2335 (ValueInfo
->Type
== REG_EXPAND_SZ
))
2337 if (lpData
!= NULL
&& MaxCopy
> ValueInfo
->DataLength
)
2339 ((PWSTR
)lpData
)[ValueInfo
->DataLength
/ sizeof(WCHAR
)] = 0;
2342 if (lpcbData
!= NULL
)
2344 *lpcbData
= (ResultSize
- sizeof(*ValueInfo
));
2345 DPRINT("(string) Returning Size: %lu\n", *lpcbData
);
2350 if (lpcbData
!= NULL
)
2352 *lpcbData
= ResultSize
- sizeof(*ValueInfo
);
2353 DPRINT("(other) Returning Size: %lu\n", *lpcbData
);
2357 DPRINT("Type %d Size %d\n", ValueInfo
->Type
, ValueInfo
->DataLength
);
2359 RtlFreeHeap (ProcessHeap
,
2367 /************************************************************************
2373 RegQueryValueExA (HKEY hKey
,
2380 UNICODE_STRING ValueName
;
2381 UNICODE_STRING ValueData
;
2382 ANSI_STRING AnsiString
;
2387 if (lpData
!= NULL
&& lpcbData
== NULL
)
2389 SetLastError(ERROR_INVALID_PARAMETER
);
2390 return ERROR_INVALID_PARAMETER
;
2395 ValueData
.Length
= *lpcbData
* sizeof(WCHAR
);
2396 ValueData
.MaximumLength
= ValueData
.Length
+ sizeof(WCHAR
);
2397 ValueData
.Buffer
= RtlAllocateHeap (ProcessHeap
,
2399 ValueData
.MaximumLength
);
2400 if (!ValueData
.Buffer
)
2402 SetLastError(ERROR_OUTOFMEMORY
);
2403 return ERROR_OUTOFMEMORY
;
2408 ValueData
.Buffer
= NULL
;
2409 ValueData
.Length
= 0;
2410 ValueData
.MaximumLength
= 0;
2413 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
2414 (LPSTR
)lpValueName
);
2416 if (NULL
!= lpcbData
)
2418 Length
= *lpcbData
* sizeof(WCHAR
);
2420 ErrorCode
= RegQueryValueExW (hKey
,
2424 (LPBYTE
)ValueData
.Buffer
,
2425 NULL
== lpcbData
? NULL
: &Length
);
2426 DPRINT("ErrorCode %lu\n", ErrorCode
);
2428 if (ErrorCode
== ERROR_SUCCESS
||
2429 ErrorCode
== ERROR_MORE_DATA
)
2436 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
))
2438 if (ErrorCode
== ERROR_SUCCESS
&& ValueData
.Buffer
!= NULL
)
2440 RtlInitAnsiString(&AnsiString
, NULL
);
2441 AnsiString
.Buffer
= lpData
;
2442 AnsiString
.MaximumLength
= *lpcbData
;
2443 ValueData
.Length
= Length
;
2444 ValueData
.MaximumLength
= ValueData
.Length
+ sizeof(WCHAR
);
2445 RtlUnicodeStringToAnsiString(&AnsiString
, &ValueData
, FALSE
);
2447 Length
= Length
/ sizeof(WCHAR
);
2449 else if (lpcbData
!= NULL
)
2451 Length
= min(*lpcbData
, Length
);
2452 if (ErrorCode
== ERROR_SUCCESS
&& ValueData
.Buffer
!= NULL
)
2454 RtlMoveMemory(lpData
, ValueData
.Buffer
, Length
);
2458 if (lpcbData
!= NULL
)
2464 if (ValueData
.Buffer
!= NULL
)
2466 RtlFreeHeap(ProcessHeap
, 0, ValueData
.Buffer
);
2473 /************************************************************************
2479 RegQueryValueA (HKEY hKey
,
2484 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2485 UNICODE_STRING SubKeyName
;
2486 UNICODE_STRING Value
;
2487 ANSI_STRING AnsiString
;
2491 if (lpValue
!= NULL
&&
2494 SetLastError(ERROR_INVALID_PARAMETER
);
2495 return ERROR_INVALID_PARAMETER
;
2498 RtlInitUnicodeString (&SubKeyName
,
2500 RtlInitUnicodeString (&Value
,
2502 if (lpSubKey
!= NULL
&&
2503 strlen(lpSubKey
) != 0)
2505 RtlInitAnsiString (&AnsiString
,
2507 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2508 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2509 RtlAnsiStringToUnicodeString (&SubKeyName
,
2514 if (lpValue
!= NULL
)
2516 ValueSize
= *lpcbValue
* sizeof(WCHAR
);
2517 Value
.MaximumLength
= ValueSize
;
2518 Value
.Buffer
= RtlAllocateHeap (ProcessHeap
,
2521 if (Value
.Buffer
== NULL
)
2523 SetLastError(ERROR_OUTOFMEMORY
);
2524 return ERROR_OUTOFMEMORY
;
2532 ErrorCode
= RegQueryValueW (hKey
,
2533 (LPCWSTR
)SubKeyName
.Buffer
,
2536 if (ErrorCode
== ERROR_SUCCESS
)
2538 Value
.Length
= ValueSize
;
2539 RtlInitAnsiString (&AnsiString
,
2541 AnsiString
.Buffer
= lpValue
;
2542 AnsiString
.MaximumLength
= *lpcbValue
;
2543 RtlUnicodeStringToAnsiString (&AnsiString
,
2548 *lpcbValue
= ValueSize
;
2549 if (Value
.Buffer
!= NULL
)
2551 RtlFreeHeap (ProcessHeap
,
2560 /************************************************************************
2566 RegQueryValueW (HKEY hKey
,
2571 OBJECT_ATTRIBUTES ObjectAttributes
;
2572 UNICODE_STRING SubKeyString
;
2579 Status
= MapDefaultKey (&KeyHandle
,
2581 if (!NT_SUCCESS(Status
))
2583 ErrorCode
= RtlNtStatusToDosError (Status
);
2584 SetLastError (ErrorCode
);
2588 if (lpSubKey
!= NULL
&&
2589 wcslen(lpSubKey
) != 0)
2591 RtlInitUnicodeString (&SubKeyString
,
2593 InitializeObjectAttributes (&ObjectAttributes
,
2595 OBJ_CASE_INSENSITIVE
,
2598 Status
= NtOpenKey (&RealKey
,
2601 if (!NT_SUCCESS(Status
))
2603 ErrorCode
= RtlNtStatusToDosError (Status
);
2604 SetLastError (ErrorCode
);
2607 CloseRealKey
= TRUE
;
2612 CloseRealKey
= FALSE
;
2615 ErrorCode
= RegQueryValueExW (RealKey
,
2620 (LPDWORD
)lpcbValue
);
2630 /************************************************************************
2636 RegReplaceKeyA (HKEY hKey
,
2641 UNICODE_STRING SubKey
;
2642 UNICODE_STRING NewFile
;
2643 UNICODE_STRING OldFile
;
2646 RtlCreateUnicodeStringFromAsciiz (&SubKey
,
2648 RtlCreateUnicodeStringFromAsciiz (&OldFile
,
2650 RtlCreateUnicodeStringFromAsciiz (&NewFile
,
2653 ErrorCode
= RegReplaceKeyW (hKey
,
2658 RtlFreeUnicodeString (&OldFile
);
2659 RtlFreeUnicodeString (&NewFile
);
2660 RtlFreeUnicodeString (&SubKey
);
2666 /************************************************************************
2672 RegReplaceKeyW (HKEY hKey
,
2677 OBJECT_ATTRIBUTES KeyObjectAttributes
;
2678 OBJECT_ATTRIBUTES NewObjectAttributes
;
2679 OBJECT_ATTRIBUTES OldObjectAttributes
;
2680 UNICODE_STRING SubKeyName
;
2681 UNICODE_STRING NewFileName
;
2682 UNICODE_STRING OldFileName
;
2683 BOOLEAN CloseRealKey
;
2684 HANDLE RealKeyHandle
;
2689 if (hKey
== HKEY_PERFORMANCE_DATA
)
2691 return ERROR_INVALID_HANDLE
;
2694 Status
= MapDefaultKey (&KeyHandle
,
2696 if (!NT_SUCCESS(Status
))
2698 ErrorCode
= RtlNtStatusToDosError (Status
);
2699 SetLastError (ErrorCode
);
2703 /* Open the real key */
2704 if (lpSubKey
!= NULL
&& *lpSubKey
!= (WCHAR
)0)
2706 RtlInitUnicodeString (&SubKeyName
,
2708 InitializeObjectAttributes (&KeyObjectAttributes
,
2710 OBJ_CASE_INSENSITIVE
,
2713 Status
= NtOpenKey (&RealKeyHandle
,
2715 &KeyObjectAttributes
);
2716 if (!NT_SUCCESS(Status
))
2718 ErrorCode
= RtlNtStatusToDosError (Status
);
2719 SetLastError (ErrorCode
);
2722 CloseRealKey
= TRUE
;
2726 RealKeyHandle
= KeyHandle
;
2727 CloseRealKey
= FALSE
;
2730 /* Convert new file name */
2731 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpNewFile
,
2738 NtClose (RealKeyHandle
);
2740 SetLastError (ERROR_INVALID_PARAMETER
);
2741 return ERROR_INVALID_PARAMETER
;
2744 InitializeObjectAttributes (&NewObjectAttributes
,
2746 OBJ_CASE_INSENSITIVE
,
2750 /* Convert old file name */
2751 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpOldFile
,
2756 RtlFreeUnicodeString (&NewFileName
);
2759 NtClose (RealKeyHandle
);
2761 SetLastError (ERROR_INVALID_PARAMETER
);
2762 return ERROR_INVALID_PARAMETER
;
2765 InitializeObjectAttributes (&OldObjectAttributes
,
2767 OBJ_CASE_INSENSITIVE
,
2771 Status
= NtReplaceKey (&NewObjectAttributes
,
2773 &OldObjectAttributes
);
2775 RtlFreeUnicodeString (&OldFileName
);
2776 RtlFreeUnicodeString (&NewFileName
);
2780 NtClose (RealKeyHandle
);
2783 if (!NT_SUCCESS(Status
))
2785 ErrorCode
= RtlNtStatusToDosError (Status
);
2786 SetLastError (ErrorCode
);
2790 return ERROR_SUCCESS
;
2794 /************************************************************************
2800 RegRestoreKeyA (HKEY hKey
,
2804 UNICODE_STRING FileName
;
2807 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2810 ErrorCode
= RegRestoreKeyW (hKey
,
2814 RtlFreeUnicodeString (&FileName
);
2820 /************************************************************************
2826 RegRestoreKeyW (HKEY hKey
,
2830 OBJECT_ATTRIBUTES ObjectAttributes
;
2831 IO_STATUS_BLOCK IoStatusBlock
;
2832 UNICODE_STRING FileName
;
2838 if (hKey
== HKEY_PERFORMANCE_DATA
)
2840 return ERROR_INVALID_HANDLE
;
2843 Status
= MapDefaultKey (&KeyHandle
,
2845 if (!NT_SUCCESS(Status
))
2847 ErrorCode
= RtlNtStatusToDosError (Status
);
2848 SetLastError (ErrorCode
);
2852 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
2857 SetLastError (ERROR_INVALID_PARAMETER
);
2858 return ERROR_INVALID_PARAMETER
;
2861 InitializeObjectAttributes (&ObjectAttributes
,
2863 OBJ_CASE_INSENSITIVE
,
2867 Status
= NtOpenFile (&FileHandle
,
2872 FILE_SYNCHRONOUS_IO_NONALERT
);
2873 RtlFreeUnicodeString (&FileName
);
2874 if (!NT_SUCCESS(Status
))
2876 ErrorCode
= RtlNtStatusToDosError (Status
);
2877 SetLastError (ErrorCode
);
2881 Status
= NtRestoreKey (KeyHandle
,
2884 NtClose (FileHandle
);
2885 if (!NT_SUCCESS(Status
))
2887 ErrorCode
= RtlNtStatusToDosError (Status
);
2888 SetLastError (ErrorCode
);
2892 return ERROR_SUCCESS
;
2896 /************************************************************************
2902 RegSaveKeyA (HKEY hKey
,
2904 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2906 UNICODE_STRING FileName
;
2909 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2911 ErrorCode
= RegSaveKeyW (hKey
,
2913 lpSecurityAttributes
);
2914 RtlFreeUnicodeString (&FileName
);
2920 /************************************************************************
2926 RegSaveKeyW (HKEY hKey
,
2928 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2930 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
2931 OBJECT_ATTRIBUTES ObjectAttributes
;
2932 UNICODE_STRING FileName
;
2933 IO_STATUS_BLOCK IoStatusBlock
;
2939 Status
= MapDefaultKey (&KeyHandle
,
2941 if (!NT_SUCCESS(Status
))
2943 ErrorCode
= RtlNtStatusToDosError (Status
);
2944 SetLastError (ErrorCode
);
2948 if (!RtlDosPathNameToNtPathName_U ((PWSTR
)lpFile
,
2953 SetLastError (ERROR_INVALID_PARAMETER
);
2954 return ERROR_INVALID_PARAMETER
;
2957 if (lpSecurityAttributes
!= NULL
)
2959 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
2962 InitializeObjectAttributes (&ObjectAttributes
,
2964 OBJ_CASE_INSENSITIVE
,
2966 SecurityDescriptor
);
2967 Status
= NtCreateFile (&FileHandle
,
2968 GENERIC_WRITE
| SYNCHRONIZE
,
2972 FILE_ATTRIBUTE_NORMAL
,
2975 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT
,
2978 RtlFreeUnicodeString (&FileName
);
2979 if (!NT_SUCCESS(Status
))
2981 ErrorCode
= RtlNtStatusToDosError (Status
);
2982 SetLastError (ErrorCode
);
2986 Status
= NtSaveKey (KeyHandle
,
2988 NtClose (FileHandle
);
2989 if (!NT_SUCCESS(Status
))
2991 ErrorCode
= RtlNtStatusToDosError (Status
);
2992 SetLastError (ErrorCode
);
2996 return ERROR_SUCCESS
;
3000 /************************************************************************
3006 RegSetKeySecurity (HKEY hKey
,
3007 SECURITY_INFORMATION SecurityInformation
,
3008 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
3014 if (hKey
== HKEY_PERFORMANCE_DATA
)
3016 SetLastError(ERROR_INVALID_HANDLE
);
3017 return ERROR_INVALID_HANDLE
;
3020 Status
= MapDefaultKey (&KeyHandle
,
3022 if (!NT_SUCCESS(Status
))
3024 ErrorCode
= RtlNtStatusToDosError (Status
);
3025 SetLastError (ErrorCode
);
3029 Status
= NtSetSecurityObject (KeyHandle
,
3030 SecurityInformation
,
3031 pSecurityDescriptor
);
3032 if (!NT_SUCCESS(Status
))
3034 ErrorCode
= RtlNtStatusToDosError (Status
);
3035 SetLastError (ErrorCode
);
3039 return ERROR_SUCCESS
;
3043 /************************************************************************
3049 RegSetValueExA (HKEY hKey
,
3056 UNICODE_STRING ValueName
;
3058 ANSI_STRING AnsiString
;
3059 UNICODE_STRING Data
;
3066 SetLastError (ERROR_INVALID_PARAMETER
);
3067 return ERROR_INVALID_PARAMETER
;
3070 if (lpValueName
!= NULL
&&
3071 strlen(lpValueName
) != 0)
3073 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
3075 pValueName
= (LPWSTR
)ValueName
.Buffer
;
3082 if ((dwType
== REG_SZ
) ||
3083 (dwType
== REG_MULTI_SZ
) ||
3084 (dwType
== REG_EXPAND_SZ
))
3086 RtlInitAnsiString (&AnsiString
,
3088 AnsiString
.Buffer
= (PSTR
)lpData
;
3089 AnsiString
.Length
= cbData
;
3090 AnsiString
.MaximumLength
= cbData
;
3091 RtlAnsiStringToUnicodeString (&Data
,
3094 pData
= (LPBYTE
)Data
.Buffer
;
3095 DataSize
= cbData
* sizeof(WCHAR
);
3099 RtlInitUnicodeString (&Data
,
3101 pData
= (LPBYTE
)lpData
;
3105 ErrorCode
= RegSetValueExW (hKey
,
3111 if (pValueName
!= NULL
)
3113 RtlFreeHeap (ProcessHeap
,
3118 if (Data
.Buffer
!= NULL
)
3120 RtlFreeHeap (ProcessHeap
,
3129 /************************************************************************
3135 RegSetValueExW (HKEY hKey
,
3136 LPCWSTR lpValueName
,
3142 UNICODE_STRING ValueName
;
3143 PUNICODE_STRING pValueName
;
3148 Status
= MapDefaultKey (&KeyHandle
,
3150 if (!NT_SUCCESS(Status
))
3152 ErrorCode
= RtlNtStatusToDosError (Status
);
3153 SetLastError (ErrorCode
);
3157 if (lpValueName
!= NULL
)
3159 RtlInitUnicodeString (&ValueName
,
3164 RtlInitUnicodeString (&ValueName
, L
"");
3166 pValueName
= &ValueName
;
3168 Status
= NtSetValueKey (KeyHandle
,
3174 if (!NT_SUCCESS(Status
))
3176 ErrorCode
= RtlNtStatusToDosError (Status
);
3177 SetLastError (ErrorCode
);
3181 return ERROR_SUCCESS
;
3185 /************************************************************************
3191 RegSetValueA (HKEY hKey
,
3197 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
3198 UNICODE_STRING SubKeyName
;
3199 UNICODE_STRING Data
;
3200 ANSI_STRING AnsiString
;
3206 SetLastError (ERROR_INVALID_PARAMETER
);
3207 return ERROR_INVALID_PARAMETER
;
3210 RtlInitUnicodeString (&SubKeyName
, NULL
);
3211 RtlInitUnicodeString (&Data
, NULL
);
3212 if (lpSubKey
!= NULL
&& (strlen(lpSubKey
) != 0))
3214 RtlInitAnsiString (&AnsiString
, (LPSTR
)lpSubKey
);
3215 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
3216 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
3217 RtlAnsiStringToUnicodeString (&SubKeyName
, &AnsiString
, FALSE
);
3220 DataSize
= cbData
* sizeof(WCHAR
);
3221 Data
.MaximumLength
= DataSize
;
3222 Data
.Buffer
= RtlAllocateHeap (ProcessHeap
,
3225 if (Data
.Buffer
== NULL
)
3227 SetLastError (ERROR_OUTOFMEMORY
);
3228 return ERROR_OUTOFMEMORY
;
3231 ErrorCode
= RegSetValueW (hKey
,
3232 (LPCWSTR
)SubKeyName
.Buffer
,
3237 RtlFreeHeap (ProcessHeap
,
3245 /************************************************************************
3251 RegSetValueW (HKEY hKey
,
3257 OBJECT_ATTRIBUTES ObjectAttributes
;
3258 UNICODE_STRING SubKeyString
;
3265 Status
= MapDefaultKey (&KeyHandle
,
3267 if (!NT_SUCCESS(Status
))
3269 ErrorCode
= RtlNtStatusToDosError (Status
);
3270 SetLastError (ErrorCode
);
3274 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
3276 RtlInitUnicodeString (&SubKeyString
,
3278 InitializeObjectAttributes (&ObjectAttributes
,
3280 OBJ_CASE_INSENSITIVE
,
3283 Status
= NtOpenKey (&RealKey
,
3286 if (!NT_SUCCESS(Status
))
3288 ErrorCode
= RtlNtStatusToDosError (Status
);
3289 SetLastError (ErrorCode
);
3292 CloseRealKey
= TRUE
;
3297 CloseRealKey
= FALSE
;
3300 ErrorCode
= RegSetValueExW (RealKey
,
3306 if (CloseRealKey
== TRUE
)
3315 /************************************************************************
3321 RegUnLoadKeyA (HKEY hKey
,
3324 UNICODE_STRING KeyName
;
3327 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
3330 ErrorCode
= RegUnLoadKeyW (hKey
,
3333 RtlFreeUnicodeString (&KeyName
);
3339 /************************************************************************
3345 RegUnLoadKeyW (HKEY hKey
,
3348 OBJECT_ATTRIBUTES ObjectAttributes
;
3349 UNICODE_STRING KeyName
;
3354 if (hKey
== HKEY_PERFORMANCE_DATA
)
3356 SetLastError(ERROR_INVALID_HANDLE
);
3357 return ERROR_INVALID_HANDLE
;
3360 Status
= MapDefaultKey (&KeyHandle
, hKey
);
3361 if (!NT_SUCCESS(Status
))
3363 ErrorCode
= RtlNtStatusToDosError (Status
);
3364 SetLastError (ErrorCode
);
3368 RtlInitUnicodeString (&KeyName
,
3371 InitializeObjectAttributes (&ObjectAttributes
,
3373 OBJ_CASE_INSENSITIVE
,
3377 Status
= NtUnloadKey (&ObjectAttributes
);
3379 if (!NT_SUCCESS(Status
))
3381 ErrorCode
= RtlNtStatusToDosError (Status
);
3382 SetLastError (ErrorCode
);
3386 return ERROR_SUCCESS
;