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 *****************************************************************/
15 #define NTOS_MODE_USER
17 #include <ddk/ntddk.h>
18 #include <ntdll/rtl.h>
25 /* DEFINES ******************************************************************/
27 #define MAX_DEFAULT_HANDLES 6
28 #define REG_MAX_NAME_SIZE 256
29 #define REG_MAX_DATA_SIZE 2048
31 /* GLOBALS ******************************************************************/
33 static CRITICAL_SECTION HandleTableCS;
34 static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
35 static HANDLE ProcessHeap;
37 /* PROTOTYPES ***************************************************************/
39 static NTSTATUS MapDefaultKey (PHKEY ParentKey, HKEY Key);
40 static VOID CloseDefaultKeys(VOID);
42 static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
43 static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
44 static NTSTATUS OpenUsersKey (PHANDLE KeyHandle);
45 static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle);
48 /* FUNCTIONS ****************************************************************/
50 /************************************************************************
51 * RegInitDefaultHandles
56 DPRINT("RegInitialize()\n");
58 ProcessHeap = RtlGetProcessHeap();
59 RtlZeroMemory (DefaultHandleTable,
60 MAX_DEFAULT_HANDLES * sizeof(HANDLE));
61 RtlInitializeCriticalSection (&HandleTableCS);
67 /************************************************************************
73 DPRINT("RegCleanup()\n");
76 RtlDeleteCriticalSection (&HandleTableCS);
83 MapDefaultKey (PHKEY RealKey,
88 NTSTATUS Status = STATUS_SUCCESS;
90 DPRINT("MapDefaultKey (Key %x)\n", Key);
92 if (((ULONG)Key & 0xF0000000) != 0x80000000)
95 return STATUS_SUCCESS;
98 /* Handle special cases here */
99 Index = (ULONG)Key & 0x0FFFFFFF;
100 if (Index >= MAX_DEFAULT_HANDLES)
102 return STATUS_INVALID_PARAMETER;
105 RtlEnterCriticalSection (&HandleTableCS);
106 Handle = &DefaultHandleTable[Index];
109 /* create/open the default handle */
112 case 0: /* HKEY_CLASSES_ROOT */
113 Status = OpenClassesRootKey (Handle);
116 case 1: /* HKEY_CURRENT_USER */
117 Status = RtlOpenCurrentUser (MAXIMUM_ALLOWED,
121 case 2: /* HKEY_LOCAL_MACHINE */
122 Status = OpenLocalMachineKey (Handle);
125 case 3: /* HKEY_USERS */
126 Status = OpenUsersKey (Handle);
129 case 4: /* HKEY_PERFORMANCE_DATA */
130 Status = OpenPerformanceDataKey (Handle);
133 case 5: /* HKEY_CURRENT_CONFIG */
134 Status = OpenCurrentConfigKey (Handle);
137 case 6: /* HKEY_DYN_DATA */
138 Status = STATUS_NOT_IMPLEMENTED;
142 DPRINT("MapDefaultHandle() no handle creator\n");
143 Status = STATUS_INVALID_PARAMETER;
146 RtlLeaveCriticalSection (&HandleTableCS);
148 if (NT_SUCCESS(Status))
150 *RealKey = (HKEY)*Handle;
158 CloseDefaultKeys (VOID)
162 RtlEnterCriticalSection (&HandleTableCS);
163 for (i = 0; i < MAX_DEFAULT_HANDLES; i++)
165 if (DefaultHandleTable[i] != NULL)
167 NtClose (DefaultHandleTable[i]);
168 DefaultHandleTable[i] = NULL;
171 RtlLeaveCriticalSection (&HandleTableCS);
176 OpenClassesRootKey (PHANDLE KeyHandle)
178 OBJECT_ATTRIBUTES Attributes;
179 UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\Software\\CLASSES");
181 DPRINT("OpenClassesRootKey()\n");
183 InitializeObjectAttributes (&Attributes,
185 OBJ_CASE_INSENSITIVE,
188 return NtOpenKey (KeyHandle,
195 OpenLocalMachineKey (PHANDLE KeyHandle)
197 OBJECT_ATTRIBUTES Attributes;
198 UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine");
200 DPRINT("OpenLocalMachineKey()\n");
202 InitializeObjectAttributes (&Attributes,
204 OBJ_CASE_INSENSITIVE,
207 return NtOpenKey (KeyHandle,
214 OpenUsersKey (PHANDLE KeyHandle)
216 OBJECT_ATTRIBUTES Attributes;
217 UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\User");
219 DPRINT("OpenUsersKey()\n");
221 InitializeObjectAttributes (&Attributes,
223 OBJ_CASE_INSENSITIVE,
226 return NtOpenKey (KeyHandle,
233 OpenCurrentConfigKey (PHANDLE KeyHandle)
235 OBJECT_ATTRIBUTES Attributes;
236 UNICODE_STRING KeyName =
237 UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
239 DPRINT("OpenCurrentConfigKey()\n");
241 InitializeObjectAttributes (&Attributes,
243 OBJ_CASE_INSENSITIVE,
246 return NtOpenKey (KeyHandle,
252 /************************************************************************
258 RegCloseKey (HKEY hKey)
263 /* don't close null handle or a pseudo handle */
264 if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000))
266 return ERROR_INVALID_HANDLE;
269 Status = NtClose (hKey);
270 if (!NT_SUCCESS(Status))
272 ErrorCode = RtlNtStatusToDosError (Status);
273 SetLastError (ErrorCode);
277 return ERROR_SUCCESS;
281 /************************************************************************
282 * RegConnectRegistryA
287 RegConnectRegistryA (LPCSTR lpMachineName,
291 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
292 return ERROR_CALL_NOT_IMPLEMENTED;
296 /************************************************************************
297 * RegConnectRegistryW
302 RegConnectRegistryW (LPCWSTR lpMachineName,
306 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
307 return ERROR_CALL_NOT_IMPLEMENTED;
311 /************************************************************************
317 RegCreateKeyExA (HKEY hKey,
323 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
325 LPDWORD lpdwDisposition)
327 UNICODE_STRING SubKeyString;
328 UNICODE_STRING ClassString;
329 OBJECT_ATTRIBUTES Attributes;
334 DPRINT("RegCreateKeyExA() called\n");
336 /* get the real parent key */
337 Status = MapDefaultKey (&ParentKey,
339 if (!NT_SUCCESS(Status))
341 ErrorCode = RtlNtStatusToDosError (Status);
342 SetLastError (ErrorCode);
345 DPRINT("ParentKey %x\n", (ULONG)ParentKey);
349 RtlCreateUnicodeStringFromAsciiz (&ClassString,
352 RtlCreateUnicodeStringFromAsciiz (&SubKeyString,
354 InitializeObjectAttributes (&Attributes,
356 OBJ_CASE_INSENSITIVE,
358 (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
359 Status = NtCreateKey (phkResult,
363 (lpClass == NULL)? NULL : &ClassString,
365 (PULONG)lpdwDisposition);
366 RtlFreeUnicodeString (&SubKeyString);
369 RtlFreeUnicodeString (&ClassString);
371 DPRINT("Status %x\n", Status);
372 if (!NT_SUCCESS(Status))
374 ErrorCode = RtlNtStatusToDosError (Status);
375 SetLastError (ErrorCode);
379 return ERROR_SUCCESS;
383 /************************************************************************
389 RegCreateKeyExW(HKEY hKey,
395 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
397 LPDWORD lpdwDisposition)
399 UNICODE_STRING SubKeyString;
400 UNICODE_STRING ClassString;
401 OBJECT_ATTRIBUTES Attributes;
406 DPRINT("RegCreateKeyExW() called\n");
408 /* get the real parent key */
409 Status = MapDefaultKey (&ParentKey,
411 if (!NT_SUCCESS(Status))
413 ErrorCode = RtlNtStatusToDosError(Status);
414 SetLastError (ErrorCode);
417 DPRINT("ParentKey %x\n", (ULONG)ParentKey);
419 RtlInitUnicodeString (&ClassString,
421 RtlInitUnicodeString (&SubKeyString,
423 InitializeObjectAttributes (&Attributes,
425 OBJ_CASE_INSENSITIVE,
427 (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
428 Status = NtCreateKey (phkResult,
432 (lpClass == NULL)? NULL : &ClassString,
434 (PULONG)lpdwDisposition);
435 DPRINT("Status %x\n", Status);
436 if (!NT_SUCCESS(Status))
438 ErrorCode = RtlNtStatusToDosError (Status);
439 SetLastError (ErrorCode);
443 return ERROR_SUCCESS;
447 /************************************************************************
453 RegCreateKeyA (HKEY hKey,
457 return RegCreateKeyExA (hKey,
469 /************************************************************************
475 RegCreateKeyW (HKEY hKey,
479 return RegCreateKeyExW (hKey,
491 /************************************************************************
497 RegDeleteKeyA (HKEY hKey,
500 OBJECT_ATTRIBUTES ObjectAttributes;
501 UNICODE_STRING SubKeyName;
507 Status = MapDefaultKey (&ParentKey,
509 if (!NT_SUCCESS(Status))
511 ErrorCode = RtlNtStatusToDosError (Status);
512 SetLastError (ErrorCode);
516 RtlCreateUnicodeStringFromAsciiz (&SubKeyName,
518 InitializeObjectAttributes(&ObjectAttributes,
520 OBJ_CASE_INSENSITIVE,
524 Status = NtOpenKey (&TargetKey,
527 RtlFreeUnicodeString (&SubKeyName);
528 if (!NT_SUCCESS(Status))
530 ErrorCode = RtlNtStatusToDosError (Status);
531 SetLastError (ErrorCode);
535 Status = NtDeleteKey (TargetKey);
537 if (!NT_SUCCESS(Status))
539 ErrorCode = RtlNtStatusToDosError(Status);
540 SetLastError (ErrorCode);
544 return ERROR_SUCCESS;
548 /************************************************************************
554 RegDeleteKeyW (HKEY hKey,
557 OBJECT_ATTRIBUTES ObjectAttributes;
558 UNICODE_STRING SubKeyName;
564 Status = MapDefaultKey (&ParentKey,
566 if (!NT_SUCCESS(Status))
568 ErrorCode = RtlNtStatusToDosError (Status);
569 SetLastError (ErrorCode);
573 RtlInitUnicodeString (&SubKeyName,
575 InitializeObjectAttributes (&ObjectAttributes,
577 OBJ_CASE_INSENSITIVE,
580 Status = NtOpenKey (&TargetKey,
583 if (!NT_SUCCESS(Status))
585 ErrorCode = RtlNtStatusToDosError (Status);
586 SetLastError (ErrorCode);
590 Status = NtDeleteKey (TargetKey);
592 if (!NT_SUCCESS(Status))
594 ErrorCode = RtlNtStatusToDosError (Status);
595 SetLastError (ErrorCode);
599 return ERROR_SUCCESS;
603 /************************************************************************
609 RegDeleteValueA (HKEY hKey,
612 UNICODE_STRING ValueName;
617 Status = MapDefaultKey (&KeyHandle,
619 if (!NT_SUCCESS(Status))
621 ErrorCode = RtlNtStatusToDosError (Status);
622 SetLastError (ErrorCode);
626 RtlCreateUnicodeStringFromAsciiz (&ValueName,
628 Status = NtDeleteValueKey (KeyHandle,
630 RtlFreeUnicodeString (&ValueName);
631 if (!NT_SUCCESS(Status))
633 ErrorCode = RtlNtStatusToDosError (Status);
634 SetLastError (ErrorCode);
638 return ERROR_SUCCESS;
642 /************************************************************************
648 RegDeleteValueW (HKEY hKey,
651 UNICODE_STRING ValueName;
656 Status = MapDefaultKey (&KeyHandle,
658 if (!NT_SUCCESS(Status))
660 ErrorCode = RtlNtStatusToDosError (Status);
661 SetLastError (ErrorCode);
665 RtlInitUnicodeString (&ValueName,
666 (LPWSTR)lpValueName);
668 Status = NtDeleteValueKey (KeyHandle,
670 if (!NT_SUCCESS(Status))
672 ErrorCode = RtlNtStatusToDosError (Status);
673 SetLastError (ErrorCode);
677 return ERROR_SUCCESS;
681 /************************************************************************
687 RegEnumKeyA (HKEY hKey,
695 return RegEnumKeyExA (hKey,
706 /************************************************************************
712 RegEnumKeyW (HKEY hKey,
720 return RegEnumKeyExW (hKey,
731 /************************************************************************
737 RegEnumKeyExA (HKEY hKey,
744 PFILETIME lpftLastWriteTime)
748 KEY_NODE_INFORMATION Node;
749 KEY_BASIC_INFORMATION Basic;
752 UNICODE_STRING StringU;
754 LONG ErrorCode = ERROR_SUCCESS;
762 DPRINT("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
763 hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass ? *lpcbClass : 0);
765 if ((lpClass) && (!lpcbClass))
767 SetLastError (ERROR_INVALID_PARAMETER);
768 return ERROR_INVALID_PARAMETER;
770 Status = MapDefaultKey(&KeyHandle,
772 if (!NT_SUCCESS(Status))
774 ErrorCode = RtlNtStatusToDosError (Status);
775 SetLastError (ErrorCode);
781 NameLength = min (*lpcbName - 1 , REG_MAX_NAME_SIZE) * sizeof (WCHAR);
791 ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
797 /* The class name should start at a dword boundary */
798 BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
802 BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
805 KeyInfo = RtlAllocateHeap (ProcessHeap,
811 SetLastError (ERROR_OUTOFMEMORY);
812 return ERROR_OUTOFMEMORY;
815 Status = NtEnumerateKey (KeyHandle,
817 lpClass == NULL ? KeyBasicInformation : KeyNodeInformation,
821 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status);
822 if (!NT_SUCCESS(Status))
824 ErrorCode = RtlNtStatusToDosError (Status);
830 if (KeyInfo->Basic.NameLength > NameLength)
832 ErrorCode = ERROR_BUFFER_OVERFLOW;
836 StringU.Buffer = KeyInfo->Basic.Name;
837 StringU.Length = KeyInfo->Basic.NameLength;
838 StringU.MaximumLength = KeyInfo->Basic.NameLength;
843 if (KeyInfo->Node.NameLength > NameLength ||
844 KeyInfo->Node.ClassLength > ClassLength)
846 ErrorCode = ERROR_BUFFER_OVERFLOW;
850 StringA.Buffer = lpClass;
852 StringA.MaximumLength = *lpcbClass;
853 StringU.Buffer = (PWCHAR)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset);
854 StringU.Length = KeyInfo->Node.ClassLength;
855 StringU.MaximumLength = KeyInfo->Node.ClassLength;
856 RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
857 lpClass[StringA.Length] = 0;
858 *lpcbClass = StringA.Length;
859 StringU.Buffer = KeyInfo->Node.Name;
860 StringU.Length = KeyInfo->Node.NameLength;
861 StringU.MaximumLength = KeyInfo->Node.NameLength;
864 if (ErrorCode == ERROR_SUCCESS)
866 StringA.Buffer = lpName;
868 StringA.MaximumLength = *lpcbName;
869 RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
870 lpName[StringA.Length] = 0;
871 *lpcbName = StringA.Length;
872 if (lpftLastWriteTime != NULL)
876 lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
877 lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
881 lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
882 lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
888 DPRINT("Key Namea0 Length %d\n", StringU.Length);
889 DPRINT("Key Namea1 Length %d\n", NameLength);
890 DPRINT("Key Namea Length %d\n", *lpcbName);
891 DPRINT("Key Namea %s\n", lpName);
893 RtlFreeHeap (ProcessHeap,
897 if (ErrorCode != ERROR_SUCCESS)
899 SetLastError(ErrorCode);
906 /************************************************************************
912 RegEnumKeyExW (HKEY hKey,
919 PFILETIME lpftLastWriteTime)
923 KEY_NODE_INFORMATION Node;
924 KEY_BASIC_INFORMATION Basic;
932 LONG ErrorCode = ERROR_SUCCESS;
935 Status = MapDefaultKey(&KeyHandle,
937 if (!NT_SUCCESS(Status))
939 ErrorCode = RtlNtStatusToDosError (Status);
940 SetLastError (ErrorCode);
945 NameLength = min (*lpcbName - 1, REG_MAX_NAME_SIZE) * sizeof (WCHAR);
955 ClassLength = min (*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
961 BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
965 BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
967 KeyInfo = RtlAllocateHeap (ProcessHeap,
972 SetLastError (ERROR_OUTOFMEMORY);
973 return ERROR_OUTOFMEMORY;
976 Status = NtEnumerateKey (KeyHandle,
978 lpClass ? KeyNodeInformation : KeyBasicInformation,
982 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status);
983 if (!NT_SUCCESS(Status))
985 ErrorCode = RtlNtStatusToDosError (Status);
991 if (KeyInfo->Basic.NameLength > NameLength)
993 ErrorCode = ERROR_BUFFER_OVERFLOW;
997 RtlCopyMemory (lpName,
999 KeyInfo->Basic.NameLength);
1000 *lpcbName = (DWORD)(KeyInfo->Basic.NameLength / sizeof(WCHAR));
1001 lpName[*lpcbName] = 0;
1006 if (KeyInfo->Node.NameLength > NameLength ||
1007 KeyInfo->Node.ClassLength > ClassLength)
1009 ErrorCode = ERROR_BUFFER_OVERFLOW;
1013 RtlCopyMemory (lpName,
1015 KeyInfo->Node.NameLength);
1016 *lpcbName = KeyInfo->Node.NameLength / sizeof(WCHAR);
1017 lpName[*lpcbName] = 0;
1018 RtlCopyMemory (lpClass,
1019 (PVOID)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset),
1020 KeyInfo->Node.ClassLength);
1021 *lpcbClass = (DWORD)(KeyInfo->Node.ClassLength / sizeof(WCHAR));
1022 lpClass[*lpcbClass] = 0;
1025 if (ErrorCode == ERROR_SUCCESS && lpftLastWriteTime != NULL)
1027 if (lpClass == NULL)
1029 lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
1030 lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
1034 lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
1035 lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
1040 RtlFreeHeap (ProcessHeap,
1044 if (ErrorCode != ERROR_SUCCESS)
1046 SetLastError(ErrorCode);
1052 /************************************************************************
1058 RegEnumValueA (HKEY hKey,
1061 LPDWORD lpcbValueName,
1069 KEY_VALUE_FULL_INFORMATION Full;
1070 KEY_VALUE_BASIC_INFORMATION Basic;
1080 UNICODE_STRING StringU;
1081 ANSI_STRING StringA;
1084 ErrorCode = ERROR_SUCCESS;
1086 Status = MapDefaultKey (&KeyHandle,
1088 if (!NT_SUCCESS(Status))
1090 ErrorCode = RtlNtStatusToDosError (Status);
1091 SetLastError (ErrorCode);
1095 if (*lpcbValueName > 0)
1097 NameLength = min (*lpcbValueName - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
1105 DataLength = min (*lpcbData * sizeof(WCHAR), REG_MAX_DATA_SIZE);
1106 BufferSize = ((sizeof(KEY_VALUE_FULL_INFORMATION) + NameLength + 3) & ~3) + DataLength;
1110 BufferSize = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameLength;
1113 ValueInfo = RtlAllocateHeap (ProcessHeap,
1116 if (ValueInfo == NULL)
1118 SetLastError(ERROR_OUTOFMEMORY);
1119 return ERROR_OUTOFMEMORY;
1122 Status = NtEnumerateValueKey (KeyHandle,
1124 lpData ? KeyValueFullInformation : KeyValueBasicInformation,
1129 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status);
1130 if (!NT_SUCCESS(Status))
1132 ErrorCode = RtlNtStatusToDosError (Status);
1138 IsStringType = (ValueInfo->Full.Type == REG_SZ) ||
1139 (ValueInfo->Full.Type == REG_MULTI_SZ) ||
1140 (ValueInfo->Full.Type == REG_EXPAND_SZ);
1141 if (ValueInfo->Full.NameLength > NameLength ||
1142 (!IsStringType && ValueInfo->Full.DataLength > *lpcbData) ||
1143 ValueInfo->Full.DataLength > DataLength)
1145 ErrorCode = ERROR_BUFFER_OVERFLOW;
1151 StringU.Buffer = (PWCHAR)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset);
1152 StringU.Length = ValueInfo->Full.DataLength;
1153 StringU.MaximumLength = DataLength;
1154 StringA.Buffer = (PCHAR)lpData;
1156 StringA.MaximumLength = *lpcbData;
1157 RtlUnicodeStringToAnsiString (&StringA,
1160 *lpcbData = StringA.Length;
1164 RtlCopyMemory(lpData,
1165 (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset),
1166 ValueInfo->Full.DataLength);
1167 *lpcbData = ValueInfo->Full.DataLength;
1169 StringU.Buffer = ValueInfo->Full.Name;
1170 StringU.Length = ValueInfo->Full.NameLength;
1171 StringU.MaximumLength = NameLength;
1176 if (ValueInfo->Basic.NameLength > NameLength)
1178 ErrorCode = ERROR_BUFFER_OVERFLOW;
1182 StringU.Buffer = ValueInfo->Basic.Name;
1183 StringU.Length = ValueInfo->Basic.NameLength;
1184 StringU.MaximumLength = NameLength;
1187 if (ErrorCode == ERROR_SUCCESS)
1189 StringA.Buffer = (PCHAR)lpValueName;
1191 StringA.MaximumLength = *lpcbValueName;
1192 RtlUnicodeStringToAnsiString (&StringA,
1195 StringA.Buffer[StringA.Length] = 0;
1196 *lpcbValueName = StringA.Length;
1199 *lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type;
1203 RtlFreeHeap (ProcessHeap,
1206 if (ErrorCode != ERROR_SUCCESS)
1208 SetLastError(ErrorCode);
1214 /************************************************************************
1220 RegEnumValueW (HKEY hKey,
1223 LPDWORD lpcbValueName,
1231 KEY_VALUE_FULL_INFORMATION Full;
1232 KEY_VALUE_BASIC_INFORMATION Basic;
1243 ErrorCode = ERROR_SUCCESS;
1245 Status = MapDefaultKey (&KeyHandle,
1247 if (!NT_SUCCESS(Status))
1249 ErrorCode = RtlNtStatusToDosError (Status);
1250 SetLastError (ErrorCode);
1254 if (*lpcbValueName > 0)
1256 NameLength = min (*lpcbValueName - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
1264 DataLength = min(*lpcbData, REG_MAX_DATA_SIZE);
1265 BufferSize = ((sizeof(KEY_VALUE_FULL_INFORMATION) + NameLength + 3) & ~3) + DataLength;
1269 BufferSize = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameLength;
1271 ValueInfo = RtlAllocateHeap (ProcessHeap,
1274 if (ValueInfo == NULL)
1276 SetLastError (ERROR_OUTOFMEMORY);
1277 return ERROR_OUTOFMEMORY;
1279 Status = NtEnumerateValueKey (KeyHandle,
1281 lpData ? KeyValueFullInformation : KeyValueBasicInformation,
1286 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status);
1287 if (!NT_SUCCESS(Status))
1289 ErrorCode = RtlNtStatusToDosError (Status);
1295 if (ValueInfo->Full.DataLength > DataLength ||
1296 ValueInfo->Full.NameLength > NameLength)
1298 ErrorCode = ERROR_BUFFER_OVERFLOW;
1302 RtlCopyMemory (lpValueName,
1303 ValueInfo->Full.Name,
1304 ValueInfo->Full.NameLength);
1305 *lpcbValueName = (DWORD)(ValueInfo->Full.NameLength / sizeof(WCHAR));
1306 lpValueName[*lpcbValueName] = 0;
1307 RtlCopyMemory (lpData,
1308 (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset),
1309 ValueInfo->Full.DataLength);
1310 *lpcbData = (DWORD)ValueInfo->Full.DataLength;
1315 if (ValueInfo->Basic.NameLength > NameLength)
1317 ErrorCode = ERROR_BUFFER_OVERFLOW;
1321 RtlCopyMemory (lpValueName,
1322 ValueInfo->Basic.Name,
1323 ValueInfo->Basic.NameLength);
1324 *lpcbValueName = (DWORD)(ValueInfo->Basic.NameLength / sizeof(WCHAR));
1325 lpValueName[*lpcbValueName] = 0;
1328 if (ErrorCode == ERROR_SUCCESS && lpType != NULL)
1330 *lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type;
1333 RtlFreeHeap (ProcessHeap,
1336 if (ErrorCode != ERROR_SUCCESS)
1338 SetLastError(ErrorCode);
1344 /************************************************************************
1350 RegFlushKey(HKEY hKey)
1356 if (hKey == HKEY_PERFORMANCE_DATA)
1358 return ERROR_SUCCESS;
1361 Status = MapDefaultKey (&KeyHandle,
1363 if (!NT_SUCCESS(Status))
1365 ErrorCode = RtlNtStatusToDosError (Status);
1366 SetLastError (ErrorCode);
1370 Status = NtFlushKey (KeyHandle);
1371 if (!NT_SUCCESS(Status))
1373 ErrorCode = RtlNtStatusToDosError (Status);
1374 SetLastError (ErrorCode);
1378 return ERROR_SUCCESS;
1382 /************************************************************************
1388 RegGetKeySecurity (HKEY hKey,
1389 SECURITY_INFORMATION SecurityInformation,
1390 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1391 LPDWORD lpcbSecurityDescriptor)
1398 if (hKey = HKEY_PERFORMANCE_DATA)
1400 return ERROR_INVALID_HANDLE;
1403 Status = MapDefaultKey (&KeyHandle,
1405 if (!NT_SUCCESS(Status))
1407 ErrorCode = RtlNtStatusToDosError (Status);
1408 SetLastError (ErrorCode);
1412 Status = NtQuerySecurityObject ()
1413 if (!NT_SUCCESS(Status))
1415 ErrorCode = RtlNtStatusToDosError (Status);
1416 SetLastError (ErrorCode);
1420 return ERROR_SUCCESS;
1424 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1425 return ERROR_CALL_NOT_IMPLEMENTED;
1429 /************************************************************************
1435 RegLoadKeyA (HKEY hKey,
1439 UNICODE_STRING FileName;
1440 UNICODE_STRING KeyName;
1443 RtlCreateUnicodeStringFromAsciiz (&KeyName,
1445 RtlCreateUnicodeStringFromAsciiz (&FileName,
1448 ErrorCode = RegLoadKeyW (hKey,
1452 RtlFreeUnicodeString (&FileName);
1453 RtlFreeUnicodeString (&KeyName);
1459 /************************************************************************
1465 RegLoadKeyW (HKEY hKey,
1469 OBJECT_ATTRIBUTES FileObjectAttributes;
1470 OBJECT_ATTRIBUTES KeyObjectAttributes;
1471 UNICODE_STRING FileName;
1472 UNICODE_STRING KeyName;
1477 if (hKey == HKEY_PERFORMANCE_DATA)
1479 return ERROR_INVALID_HANDLE;
1482 Status = MapDefaultKey (&KeyHandle,
1484 if (!NT_SUCCESS(Status))
1486 ErrorCode = RtlNtStatusToDosError (Status);
1487 SetLastError (ErrorCode);
1491 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
1496 SetLastError (ERROR_BAD_PATHNAME);
1497 return ERROR_BAD_PATHNAME;
1500 InitializeObjectAttributes (&FileObjectAttributes,
1502 OBJ_CASE_INSENSITIVE,
1506 RtlInitUnicodeString (&KeyName,
1509 InitializeObjectAttributes (&KeyObjectAttributes,
1511 OBJ_CASE_INSENSITIVE,
1515 Status = NtLoadKey (&KeyObjectAttributes,
1516 &FileObjectAttributes);
1518 RtlFreeUnicodeString (&FileName);
1520 if (!NT_SUCCESS(Status))
1522 ErrorCode = RtlNtStatusToDosError (Status);
1523 SetLastError (ErrorCode);
1527 return ERROR_SUCCESS;
1531 /************************************************************************
1532 * RegNotifyChangeKeyValue
1537 RegNotifyChangeKeyValue (HKEY hKey,
1539 DWORD dwNotifyFilter,
1543 IO_STATUS_BLOCK IoStatusBlock;
1547 if (hKey == HKEY_PERFORMANCE_DATA)
1549 return ERROR_INVALID_HANDLE;
1552 if (fAsynchronous == TRUE && hEvent == NULL)
1554 return ERROR_INVALID_PARAMETER;
1557 Status = MapDefaultKey (&KeyHandle,
1559 if (!NT_SUCCESS(Status))
1561 return RtlNtStatusToDosError (Status);
1564 /* FIXME: Remote key handles must fail */
1566 Status = NtNotifyChangeKey (KeyHandle,
1576 if (!NT_SUCCESS(Status) && Status != STATUS_TIMEOUT)
1578 return RtlNtStatusToDosError (Status);
1581 return ERROR_SUCCESS;
1586 /************************************************************************
1592 RegOpenKeyA (HKEY hKey,
1596 OBJECT_ATTRIBUTES ObjectAttributes;
1597 UNICODE_STRING SubKeyString;
1602 Status = MapDefaultKey (&KeyHandle,
1604 if (!NT_SUCCESS(Status))
1606 ErrorCode = RtlNtStatusToDosError (Status);
1607 SetLastError (ErrorCode);
1611 RtlCreateUnicodeStringFromAsciiz (&SubKeyString,
1613 InitializeObjectAttributes (&ObjectAttributes,
1615 OBJ_CASE_INSENSITIVE,
1618 Status = NtOpenKey (phkResult,
1621 RtlFreeUnicodeString (&SubKeyString);
1622 if (!NT_SUCCESS(Status))
1624 ErrorCode = RtlNtStatusToDosError (Status);
1625 SetLastError (ErrorCode);
1629 return ERROR_SUCCESS;
1633 /************************************************************************
1642 RegOpenKeyW (HKEY hKey,
1646 OBJECT_ATTRIBUTES ObjectAttributes;
1647 UNICODE_STRING SubKeyString;
1652 Status = MapDefaultKey (&KeyHandle,
1654 if (!NT_SUCCESS(Status))
1656 ErrorCode = RtlNtStatusToDosError (Status);
1657 SetLastError (ErrorCode);
1661 RtlInitUnicodeString (&SubKeyString,
1663 InitializeObjectAttributes (&ObjectAttributes,
1665 OBJ_CASE_INSENSITIVE,
1668 Status = NtOpenKey (phkResult,
1671 if (!NT_SUCCESS(Status))
1673 ErrorCode = RtlNtStatusToDosError (Status);
1674 SetLastError(ErrorCode);
1678 return ERROR_SUCCESS;
1682 /************************************************************************
1688 RegOpenKeyExA (HKEY hKey,
1694 OBJECT_ATTRIBUTES ObjectAttributes;
1695 UNICODE_STRING SubKeyString;
1700 Status = MapDefaultKey (&KeyHandle,
1702 if (!NT_SUCCESS(Status))
1704 ErrorCode = RtlNtStatusToDosError (Status);
1705 SetLastError (ErrorCode);
1709 RtlCreateUnicodeStringFromAsciiz (&SubKeyString,
1711 InitializeObjectAttributes (&ObjectAttributes,
1713 OBJ_CASE_INSENSITIVE,
1716 Status = NtOpenKey (phkResult,
1719 RtlFreeUnicodeString (&SubKeyString);
1720 if (!NT_SUCCESS(Status))
1722 ErrorCode = RtlNtStatusToDosError (Status);
1723 SetLastError (ErrorCode);
1727 return ERROR_SUCCESS;
1731 /************************************************************************
1737 RegOpenKeyExW (HKEY hKey,
1743 OBJECT_ATTRIBUTES ObjectAttributes;
1744 UNICODE_STRING SubKeyString;
1749 Status = MapDefaultKey (&KeyHandle,
1751 if (!NT_SUCCESS(Status))
1753 ErrorCode = RtlNtStatusToDosError (Status);
1754 SetLastError (ErrorCode);
1758 if (lpSubKey != NULL)
1760 RtlInitUnicodeString (&SubKeyString,
1765 RtlInitUnicodeString (&SubKeyString,
1768 InitializeObjectAttributes (&ObjectAttributes,
1770 OBJ_CASE_INSENSITIVE,
1773 Status = NtOpenKey (phkResult,
1776 if (!NT_SUCCESS(Status))
1778 ErrorCode = RtlNtStatusToDosError (Status);
1779 SetLastError (ErrorCode);
1783 return ERROR_SUCCESS;
1787 /************************************************************************
1793 RegQueryInfoKeyA (HKEY hKey,
1798 LPDWORD lpcbMaxSubKeyLen,
1799 LPDWORD lpcbMaxClassLen,
1801 LPDWORD lpcbMaxValueNameLen,
1802 LPDWORD lpcbMaxValueLen,
1803 LPDWORD lpcbSecurityDescriptor,
1804 PFILETIME lpftLastWriteTime)
1806 WCHAR ClassName[MAX_PATH];
1807 UNICODE_STRING UnicodeString;
1808 ANSI_STRING AnsiString;
1811 RtlInitUnicodeString (&UnicodeString,
1813 if (lpClass != NULL)
1815 UnicodeString.Buffer = &ClassName[0];
1816 UnicodeString.MaximumLength = sizeof(ClassName);
1817 AnsiString.MaximumLength = *lpcbClass;
1820 ErrorCode = RegQueryInfoKeyW (hKey,
1821 UnicodeString.Buffer,
1828 lpcbMaxValueNameLen,
1830 lpcbSecurityDescriptor,
1832 if ((ErrorCode == ERROR_SUCCESS) && (lpClass != NULL))
1834 AnsiString.Buffer = lpClass;
1835 AnsiString.Length = 0;
1836 UnicodeString.Length = *lpcbClass * sizeof(WCHAR);
1837 RtlUnicodeStringToAnsiString (&AnsiString,
1840 *lpcbClass = AnsiString.Length;
1841 lpClass[AnsiString.Length] = 0;
1848 /************************************************************************
1854 RegQueryInfoKeyW (HKEY hKey,
1859 LPDWORD lpcbMaxSubKeyLen,
1860 LPDWORD lpcbMaxClassLen,
1862 LPDWORD lpcbMaxValueNameLen,
1863 LPDWORD lpcbMaxValueLen,
1864 LPDWORD lpcbSecurityDescriptor,
1865 PFILETIME lpftLastWriteTime)
1867 KEY_FULL_INFORMATION FullInfoBuffer;
1868 PKEY_FULL_INFORMATION FullInfo;
1873 LONG ErrorCode = ERROR_SUCCESS;
1876 if ((lpClass) && (!lpcbClass))
1878 SetLastError(ERROR_INVALID_PARAMETER);
1879 return ERROR_INVALID_PARAMETER;
1882 Status = MapDefaultKey (&KeyHandle,
1884 if (!NT_SUCCESS(Status))
1886 ErrorCode = RtlNtStatusToDosError (Status);
1887 SetLastError (ErrorCode);
1891 if (lpClass != NULL)
1895 ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
1901 FullInfoSize = sizeof(KEY_FULL_INFORMATION) + ((ClassLength + 3) & ~3);
1902 FullInfo = RtlAllocateHeap (ProcessHeap,
1905 if (FullInfo == NULL)
1907 SetLastError (ERROR_OUTOFMEMORY);
1908 return ERROR_OUTOFMEMORY;
1910 FullInfo->ClassLength = ClassLength;
1914 FullInfoSize = sizeof(KEY_FULL_INFORMATION);
1915 FullInfo = &FullInfoBuffer;
1916 FullInfo->ClassLength = 0;
1918 FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
1920 Status = NtQueryKey (KeyHandle,
1925 DPRINT("NtQueryKey() returned status 0x%X\n", Status);
1926 if (!NT_SUCCESS(Status))
1928 ErrorCode = RtlNtStatusToDosError (Status);
1932 DPRINT("SubKeys %d\n", FullInfo->SubKeys);
1933 if (lpcSubKeys != NULL)
1935 *lpcSubKeys = FullInfo->SubKeys;
1938 DPRINT("MaxNameLen %lu\n", FullInfo->MaxNameLen);
1939 if (lpcbMaxSubKeyLen != NULL)
1941 *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
1944 DPRINT("MaxClassLen %lu\n", FullInfo->MaxClassLen);
1945 if (lpcbMaxClassLen != NULL)
1947 *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
1950 DPRINT("Values %lu\n", FullInfo->Values);
1953 *lpcValues = FullInfo->Values;
1956 DPRINT("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
1957 if (lpcbMaxValueNameLen)
1959 *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
1962 DPRINT("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
1963 if (lpcbMaxValueLen)
1965 *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
1968 if (lpcbSecurityDescriptor)
1970 *lpcbSecurityDescriptor = 0;
1974 if (lpftLastWriteTime != NULL)
1976 lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
1977 lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
1980 if (lpClass != NULL)
1982 if (FullInfo->ClassLength > ClassLength)
1984 ErrorCode = ERROR_BUFFER_OVERFLOW;
1988 RtlCopyMemory (lpClass,
1990 FullInfo->ClassLength);
1991 *lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
1992 lpClass[*lpcbClass] = 0;
1996 if (lpClass != NULL)
1998 RtlFreeHeap (ProcessHeap,
2002 if (ErrorCode != ERROR_SUCCESS)
2004 SetLastError(ErrorCode);
2011 /************************************************************************
2012 * RegQueryMultipleValuesA
2017 RegQueryMultipleValuesA (HKEY hKey,
2024 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2025 return ERROR_CALL_NOT_IMPLEMENTED;
2029 /************************************************************************
2030 * RegQueryMultipleValuesW
2035 RegQueryMultipleValuesW (HKEY hKey,
2042 DWORD maxBytes = *ldwTotsize;
2044 LPSTR bufptr = (LPSTR)lpValueBuf;
2046 if ( maxBytes >= (1024*1024) )
2047 return ERROR_TRANSFER_TOO_LONG;
2051 //TRACE("(%p,%p,%ld,%p,%p=%ld)\n", hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
2053 for(i=0; i < num_vals; ++i)
2055 val_list[i].ve_valuelen=0;
2056 status = RegQueryValueExW(hKey, val_list[i].ve_valuename, NULL, NULL, NULL, &val_list[i].ve_valuelen);
2057 if(status != ERROR_SUCCESS)
2062 if(lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
2064 status = RegQueryValueExW(hKey, val_list[i].ve_valuename, NULL, &val_list[i].ve_type,
2065 bufptr, &val_list[i].ve_valuelen);
2066 if(status != ERROR_SUCCESS)
2071 val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
2073 bufptr += val_list[i].ve_valuelen;
2076 *ldwTotsize += val_list[i].ve_valuelen;
2078 return lpValueBuf != NULL && *ldwTotsize <= maxBytes ? ERROR_SUCCESS : ERROR_MORE_DATA;
2082 /************************************************************************
2088 RegQueryValueExW (HKEY hKey,
2089 LPCWSTR lpValueName,
2095 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
2096 UNICODE_STRING ValueName;
2098 LONG ErrorCode = ERROR_SUCCESS;
2103 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
2104 hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
2106 Status = MapDefaultKey (&KeyHandle,
2108 if (!NT_SUCCESS(Status))
2110 ErrorCode = RtlNtStatusToDosError (Status);
2111 SetLastError (ErrorCode);
2115 if (lpData != NULL && lpcbData == NULL)
2117 SetLastError (ERROR_INVALID_PARAMETER);
2118 return ERROR_INVALID_PARAMETER;
2121 RtlInitUnicodeString (&ValueName,
2123 BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData;
2124 ValueInfo = RtlAllocateHeap (ProcessHeap,
2127 if (ValueInfo == NULL)
2129 SetLastError(ERROR_OUTOFMEMORY);
2130 return ERROR_OUTOFMEMORY;
2133 Status = NtQueryValueKey (hKey,
2135 KeyValuePartialInformation,
2139 DPRINT("Status 0x%X\n", Status);
2140 if (Status == STATUS_BUFFER_TOO_SMALL)
2142 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
2143 ErrorCode = ERROR_SUCCESS;
2145 else if (!NT_SUCCESS(Status))
2147 ErrorCode = RtlNtStatusToDosError (Status);
2148 SetLastError (ErrorCode);
2154 *lpType = ValueInfo->Type;
2156 RtlMoveMemory (lpData,
2158 ValueInfo->DataLength);
2159 if ((ValueInfo->Type == REG_SZ) ||
2160 (ValueInfo->Type == REG_MULTI_SZ) ||
2161 (ValueInfo->Type == REG_EXPAND_SZ))
2163 ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
2166 DPRINT("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
2168 if (NULL != lpcbData)
2170 *lpcbData = (DWORD)ValueInfo->DataLength;
2172 RtlFreeHeap (ProcessHeap,
2180 /************************************************************************
2195 WCHAR ValueNameBuffer[MAX_PATH+1];
2196 UNICODE_STRING ValueName;
2197 UNICODE_STRING ValueData;
2198 ANSI_STRING AnsiString;
2203 /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
2205 if ((lpData) && (!lpcbData)) {
2206 SetLastError(ERROR_INVALID_PARAMETER);
2207 return ERROR_INVALID_PARAMETER;
2209 RtlInitUnicodeString(&ValueData, NULL);
2211 ValueData.MaximumLength = *lpcbData * sizeof(WCHAR);
2212 ValueData.Buffer = RtlAllocateHeap(
2215 ValueData.MaximumLength);
2216 if (!ValueData.Buffer) {
2217 SetLastError(ERROR_OUTOFMEMORY);
2218 return ERROR_OUTOFMEMORY;
2221 RtlInitAnsiString(&AnsiString, (LPSTR)lpValueName);
2222 RtlInitUnicodeString(&ValueName, NULL);
2223 ValueName.Buffer = &ValueNameBuffer[0];
2224 ValueName.MaximumLength = sizeof(ValueNameBuffer);
2225 RtlAnsiStringToUnicodeString(&ValueName, &AnsiString, FALSE);
2227 ResultSize = *lpcbData;
2231 ErrorCode = RegQueryValueExW(
2236 (LPBYTE)ValueData.Buffer,
2238 if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL)) {
2242 if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) {
2243 ValueData.Length = ResultSize;
2244 RtlInitAnsiString(&AnsiString, NULL);
2245 AnsiString.Buffer = lpData;
2246 AnsiString.MaximumLength = *lpcbData;
2247 RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
2249 RtlMoveMemory(lpData, ValueData.Buffer, ResultSize);
2253 *lpcbData = ResultSize;
2255 if (ValueData.Buffer) {
2256 RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
2262 /************************************************************************
2268 RegQueryValueA (HKEY hKey,
2273 WCHAR SubKeyNameBuffer[MAX_PATH+1];
2274 UNICODE_STRING SubKeyName;
2275 UNICODE_STRING Value;
2276 ANSI_STRING AnsiString;
2280 if (lpValue != NULL &&
2283 SetLastError(ERROR_INVALID_PARAMETER);
2284 return ERROR_INVALID_PARAMETER;
2287 RtlInitUnicodeString (&SubKeyName,
2289 RtlInitUnicodeString (&Value,
2291 if (lpSubKey != NULL &&
2292 strlen(lpSubKey) != 0)
2294 RtlInitAnsiString (&AnsiString,
2296 SubKeyName.Buffer = &SubKeyNameBuffer[0];
2297 SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
2298 RtlAnsiStringToUnicodeString (&SubKeyName,
2303 if (lpValue != NULL)
2305 ValueSize = *lpcbValue * sizeof(WCHAR);
2306 Value.MaximumLength = ValueSize;
2307 Value.Buffer = RtlAllocateHeap (ProcessHeap,
2310 if (Value.Buffer == NULL)
2312 SetLastError(ERROR_OUTOFMEMORY);
2313 return ERROR_OUTOFMEMORY;
2321 ErrorCode = RegQueryValueW (hKey,
2322 (LPCWSTR)SubKeyName.Buffer,
2325 if (ErrorCode == ERROR_SUCCESS)
2327 Value.Length = ValueSize;
2328 RtlInitAnsiString (&AnsiString,
2330 AnsiString.Buffer = lpValue;
2331 AnsiString.MaximumLength = *lpcbValue;
2332 RtlUnicodeStringToAnsiString (&AnsiString,
2337 *lpcbValue = ValueSize;
2338 if (Value.Buffer != NULL)
2340 RtlFreeHeap (ProcessHeap,
2349 /************************************************************************
2355 RegQueryValueW (HKEY hKey,
2360 OBJECT_ATTRIBUTES ObjectAttributes;
2361 UNICODE_STRING SubKeyString;
2368 Status = MapDefaultKey (&KeyHandle,
2370 if (!NT_SUCCESS(Status))
2372 ErrorCode = RtlNtStatusToDosError (Status);
2373 SetLastError (ErrorCode);
2377 if (lpSubKey != NULL &&
2378 wcslen(lpSubKey) != 0)
2380 RtlInitUnicodeString (&SubKeyString,
2382 InitializeObjectAttributes (&ObjectAttributes,
2384 OBJ_CASE_INSENSITIVE,
2387 Status = NtOpenKey (&RealKey,
2390 if (!NT_SUCCESS(Status))
2392 ErrorCode = RtlNtStatusToDosError (Status);
2393 SetLastError (ErrorCode);
2396 CloseRealKey = TRUE;
2401 CloseRealKey = FALSE;
2404 ErrorCode = RegQueryValueExW (RealKey,
2409 (LPDWORD)lpcbValue);
2419 /************************************************************************
2425 RegReplaceKeyA (HKEY hKey,
2430 UNICODE_STRING lpSubKeyW;
2431 UNICODE_STRING lpNewFileW;
2432 UNICODE_STRING lpOldFileW;
2435 RtlCreateUnicodeStringFromAsciiz( &lpSubKeyW, (PCSZ)lpSubKey );
2436 RtlCreateUnicodeStringFromAsciiz( &lpOldFileW, (PCSZ)lpOldFile );
2437 RtlCreateUnicodeStringFromAsciiz( &lpNewFileW, (PCSZ)lpNewFile );
2438 ret = RegReplaceKeyW( hKey, lpSubKeyW.Buffer, lpNewFileW.Buffer, lpOldFileW.Buffer );
2439 RtlFreeUnicodeString( &lpOldFileW );
2440 RtlFreeUnicodeString( &lpNewFileW );
2441 RtlFreeUnicodeString( &lpSubKeyW );
2446 /************************************************************************
2452 RegReplaceKeyW (HKEY hKey,
2458 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2459 return ERROR_CALL_NOT_IMPLEMENTED;
2463 /************************************************************************
2469 RegRestoreKeyA (HKEY hKey,
2473 UNICODE_STRING lpFileW;
2476 RtlCreateUnicodeStringFromAsciiz( &lpFileW, (PCSZ)lpFile );
2477 ret = RegRestoreKeyW( hKey, lpFileW.Buffer, dwFlags );
2478 RtlFreeUnicodeString( &lpFileW );
2483 /************************************************************************
2489 RegRestoreKeyW (HKEY hKey,
2494 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2495 return ERROR_CALL_NOT_IMPLEMENTED;
2499 /************************************************************************
2505 RegSaveKeyA(HKEY hKey,
2507 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
2509 UNICODE_STRING FileName;
2512 RtlCreateUnicodeStringFromAsciiz (&FileName,
2514 ErrorCode = RegSaveKeyW (hKey,
2516 lpSecurityAttributes);
2517 RtlFreeUnicodeString (&FileName);
2523 /************************************************************************
2529 RegSaveKeyW (HKEY hKey,
2531 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
2533 PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
2534 OBJECT_ATTRIBUTES ObjectAttributes;
2535 UNICODE_STRING NtName;
2536 IO_STATUS_BLOCK IoStatusBlock;
2542 Status = MapDefaultKey (&KeyHandle,
2544 if (!NT_SUCCESS(Status))
2546 ErrorCode = RtlNtStatusToDosError (Status);
2547 SetLastError (ErrorCode);
2551 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
2556 SetLastError (ERROR_INVALID_PARAMETER);
2557 return ERROR_INVALID_PARAMETER;
2560 if (lpSecurityAttributes != NULL)
2562 SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
2565 InitializeObjectAttributes (&ObjectAttributes,
2567 OBJ_CASE_INSENSITIVE,
2569 SecurityDescriptor);
2570 Status = NtCreateFile (&FileHandle,
2571 GENERIC_WRITE | SYNCHRONIZE,
2575 FILE_ATTRIBUTE_NORMAL,
2578 FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
2581 RtlFreeUnicodeString (&NtName);
2582 if (!NT_SUCCESS(Status))
2584 ErrorCode = RtlNtStatusToDosError (Status);
2585 SetLastError (ErrorCode);
2589 Status = NtSaveKey (KeyHandle,
2591 NtClose (FileHandle);
2592 if (!NT_SUCCESS(Status))
2594 ErrorCode = RtlNtStatusToDosError (Status);
2595 SetLastError (ErrorCode);
2599 return ERROR_SUCCESS;
2603 /************************************************************************
2609 RegSetKeySecurity (HKEY hKey,
2610 SECURITY_INFORMATION SecurityInformation,
2611 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2617 if (hKey == HKEY_PERFORMANCE_DATA)
2618 return ERROR_INVALID_HANDLE;
2620 Status = MapDefaultKey (&KeyHandle,
2622 if (!NT_SUCCESS(Status))
2624 ErrorCode = RtlNtStatusToDosError (Status);
2625 SetLastError (ErrorCode);
2629 Status = NtSetSecurityObject (KeyHandle,
2630 SecurityInformation,
2631 pSecurityDescriptor);
2632 if (!NT_SUCCESS(Status))
2634 ErrorCode = RtlNtStatusToDosError (Status);
2635 SetLastError (ErrorCode);
2639 return ERROR_SUCCESS;
2643 /************************************************************************
2649 RegSetValueExA (HKEY hKey,
2656 UNICODE_STRING ValueName;
2658 ANSI_STRING AnsiString;
2659 UNICODE_STRING Data;
2666 SetLastError (ERROR_INVALID_PARAMETER);
2667 return ERROR_INVALID_PARAMETER;
2670 if (lpValueName != NULL &&
2671 strlen(lpValueName) != 0)
2673 RtlCreateUnicodeStringFromAsciiz (&ValueName,
2674 (LPSTR)lpValueName);
2675 pValueName = (LPWSTR)ValueName.Buffer;
2682 if ((dwType == REG_SZ) ||
2683 (dwType == REG_MULTI_SZ) ||
2684 (dwType == REG_EXPAND_SZ))
2686 RtlInitAnsiString (&AnsiString,
2688 AnsiString.Buffer = (LPSTR)lpData;
2689 AnsiString.Length = cbData;
2690 AnsiString.MaximumLength = cbData;
2691 RtlAnsiStringToUnicodeString (&Data,
2694 pData = (LPBYTE)Data.Buffer;
2695 DataSize = cbData * sizeof(WCHAR);
2699 RtlInitUnicodeString (&Data,
2701 pData = (LPBYTE)lpData;
2705 ErrorCode = RegSetValueExW (hKey,
2711 if (pValueName != NULL)
2713 RtlFreeHeap (ProcessHeap,
2718 if (Data.Buffer != NULL)
2720 RtlFreeHeap (ProcessHeap,
2729 /************************************************************************
2735 RegSetValueExW (HKEY hKey,
2736 LPCWSTR lpValueName,
2742 UNICODE_STRING ValueName;
2743 PUNICODE_STRING pValueName;
2748 Status = MapDefaultKey (&KeyHandle,
2750 if (!NT_SUCCESS(Status))
2752 ErrorCode = RtlNtStatusToDosError (Status);
2753 SetLastError (ErrorCode);
2757 if (lpValueName != NULL)
2759 RtlInitUnicodeString (&ValueName,
2761 pValueName = &ValueName;
2768 Status = NtSetValueKey (KeyHandle,
2774 if (!NT_SUCCESS(Status))
2776 ErrorCode = RtlNtStatusToDosError (Status);
2777 SetLastError (ErrorCode);
2781 return ERROR_SUCCESS;
2785 /************************************************************************
2791 RegSetValueA (HKEY hKey,
2797 WCHAR SubKeyNameBuffer[MAX_PATH+1];
2798 UNICODE_STRING SubKeyName;
2799 UNICODE_STRING Data;
2800 ANSI_STRING AnsiString;
2806 SetLastError (ERROR_INVALID_PARAMETER);
2807 return ERROR_INVALID_PARAMETER;
2810 RtlInitUnicodeString (&SubKeyName, NULL);
2811 RtlInitUnicodeString (&Data, NULL);
2812 if (lpSubKey != NULL && (strlen(lpSubKey) != 0))
2814 RtlInitAnsiString (&AnsiString, (LPSTR)lpSubKey);
2815 SubKeyName.Buffer = &SubKeyNameBuffer[0];
2816 SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
2817 RtlAnsiStringToUnicodeString (&SubKeyName, &AnsiString, FALSE);
2820 DataSize = cbData * sizeof(WCHAR);
2821 Data.MaximumLength = DataSize;
2822 Data.Buffer = RtlAllocateHeap (ProcessHeap,
2825 if (Data.Buffer == NULL)
2827 SetLastError (ERROR_OUTOFMEMORY);
2828 return ERROR_OUTOFMEMORY;
2831 ErrorCode = RegSetValueW (hKey,
2832 (LPCWSTR)SubKeyName.Buffer,
2836 RtlFreeHeap (ProcessHeap,
2844 /************************************************************************
2850 RegSetValueW (HKEY hKey,
2856 OBJECT_ATTRIBUTES ObjectAttributes;
2857 UNICODE_STRING SubKeyString;
2864 Status = MapDefaultKey (&KeyHandle,
2866 if (!NT_SUCCESS(Status))
2868 ErrorCode = RtlNtStatusToDosError (Status);
2869 SetLastError (ErrorCode);
2873 if ((lpSubKey) && (wcslen(lpSubKey) != 0))
2875 RtlInitUnicodeString (&SubKeyString,
2877 InitializeObjectAttributes (&ObjectAttributes,
2879 OBJ_CASE_INSENSITIVE,
2882 Status = NtOpenKey (&RealKey,
2885 if (!NT_SUCCESS(Status))
2887 ErrorCode = RtlNtStatusToDosError (Status);
2888 SetLastError (ErrorCode);
2891 CloseRealKey = TRUE;
2896 CloseRealKey = FALSE;
2899 ErrorCode = RegSetValueExW (RealKey,
2905 if (CloseRealKey == TRUE)
2914 /************************************************************************
2920 RegUnLoadKeyA (HKEY hKey,
2923 UNICODE_STRING KeyName;
2926 RtlCreateUnicodeStringFromAsciiz (&KeyName,
2929 ErrorCode = RegUnLoadKeyW (hKey,
2932 RtlFreeUnicodeString (&KeyName);
2938 /************************************************************************
2944 RegUnLoadKeyW (HKEY hKey,
2947 OBJECT_ATTRIBUTES ObjectAttributes;
2948 UNICODE_STRING KeyName;
2953 if (hKey == HKEY_PERFORMANCE_DATA)
2954 return ERROR_INVALID_HANDLE;
2956 Status = MapDefaultKey (&KeyHandle, hKey);
2957 if (!NT_SUCCESS(Status))
2959 ErrorCode = RtlNtStatusToDosError (Status);
2960 SetLastError (ErrorCode);
2964 RtlInitUnicodeString (&KeyName,
2967 InitializeObjectAttributes (&ObjectAttributes,
2969 OBJ_CASE_INSENSITIVE,
2973 Status = NtUnloadKey (&ObjectAttributes);
2975 if (!NT_SUCCESS(Status))
2977 ErrorCode = RtlNtStatusToDosError (Status);
2978 SetLastError (ErrorCode);
2982 return ERROR_SUCCESS;