1 /* $Id: reg.c,v 1.61 2004/10/10 10:43:23 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/reg/reg.c
6 * PURPOSE: Registry functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
13 /* INCLUDES *****************************************************************/
19 /* DEFINES ******************************************************************/
21 #define MAX_DEFAULT_HANDLES 6
22 #define REG_MAX_NAME_SIZE 256
23 #define REG_MAX_DATA_SIZE 2048
25 /* GLOBALS ******************************************************************/
27 static CRITICAL_SECTION HandleTableCS
;
28 static HANDLE DefaultHandleTable
[MAX_DEFAULT_HANDLES
];
29 static HANDLE ProcessHeap
;
31 /* PROTOTYPES ***************************************************************/
33 static NTSTATUS
MapDefaultKey (PHANDLE ParentKey
, HKEY Key
);
34 static VOID
CloseDefaultKeys(VOID
);
36 static NTSTATUS
OpenClassesRootKey(PHANDLE KeyHandle
);
37 static NTSTATUS
OpenLocalMachineKey (PHANDLE KeyHandle
);
38 static NTSTATUS
OpenUsersKey (PHANDLE KeyHandle
);
39 static NTSTATUS
OpenCurrentConfigKey(PHANDLE KeyHandle
);
42 /* FUNCTIONS ****************************************************************/
44 /************************************************************************
45 * RegInitDefaultHandles
50 DPRINT("RegInitialize()\n");
52 ProcessHeap
= RtlGetProcessHeap();
53 RtlZeroMemory (DefaultHandleTable
,
54 MAX_DEFAULT_HANDLES
* sizeof(HANDLE
));
55 RtlInitializeCriticalSection (&HandleTableCS
);
61 /************************************************************************
67 DPRINT("RegCleanup()\n");
70 RtlDeleteCriticalSection (&HandleTableCS
);
77 MapDefaultKey (PHANDLE RealKey
,
82 NTSTATUS Status
= STATUS_SUCCESS
;
84 DPRINT("MapDefaultKey (Key %x)\n", Key
);
86 if (((ULONG
)Key
& 0xF0000000) != 0x80000000)
88 *RealKey
= (HANDLE
)Key
;
89 return STATUS_SUCCESS
;
92 /* Handle special cases here */
93 Index
= (ULONG
)Key
& 0x0FFFFFFF;
94 if (Index
>= MAX_DEFAULT_HANDLES
)
96 return STATUS_INVALID_PARAMETER
;
99 RtlEnterCriticalSection (&HandleTableCS
);
100 Handle
= &DefaultHandleTable
[Index
];
103 /* create/open the default handle */
106 case 0: /* HKEY_CLASSES_ROOT */
107 Status
= OpenClassesRootKey (Handle
);
110 case 1: /* HKEY_CURRENT_USER */
111 Status
= RtlOpenCurrentUser (MAXIMUM_ALLOWED
,
115 case 2: /* HKEY_LOCAL_MACHINE */
116 Status
= OpenLocalMachineKey (Handle
);
119 case 3: /* HKEY_USERS */
120 Status
= OpenUsersKey (Handle
);
123 case 4: /* HKEY_PERFORMANCE_DATA */
124 Status
= OpenPerformanceDataKey (Handle
);
127 case 5: /* HKEY_CURRENT_CONFIG */
128 Status
= OpenCurrentConfigKey (Handle
);
131 case 6: /* HKEY_DYN_DATA */
132 Status
= STATUS_NOT_IMPLEMENTED
;
136 DPRINT("MapDefaultHandle() no handle creator\n");
137 Status
= STATUS_INVALID_PARAMETER
;
140 RtlLeaveCriticalSection (&HandleTableCS
);
142 if (NT_SUCCESS(Status
))
152 CloseDefaultKeys (VOID
)
156 RtlEnterCriticalSection (&HandleTableCS
);
157 for (i
= 0; i
< MAX_DEFAULT_HANDLES
; i
++)
159 if (DefaultHandleTable
[i
] != NULL
)
161 NtClose (DefaultHandleTable
[i
]);
162 DefaultHandleTable
[i
] = NULL
;
165 RtlLeaveCriticalSection (&HandleTableCS
);
170 OpenClassesRootKey (PHANDLE KeyHandle
)
172 OBJECT_ATTRIBUTES Attributes
;
173 UNICODE_STRING KeyName
= ROS_STRING_INITIALIZER(L
"\\Registry\\Machine\\Software\\CLASSES");
175 DPRINT("OpenClassesRootKey()\n");
177 InitializeObjectAttributes (&Attributes
,
179 OBJ_CASE_INSENSITIVE
,
182 return NtOpenKey (KeyHandle
,
189 OpenLocalMachineKey (PHANDLE KeyHandle
)
191 OBJECT_ATTRIBUTES Attributes
;
192 UNICODE_STRING KeyName
= ROS_STRING_INITIALIZER(L
"\\Registry\\Machine");
195 DPRINT("OpenLocalMachineKey()\n");
197 InitializeObjectAttributes (&Attributes
,
199 OBJ_CASE_INSENSITIVE
,
202 Status
= NtOpenKey (KeyHandle
,
206 DPRINT("NtOpenKey(%wZ) => %08x\n", &KeyName
, Status
);
212 OpenUsersKey (PHANDLE KeyHandle
)
214 OBJECT_ATTRIBUTES Attributes
;
215 UNICODE_STRING KeyName
= ROS_STRING_INITIALIZER(L
"\\Registry\\User");
217 DPRINT("OpenUsersKey()\n");
219 InitializeObjectAttributes (&Attributes
,
221 OBJ_CASE_INSENSITIVE
,
224 return NtOpenKey (KeyHandle
,
231 OpenCurrentConfigKey (PHANDLE KeyHandle
)
233 OBJECT_ATTRIBUTES Attributes
;
234 UNICODE_STRING KeyName
=
235 ROS_STRING_INITIALIZER(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
237 DPRINT("OpenCurrentConfigKey()\n");
239 InitializeObjectAttributes (&Attributes
,
241 OBJ_CASE_INSENSITIVE
,
244 return NtOpenKey (KeyHandle
,
250 /************************************************************************
256 RegCloseKey (HKEY hKey
)
261 /* don't close null handle or a pseudo handle */
262 if ((!hKey
) || (((ULONG
)hKey
& 0xF0000000) == 0x80000000))
264 return ERROR_INVALID_HANDLE
;
267 Status
= NtClose (hKey
);
268 if (!NT_SUCCESS(Status
))
270 ErrorCode
= RtlNtStatusToDosError (Status
);
271 SetLastError (ErrorCode
);
275 return ERROR_SUCCESS
;
279 /************************************************************************
280 * RegConnectRegistryA
285 RegConnectRegistryA (LPCSTR lpMachineName
,
289 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
290 return ERROR_CALL_NOT_IMPLEMENTED
;
294 /************************************************************************
295 * RegConnectRegistryW
300 RegConnectRegistryW (LPCWSTR lpMachineName
,
304 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
305 return ERROR_CALL_NOT_IMPLEMENTED
;
309 /************************************************************************
312 * Create key and all necessary intermediate keys
315 CreateNestedKey(PHKEY KeyHandle
,
316 POBJECT_ATTRIBUTES ObjectAttributes
,
317 PUNICODE_STRING ClassString
,
320 DWORD
*lpdwDisposition
)
322 OBJECT_ATTRIBUTES LocalObjectAttributes
;
323 UNICODE_STRING LocalKeyName
;
326 ULONG FullNameLength
;
329 HANDLE LocalKeyHandle
;
331 Status
= NtCreateKey((PHANDLE
) KeyHandle
,
337 (PULONG
)lpdwDisposition
);
338 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes
->ObjectName
, Status
);
339 if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
342 /* Copy object attributes */
343 RtlCopyMemory (&LocalObjectAttributes
,
345 sizeof(OBJECT_ATTRIBUTES
));
346 RtlCreateUnicodeString (&LocalKeyName
,
347 ObjectAttributes
->ObjectName
->Buffer
);
348 LocalObjectAttributes
.ObjectName
= &LocalKeyName
;
349 FullNameLength
= LocalKeyName
.Length
/ sizeof(WCHAR
);
351 /* Remove the last part of the key name and try to create the key again. */
352 while (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
354 Ptr
= wcsrchr (LocalKeyName
.Buffer
, '\\');
355 if (Ptr
== NULL
|| Ptr
== LocalKeyName
.Buffer
)
357 Status
= STATUS_UNSUCCESSFUL
;
361 LocalKeyName
.Length
= wcslen (LocalKeyName
.Buffer
) * sizeof(WCHAR
);
363 Status
= NtCreateKey (&LocalKeyHandle
,
365 &LocalObjectAttributes
,
370 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName
, Status
);
373 if (!NT_SUCCESS(Status
))
375 RtlFreeUnicodeString (&LocalKeyName
);
379 /* Add removed parts of the key name and create them too. */
380 Length
= wcslen (LocalKeyName
.Buffer
);
383 NtClose (LocalKeyHandle
);
385 LocalKeyName
.Buffer
[Length
] = L
'\\';
386 Length
= wcslen (LocalKeyName
.Buffer
);
387 LocalKeyName
.Length
= Length
* sizeof(WCHAR
);
389 if (Length
== FullNameLength
)
391 Status
= NtCreateKey((PHANDLE
) KeyHandle
,
397 (PULONG
)lpdwDisposition
);
400 Status
= NtCreateKey (&LocalKeyHandle
,
402 &LocalObjectAttributes
,
407 DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName
, Status
);
408 if (!NT_SUCCESS(Status
))
412 RtlFreeUnicodeString (&LocalKeyName
);
418 /************************************************************************
424 RegCreateKeyExA (HKEY hKey
,
430 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
432 LPDWORD lpdwDisposition
)
434 UNICODE_STRING SubKeyString
;
435 UNICODE_STRING ClassString
;
436 OBJECT_ATTRIBUTES Attributes
;
441 DPRINT("RegCreateKeyExA() called\n");
443 /* get the real parent key */
444 Status
= MapDefaultKey (&ParentKey
,
446 if (!NT_SUCCESS(Status
))
448 ErrorCode
= RtlNtStatusToDosError (Status
);
449 SetLastError (ErrorCode
);
452 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
456 RtlCreateUnicodeStringFromAsciiz (&ClassString
,
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 Status
= MapDefaultKey (&KeyHandle
,
1735 if (!NT_SUCCESS(Status
))
1737 ErrorCode
= RtlNtStatusToDosError (Status
);
1738 SetLastError (ErrorCode
);
1742 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1744 InitializeObjectAttributes (&ObjectAttributes
,
1746 OBJ_CASE_INSENSITIVE
,
1749 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1752 RtlFreeUnicodeString (&SubKeyString
);
1753 if (!NT_SUCCESS(Status
))
1755 ErrorCode
= RtlNtStatusToDosError (Status
);
1756 SetLastError (ErrorCode
);
1760 return ERROR_SUCCESS
;
1764 /************************************************************************
1773 RegOpenKeyW (HKEY hKey
,
1777 OBJECT_ATTRIBUTES ObjectAttributes
;
1778 UNICODE_STRING SubKeyString
;
1783 Status
= MapDefaultKey (&KeyHandle
,
1785 if (!NT_SUCCESS(Status
))
1787 ErrorCode
= RtlNtStatusToDosError (Status
);
1788 SetLastError (ErrorCode
);
1792 RtlInitUnicodeString (&SubKeyString
,
1794 InitializeObjectAttributes (&ObjectAttributes
,
1796 OBJ_CASE_INSENSITIVE
,
1799 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1802 if (!NT_SUCCESS(Status
))
1804 ErrorCode
= RtlNtStatusToDosError (Status
);
1805 SetLastError(ErrorCode
);
1809 return ERROR_SUCCESS
;
1813 /************************************************************************
1819 RegOpenKeyExA (HKEY hKey
,
1825 OBJECT_ATTRIBUTES ObjectAttributes
;
1826 UNICODE_STRING SubKeyString
;
1831 Status
= MapDefaultKey (&KeyHandle
,
1833 if (!NT_SUCCESS(Status
))
1835 ErrorCode
= RtlNtStatusToDosError (Status
);
1836 SetLastError (ErrorCode
);
1840 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1842 InitializeObjectAttributes (&ObjectAttributes
,
1844 OBJ_CASE_INSENSITIVE
,
1847 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1850 RtlFreeUnicodeString (&SubKeyString
);
1851 if (!NT_SUCCESS(Status
))
1853 ErrorCode
= RtlNtStatusToDosError (Status
);
1854 SetLastError (ErrorCode
);
1858 return ERROR_SUCCESS
;
1862 /************************************************************************
1868 RegOpenKeyExW (HKEY hKey
,
1874 OBJECT_ATTRIBUTES ObjectAttributes
;
1875 UNICODE_STRING SubKeyString
;
1880 Status
= MapDefaultKey (&KeyHandle
,
1882 if (!NT_SUCCESS(Status
))
1884 ErrorCode
= RtlNtStatusToDosError (Status
);
1885 SetLastError (ErrorCode
);
1889 if (lpSubKey
!= NULL
)
1891 RtlInitUnicodeString (&SubKeyString
,
1896 RtlInitUnicodeString (&SubKeyString
,
1899 InitializeObjectAttributes (&ObjectAttributes
,
1901 OBJ_CASE_INSENSITIVE
,
1904 Status
= NtOpenKey ((PHANDLE
)phkResult
,
1907 if (!NT_SUCCESS(Status
))
1909 ErrorCode
= RtlNtStatusToDosError (Status
);
1910 SetLastError (ErrorCode
);
1914 return ERROR_SUCCESS
;
1918 /************************************************************************
1924 RegQueryInfoKeyA (HKEY hKey
,
1929 LPDWORD lpcbMaxSubKeyLen
,
1930 LPDWORD lpcbMaxClassLen
,
1932 LPDWORD lpcbMaxValueNameLen
,
1933 LPDWORD lpcbMaxValueLen
,
1934 LPDWORD lpcbSecurityDescriptor
,
1935 PFILETIME lpftLastWriteTime
)
1937 WCHAR ClassName
[MAX_PATH
];
1938 UNICODE_STRING UnicodeString
;
1939 ANSI_STRING AnsiString
;
1942 RtlInitUnicodeString (&UnicodeString
,
1944 if (lpClass
!= NULL
)
1946 UnicodeString
.Buffer
= &ClassName
[0];
1947 UnicodeString
.MaximumLength
= sizeof(ClassName
);
1948 AnsiString
.MaximumLength
= *lpcbClass
;
1951 ErrorCode
= RegQueryInfoKeyW (hKey
,
1952 UnicodeString
.Buffer
,
1959 lpcbMaxValueNameLen
,
1961 lpcbSecurityDescriptor
,
1963 if ((ErrorCode
== ERROR_SUCCESS
) && (lpClass
!= NULL
))
1965 AnsiString
.Buffer
= lpClass
;
1966 AnsiString
.Length
= 0;
1967 UnicodeString
.Length
= *lpcbClass
* sizeof(WCHAR
);
1968 RtlUnicodeStringToAnsiString (&AnsiString
,
1971 *lpcbClass
= AnsiString
.Length
;
1972 lpClass
[AnsiString
.Length
] = 0;
1979 /************************************************************************
1985 RegQueryInfoKeyW (HKEY hKey
,
1990 LPDWORD lpcbMaxSubKeyLen
,
1991 LPDWORD lpcbMaxClassLen
,
1993 LPDWORD lpcbMaxValueNameLen
,
1994 LPDWORD lpcbMaxValueLen
,
1995 LPDWORD lpcbSecurityDescriptor
,
1996 PFILETIME lpftLastWriteTime
)
1998 KEY_FULL_INFORMATION FullInfoBuffer
;
1999 PKEY_FULL_INFORMATION FullInfo
;
2001 ULONG ClassLength
= 0;
2004 LONG ErrorCode
= ERROR_SUCCESS
;
2007 if ((lpClass
) && (!lpcbClass
))
2009 SetLastError(ERROR_INVALID_PARAMETER
);
2010 return ERROR_INVALID_PARAMETER
;
2013 Status
= MapDefaultKey (&KeyHandle
,
2015 if (!NT_SUCCESS(Status
))
2017 ErrorCode
= RtlNtStatusToDosError (Status
);
2018 SetLastError (ErrorCode
);
2022 if (lpClass
!= NULL
)
2026 ClassLength
= min(*lpcbClass
- 1, REG_MAX_NAME_SIZE
) * sizeof(WCHAR
);
2033 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
) + ((ClassLength
+ 3) & ~3);
2034 FullInfo
= RtlAllocateHeap (ProcessHeap
,
2037 if (FullInfo
== NULL
)
2039 SetLastError (ERROR_OUTOFMEMORY
);
2040 return ERROR_OUTOFMEMORY
;
2043 FullInfo
->ClassLength
= ClassLength
;
2047 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
);
2048 FullInfo
= &FullInfoBuffer
;
2049 FullInfo
->ClassLength
= 0;
2051 FullInfo
->ClassOffset
= FIELD_OFFSET(KEY_FULL_INFORMATION
, Class
);
2053 Status
= NtQueryKey (KeyHandle
,
2058 DPRINT("NtQueryKey() returned status 0x%X\n", Status
);
2059 if (!NT_SUCCESS(Status
))
2061 if (lpClass
!= NULL
)
2063 RtlFreeHeap (ProcessHeap
,
2068 ErrorCode
= RtlNtStatusToDosError (Status
);
2069 SetLastError (ErrorCode
);
2073 DPRINT("SubKeys %d\n", FullInfo
->SubKeys
);
2074 if (lpcSubKeys
!= NULL
)
2076 *lpcSubKeys
= FullInfo
->SubKeys
;
2079 DPRINT("MaxNameLen %lu\n", FullInfo
->MaxNameLen
);
2080 if (lpcbMaxSubKeyLen
!= NULL
)
2082 *lpcbMaxSubKeyLen
= FullInfo
->MaxNameLen
/ sizeof(WCHAR
) + 1;
2085 DPRINT("MaxClassLen %lu\n", FullInfo
->MaxClassLen
);
2086 if (lpcbMaxClassLen
!= NULL
)
2088 *lpcbMaxClassLen
= FullInfo
->MaxClassLen
/ sizeof(WCHAR
) + 1;
2091 DPRINT("Values %lu\n", FullInfo
->Values
);
2092 if (lpcValues
!= NULL
)
2094 *lpcValues
= FullInfo
->Values
;
2097 DPRINT("MaxValueNameLen %lu\n", FullInfo
->MaxValueNameLen
);
2098 if (lpcbMaxValueNameLen
!= NULL
)
2100 *lpcbMaxValueNameLen
= FullInfo
->MaxValueNameLen
/ sizeof(WCHAR
) + 1;
2103 DPRINT("MaxValueDataLen %lu\n", FullInfo
->MaxValueDataLen
);
2104 if (lpcbMaxValueLen
!= NULL
)
2106 *lpcbMaxValueLen
= FullInfo
->MaxValueDataLen
;
2109 if (lpcbSecurityDescriptor
!= NULL
)
2111 Status
= NtQuerySecurityObject(KeyHandle
,
2112 OWNER_SECURITY_INFORMATION
|
2113 GROUP_SECURITY_INFORMATION
|
2114 DACL_SECURITY_INFORMATION
,
2117 lpcbSecurityDescriptor
);
2118 if (!NT_SUCCESS(Status
))
2120 if (lpClass
!= NULL
)
2122 RtlFreeHeap(ProcessHeap
,
2127 ErrorCode
= RtlNtStatusToDosError(Status
);
2128 SetLastError(ErrorCode
);
2133 if (lpftLastWriteTime
!= NULL
)
2135 lpftLastWriteTime
->dwLowDateTime
= FullInfo
->LastWriteTime
.u
.LowPart
;
2136 lpftLastWriteTime
->dwHighDateTime
= FullInfo
->LastWriteTime
.u
.HighPart
;
2139 if (lpClass
!= NULL
)
2141 if (FullInfo
->ClassLength
> ClassLength
)
2143 ErrorCode
= ERROR_BUFFER_OVERFLOW
;
2147 RtlCopyMemory (lpClass
,
2149 FullInfo
->ClassLength
);
2150 *lpcbClass
= FullInfo
->ClassLength
/ sizeof(WCHAR
);
2151 lpClass
[*lpcbClass
] = 0;
2154 RtlFreeHeap (ProcessHeap
,
2159 if (ErrorCode
!= ERROR_SUCCESS
)
2161 SetLastError (ErrorCode
);
2168 /************************************************************************
2169 * RegQueryMultipleValuesA
2174 RegQueryMultipleValuesA (HKEY hKey
,
2181 DWORD maxBytes
= *ldwTotsize
;
2182 LPSTR bufptr
= (LPSTR
)lpValueBuf
;
2185 if (maxBytes
>= (1024*1024))
2186 return ERROR_TRANSFER_TOO_LONG
;
2190 DPRINT ("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n",
2191 hKey
, val_list
, num_vals
, lpValueBuf
, ldwTotsize
, *ldwTotsize
);
2193 for (i
= 0; i
< num_vals
; i
++)
2195 val_list
[i
].ve_valuelen
= 0;
2196 ErrorCode
= RegQueryValueExA (hKey
,
2197 val_list
[i
].ve_valuename
,
2201 &val_list
[i
].ve_valuelen
);
2202 if (ErrorCode
!= ERROR_SUCCESS
)
2207 if (lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
2209 ErrorCode
= RegQueryValueExA (hKey
,
2210 val_list
[i
].ve_valuename
,
2212 &val_list
[i
].ve_type
,
2214 &val_list
[i
].ve_valuelen
);
2215 if (ErrorCode
!= ERROR_SUCCESS
)
2220 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
2222 bufptr
+= val_list
[i
].ve_valuelen
;
2225 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
2228 return (lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
) ? ERROR_SUCCESS
: ERROR_MORE_DATA
;
2232 /************************************************************************
2233 * RegQueryMultipleValuesW
2238 RegQueryMultipleValuesW (HKEY hKey
,
2245 DWORD maxBytes
= *ldwTotsize
;
2246 LPSTR bufptr
= (LPSTR
)lpValueBuf
;
2249 if (maxBytes
>= (1024*1024))
2250 return ERROR_TRANSFER_TOO_LONG
;
2254 DPRINT ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
2255 hKey
, val_list
, num_vals
, lpValueBuf
, ldwTotsize
, *ldwTotsize
);
2257 for (i
= 0; i
< num_vals
; i
++)
2259 val_list
[i
].ve_valuelen
= 0;
2260 ErrorCode
= RegQueryValueExW (hKey
,
2261 val_list
[i
].ve_valuename
,
2265 &val_list
[i
].ve_valuelen
);
2266 if (ErrorCode
!= ERROR_SUCCESS
)
2271 if (lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
2273 ErrorCode
= RegQueryValueExW (hKey
,
2274 val_list
[i
].ve_valuename
,
2276 &val_list
[i
].ve_type
,
2278 &val_list
[i
].ve_valuelen
);
2279 if (ErrorCode
!= ERROR_SUCCESS
)
2284 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
2286 bufptr
+= val_list
[i
].ve_valuelen
;
2289 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
2292 return (lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
) ? ERROR_SUCCESS
: ERROR_MORE_DATA
;
2296 /************************************************************************
2302 RegQueryValueExW (HKEY hKey
,
2303 LPCWSTR lpValueName
,
2309 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
2310 UNICODE_STRING ValueName
;
2312 LONG ErrorCode
= ERROR_SUCCESS
;
2316 ULONG MaxCopy
= lpcbData
!= NULL
&& lpData
!= NULL
? *lpcbData
: 0;
2318 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
2319 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
2321 Status
= MapDefaultKey (&KeyHandle
,
2323 if (!NT_SUCCESS(Status
))
2325 ErrorCode
= RtlNtStatusToDosError (Status
);
2326 SetLastError (ErrorCode
);
2330 if (lpData
!= NULL
&& lpcbData
== NULL
)
2332 SetLastError (ERROR_INVALID_PARAMETER
);
2333 return ERROR_INVALID_PARAMETER
;
2336 RtlInitUnicodeString (&ValueName
,
2338 BufferSize
= FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]) + MaxCopy
;
2339 ValueInfo
= RtlAllocateHeap (ProcessHeap
,
2342 if (ValueInfo
== NULL
)
2344 SetLastError(ERROR_OUTOFMEMORY
);
2345 return ERROR_OUTOFMEMORY
;
2348 Status
= NtQueryValueKey (hKey
,
2350 KeyValuePartialInformation
,
2354 DPRINT("Status 0x%X\n", Status
);
2355 if (Status
== STATUS_BUFFER_OVERFLOW
)
2357 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
2359 ErrorCode
= lpData
? ERROR_MORE_DATA
: ERROR_SUCCESS
;
2361 else if (!NT_SUCCESS(Status
))
2363 ErrorCode
= RtlNtStatusToDosError (Status
);
2364 SetLastError (ErrorCode
);
2366 if (lpcbData
!= NULL
)
2368 ResultSize
= FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]) + *lpcbData
;
2374 *lpType
= ValueInfo
->Type
;
2377 if (NT_SUCCESS(Status
) && lpData
!= NULL
)
2379 RtlMoveMemory (lpData
,
2381 min(ValueInfo
->DataLength
, MaxCopy
));
2384 if ((ValueInfo
->Type
== REG_SZ
) ||
2385 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
2386 (ValueInfo
->Type
== REG_EXPAND_SZ
))
2388 if (lpData
!= NULL
&& MaxCopy
> ValueInfo
->DataLength
)
2390 ((PWSTR
)lpData
)[ValueInfo
->DataLength
/ sizeof(WCHAR
)] = 0;
2393 if (lpcbData
!= NULL
)
2395 *lpcbData
= (ResultSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]));
2396 DPRINT("(string) Returning Size: %lu\n", *lpcbData
);
2401 if (lpcbData
!= NULL
)
2403 *lpcbData
= ResultSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[0]);
2404 DPRINT("(other) Returning Size: %lu\n", *lpcbData
);
2408 DPRINT("Type %d Size %d\n", ValueInfo
->Type
, ValueInfo
->DataLength
);
2410 RtlFreeHeap (ProcessHeap
,
2418 /************************************************************************
2424 RegQueryValueExA (HKEY hKey
,
2431 UNICODE_STRING ValueName
;
2432 UNICODE_STRING ValueData
;
2433 ANSI_STRING AnsiString
;
2438 if (lpData
!= NULL
&& lpcbData
== NULL
)
2440 SetLastError(ERROR_INVALID_PARAMETER
);
2441 return ERROR_INVALID_PARAMETER
;
2446 ValueData
.Length
= *lpcbData
* sizeof(WCHAR
);
2447 ValueData
.MaximumLength
= ValueData
.Length
+ sizeof(WCHAR
);
2448 ValueData
.Buffer
= RtlAllocateHeap (ProcessHeap
,
2450 ValueData
.MaximumLength
);
2451 if (!ValueData
.Buffer
)
2453 SetLastError(ERROR_OUTOFMEMORY
);
2454 return ERROR_OUTOFMEMORY
;
2459 ValueData
.Buffer
= NULL
;
2460 ValueData
.Length
= 0;
2461 ValueData
.MaximumLength
= 0;
2464 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
2465 (LPSTR
)lpValueName
);
2467 if (NULL
!= lpcbData
)
2469 Length
= *lpcbData
* sizeof(WCHAR
);
2471 ErrorCode
= RegQueryValueExW (hKey
,
2475 (LPBYTE
)ValueData
.Buffer
,
2476 NULL
== lpcbData
? NULL
: &Length
);
2477 DPRINT("ErrorCode %lu\n", ErrorCode
);
2479 if (ErrorCode
== ERROR_SUCCESS
||
2480 ErrorCode
== ERROR_MORE_DATA
)
2487 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
))
2489 if (ErrorCode
== ERROR_SUCCESS
&& ValueData
.Buffer
!= NULL
)
2491 RtlInitAnsiString(&AnsiString
, NULL
);
2492 AnsiString
.Buffer
= lpData
;
2493 AnsiString
.MaximumLength
= *lpcbData
;
2494 ValueData
.Length
= Length
;
2495 ValueData
.MaximumLength
= ValueData
.Length
+ sizeof(WCHAR
);
2496 RtlUnicodeStringToAnsiString(&AnsiString
, &ValueData
, FALSE
);
2498 Length
= Length
/ sizeof(WCHAR
);
2500 else if (lpcbData
!= NULL
)
2502 Length
= min(*lpcbData
, Length
);
2503 if (ErrorCode
== ERROR_SUCCESS
&& ValueData
.Buffer
!= NULL
)
2505 RtlMoveMemory(lpData
, ValueData
.Buffer
, Length
);
2509 if (lpcbData
!= NULL
)
2515 if (ValueData
.Buffer
!= NULL
)
2517 RtlFreeHeap(ProcessHeap
, 0, ValueData
.Buffer
);
2524 /************************************************************************
2530 RegQueryValueA (HKEY hKey
,
2535 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2536 UNICODE_STRING SubKeyName
;
2537 UNICODE_STRING Value
;
2538 ANSI_STRING AnsiString
;
2542 if (lpValue
!= NULL
&&
2545 SetLastError(ERROR_INVALID_PARAMETER
);
2546 return ERROR_INVALID_PARAMETER
;
2549 RtlInitUnicodeString (&SubKeyName
,
2551 RtlInitUnicodeString (&Value
,
2553 if (lpSubKey
!= NULL
&&
2554 strlen(lpSubKey
) != 0)
2556 RtlInitAnsiString (&AnsiString
,
2558 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2559 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2560 RtlAnsiStringToUnicodeString (&SubKeyName
,
2565 if (lpValue
!= NULL
)
2567 ValueSize
= *lpcbValue
* sizeof(WCHAR
);
2568 Value
.MaximumLength
= ValueSize
;
2569 Value
.Buffer
= RtlAllocateHeap (ProcessHeap
,
2572 if (Value
.Buffer
== NULL
)
2574 SetLastError(ERROR_OUTOFMEMORY
);
2575 return ERROR_OUTOFMEMORY
;
2583 ErrorCode
= RegQueryValueW (hKey
,
2584 (LPCWSTR
)SubKeyName
.Buffer
,
2587 if (ErrorCode
== ERROR_SUCCESS
)
2589 Value
.Length
= ValueSize
;
2590 RtlInitAnsiString (&AnsiString
,
2592 AnsiString
.Buffer
= lpValue
;
2593 AnsiString
.MaximumLength
= *lpcbValue
;
2594 RtlUnicodeStringToAnsiString (&AnsiString
,
2599 *lpcbValue
= ValueSize
;
2600 if (Value
.Buffer
!= NULL
)
2602 RtlFreeHeap (ProcessHeap
,
2611 /************************************************************************
2617 RegQueryValueW (HKEY hKey
,
2622 OBJECT_ATTRIBUTES ObjectAttributes
;
2623 UNICODE_STRING SubKeyString
;
2630 Status
= MapDefaultKey (&KeyHandle
,
2632 if (!NT_SUCCESS(Status
))
2634 ErrorCode
= RtlNtStatusToDosError (Status
);
2635 SetLastError (ErrorCode
);
2639 if (lpSubKey
!= NULL
&&
2640 wcslen(lpSubKey
) != 0)
2642 RtlInitUnicodeString (&SubKeyString
,
2644 InitializeObjectAttributes (&ObjectAttributes
,
2646 OBJ_CASE_INSENSITIVE
,
2649 Status
= NtOpenKey (&RealKey
,
2652 if (!NT_SUCCESS(Status
))
2654 ErrorCode
= RtlNtStatusToDosError (Status
);
2655 SetLastError (ErrorCode
);
2658 CloseRealKey
= TRUE
;
2663 CloseRealKey
= FALSE
;
2666 ErrorCode
= RegQueryValueExW (RealKey
,
2671 (LPDWORD
)lpcbValue
);
2681 /************************************************************************
2687 RegReplaceKeyA (HKEY hKey
,
2692 UNICODE_STRING SubKey
;
2693 UNICODE_STRING NewFile
;
2694 UNICODE_STRING OldFile
;
2697 RtlCreateUnicodeStringFromAsciiz (&SubKey
,
2699 RtlCreateUnicodeStringFromAsciiz (&OldFile
,
2701 RtlCreateUnicodeStringFromAsciiz (&NewFile
,
2704 ErrorCode
= RegReplaceKeyW (hKey
,
2709 RtlFreeUnicodeString (&OldFile
);
2710 RtlFreeUnicodeString (&NewFile
);
2711 RtlFreeUnicodeString (&SubKey
);
2717 /************************************************************************
2723 RegReplaceKeyW (HKEY hKey
,
2728 OBJECT_ATTRIBUTES KeyObjectAttributes
;
2729 OBJECT_ATTRIBUTES NewObjectAttributes
;
2730 OBJECT_ATTRIBUTES OldObjectAttributes
;
2731 UNICODE_STRING SubKeyName
;
2732 UNICODE_STRING NewFileName
;
2733 UNICODE_STRING OldFileName
;
2734 BOOLEAN CloseRealKey
;
2735 HANDLE RealKeyHandle
;
2740 if (hKey
== HKEY_PERFORMANCE_DATA
)
2742 return ERROR_INVALID_HANDLE
;
2745 Status
= MapDefaultKey (&KeyHandle
,
2747 if (!NT_SUCCESS(Status
))
2749 ErrorCode
= RtlNtStatusToDosError (Status
);
2750 SetLastError (ErrorCode
);
2754 /* Open the real key */
2755 if (lpSubKey
!= NULL
&& *lpSubKey
!= (WCHAR
)0)
2757 RtlInitUnicodeString (&SubKeyName
,
2759 InitializeObjectAttributes (&KeyObjectAttributes
,
2761 OBJ_CASE_INSENSITIVE
,
2764 Status
= NtOpenKey (&RealKeyHandle
,
2766 &KeyObjectAttributes
);
2767 if (!NT_SUCCESS(Status
))
2769 ErrorCode
= RtlNtStatusToDosError (Status
);
2770 SetLastError (ErrorCode
);
2773 CloseRealKey
= TRUE
;
2777 RealKeyHandle
= KeyHandle
;
2778 CloseRealKey
= FALSE
;
2781 /* Convert new file name */
2782 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpNewFile
,
2789 NtClose (RealKeyHandle
);
2791 SetLastError (ERROR_INVALID_PARAMETER
);
2792 return ERROR_INVALID_PARAMETER
;
2795 InitializeObjectAttributes (&NewObjectAttributes
,
2797 OBJ_CASE_INSENSITIVE
,
2801 /* Convert old file name */
2802 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpOldFile
,
2807 RtlFreeUnicodeString (&NewFileName
);
2810 NtClose (RealKeyHandle
);
2812 SetLastError (ERROR_INVALID_PARAMETER
);
2813 return ERROR_INVALID_PARAMETER
;
2816 InitializeObjectAttributes (&OldObjectAttributes
,
2818 OBJ_CASE_INSENSITIVE
,
2822 Status
= NtReplaceKey (&NewObjectAttributes
,
2824 &OldObjectAttributes
);
2826 RtlFreeUnicodeString (&OldFileName
);
2827 RtlFreeUnicodeString (&NewFileName
);
2831 NtClose (RealKeyHandle
);
2834 if (!NT_SUCCESS(Status
))
2836 ErrorCode
= RtlNtStatusToDosError (Status
);
2837 SetLastError (ErrorCode
);
2841 return ERROR_SUCCESS
;
2845 /************************************************************************
2851 RegRestoreKeyA (HKEY hKey
,
2855 UNICODE_STRING FileName
;
2858 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2861 ErrorCode
= RegRestoreKeyW (hKey
,
2865 RtlFreeUnicodeString (&FileName
);
2871 /************************************************************************
2877 RegRestoreKeyW (HKEY hKey
,
2881 OBJECT_ATTRIBUTES ObjectAttributes
;
2882 IO_STATUS_BLOCK IoStatusBlock
;
2883 UNICODE_STRING FileName
;
2889 if (hKey
== HKEY_PERFORMANCE_DATA
)
2891 return ERROR_INVALID_HANDLE
;
2894 Status
= MapDefaultKey (&KeyHandle
,
2896 if (!NT_SUCCESS(Status
))
2898 ErrorCode
= RtlNtStatusToDosError (Status
);
2899 SetLastError (ErrorCode
);
2903 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
2908 SetLastError (ERROR_INVALID_PARAMETER
);
2909 return ERROR_INVALID_PARAMETER
;
2912 InitializeObjectAttributes (&ObjectAttributes
,
2914 OBJ_CASE_INSENSITIVE
,
2918 Status
= NtOpenFile (&FileHandle
,
2923 FILE_SYNCHRONOUS_IO_NONALERT
);
2924 RtlFreeUnicodeString (&FileName
);
2925 if (!NT_SUCCESS(Status
))
2927 ErrorCode
= RtlNtStatusToDosError (Status
);
2928 SetLastError (ErrorCode
);
2932 Status
= NtRestoreKey (KeyHandle
,
2935 NtClose (FileHandle
);
2936 if (!NT_SUCCESS(Status
))
2938 ErrorCode
= RtlNtStatusToDosError (Status
);
2939 SetLastError (ErrorCode
);
2943 return ERROR_SUCCESS
;
2947 /************************************************************************
2953 RegSaveKeyA (HKEY hKey
,
2955 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2957 UNICODE_STRING FileName
;
2960 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2962 ErrorCode
= RegSaveKeyW (hKey
,
2964 lpSecurityAttributes
);
2965 RtlFreeUnicodeString (&FileName
);
2971 /************************************************************************
2977 RegSaveKeyW (HKEY hKey
,
2979 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2981 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
2982 OBJECT_ATTRIBUTES ObjectAttributes
;
2983 UNICODE_STRING FileName
;
2984 IO_STATUS_BLOCK IoStatusBlock
;
2990 Status
= MapDefaultKey (&KeyHandle
,
2992 if (!NT_SUCCESS(Status
))
2994 ErrorCode
= RtlNtStatusToDosError (Status
);
2995 SetLastError (ErrorCode
);
2999 if (!RtlDosPathNameToNtPathName_U ((PWSTR
)lpFile
,
3004 SetLastError (ERROR_INVALID_PARAMETER
);
3005 return ERROR_INVALID_PARAMETER
;
3008 if (lpSecurityAttributes
!= NULL
)
3010 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
3013 InitializeObjectAttributes (&ObjectAttributes
,
3015 OBJ_CASE_INSENSITIVE
,
3017 SecurityDescriptor
);
3018 Status
= NtCreateFile (&FileHandle
,
3019 GENERIC_WRITE
| SYNCHRONIZE
,
3023 FILE_ATTRIBUTE_NORMAL
,
3026 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT
,
3029 RtlFreeUnicodeString (&FileName
);
3030 if (!NT_SUCCESS(Status
))
3032 ErrorCode
= RtlNtStatusToDosError (Status
);
3033 SetLastError (ErrorCode
);
3037 Status
= NtSaveKey (KeyHandle
,
3039 NtClose (FileHandle
);
3040 if (!NT_SUCCESS(Status
))
3042 ErrorCode
= RtlNtStatusToDosError (Status
);
3043 SetLastError (ErrorCode
);
3047 return ERROR_SUCCESS
;
3051 /************************************************************************
3057 RegSetKeySecurity (HKEY hKey
,
3058 SECURITY_INFORMATION SecurityInformation
,
3059 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
3065 if (hKey
== HKEY_PERFORMANCE_DATA
)
3067 SetLastError(ERROR_INVALID_HANDLE
);
3068 return ERROR_INVALID_HANDLE
;
3071 Status
= MapDefaultKey (&KeyHandle
,
3073 if (!NT_SUCCESS(Status
))
3075 ErrorCode
= RtlNtStatusToDosError (Status
);
3076 SetLastError (ErrorCode
);
3080 Status
= NtSetSecurityObject (KeyHandle
,
3081 SecurityInformation
,
3082 pSecurityDescriptor
);
3083 if (!NT_SUCCESS(Status
))
3085 ErrorCode
= RtlNtStatusToDosError (Status
);
3086 SetLastError (ErrorCode
);
3090 return ERROR_SUCCESS
;
3094 /************************************************************************
3100 RegSetValueExA (HKEY hKey
,
3107 UNICODE_STRING ValueName
;
3109 ANSI_STRING AnsiString
;
3110 UNICODE_STRING Data
;
3117 SetLastError (ERROR_INVALID_PARAMETER
);
3118 return ERROR_INVALID_PARAMETER
;
3121 if (lpValueName
!= NULL
&&
3122 strlen(lpValueName
) != 0)
3124 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
3126 pValueName
= (LPWSTR
)ValueName
.Buffer
;
3133 if ((dwType
== REG_SZ
) ||
3134 (dwType
== REG_MULTI_SZ
) ||
3135 (dwType
== REG_EXPAND_SZ
))
3137 RtlInitAnsiString (&AnsiString
,
3139 AnsiString
.Buffer
= (PSTR
)lpData
;
3140 AnsiString
.Length
= cbData
;
3141 AnsiString
.MaximumLength
= cbData
;
3142 RtlAnsiStringToUnicodeString (&Data
,
3145 pData
= (LPBYTE
)Data
.Buffer
;
3146 DataSize
= cbData
* sizeof(WCHAR
);
3150 RtlInitUnicodeString (&Data
,
3152 pData
= (LPBYTE
)lpData
;
3156 ErrorCode
= RegSetValueExW (hKey
,
3162 if (pValueName
!= NULL
)
3164 RtlFreeHeap (ProcessHeap
,
3169 if (Data
.Buffer
!= NULL
)
3171 RtlFreeHeap (ProcessHeap
,
3180 /************************************************************************
3186 RegSetValueExW (HKEY hKey
,
3187 LPCWSTR lpValueName
,
3193 UNICODE_STRING ValueName
;
3194 PUNICODE_STRING pValueName
;
3199 Status
= MapDefaultKey (&KeyHandle
,
3201 if (!NT_SUCCESS(Status
))
3203 ErrorCode
= RtlNtStatusToDosError (Status
);
3204 SetLastError (ErrorCode
);
3208 if (lpValueName
!= NULL
)
3210 RtlInitUnicodeString (&ValueName
,
3215 RtlInitUnicodeString (&ValueName
, L
"");
3217 pValueName
= &ValueName
;
3219 Status
= NtSetValueKey (KeyHandle
,
3225 if (!NT_SUCCESS(Status
))
3227 ErrorCode
= RtlNtStatusToDosError (Status
);
3228 SetLastError (ErrorCode
);
3232 return ERROR_SUCCESS
;
3236 /************************************************************************
3242 RegSetValueA (HKEY hKey
,
3248 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
3249 UNICODE_STRING SubKeyName
;
3250 UNICODE_STRING Data
;
3251 ANSI_STRING AnsiString
;
3257 SetLastError (ERROR_INVALID_PARAMETER
);
3258 return ERROR_INVALID_PARAMETER
;
3261 RtlInitUnicodeString (&SubKeyName
, NULL
);
3262 RtlInitUnicodeString (&Data
, NULL
);
3263 if (lpSubKey
!= NULL
&& (strlen(lpSubKey
) != 0))
3265 RtlInitAnsiString (&AnsiString
, (LPSTR
)lpSubKey
);
3266 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
3267 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
3268 RtlAnsiStringToUnicodeString (&SubKeyName
, &AnsiString
, FALSE
);
3271 DataSize
= cbData
* sizeof(WCHAR
);
3272 Data
.MaximumLength
= DataSize
;
3273 Data
.Buffer
= RtlAllocateHeap (ProcessHeap
,
3276 if (Data
.Buffer
== NULL
)
3278 SetLastError (ERROR_OUTOFMEMORY
);
3279 return ERROR_OUTOFMEMORY
;
3282 ErrorCode
= RegSetValueW (hKey
,
3283 (LPCWSTR
)SubKeyName
.Buffer
,
3288 RtlFreeHeap (ProcessHeap
,
3296 /************************************************************************
3302 RegSetValueW (HKEY hKey
,
3308 OBJECT_ATTRIBUTES ObjectAttributes
;
3309 UNICODE_STRING SubKeyString
;
3316 Status
= MapDefaultKey (&KeyHandle
,
3318 if (!NT_SUCCESS(Status
))
3320 ErrorCode
= RtlNtStatusToDosError (Status
);
3321 SetLastError (ErrorCode
);
3325 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
3327 RtlInitUnicodeString (&SubKeyString
,
3329 InitializeObjectAttributes (&ObjectAttributes
,
3331 OBJ_CASE_INSENSITIVE
,
3334 Status
= NtOpenKey (&RealKey
,
3337 if (!NT_SUCCESS(Status
))
3339 ErrorCode
= RtlNtStatusToDosError (Status
);
3340 SetLastError (ErrorCode
);
3343 CloseRealKey
= TRUE
;
3348 CloseRealKey
= FALSE
;
3351 ErrorCode
= RegSetValueExW (RealKey
,
3357 if (CloseRealKey
== TRUE
)
3366 /************************************************************************
3372 RegUnLoadKeyA (HKEY hKey
,
3375 UNICODE_STRING KeyName
;
3378 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
3381 ErrorCode
= RegUnLoadKeyW (hKey
,
3384 RtlFreeUnicodeString (&KeyName
);
3390 /************************************************************************
3396 RegUnLoadKeyW (HKEY hKey
,
3399 OBJECT_ATTRIBUTES ObjectAttributes
;
3400 UNICODE_STRING KeyName
;
3405 if (hKey
== HKEY_PERFORMANCE_DATA
)
3407 SetLastError(ERROR_INVALID_HANDLE
);
3408 return ERROR_INVALID_HANDLE
;
3411 Status
= MapDefaultKey (&KeyHandle
, hKey
);
3412 if (!NT_SUCCESS(Status
))
3414 ErrorCode
= RtlNtStatusToDosError (Status
);
3415 SetLastError (ErrorCode
);
3419 RtlInitUnicodeString (&KeyName
,
3422 InitializeObjectAttributes (&ObjectAttributes
,
3424 OBJ_CASE_INSENSITIVE
,
3428 Status
= NtUnloadKey (&ObjectAttributes
);
3430 if (!NT_SUCCESS(Status
))
3432 ErrorCode
= RtlNtStatusToDosError (Status
);
3433 SetLastError (ErrorCode
);
3437 return ERROR_SUCCESS
;