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 RTL_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
,
460 RtlCreateUnicodeStringFromAsciiz(&SubKeyString
,
462 InitializeObjectAttributes (&Attributes
,
464 OBJ_CASE_INSENSITIVE
,
466 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
467 Status
= CreateNestedKey(phkResult
,
469 (lpClass
== NULL
)? NULL
: &ClassString
,
473 RtlFreeUnicodeString (&SubKeyString
);
476 RtlFreeUnicodeString (&ClassString
);
479 DPRINT("Status %x\n", Status
);
480 if (!NT_SUCCESS(Status
))
482 ErrorCode
= RtlNtStatusToDosError (Status
);
483 SetLastError (ErrorCode
);
487 return ERROR_SUCCESS
;
491 /************************************************************************
497 RegCreateKeyExW (HKEY hKey
,
503 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
505 LPDWORD lpdwDisposition
)
507 UNICODE_STRING SubKeyString
;
508 UNICODE_STRING ClassString
;
509 OBJECT_ATTRIBUTES Attributes
;
514 DPRINT("RegCreateKeyExW() called\n");
516 /* get the real parent key */
517 Status
= MapDefaultKey (&ParentKey
,
519 if (!NT_SUCCESS(Status
))
521 ErrorCode
= RtlNtStatusToDosError(Status
);
522 SetLastError (ErrorCode
);
525 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
527 RtlInitUnicodeString (&ClassString
,
529 RtlInitUnicodeString (&SubKeyString
,
531 InitializeObjectAttributes (&Attributes
,
533 OBJ_CASE_INSENSITIVE
,
535 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
536 Status
= CreateNestedKey(phkResult
,
538 (lpClass
== NULL
)? NULL
: &ClassString
,
542 DPRINT("Status %x\n", Status
);
543 if (!NT_SUCCESS(Status
))
545 ErrorCode
= RtlNtStatusToDosError (Status
);
546 SetLastError (ErrorCode
);
550 return ERROR_SUCCESS
;
554 /************************************************************************
560 RegCreateKeyA (HKEY hKey
,
564 return RegCreateKeyExA (hKey
,
576 /************************************************************************
582 RegCreateKeyW (HKEY hKey
,
586 return RegCreateKeyExW (hKey
,
598 /************************************************************************
604 RegDeleteKeyA (HKEY hKey
,
607 OBJECT_ATTRIBUTES ObjectAttributes
;
608 UNICODE_STRING SubKeyName
;
614 Status
= MapDefaultKey (&ParentKey
,
616 if (!NT_SUCCESS(Status
))
618 ErrorCode
= RtlNtStatusToDosError (Status
);
619 SetLastError (ErrorCode
);
623 RtlCreateUnicodeStringFromAsciiz (&SubKeyName
,
625 InitializeObjectAttributes(&ObjectAttributes
,
627 OBJ_CASE_INSENSITIVE
,
631 Status
= NtOpenKey (&TargetKey
,
634 RtlFreeUnicodeString (&SubKeyName
);
635 if (!NT_SUCCESS(Status
))
637 ErrorCode
= RtlNtStatusToDosError (Status
);
638 SetLastError (ErrorCode
);
642 Status
= NtDeleteKey (TargetKey
);
644 if (!NT_SUCCESS(Status
))
646 ErrorCode
= RtlNtStatusToDosError(Status
);
647 SetLastError (ErrorCode
);
651 return ERROR_SUCCESS
;
655 /************************************************************************
661 RegDeleteKeyW (HKEY hKey
,
664 OBJECT_ATTRIBUTES ObjectAttributes
;
665 UNICODE_STRING SubKeyName
;
671 Status
= MapDefaultKey (&ParentKey
,
673 if (!NT_SUCCESS(Status
))
675 ErrorCode
= RtlNtStatusToDosError (Status
);
676 SetLastError (ErrorCode
);
680 RtlInitUnicodeString (&SubKeyName
,
682 InitializeObjectAttributes (&ObjectAttributes
,
684 OBJ_CASE_INSENSITIVE
,
687 Status
= NtOpenKey (&TargetKey
,
690 if (!NT_SUCCESS(Status
))
692 ErrorCode
= RtlNtStatusToDosError (Status
);
693 SetLastError (ErrorCode
);
697 Status
= NtDeleteKey (TargetKey
);
699 if (!NT_SUCCESS(Status
))
701 ErrorCode
= RtlNtStatusToDosError (Status
);
702 SetLastError (ErrorCode
);
706 return ERROR_SUCCESS
;
710 /************************************************************************
716 RegDeleteValueA (HKEY hKey
,
719 UNICODE_STRING ValueName
;
724 Status
= MapDefaultKey (&KeyHandle
,
726 if (!NT_SUCCESS(Status
))
728 ErrorCode
= RtlNtStatusToDosError (Status
);
729 SetLastError (ErrorCode
);
733 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
735 Status
= NtDeleteValueKey (KeyHandle
,
737 RtlFreeUnicodeString (&ValueName
);
738 if (!NT_SUCCESS(Status
))
740 ErrorCode
= RtlNtStatusToDosError (Status
);
741 SetLastError (ErrorCode
);
745 return ERROR_SUCCESS
;
749 /************************************************************************
755 RegDeleteValueW (HKEY hKey
,
758 UNICODE_STRING ValueName
;
763 Status
= MapDefaultKey (&KeyHandle
,
765 if (!NT_SUCCESS(Status
))
767 ErrorCode
= RtlNtStatusToDosError (Status
);
768 SetLastError (ErrorCode
);
772 RtlInitUnicodeString (&ValueName
,
773 (LPWSTR
)lpValueName
);
775 Status
= NtDeleteValueKey (KeyHandle
,
777 if (!NT_SUCCESS(Status
))
779 ErrorCode
= RtlNtStatusToDosError (Status
);
780 SetLastError (ErrorCode
);
784 return ERROR_SUCCESS
;
788 /************************************************************************
794 RegEnumKeyA (HKEY hKey
,
802 return RegEnumKeyExA (hKey
,
813 /************************************************************************
819 RegEnumKeyW (HKEY hKey
,
827 return RegEnumKeyExW (hKey
,
838 /************************************************************************
844 RegEnumKeyExA (HKEY hKey
,
851 PFILETIME lpftLastWriteTime
)
855 KEY_NODE_INFORMATION Node
;
856 KEY_BASIC_INFORMATION Basic
;
859 UNICODE_STRING StringU
;
861 LONG ErrorCode
= ERROR_SUCCESS
;
863 DWORD ClassLength
= 0;
869 DPRINT("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
870 hKey
, dwIndex
, lpName
, *lpcbName
, lpClass
, lpcbClass
? *lpcbClass
: 0);
872 if ((lpClass
) && (!lpcbClass
))
874 SetLastError (ERROR_INVALID_PARAMETER
);
875 return ERROR_INVALID_PARAMETER
;
878 Status
= MapDefaultKey(&KeyHandle
,
880 if (!NT_SUCCESS(Status
))
882 ErrorCode
= RtlNtStatusToDosError (Status
);
883 SetLastError (ErrorCode
);
889 NameLength
= min (*lpcbName
- 1 , REG_MAX_NAME_SIZE
) * sizeof (WCHAR
);
900 ClassLength
= min (*lpcbClass
-1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
907 /* The class name should start at a dword boundary */
908 BufferSize
= ((sizeof(KEY_NODE_INFORMATION
) + NameLength
+ 3) & ~3) + ClassLength
;
912 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + NameLength
;
915 KeyInfo
= RtlAllocateHeap (ProcessHeap
,
920 SetLastError (ERROR_OUTOFMEMORY
);
921 return ERROR_OUTOFMEMORY
;
924 Status
= NtEnumerateKey (KeyHandle
,
926 lpClass
== NULL
? KeyBasicInformation
: KeyNodeInformation
,
930 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status
);
931 if (!NT_SUCCESS(Status
))
933 ErrorCode
= RtlNtStatusToDosError (Status
);
939 if (KeyInfo
->Basic
.NameLength
> NameLength
)
941 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
945 StringU
.Buffer
= KeyInfo
->Basic
.Name
;
946 StringU
.Length
= KeyInfo
->Basic
.NameLength
;
947 StringU
.MaximumLength
= KeyInfo
->Basic
.NameLength
;
952 if (KeyInfo
->Node
.NameLength
> NameLength
||
953 KeyInfo
->Node
.ClassLength
> ClassLength
)
955 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
959 StringA
.Buffer
= lpClass
;
961 StringA
.MaximumLength
= *lpcbClass
;
962 StringU
.Buffer
= (PWCHAR
)((ULONG_PTR
)KeyInfo
->Node
.Name
+ KeyInfo
->Node
.ClassOffset
);
963 StringU
.Length
= KeyInfo
->Node
.ClassLength
;
964 StringU
.MaximumLength
= KeyInfo
->Node
.ClassLength
;
965 RtlUnicodeStringToAnsiString (&StringA
, &StringU
, FALSE
);
966 lpClass
[StringA
.Length
] = 0;
967 *lpcbClass
= StringA
.Length
;
968 StringU
.Buffer
= KeyInfo
->Node
.Name
;
969 StringU
.Length
= KeyInfo
->Node
.NameLength
;
970 StringU
.MaximumLength
= KeyInfo
->Node
.NameLength
;
974 if (ErrorCode
== ERROR_SUCCESS
)
976 StringA
.Buffer
= lpName
;
978 StringA
.MaximumLength
= *lpcbName
;
979 RtlUnicodeStringToAnsiString (&StringA
, &StringU
, FALSE
);
980 lpName
[StringA
.Length
] = 0;
981 *lpcbName
= StringA
.Length
;
982 if (lpftLastWriteTime
!= NULL
)
986 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.LowPart
;
987 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.HighPart
;
991 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.LowPart
;
992 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.HighPart
;
998 DPRINT("Key Namea0 Length %d\n", StringU
.Length
);
999 DPRINT("Key Namea1 Length %d\n", NameLength
);
1000 DPRINT("Key Namea Length %d\n", *lpcbName
);
1001 DPRINT("Key Namea %s\n", lpName
);
1003 RtlFreeHeap (ProcessHeap
,
1007 if (ErrorCode
!= ERROR_SUCCESS
)
1009 SetLastError(ErrorCode
);
1016 /************************************************************************
1022 RegEnumKeyExW (HKEY hKey
,
1029 PFILETIME lpftLastWriteTime
)
1033 KEY_NODE_INFORMATION Node
;
1034 KEY_BASIC_INFORMATION Basic
;
1040 ULONG ClassLength
= 0;
1042 LONG ErrorCode
= ERROR_SUCCESS
;
1045 Status
= MapDefaultKey(&KeyHandle
,
1047 if (!NT_SUCCESS(Status
))
1049 ErrorCode
= RtlNtStatusToDosError (Status
);
1050 SetLastError (ErrorCode
);
1056 NameLength
= min (*lpcbName
- 1, REG_MAX_NAME_SIZE
) * sizeof (WCHAR
);
1067 ClassLength
= min (*lpcbClass
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
1074 BufferSize
= ((sizeof(KEY_NODE_INFORMATION
) + NameLength
+ 3) & ~3) + ClassLength
;
1078 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + NameLength
;
1081 KeyInfo
= RtlAllocateHeap (ProcessHeap
,
1084 if (KeyInfo
== NULL
)
1086 SetLastError (ERROR_OUTOFMEMORY
);
1087 return ERROR_OUTOFMEMORY
;
1090 Status
= NtEnumerateKey (KeyHandle
,
1092 lpClass
? KeyNodeInformation
: KeyBasicInformation
,
1096 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status
);
1097 if (!NT_SUCCESS(Status
))
1099 ErrorCode
= RtlNtStatusToDosError (Status
);
1103 if (lpClass
== NULL
)
1105 if (KeyInfo
->Basic
.NameLength
> NameLength
)
1107 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1111 RtlCopyMemory (lpName
,
1112 KeyInfo
->Basic
.Name
,
1113 KeyInfo
->Basic
.NameLength
);
1114 *lpcbName
= (DWORD
)(KeyInfo
->Basic
.NameLength
/ sizeof(WCHAR
));
1115 lpName
[*lpcbName
] = 0;
1120 if (KeyInfo
->Node
.NameLength
> NameLength
||
1121 KeyInfo
->Node
.ClassLength
> ClassLength
)
1123 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1127 RtlCopyMemory (lpName
,
1129 KeyInfo
->Node
.NameLength
);
1130 *lpcbName
= KeyInfo
->Node
.NameLength
/ sizeof(WCHAR
);
1131 lpName
[*lpcbName
] = 0;
1132 RtlCopyMemory (lpClass
,
1133 (PVOID
)((ULONG_PTR
)KeyInfo
->Node
.Name
+ KeyInfo
->Node
.ClassOffset
),
1134 KeyInfo
->Node
.ClassLength
);
1135 *lpcbClass
= (DWORD
)(KeyInfo
->Node
.ClassLength
/ sizeof(WCHAR
));
1136 lpClass
[*lpcbClass
] = 0;
1140 if (ErrorCode
== ERROR_SUCCESS
&& lpftLastWriteTime
!= NULL
)
1142 if (lpClass
== NULL
)
1144 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.LowPart
;
1145 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Basic
.LastWriteTime
.u
.HighPart
;
1149 lpftLastWriteTime
->dwLowDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.LowPart
;
1150 lpftLastWriteTime
->dwHighDateTime
= KeyInfo
->Node
.LastWriteTime
.u
.HighPart
;
1155 RtlFreeHeap (ProcessHeap
,
1159 if (ErrorCode
!= ERROR_SUCCESS
)
1161 SetLastError(ErrorCode
);
1168 /************************************************************************
1174 RegEnumValueA (HKEY hKey
,
1177 LPDWORD lpcbValueName
,
1185 KEY_VALUE_FULL_INFORMATION Full
;
1186 KEY_VALUE_BASIC_INFORMATION Basic
;
1191 ULONG DataLength
= 0;
1196 UNICODE_STRING StringU
;
1197 ANSI_STRING StringA
;
1200 ErrorCode
= ERROR_SUCCESS
;
1202 Status
= MapDefaultKey (&KeyHandle
,
1204 if (!NT_SUCCESS(Status
))
1206 ErrorCode
= RtlNtStatusToDosError (Status
);
1207 SetLastError (ErrorCode
);
1211 if (*lpcbValueName
> 0)
1213 NameLength
= min (*lpcbValueName
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
1222 DataLength
= min (*lpcbData
* sizeof(WCHAR
), REG_MAX_DATA_SIZE
);
1223 BufferSize
= ((sizeof(KEY_VALUE_FULL_INFORMATION
) + NameLength
+ 3) & ~3) + DataLength
;
1227 BufferSize
= sizeof(KEY_VALUE_BASIC_INFORMATION
) + NameLength
;
1230 ValueInfo
= RtlAllocateHeap (ProcessHeap
,
1233 if (ValueInfo
== NULL
)
1235 SetLastError(ERROR_OUTOFMEMORY
);
1236 return ERROR_OUTOFMEMORY
;
1239 Status
= NtEnumerateValueKey (KeyHandle
,
1241 lpData
? KeyValueFullInformation
: KeyValueBasicInformation
,
1246 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status
);
1247 if (!NT_SUCCESS(Status
))
1249 ErrorCode
= RtlNtStatusToDosError (Status
);
1255 IsStringType
= (ValueInfo
->Full
.Type
== REG_SZ
) ||
1256 (ValueInfo
->Full
.Type
== REG_MULTI_SZ
) ||
1257 (ValueInfo
->Full
.Type
== REG_EXPAND_SZ
);
1258 if (ValueInfo
->Full
.NameLength
> NameLength
||
1259 (!IsStringType
&& ValueInfo
->Full
.DataLength
> *lpcbData
) ||
1260 ValueInfo
->Full
.DataLength
> DataLength
)
1262 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1268 StringU
.Buffer
= (PWCHAR
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->Full
.DataOffset
);
1269 StringU
.Length
= ValueInfo
->Full
.DataLength
;
1270 StringU
.MaximumLength
= DataLength
;
1271 StringA
.Buffer
= (PCHAR
)lpData
;
1273 StringA
.MaximumLength
= *lpcbData
;
1274 RtlUnicodeStringToAnsiString (&StringA
,
1277 *lpcbData
= StringA
.Length
;
1281 RtlCopyMemory (lpData
,
1282 (PVOID
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->Full
.DataOffset
),
1283 ValueInfo
->Full
.DataLength
);
1284 *lpcbData
= ValueInfo
->Full
.DataLength
;
1287 StringU
.Buffer
= ValueInfo
->Full
.Name
;
1288 StringU
.Length
= ValueInfo
->Full
.NameLength
;
1289 StringU
.MaximumLength
= NameLength
;
1294 if (ValueInfo
->Basic
.NameLength
> NameLength
)
1296 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1300 StringU
.Buffer
= ValueInfo
->Basic
.Name
;
1301 StringU
.Length
= ValueInfo
->Basic
.NameLength
;
1302 StringU
.MaximumLength
= NameLength
;
1306 if (ErrorCode
== ERROR_SUCCESS
)
1308 StringA
.Buffer
= (PCHAR
)lpValueName
;
1310 StringA
.MaximumLength
= *lpcbValueName
;
1311 RtlUnicodeStringToAnsiString (&StringA
,
1314 StringA
.Buffer
[StringA
.Length
] = 0;
1315 *lpcbValueName
= StringA
.Length
;
1318 *lpType
= lpData
? ValueInfo
->Full
.Type
: ValueInfo
->Basic
.Type
;
1323 RtlFreeHeap (ProcessHeap
,
1326 if (ErrorCode
!= ERROR_SUCCESS
)
1328 SetLastError(ErrorCode
);
1335 /************************************************************************
1341 RegEnumValueW (HKEY hKey
,
1344 LPDWORD lpcbValueName
,
1352 KEY_VALUE_FULL_INFORMATION Full
;
1353 KEY_VALUE_BASIC_INFORMATION Basic
;
1358 ULONG DataLength
= 0;
1364 ErrorCode
= ERROR_SUCCESS
;
1366 Status
= MapDefaultKey (&KeyHandle
,
1368 if (!NT_SUCCESS(Status
))
1370 ErrorCode
= RtlNtStatusToDosError (Status
);
1371 SetLastError (ErrorCode
);
1375 if (*lpcbValueName
> 0)
1377 NameLength
= min (*lpcbValueName
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
1386 DataLength
= min(*lpcbData
, REG_MAX_DATA_SIZE
);
1387 BufferSize
= ((sizeof(KEY_VALUE_FULL_INFORMATION
) + NameLength
+ 3) & ~3) + DataLength
;
1391 BufferSize
= sizeof(KEY_VALUE_BASIC_INFORMATION
) + NameLength
;
1393 ValueInfo
= RtlAllocateHeap (ProcessHeap
,
1396 if (ValueInfo
== NULL
)
1398 SetLastError (ERROR_OUTOFMEMORY
);
1399 return ERROR_OUTOFMEMORY
;
1401 Status
= NtEnumerateValueKey (KeyHandle
,
1403 lpData
? KeyValueFullInformation
: KeyValueBasicInformation
,
1408 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status
);
1409 if (!NT_SUCCESS(Status
))
1411 ErrorCode
= RtlNtStatusToDosError (Status
);
1417 if (ValueInfo
->Full
.DataLength
> DataLength
||
1418 ValueInfo
->Full
.NameLength
> NameLength
)
1420 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1424 RtlCopyMemory (lpValueName
,
1425 ValueInfo
->Full
.Name
,
1426 ValueInfo
->Full
.NameLength
);
1427 *lpcbValueName
= (DWORD
)(ValueInfo
->Full
.NameLength
/ sizeof(WCHAR
));
1428 lpValueName
[*lpcbValueName
] = 0;
1429 RtlCopyMemory (lpData
,
1430 (PVOID
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->Full
.DataOffset
),
1431 ValueInfo
->Full
.DataLength
);
1432 *lpcbData
= (DWORD
)ValueInfo
->Full
.DataLength
;
1437 if (ValueInfo
->Basic
.NameLength
> NameLength
)
1439 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
1443 RtlCopyMemory (lpValueName
,
1444 ValueInfo
->Basic
.Name
,
1445 ValueInfo
->Basic
.NameLength
);
1446 *lpcbValueName
= (DWORD
)(ValueInfo
->Basic
.NameLength
/ sizeof(WCHAR
));
1447 lpValueName
[*lpcbValueName
] = 0;
1449 if (NULL
!= lpcbData
)
1451 *lpcbData
= (DWORD
)ValueInfo
->Full
.DataLength
;
1455 if (ErrorCode
== ERROR_SUCCESS
&& lpType
!= NULL
)
1457 *lpType
= lpData
? ValueInfo
->Full
.Type
: ValueInfo
->Basic
.Type
;
1461 RtlFreeHeap (ProcessHeap
,
1465 if (ErrorCode
!= ERROR_SUCCESS
)
1467 SetLastError (ErrorCode
);
1474 /************************************************************************
1480 RegFlushKey(HKEY hKey
)
1486 if (hKey
== HKEY_PERFORMANCE_DATA
)
1488 return ERROR_SUCCESS
;
1491 Status
= MapDefaultKey (&KeyHandle
,
1493 if (!NT_SUCCESS(Status
))
1495 ErrorCode
= RtlNtStatusToDosError (Status
);
1496 SetLastError (ErrorCode
);
1500 Status
= NtFlushKey (KeyHandle
);
1501 if (!NT_SUCCESS(Status
))
1503 ErrorCode
= RtlNtStatusToDosError (Status
);
1504 SetLastError (ErrorCode
);
1508 return ERROR_SUCCESS
;
1512 /************************************************************************
1518 RegGetKeySecurity(HKEY hKey
,
1519 SECURITY_INFORMATION SecurityInformation
,
1520 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1521 LPDWORD lpcbSecurityDescriptor
)
1527 if (hKey
== HKEY_PERFORMANCE_DATA
)
1529 SetLastError(ERROR_INVALID_HANDLE
);
1530 return ERROR_INVALID_HANDLE
;
1533 Status
= MapDefaultKey(&KeyHandle
,
1535 if (!NT_SUCCESS(Status
))
1537 DPRINT("MapDefaultKey() failed (Status %lx)\n", Status
);
1538 ErrorCode
= RtlNtStatusToDosError(Status
);
1539 SetLastError(ErrorCode
);
1543 Status
= NtQuerySecurityObject(KeyHandle
,
1544 SecurityInformation
,
1545 pSecurityDescriptor
,
1546 *lpcbSecurityDescriptor
,
1547 lpcbSecurityDescriptor
);
1548 if (!NT_SUCCESS(Status
))
1550 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1551 ErrorCode
= RtlNtStatusToDosError(Status
);
1552 SetLastError(ErrorCode
);
1556 return ERROR_SUCCESS
;
1560 /************************************************************************
1566 RegLoadKeyA (HKEY hKey
,
1570 UNICODE_STRING FileName
;
1571 UNICODE_STRING KeyName
;
1574 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
1576 RtlCreateUnicodeStringFromAsciiz (&FileName
,
1579 ErrorCode
= RegLoadKeyW (hKey
,
1583 RtlFreeUnicodeString (&FileName
);
1584 RtlFreeUnicodeString (&KeyName
);
1590 /************************************************************************
1596 RegLoadKeyW (HKEY hKey
,
1600 OBJECT_ATTRIBUTES FileObjectAttributes
;
1601 OBJECT_ATTRIBUTES KeyObjectAttributes
;
1602 UNICODE_STRING FileName
;
1603 UNICODE_STRING KeyName
;
1608 if (hKey
== HKEY_PERFORMANCE_DATA
)
1610 SetLastError(ERROR_INVALID_HANDLE
);
1611 return ERROR_INVALID_HANDLE
;
1614 Status
= MapDefaultKey (&KeyHandle
,
1616 if (!NT_SUCCESS(Status
))
1618 ErrorCode
= RtlNtStatusToDosError (Status
);
1619 SetLastError (ErrorCode
);
1623 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
1628 SetLastError (ERROR_BAD_PATHNAME
);
1629 return ERROR_BAD_PATHNAME
;
1632 InitializeObjectAttributes (&FileObjectAttributes
,
1634 OBJ_CASE_INSENSITIVE
,
1638 RtlInitUnicodeString (&KeyName
,
1641 InitializeObjectAttributes (&KeyObjectAttributes
,
1643 OBJ_CASE_INSENSITIVE
,
1647 Status
= NtLoadKey (&KeyObjectAttributes
,
1648 &FileObjectAttributes
);
1650 RtlFreeUnicodeString (&FileName
);
1652 if (!NT_SUCCESS(Status
))
1654 ErrorCode
= RtlNtStatusToDosError (Status
);
1655 SetLastError (ErrorCode
);
1659 return ERROR_SUCCESS
;
1663 /************************************************************************
1664 * RegNotifyChangeKeyValue
1669 RegNotifyChangeKeyValue (HKEY hKey
,
1671 DWORD dwNotifyFilter
,
1675 IO_STATUS_BLOCK IoStatusBlock
;
1679 if (hKey
== HKEY_PERFORMANCE_DATA
)
1681 return ERROR_INVALID_HANDLE
;
1684 if (fAsynchronous
== TRUE
&& hEvent
== NULL
)
1686 return ERROR_INVALID_PARAMETER
;
1689 Status
= MapDefaultKey (&KeyHandle
,
1691 if (!NT_SUCCESS(Status
))
1693 return RtlNtStatusToDosError (Status
);
1696 /* FIXME: Remote key handles must fail */
1698 Status
= NtNotifyChangeKey (KeyHandle
,
1708 if (!NT_SUCCESS(Status
) && Status
!= STATUS_TIMEOUT
)
1710 return RtlNtStatusToDosError (Status
);
1713 return ERROR_SUCCESS
;
1717 /************************************************************************
1723 RegOpenKeyA (HKEY hKey
,
1727 OBJECT_ATTRIBUTES ObjectAttributes
;
1728 UNICODE_STRING SubKeyString
;
1733 DPRINT("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey
, lpSubKey
, phkResult
);
1734 Status
= MapDefaultKey (&KeyHandle
,
1736 if (!NT_SUCCESS(Status
))
1738 ErrorCode
= RtlNtStatusToDosError (Status
);
1739 SetLastError (ErrorCode
);
1743 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1745 InitializeObjectAttributes (&ObjectAttributes
,
1747 OBJ_CASE_INSENSITIVE
,
1750 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1753 RtlFreeUnicodeString (&SubKeyString
);
1754 if (!NT_SUCCESS(Status
))
1756 ErrorCode
= RtlNtStatusToDosError (Status
);
1757 SetLastError (ErrorCode
);
1761 return ERROR_SUCCESS
;
1765 /************************************************************************
1774 RegOpenKeyW (HKEY hKey
,
1778 OBJECT_ATTRIBUTES ObjectAttributes
;
1779 UNICODE_STRING SubKeyString
;
1784 DPRINT("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey
, lpSubKey
, phkResult
);
1785 Status
= MapDefaultKey (&KeyHandle
,
1787 if (!NT_SUCCESS(Status
))
1789 ErrorCode
= RtlNtStatusToDosError (Status
);
1790 SetLastError (ErrorCode
);
1794 RtlInitUnicodeString (&SubKeyString
,
1796 InitializeObjectAttributes (&ObjectAttributes
,
1798 OBJ_CASE_INSENSITIVE
,
1801 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1804 if (!NT_SUCCESS(Status
))
1806 ErrorCode
= RtlNtStatusToDosError (Status
);
1807 SetLastError(ErrorCode
);
1811 return ERROR_SUCCESS
;
1815 /************************************************************************
1821 RegOpenKeyExA (HKEY hKey
,
1827 OBJECT_ATTRIBUTES ObjectAttributes
;
1828 UNICODE_STRING SubKeyString
;
1833 DPRINT("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
1834 hKey
, lpSubKey
, ulOptions
, samDesired
, phkResult
);
1835 Status
= MapDefaultKey (&KeyHandle
,
1837 if (!NT_SUCCESS(Status
))
1839 ErrorCode
= RtlNtStatusToDosError (Status
);
1840 SetLastError (ErrorCode
);
1844 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1846 InitializeObjectAttributes (&ObjectAttributes
,
1848 OBJ_CASE_INSENSITIVE
,
1851 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1854 RtlFreeUnicodeString (&SubKeyString
);
1855 if (!NT_SUCCESS(Status
))
1857 ErrorCode
= RtlNtStatusToDosError (Status
);
1858 SetLastError (ErrorCode
);
1862 return ERROR_SUCCESS
;
1866 /************************************************************************
1872 RegOpenKeyExW (HKEY hKey
,
1878 OBJECT_ATTRIBUTES ObjectAttributes
;
1879 UNICODE_STRING SubKeyString
;
1884 DPRINT("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
1885 hKey
, lpSubKey
, ulOptions
, samDesired
, phkResult
);
1886 Status
= MapDefaultKey (&KeyHandle
,
1888 if (!NT_SUCCESS(Status
))
1890 ErrorCode
= RtlNtStatusToDosError (Status
);
1891 SetLastError (ErrorCode
);
1895 if (lpSubKey
!= NULL
)
1897 RtlInitUnicodeString (&SubKeyString
,
1902 RtlInitUnicodeString (&SubKeyString
,
1905 InitializeObjectAttributes (&ObjectAttributes
,
1907 OBJ_CASE_INSENSITIVE
,
1910 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1913 if (!NT_SUCCESS(Status
))
1915 ErrorCode
= RtlNtStatusToDosError (Status
);
1916 SetLastError (ErrorCode
);
1920 return ERROR_SUCCESS
;
1924 /************************************************************************
1930 RegQueryInfoKeyA (HKEY hKey
,
1935 LPDWORD lpcbMaxSubKeyLen
,
1936 LPDWORD lpcbMaxClassLen
,
1938 LPDWORD lpcbMaxValueNameLen
,
1939 LPDWORD lpcbMaxValueLen
,
1940 LPDWORD lpcbSecurityDescriptor
,
1941 PFILETIME lpftLastWriteTime
)
1943 WCHAR ClassName
[MAX_PATH
];
1944 UNICODE_STRING UnicodeString
;
1945 ANSI_STRING AnsiString
;
1948 RtlInitUnicodeString (&UnicodeString
,
1950 if (lpClass
!= NULL
)
1952 UnicodeString
.Buffer
= &ClassName
[0];
1953 UnicodeString
.MaximumLength
= sizeof(ClassName
);
1954 AnsiString
.MaximumLength
= *lpcbClass
;
1957 ErrorCode
= RegQueryInfoKeyW (hKey
,
1958 UnicodeString
.Buffer
,
1965 lpcbMaxValueNameLen
,
1967 lpcbSecurityDescriptor
,
1969 if ((ErrorCode
== ERROR_SUCCESS
) && (lpClass
!= NULL
))
1971 AnsiString
.Buffer
= lpClass
;
1972 AnsiString
.Length
= 0;
1973 UnicodeString
.Length
= *lpcbClass
* sizeof(WCHAR
);
1974 RtlUnicodeStringToAnsiString (&AnsiString
,
1977 *lpcbClass
= AnsiString
.Length
;
1978 lpClass
[AnsiString
.Length
] = 0;
1985 /************************************************************************
1991 RegQueryInfoKeyW (HKEY hKey
,
1996 LPDWORD lpcbMaxSubKeyLen
,
1997 LPDWORD lpcbMaxClassLen
,
1999 LPDWORD lpcbMaxValueNameLen
,
2000 LPDWORD lpcbMaxValueLen
,
2001 LPDWORD lpcbSecurityDescriptor
,
2002 PFILETIME lpftLastWriteTime
)
2004 KEY_FULL_INFORMATION FullInfoBuffer
;
2005 PKEY_FULL_INFORMATION FullInfo
;
2007 ULONG ClassLength
= 0;
2010 LONG ErrorCode
= ERROR_SUCCESS
;
2013 if ((lpClass
) && (!lpcbClass
))
2015 SetLastError(ERROR_INVALID_PARAMETER
);
2016 return ERROR_INVALID_PARAMETER
;
2019 Status
= MapDefaultKey (&KeyHandle
,
2021 if (!NT_SUCCESS(Status
))
2023 ErrorCode
= RtlNtStatusToDosError (Status
);
2024 SetLastError (ErrorCode
);
2028 if (lpClass
!= NULL
)
2032 ClassLength
= min(*lpcbClass
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
2039 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
) + ((ClassLength
+ 3) & ~3);
2040 FullInfo
= RtlAllocateHeap (ProcessHeap
,
2043 if (FullInfo
== NULL
)
2045 SetLastError (ERROR_OUTOFMEMORY
);
2046 return ERROR_OUTOFMEMORY
;
2049 FullInfo
->ClassLength
= ClassLength
;
2053 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
);
2054 FullInfo
= &FullInfoBuffer
;
2055 FullInfo
->ClassLength
= 0;
2057 FullInfo
->ClassOffset
= FIELD_OFFSET(KEY_FULL_INFORMATION
, Class
);
2059 Status
= NtQueryKey (KeyHandle
,
2064 DPRINT("NtQueryKey() returned status 0x%X\n", Status
);
2065 if (!NT_SUCCESS(Status
))
2067 if (lpClass
!= NULL
)
2069 RtlFreeHeap (ProcessHeap
,
2074 ErrorCode
= RtlNtStatusToDosError (Status
);
2075 SetLastError (ErrorCode
);
2079 DPRINT("SubKeys %d\n", FullInfo
->SubKeys
);
2080 if (lpcSubKeys
!= NULL
)
2082 *lpcSubKeys
= FullInfo
->SubKeys
;
2085 DPRINT("MaxNameLen %lu\n", FullInfo
->MaxNameLen
);
2086 if (lpcbMaxSubKeyLen
!= NULL
)
2088 *lpcbMaxSubKeyLen
= FullInfo
->MaxNameLen
/ sizeof(WCHAR
) + 1;
2091 DPRINT("MaxClassLen %lu\n", FullInfo
->MaxClassLen
);
2092 if (lpcbMaxClassLen
!= NULL
)
2094 *lpcbMaxClassLen
= FullInfo
->MaxClassLen
/ sizeof(WCHAR
) + 1;
2097 DPRINT("Values %lu\n", FullInfo
->Values
);
2098 if (lpcValues
!= NULL
)
2100 *lpcValues
= FullInfo
->Values
;
2103 DPRINT("MaxValueNameLen %lu\n", FullInfo
->MaxValueNameLen
);
2104 if (lpcbMaxValueNameLen
!= NULL
)
2106 *lpcbMaxValueNameLen
= FullInfo
->MaxValueNameLen
/ sizeof(WCHAR
) + 1;
2109 DPRINT("MaxValueDataLen %lu\n", FullInfo
->MaxValueDataLen
);
2110 if (lpcbMaxValueLen
!= NULL
)
2112 *lpcbMaxValueLen
= FullInfo
->MaxValueDataLen
;
2115 if (lpcbSecurityDescriptor
!= NULL
)
2117 Status
= NtQuerySecurityObject(KeyHandle
,
2118 OWNER_SECURITY_INFORMATION
|
2119 GROUP_SECURITY_INFORMATION
|
2120 DACL_SECURITY_INFORMATION
,
2123 lpcbSecurityDescriptor
);
2124 if (!NT_SUCCESS(Status
))
2126 if (lpClass
!= NULL
)
2128 RtlFreeHeap(ProcessHeap
,
2133 ErrorCode
= RtlNtStatusToDosError(Status
);
2134 SetLastError(ErrorCode
);
2139 if (lpftLastWriteTime
!= NULL
)
2141 lpftLastWriteTime
->dwLowDateTime
= FullInfo
->LastWriteTime
.u
.LowPart
;
2142 lpftLastWriteTime
->dwHighDateTime
= FullInfo
->LastWriteTime
.u
.HighPart
;
2145 if (lpClass
!= NULL
)
2147 if (FullInfo
->ClassLength
> ClassLength
)
2149 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
2153 RtlCopyMemory (lpClass
,
2155 FullInfo
->ClassLength
);
2156 *lpcbClass
= FullInfo
->ClassLength
/ sizeof(WCHAR
);
2157 lpClass
[*lpcbClass
] = 0;
2160 RtlFreeHeap (ProcessHeap
,
2165 if (ErrorCode
!= ERROR_SUCCESS
)
2167 SetLastError (ErrorCode
);
2174 /************************************************************************
2175 * RegQueryMultipleValuesA
2180 RegQueryMultipleValuesA (HKEY hKey
,
2187 DWORD maxBytes
= *ldwTotsize
;
2188 LPSTR bufptr
= (LPSTR
)lpValueBuf
;
2191 if (maxBytes
>= (1024*1024))
2192 return ERROR_TRANSFER_TOO_LONG
;
2196 DPRINT ("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n",
2197 hKey
, val_list
, num_vals
, lpValueBuf
, ldwTotsize
, *ldwTotsize
);
2199 for (i
= 0; i
< num_vals
; i
++)
2201 val_list
[i
].ve_valuelen
= 0;
2202 ErrorCode
= RegQueryValueExA (hKey
,
2203 val_list
[i
].ve_valuename
,
2207 &val_list
[i
].ve_valuelen
);
2208 if (ErrorCode
!= ERROR_SUCCESS
)
2213 if (lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
2215 ErrorCode
= RegQueryValueExA (hKey
,
2216 val_list
[i
].ve_valuename
,
2218 &val_list
[i
].ve_type
,
2220 &val_list
[i
].ve_valuelen
);
2221 if (ErrorCode
!= ERROR_SUCCESS
)
2226 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
2228 bufptr
+= val_list
[i
].ve_valuelen
;
2231 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
2234 return (lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
) ? ERROR_SUCCESS
: ERROR_MORE_DATA
;
2238 /************************************************************************
2239 * RegQueryMultipleValuesW
2244 RegQueryMultipleValuesW (HKEY hKey
,
2251 DWORD maxBytes
= *ldwTotsize
;
2252 LPSTR bufptr
= (LPSTR
)lpValueBuf
;
2255 if (maxBytes
>= (1024*1024))
2256 return ERROR_TRANSFER_TOO_LONG
;
2260 DPRINT ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
2261 hKey
, val_list
, num_vals
, lpValueBuf
, ldwTotsize
, *ldwTotsize
);
2263 for (i
= 0; i
< num_vals
; i
++)
2265 val_list
[i
].ve_valuelen
= 0;
2266 ErrorCode
= RegQueryValueExW (hKey
,
2267 val_list
[i
].ve_valuename
,
2271 &val_list
[i
].ve_valuelen
);
2272 if (ErrorCode
!= ERROR_SUCCESS
)
2277 if (lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
2279 ErrorCode
= RegQueryValueExW (hKey
,
2280 val_list
[i
].ve_valuename
,
2282 &val_list
[i
].ve_type
,
2284 &val_list
[i
].ve_valuelen
);
2285 if (ErrorCode
!= ERROR_SUCCESS
)
2290 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
2292 bufptr
+= val_list
[i
].ve_valuelen
;
2295 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
2298 return (lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
) ? ERROR_SUCCESS
: ERROR_MORE_DATA
;
2302 /************************************************************************
2308 RegQueryValueExW (HKEY hKey
,
2309 LPCWSTR lpValueName
,
2315 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
2316 UNICODE_STRING ValueName
;
2318 LONG ErrorCode
= ERROR_SUCCESS
;
2322 ULONG MaxCopy
= lpcbData
!= NULL
&& lpData
!= NULL
? *lpcbData
: 0;
2324 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
2325 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
2327 Status
= MapDefaultKey (&KeyHandle
,
2329 if (!NT_SUCCESS(Status
))
2331 ErrorCode
= RtlNtStatusToDosError (Status
);
2332 SetLastError (ErrorCode
);
2336 if (lpData
!= NULL
&& lpcbData
== NULL
)
2338 SetLastError (ERROR_INVALID_PARAMETER
);
2339 return ERROR_INVALID_PARAMETER
;
2342 RtlInitUnicodeString (&ValueName
,
2344 BufferSize
= FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]) + MaxCopy
;
2345 ValueInfo
= RtlAllocateHeap (ProcessHeap
,
2348 if (ValueInfo
== NULL
)
2350 SetLastError(ERROR_OUTOFMEMORY
);
2351 return ERROR_OUTOFMEMORY
;
2354 Status
= NtQueryValueKey (hKey
,
2356 KeyValuePartialInformation
,
2360 DPRINT("Status 0x%X\n", Status
);
2361 if (Status
== STATUS_BUFFER_OVERFLOW
)
2363 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
2365 ErrorCode
= lpData
? ERROR_MORE_DATA
: ERROR_SUCCESS
;
2367 else if (!NT_SUCCESS(Status
))
2369 ErrorCode
= RtlNtStatusToDosError (Status
);
2370 SetLastError (ErrorCode
);
2372 if (lpcbData
!= NULL
)
2374 ResultSize
= FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]) + *lpcbData
;
2380 *lpType
= ValueInfo
->Type
;
2383 if (NT_SUCCESS(Status
) && lpData
!= NULL
)
2385 RtlMoveMemory (lpData
,
2387 min(ValueInfo
->DataLength
, MaxCopy
));
2390 if ((ValueInfo
->Type
== REG_SZ
) ||
2391 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
2392 (ValueInfo
->Type
== REG_EXPAND_SZ
))
2394 if (lpData
!= NULL
&& MaxCopy
> ValueInfo
->DataLength
)
2396 ((PWSTR
)lpData
)[ValueInfo
->DataLength
/ sizeof(WCHAR
)] = 0;
2399 if (lpcbData
!= NULL
)
2401 *lpcbData
= (ResultSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]));
2402 DPRINT("(string) Returning Size: %lu\n", *lpcbData
);
2407 if (lpcbData
!= NULL
)
2409 *lpcbData
= ResultSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]);
2410 DPRINT("(other) Returning Size: %lu\n", *lpcbData
);
2414 DPRINT("Type %d Size %d\n", ValueInfo
->Type
, ValueInfo
->DataLength
);
2416 RtlFreeHeap (ProcessHeap
,
2424 /************************************************************************
2430 RegQueryValueExA (HKEY hKey
,
2437 UNICODE_STRING ValueName
;
2438 UNICODE_STRING ValueData
;
2439 ANSI_STRING AnsiString
;
2444 DPRINT("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
2445 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
2447 if (lpData
!= NULL
&& lpcbData
== NULL
)
2449 SetLastError(ERROR_INVALID_PARAMETER
);
2450 return ERROR_INVALID_PARAMETER
;
2455 ValueData
.Length
= 0;
2456 ValueData
.MaximumLength
= (*lpcbData
+ 1) * sizeof(WCHAR
);
2457 ValueData
.Buffer
= RtlAllocateHeap (ProcessHeap
,
2459 ValueData
.MaximumLength
);
2460 if (!ValueData
.Buffer
)
2462 SetLastError(ERROR_OUTOFMEMORY
);
2463 return ERROR_OUTOFMEMORY
;
2468 ValueData
.Buffer
= NULL
;
2469 ValueData
.Length
= 0;
2470 ValueData
.MaximumLength
= 0;
2473 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
2474 (LPSTR
)lpValueName
);
2476 Length
= (lpcbData
== NULL
) ? 0 : *lpcbData
* sizeof(WCHAR
);
2477 ErrorCode
= RegQueryValueExW (hKey
,
2481 (lpData
== NULL
) ? NULL
: (LPBYTE
)ValueData
.Buffer
,
2483 DPRINT("ErrorCode %lu\n", ErrorCode
);
2484 RtlFreeUnicodeString(&ValueName
);
2486 if (ErrorCode
== ERROR_SUCCESS
||
2487 ErrorCode
== ERROR_MORE_DATA
)
2494 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
))
2496 if (ErrorCode
== ERROR_SUCCESS
&& ValueData
.Buffer
!= NULL
)
2498 RtlInitAnsiString(&AnsiString
, NULL
);
2499 AnsiString
.Buffer
= (LPSTR
)lpData
;
2500 AnsiString
.MaximumLength
= *lpcbData
;
2501 ValueData
.Length
= Length
;
2502 ValueData
.MaximumLength
= ValueData
.Length
+ sizeof(WCHAR
);
2503 RtlUnicodeStringToAnsiString(&AnsiString
, &ValueData
, FALSE
);
2505 Length
= Length
/ sizeof(WCHAR
);
2507 else if (ErrorCode
== ERROR_SUCCESS
&& ValueData
.Buffer
!= NULL
)
2509 if (*lpcbData
< Length
)
2511 ErrorCode
= ERROR_MORE_DATA
;
2515 RtlMoveMemory(lpData
, ValueData
.Buffer
, Length
);
2519 if (lpcbData
!= NULL
)
2525 if (ValueData
.Buffer
!= NULL
)
2527 RtlFreeHeap(ProcessHeap
, 0, ValueData
.Buffer
);
2534 /************************************************************************
2540 RegQueryValueA (HKEY hKey
,
2545 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2546 UNICODE_STRING SubKeyName
;
2547 UNICODE_STRING Value
;
2548 ANSI_STRING AnsiString
;
2552 DPRINT("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
2553 hKey
, lpSubKey
, lpValue
, lpcbValue
? *lpcbValue
: 0);
2555 if (lpValue
!= NULL
&&
2558 SetLastError(ERROR_INVALID_PARAMETER
);
2559 return ERROR_INVALID_PARAMETER
;
2562 RtlInitUnicodeString (&SubKeyName
,
2564 RtlInitUnicodeString (&Value
,
2566 if (lpSubKey
!= NULL
&&
2567 strlen(lpSubKey
) != 0)
2569 RtlInitAnsiString (&AnsiString
,
2571 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2572 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2573 RtlAnsiStringToUnicodeString (&SubKeyName
,
2578 if (lpValue
!= NULL
)
2580 ValueSize
= *lpcbValue
* sizeof(WCHAR
);
2581 Value
.MaximumLength
= ValueSize
;
2582 Value
.Buffer
= RtlAllocateHeap (ProcessHeap
,
2585 if (Value
.Buffer
== NULL
)
2587 SetLastError(ERROR_OUTOFMEMORY
);
2588 return ERROR_OUTOFMEMORY
;
2596 ErrorCode
= RegQueryValueW (hKey
,
2597 (LPCWSTR
)SubKeyName
.Buffer
,
2600 if (ErrorCode
== ERROR_SUCCESS
)
2602 Value
.Length
= ValueSize
;
2603 RtlInitAnsiString (&AnsiString
,
2605 AnsiString
.Buffer
= lpValue
;
2606 AnsiString
.MaximumLength
= *lpcbValue
;
2607 RtlUnicodeStringToAnsiString (&AnsiString
,
2612 *lpcbValue
= ValueSize
;
2613 if (Value
.Buffer
!= NULL
)
2615 RtlFreeHeap (ProcessHeap
,
2624 /************************************************************************
2630 RegQueryValueW (HKEY hKey
,
2635 OBJECT_ATTRIBUTES ObjectAttributes
;
2636 UNICODE_STRING SubKeyString
;
2643 DPRINT("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
2644 hKey
, lpSubKey
, lpValue
, lpcbValue
? *lpcbValue
: 0);
2646 Status
= MapDefaultKey (&KeyHandle
,
2648 if (!NT_SUCCESS(Status
))
2650 ErrorCode
= RtlNtStatusToDosError (Status
);
2651 SetLastError (ErrorCode
);
2655 if (lpSubKey
!= NULL
&&
2656 wcslen(lpSubKey
) != 0)
2658 RtlInitUnicodeString (&SubKeyString
,
2660 InitializeObjectAttributes (&ObjectAttributes
,
2662 OBJ_CASE_INSENSITIVE
,
2665 Status
= NtOpenKey (&RealKey
,
2668 if (!NT_SUCCESS(Status
))
2670 ErrorCode
= RtlNtStatusToDosError (Status
);
2671 SetLastError (ErrorCode
);
2674 CloseRealKey
= TRUE
;
2679 CloseRealKey
= FALSE
;
2682 ErrorCode
= RegQueryValueExW (RealKey
,
2687 (LPDWORD
)lpcbValue
);
2697 /************************************************************************
2703 RegReplaceKeyA (HKEY hKey
,
2708 UNICODE_STRING SubKey
;
2709 UNICODE_STRING NewFile
;
2710 UNICODE_STRING OldFile
;
2713 RtlCreateUnicodeStringFromAsciiz (&SubKey
,
2715 RtlCreateUnicodeStringFromAsciiz (&OldFile
,
2717 RtlCreateUnicodeStringFromAsciiz (&NewFile
,
2720 ErrorCode
= RegReplaceKeyW (hKey
,
2725 RtlFreeUnicodeString (&OldFile
);
2726 RtlFreeUnicodeString (&NewFile
);
2727 RtlFreeUnicodeString (&SubKey
);
2733 /************************************************************************
2739 RegReplaceKeyW (HKEY hKey
,
2744 OBJECT_ATTRIBUTES KeyObjectAttributes
;
2745 OBJECT_ATTRIBUTES NewObjectAttributes
;
2746 OBJECT_ATTRIBUTES OldObjectAttributes
;
2747 UNICODE_STRING SubKeyName
;
2748 UNICODE_STRING NewFileName
;
2749 UNICODE_STRING OldFileName
;
2750 BOOLEAN CloseRealKey
;
2751 HANDLE RealKeyHandle
;
2756 if (hKey
== HKEY_PERFORMANCE_DATA
)
2758 return ERROR_INVALID_HANDLE
;
2761 Status
= MapDefaultKey (&KeyHandle
,
2763 if (!NT_SUCCESS(Status
))
2765 ErrorCode
= RtlNtStatusToDosError (Status
);
2766 SetLastError (ErrorCode
);
2770 /* Open the real key */
2771 if (lpSubKey
!= NULL
&& *lpSubKey
!= (WCHAR
)0)
2773 RtlInitUnicodeString (&SubKeyName
,
2775 InitializeObjectAttributes (&KeyObjectAttributes
,
2777 OBJ_CASE_INSENSITIVE
,
2780 Status
= NtOpenKey (&RealKeyHandle
,
2782 &KeyObjectAttributes
);
2783 if (!NT_SUCCESS(Status
))
2785 ErrorCode
= RtlNtStatusToDosError (Status
);
2786 SetLastError (ErrorCode
);
2789 CloseRealKey
= TRUE
;
2793 RealKeyHandle
= KeyHandle
;
2794 CloseRealKey
= FALSE
;
2797 /* Convert new file name */
2798 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpNewFile
,
2805 NtClose (RealKeyHandle
);
2807 SetLastError (ERROR_INVALID_PARAMETER
);
2808 return ERROR_INVALID_PARAMETER
;
2811 InitializeObjectAttributes (&NewObjectAttributes
,
2813 OBJ_CASE_INSENSITIVE
,
2817 /* Convert old file name */
2818 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpOldFile
,
2823 RtlFreeUnicodeString (&NewFileName
);
2826 NtClose (RealKeyHandle
);
2828 SetLastError (ERROR_INVALID_PARAMETER
);
2829 return ERROR_INVALID_PARAMETER
;
2832 InitializeObjectAttributes (&OldObjectAttributes
,
2834 OBJ_CASE_INSENSITIVE
,
2838 Status
= NtReplaceKey (&NewObjectAttributes
,
2840 &OldObjectAttributes
);
2842 RtlFreeUnicodeString (&OldFileName
);
2843 RtlFreeUnicodeString (&NewFileName
);
2847 NtClose (RealKeyHandle
);
2850 if (!NT_SUCCESS(Status
))
2852 ErrorCode
= RtlNtStatusToDosError (Status
);
2853 SetLastError (ErrorCode
);
2857 return ERROR_SUCCESS
;
2861 /************************************************************************
2867 RegRestoreKeyA (HKEY hKey
,
2871 UNICODE_STRING FileName
;
2874 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2877 ErrorCode
= RegRestoreKeyW (hKey
,
2881 RtlFreeUnicodeString (&FileName
);
2887 /************************************************************************
2893 RegRestoreKeyW (HKEY hKey
,
2897 OBJECT_ATTRIBUTES ObjectAttributes
;
2898 IO_STATUS_BLOCK IoStatusBlock
;
2899 UNICODE_STRING FileName
;
2905 if (hKey
== HKEY_PERFORMANCE_DATA
)
2907 return ERROR_INVALID_HANDLE
;
2910 Status
= MapDefaultKey (&KeyHandle
,
2912 if (!NT_SUCCESS(Status
))
2914 ErrorCode
= RtlNtStatusToDosError (Status
);
2915 SetLastError (ErrorCode
);
2919 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
2924 SetLastError (ERROR_INVALID_PARAMETER
);
2925 return ERROR_INVALID_PARAMETER
;
2928 InitializeObjectAttributes (&ObjectAttributes
,
2930 OBJ_CASE_INSENSITIVE
,
2934 Status
= NtOpenFile (&FileHandle
,
2939 FILE_SYNCHRONOUS_IO_NONALERT
);
2940 RtlFreeUnicodeString (&FileName
);
2941 if (!NT_SUCCESS(Status
))
2943 ErrorCode
= RtlNtStatusToDosError (Status
);
2944 SetLastError (ErrorCode
);
2948 Status
= NtRestoreKey (KeyHandle
,
2951 NtClose (FileHandle
);
2952 if (!NT_SUCCESS(Status
))
2954 ErrorCode
= RtlNtStatusToDosError (Status
);
2955 SetLastError (ErrorCode
);
2959 return ERROR_SUCCESS
;
2963 /************************************************************************
2969 RegSaveKeyA (HKEY hKey
,
2971 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2973 UNICODE_STRING FileName
;
2976 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2978 ErrorCode
= RegSaveKeyW (hKey
,
2980 lpSecurityAttributes
);
2981 RtlFreeUnicodeString (&FileName
);
2987 /************************************************************************
2993 RegSaveKeyW (HKEY hKey
,
2995 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2997 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
2998 OBJECT_ATTRIBUTES ObjectAttributes
;
2999 UNICODE_STRING FileName
;
3000 IO_STATUS_BLOCK IoStatusBlock
;
3006 Status
= MapDefaultKey (&KeyHandle
,
3008 if (!NT_SUCCESS(Status
))
3010 ErrorCode
= RtlNtStatusToDosError (Status
);
3011 SetLastError (ErrorCode
);
3015 if (!RtlDosPathNameToNtPathName_U ((PWSTR
)lpFile
,
3020 SetLastError (ERROR_INVALID_PARAMETER
);
3021 return ERROR_INVALID_PARAMETER
;
3024 if (lpSecurityAttributes
!= NULL
)
3026 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
3029 InitializeObjectAttributes (&ObjectAttributes
,
3031 OBJ_CASE_INSENSITIVE
,
3033 SecurityDescriptor
);
3034 Status
= NtCreateFile (&FileHandle
,
3035 GENERIC_WRITE
| SYNCHRONIZE
,
3039 FILE_ATTRIBUTE_NORMAL
,
3042 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT
,
3045 RtlFreeUnicodeString (&FileName
);
3046 if (!NT_SUCCESS(Status
))
3048 ErrorCode
= RtlNtStatusToDosError (Status
);
3049 SetLastError (ErrorCode
);
3053 Status
= NtSaveKey (KeyHandle
,
3055 NtClose (FileHandle
);
3056 if (!NT_SUCCESS(Status
))
3058 ErrorCode
= RtlNtStatusToDosError (Status
);
3059 SetLastError (ErrorCode
);
3063 return ERROR_SUCCESS
;
3067 /************************************************************************
3073 RegSetKeySecurity (HKEY hKey
,
3074 SECURITY_INFORMATION SecurityInformation
,
3075 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
3081 if (hKey
== HKEY_PERFORMANCE_DATA
)
3083 SetLastError(ERROR_INVALID_HANDLE
);
3084 return ERROR_INVALID_HANDLE
;
3087 Status
= MapDefaultKey (&KeyHandle
,
3089 if (!NT_SUCCESS(Status
))
3091 ErrorCode
= RtlNtStatusToDosError (Status
);
3092 SetLastError (ErrorCode
);
3096 Status
= NtSetSecurityObject (KeyHandle
,
3097 SecurityInformation
,
3098 pSecurityDescriptor
);
3099 if (!NT_SUCCESS(Status
))
3101 ErrorCode
= RtlNtStatusToDosError (Status
);
3102 SetLastError (ErrorCode
);
3106 return ERROR_SUCCESS
;
3110 /************************************************************************
3116 RegSetValueExA (HKEY hKey
,
3123 UNICODE_STRING ValueName
;
3125 ANSI_STRING AnsiString
;
3126 UNICODE_STRING Data
;
3131 if (lpValueName
!= NULL
&&
3132 strlen(lpValueName
) != 0)
3134 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
3136 pValueName
= (LPWSTR
)ValueName
.Buffer
;
3143 if ((dwType
== REG_SZ
) ||
3144 (dwType
== REG_MULTI_SZ
) ||
3145 (dwType
== REG_EXPAND_SZ
))
3147 RtlInitAnsiString (&AnsiString
,
3149 AnsiString
.Buffer
= (PSTR
)lpData
;
3150 AnsiString
.Length
= cbData
;
3151 AnsiString
.MaximumLength
= cbData
;
3152 RtlAnsiStringToUnicodeString (&Data
,
3155 pData
= (LPBYTE
)Data
.Buffer
;
3156 DataSize
= cbData
* sizeof(WCHAR
);
3160 RtlInitUnicodeString (&Data
,
3162 pData
= (LPBYTE
)lpData
;
3166 ErrorCode
= RegSetValueExW (hKey
,
3172 if (pValueName
!= NULL
)
3174 RtlFreeHeap (ProcessHeap
,
3179 if (Data
.Buffer
!= NULL
)
3181 RtlFreeHeap (ProcessHeap
,
3190 /************************************************************************
3196 RegSetValueExW (HKEY hKey
,
3197 LPCWSTR lpValueName
,
3203 UNICODE_STRING ValueName
;
3204 PUNICODE_STRING pValueName
;
3209 Status
= MapDefaultKey (&KeyHandle
,
3211 if (!NT_SUCCESS(Status
))
3213 ErrorCode
= RtlNtStatusToDosError (Status
);
3214 SetLastError (ErrorCode
);
3218 if (lpValueName
!= NULL
)
3220 RtlInitUnicodeString (&ValueName
,
3225 RtlInitUnicodeString (&ValueName
, L
"");
3227 pValueName
= &ValueName
;
3229 Status
= NtSetValueKey (KeyHandle
,
3235 if (!NT_SUCCESS(Status
))
3237 ErrorCode
= RtlNtStatusToDosError (Status
);
3238 SetLastError (ErrorCode
);
3242 return ERROR_SUCCESS
;
3246 /************************************************************************
3252 RegSetValueA (HKEY hKey
,
3258 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
3259 UNICODE_STRING SubKeyName
;
3260 UNICODE_STRING Data
;
3261 ANSI_STRING AnsiString
;
3267 SetLastError (ERROR_INVALID_PARAMETER
);
3268 return ERROR_INVALID_PARAMETER
;
3271 RtlInitUnicodeString (&SubKeyName
, NULL
);
3272 RtlInitUnicodeString (&Data
, NULL
);
3273 if (lpSubKey
!= NULL
&& (strlen(lpSubKey
) != 0))
3275 RtlInitAnsiString (&AnsiString
, (LPSTR
)lpSubKey
);
3276 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
3277 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
3278 RtlAnsiStringToUnicodeString (&SubKeyName
, &AnsiString
, FALSE
);
3281 DataSize
= cbData
* sizeof(WCHAR
);
3282 Data
.MaximumLength
= DataSize
;
3283 Data
.Buffer
= RtlAllocateHeap (ProcessHeap
,
3286 if (Data
.Buffer
== NULL
)
3288 SetLastError (ERROR_OUTOFMEMORY
);
3289 return ERROR_OUTOFMEMORY
;
3292 ErrorCode
= RegSetValueW (hKey
,
3293 (LPCWSTR
)SubKeyName
.Buffer
,
3298 RtlFreeHeap (ProcessHeap
,
3306 /************************************************************************
3312 RegSetValueW (HKEY hKey
,
3318 OBJECT_ATTRIBUTES ObjectAttributes
;
3319 UNICODE_STRING SubKeyString
;
3326 Status
= MapDefaultKey (&KeyHandle
,
3328 if (!NT_SUCCESS(Status
))
3330 ErrorCode
= RtlNtStatusToDosError (Status
);
3331 SetLastError (ErrorCode
);
3335 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
3337 RtlInitUnicodeString (&SubKeyString
,
3339 InitializeObjectAttributes (&ObjectAttributes
,
3341 OBJ_CASE_INSENSITIVE
,
3344 Status
= NtOpenKey (&RealKey
,
3347 if (!NT_SUCCESS(Status
))
3349 ErrorCode
= RtlNtStatusToDosError (Status
);
3350 SetLastError (ErrorCode
);
3353 CloseRealKey
= TRUE
;
3358 CloseRealKey
= FALSE
;
3361 ErrorCode
= RegSetValueExW (RealKey
,
3367 if (CloseRealKey
== TRUE
)
3376 /************************************************************************
3382 RegUnLoadKeyA (HKEY hKey
,
3385 UNICODE_STRING KeyName
;
3388 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
3391 ErrorCode
= RegUnLoadKeyW (hKey
,
3394 RtlFreeUnicodeString (&KeyName
);
3400 /************************************************************************
3406 RegUnLoadKeyW (HKEY hKey
,
3409 OBJECT_ATTRIBUTES ObjectAttributes
;
3410 UNICODE_STRING KeyName
;
3415 if (hKey
== HKEY_PERFORMANCE_DATA
)
3417 SetLastError(ERROR_INVALID_HANDLE
);
3418 return ERROR_INVALID_HANDLE
;
3421 Status
= MapDefaultKey (&KeyHandle
, hKey
);
3422 if (!NT_SUCCESS(Status
))
3424 ErrorCode
= RtlNtStatusToDosError (Status
);
3425 SetLastError (ErrorCode
);
3429 RtlInitUnicodeString (&KeyName
,
3432 InitializeObjectAttributes (&ObjectAttributes
,
3434 OBJ_CASE_INSENSITIVE
,
3438 Status
= NtUnloadKey (&ObjectAttributes
);
3440 if (!NT_SUCCESS(Status
))
3442 ErrorCode
= RtlNtStatusToDosError (Status
);
3443 SetLastError (ErrorCode
);
3447 return ERROR_SUCCESS
;