1 /* $Id: reg.c,v 1.28 2003/07/21 03:38:42 royce 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 *****************************************************************/
15 #define NTOS_MODE_USER
17 #include <ddk/ntddk.h>
18 #include <ntdll/rtl.h>
26 /* GLOBALS ******************************************************************/
28 #define MAX_DEFAULT_HANDLES 6
30 static CRITICAL_SECTION HandleTableCS
;
31 static HANDLE DefaultHandleTable
[MAX_DEFAULT_HANDLES
];
34 /* PROTOTYPES ***************************************************************/
36 static NTSTATUS
MapDefaultKey (PHKEY ParentKey
, HKEY Key
);
37 static VOID
CloseDefaultKeys(VOID
);
39 static NTSTATUS
OpenClassesRootKey(PHANDLE KeyHandle
);
40 static NTSTATUS
OpenLocalMachineKey (PHANDLE KeyHandle
);
41 static NTSTATUS
OpenUsersKey (PHANDLE KeyHandle
);
42 static NTSTATUS
OpenCurrentConfigKey(PHANDLE KeyHandle
);
45 /* FUNCTIONS ****************************************************************/
47 /************************************************************************
48 * RegInitDefaultHandles
53 DPRINT("RegInitialize()\n");
55 RtlZeroMemory (DefaultHandleTable
,
56 MAX_DEFAULT_HANDLES
* sizeof(HANDLE
));
57 RtlInitializeCriticalSection (&HandleTableCS
);
63 /************************************************************************
69 DPRINT("RegCleanup()\n");
72 RtlDeleteCriticalSection (&HandleTableCS
);
79 MapDefaultKey (PHKEY RealKey
,
84 NTSTATUS Status
= STATUS_SUCCESS
;
86 DPRINT("MapDefaultKey (Key %x)\n", Key
);
88 if (((ULONG
)Key
& 0xF0000000) != 0x80000000)
91 return STATUS_SUCCESS
;
94 /* Handle special cases here */
95 Index
= (ULONG
)Key
& 0x0FFFFFFF;
96 if (Index
>= MAX_DEFAULT_HANDLES
)
98 return STATUS_INVALID_PARAMETER
;
101 RtlEnterCriticalSection (&HandleTableCS
);
102 Handle
= &DefaultHandleTable
[Index
];
105 /* create/open the default handle */
108 case 0: /* HKEY_CLASSES_ROOT */
109 Status
= OpenClassesRootKey (Handle
);
112 case 1: /* HKEY_CURRENT_USER */
113 Status
= RtlOpenCurrentUser (KEY_ALL_ACCESS
,
117 case 2: /* HKEY_LOCAL_MACHINE */
118 Status
= OpenLocalMachineKey (Handle
);
121 case 3: /* HKEY_USERS */
122 Status
= OpenUsersKey (Handle
);
125 case 4: /* HKEY_PERFORMANCE_DATA */
126 Status
= OpenPerformanceDataKey (Handle
);
129 case 5: /* HKEY_CURRENT_CONFIG */
130 Status
= OpenCurrentConfigKey (Handle
);
133 case 6: /* HKEY_DYN_DATA */
134 Status
= STATUS_NOT_IMPLEMENTED
;
138 DPRINT("MapDefaultHandle() no handle creator\n");
139 Status
= STATUS_INVALID_PARAMETER
;
142 RtlLeaveCriticalSection (&HandleTableCS
);
144 if (NT_SUCCESS(Status
))
146 *RealKey
= (HKEY
)*Handle
;
154 CloseDefaultKeys (VOID
)
158 RtlEnterCriticalSection (&HandleTableCS
);
159 for (i
= 0; i
< MAX_DEFAULT_HANDLES
; i
++)
161 if (DefaultHandleTable
[i
] != NULL
)
163 NtClose (DefaultHandleTable
[i
]);
164 DefaultHandleTable
[i
] = NULL
;
167 RtlLeaveCriticalSection (&HandleTableCS
);
172 OpenClassesRootKey (PHANDLE KeyHandle
)
174 OBJECT_ATTRIBUTES Attributes
;
175 UNICODE_STRING KeyName
= UNICODE_STRING_INITIALIZER(L
"\\Registry\\Machine\\Software\\CLASSES");
177 DPRINT("OpenClassesRootKey()\n");
179 InitializeObjectAttributes (&Attributes
,
181 OBJ_CASE_INSENSITIVE
,
184 return NtOpenKey (KeyHandle
,
191 OpenLocalMachineKey (PHANDLE KeyHandle
)
193 OBJECT_ATTRIBUTES Attributes
;
194 UNICODE_STRING KeyName
= UNICODE_STRING_INITIALIZER(L
"\\Registry\\Machine");
196 DPRINT("OpenLocalMachineKey()\n");
198 InitializeObjectAttributes (&Attributes
,
200 OBJ_CASE_INSENSITIVE
,
203 return NtOpenKey (KeyHandle
,
210 OpenUsersKey (PHANDLE KeyHandle
)
212 OBJECT_ATTRIBUTES Attributes
;
213 UNICODE_STRING KeyName
= UNICODE_STRING_INITIALIZER(L
"\\Registry\\User");
215 DPRINT("OpenUsersKey()\n");
217 InitializeObjectAttributes (&Attributes
,
219 OBJ_CASE_INSENSITIVE
,
222 return NtOpenKey (KeyHandle
,
229 OpenCurrentConfigKey (PHANDLE KeyHandle
)
231 OBJECT_ATTRIBUTES Attributes
;
232 UNICODE_STRING KeyName
=
233 UNICODE_STRING_INITIALIZER(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
235 DPRINT("OpenCurrentConfigKey()\n");
237 InitializeObjectAttributes (&Attributes
,
239 OBJ_CASE_INSENSITIVE
,
242 return NtOpenKey (KeyHandle
,
248 /************************************************************************
254 RegCloseKey (HKEY hKey
)
259 /* don't close null handle or a pseudo handle */
260 if ((!hKey
) || (((ULONG
)hKey
& 0xF0000000) == 0x80000000))
262 return ERROR_INVALID_HANDLE
;
265 Status
= NtClose (hKey
);
266 if (!NT_SUCCESS(Status
))
268 ErrorCode
= RtlNtStatusToDosError (Status
);
269 SetLastError (ErrorCode
);
273 return ERROR_SUCCESS
;
277 /************************************************************************
278 * RegConnectRegistryA
283 RegConnectRegistryA (LPCSTR lpMachineName
,
287 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
288 return ERROR_CALL_NOT_IMPLEMENTED
;
292 /************************************************************************
293 * RegConnectRegistryW
298 RegConnectRegistryW (LPCWSTR lpMachineName
,
302 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
303 return ERROR_CALL_NOT_IMPLEMENTED
;
307 /************************************************************************
313 RegCreateKeyExA (HKEY hKey
,
319 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
321 LPDWORD lpdwDisposition
)
323 UNICODE_STRING SubKeyString
;
324 UNICODE_STRING ClassString
;
325 OBJECT_ATTRIBUTES Attributes
;
330 DPRINT("RegCreateKeyExW() called\n");
332 /* get the real parent key */
333 Status
= MapDefaultKey (&ParentKey
,
335 if (!NT_SUCCESS(Status
))
337 ErrorCode
= RtlNtStatusToDosError (Status
);
338 SetLastError (ErrorCode
);
341 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
345 RtlCreateUnicodeStringFromAsciiz (&ClassString
,
348 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
350 InitializeObjectAttributes (&Attributes
,
352 OBJ_CASE_INSENSITIVE
,
354 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
355 Status
= NtCreateKey (phkResult
,
359 (lpClass
== NULL
)? NULL
: &ClassString
,
361 (PULONG
)lpdwDisposition
);
362 RtlFreeUnicodeString (&SubKeyString
);
365 RtlFreeUnicodeString (&ClassString
);
367 DPRINT("Status %x\n", Status
);
368 if (!NT_SUCCESS(Status
))
370 ErrorCode
= RtlNtStatusToDosError (Status
);
371 SetLastError (ErrorCode
);
375 return ERROR_SUCCESS
;
379 /************************************************************************
385 RegCreateKeyExW(HKEY hKey
,
391 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
393 LPDWORD lpdwDisposition
)
395 UNICODE_STRING SubKeyString
;
396 UNICODE_STRING ClassString
;
397 OBJECT_ATTRIBUTES Attributes
;
402 DPRINT("RegCreateKeyExW() called\n");
404 /* get the real parent key */
405 Status
= MapDefaultKey (&ParentKey
,
407 if (!NT_SUCCESS(Status
))
409 ErrorCode
= RtlNtStatusToDosError(Status
);
410 SetLastError (ErrorCode
);
413 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
415 RtlInitUnicodeString (&ClassString
,
417 RtlInitUnicodeString (&SubKeyString
,
419 InitializeObjectAttributes (&Attributes
,
421 OBJ_CASE_INSENSITIVE
,
423 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
424 Status
= NtCreateKey (phkResult
,
428 (lpClass
== NULL
)? NULL
: &ClassString
,
430 (PULONG
)lpdwDisposition
);
431 DPRINT("Status %x\n", Status
);
432 if (!NT_SUCCESS(Status
))
434 ErrorCode
= RtlNtStatusToDosError (Status
);
435 SetLastError (ErrorCode
);
439 return ERROR_SUCCESS
;
443 /************************************************************************
449 RegCreateKeyA (HKEY hKey
,
453 return RegCreateKeyExA (hKey
,
465 /************************************************************************
471 RegCreateKeyW (HKEY hKey
,
475 return RegCreateKeyExW (hKey
,
487 /************************************************************************
493 RegDeleteKeyA (HKEY hKey
,
496 OBJECT_ATTRIBUTES ObjectAttributes
;
497 UNICODE_STRING SubKeyName
;
503 Status
= MapDefaultKey (&ParentKey
,
505 if (!NT_SUCCESS(Status
))
507 ErrorCode
= RtlNtStatusToDosError (Status
);
508 SetLastError (ErrorCode
);
512 RtlCreateUnicodeStringFromAsciiz (&SubKeyName
,
514 InitializeObjectAttributes(&ObjectAttributes
,
516 OBJ_CASE_INSENSITIVE
,
520 Status
= NtOpenKey (&TargetKey
,
523 RtlFreeUnicodeString (&SubKeyName
);
524 if (!NT_SUCCESS(Status
))
526 ErrorCode
= RtlNtStatusToDosError (Status
);
527 SetLastError (ErrorCode
);
531 Status
= NtDeleteKey (TargetKey
);
533 if (!NT_SUCCESS(Status
))
535 ErrorCode
= RtlNtStatusToDosError(Status
);
536 SetLastError (ErrorCode
);
540 return ERROR_SUCCESS
;
544 /************************************************************************
550 RegDeleteKeyW (HKEY hKey
,
553 OBJECT_ATTRIBUTES ObjectAttributes
;
554 UNICODE_STRING SubKeyName
;
560 Status
= MapDefaultKey (&ParentKey
,
562 if (!NT_SUCCESS(Status
))
564 ErrorCode
= RtlNtStatusToDosError (Status
);
565 SetLastError (ErrorCode
);
569 RtlInitUnicodeString (&SubKeyName
,
571 InitializeObjectAttributes (&ObjectAttributes
,
573 OBJ_CASE_INSENSITIVE
,
576 Status
= NtOpenKey (&TargetKey
,
579 if (!NT_SUCCESS(Status
))
581 ErrorCode
= RtlNtStatusToDosError (Status
);
582 SetLastError (ErrorCode
);
586 Status
= NtDeleteKey (TargetKey
);
588 if (!NT_SUCCESS(Status
))
590 ErrorCode
= RtlNtStatusToDosError (Status
);
591 SetLastError (ErrorCode
);
595 return ERROR_SUCCESS
;
599 /************************************************************************
605 RegDeleteValueA (HKEY hKey
,
608 UNICODE_STRING ValueName
;
613 Status
= MapDefaultKey (&KeyHandle
,
615 if (!NT_SUCCESS(Status
))
617 ErrorCode
= RtlNtStatusToDosError (Status
);
618 SetLastError (ErrorCode
);
622 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
624 Status
= NtDeleteValueKey (KeyHandle
,
626 RtlFreeUnicodeString (&ValueName
);
627 if (!NT_SUCCESS(Status
))
629 ErrorCode
= RtlNtStatusToDosError (Status
);
630 SetLastError (ErrorCode
);
634 return ERROR_SUCCESS
;
638 /************************************************************************
644 RegDeleteValueW (HKEY hKey
,
647 UNICODE_STRING ValueName
;
652 Status
= MapDefaultKey (&KeyHandle
,
654 if (!NT_SUCCESS(Status
))
656 ErrorCode
= RtlNtStatusToDosError (Status
);
657 SetLastError (ErrorCode
);
661 RtlInitUnicodeString (&ValueName
,
662 (LPWSTR
)lpValueName
);
664 Status
= NtDeleteValueKey (KeyHandle
,
666 if (!NT_SUCCESS(Status
))
668 ErrorCode
= RtlNtStatusToDosError (Status
);
669 SetLastError (ErrorCode
);
673 return ERROR_SUCCESS
;
677 /************************************************************************
683 RegEnumKeyA (HKEY hKey
,
691 return RegEnumKeyExA (hKey
,
702 /************************************************************************
708 RegEnumKeyW (HKEY hKey
,
716 return RegEnumKeyExW (hKey
,
727 /************************************************************************
733 RegEnumKeyExA (HKEY hKey
,
740 PFILETIME lpftLastWriteTime
)
742 WCHAR Name
[MAX_PATH
+1];
743 UNICODE_STRING UnicodeStringName
;
744 WCHAR Class
[MAX_PATH
+1];
745 UNICODE_STRING UnicodeStringClass
;
746 ANSI_STRING AnsiString
;
751 DPRINT("hKey 0x%x dwIndex %d lpName 0x%x *lpcbName %d lpClass 0x%x lpcbClass %d\n",
752 hKey
, dwIndex
, lpName
, *lpcbName
, lpClass
, lpcbClass
);
754 if ((lpClass
) && (!lpcbClass
))
756 SetLastError (ERROR_INVALID_PARAMETER
);
757 return ERROR_INVALID_PARAMETER
;
760 RtlInitUnicodeString (&UnicodeStringName
,
762 UnicodeStringName
.Buffer
= &Name
[0];
763 UnicodeStringName
.MaximumLength
= sizeof(Name
);
764 RtlInitUnicodeString (&UnicodeStringClass
,
768 UnicodeStringClass
.Buffer
= &Class
[0];
769 UnicodeStringClass
.MaximumLength
= sizeof(Class
);
770 ClassLength
= *lpcbClass
;
776 NameLength
= *lpcbName
;
778 ErrorCode
= RegEnumKeyExW (hKey
,
780 UnicodeStringName
.Buffer
,
783 UnicodeStringClass
.Buffer
,
786 if (ErrorCode
!= ERROR_SUCCESS
)
791 UnicodeStringName
.Length
= NameLength
* sizeof(WCHAR
);
792 UnicodeStringClass
.Length
= ClassLength
* sizeof(WCHAR
);
793 RtlInitAnsiString (&AnsiString
,
795 AnsiString
.Buffer
= lpName
;
796 AnsiString
.MaximumLength
= *lpcbName
;
797 RtlUnicodeStringToAnsiString (&AnsiString
,
800 *lpcbName
= AnsiString
.Length
;
802 DPRINT("Key Namea0 Length %d\n", UnicodeStringName
.Length
);
803 DPRINT("Key Namea1 Length %d\n", NameLength
);
804 DPRINT("Key Namea Length %d\n", *lpcbName
);
805 DPRINT("Key Namea %s\n", lpName
);
809 RtlInitAnsiString (&AnsiString
,
811 AnsiString
.Buffer
= lpClass
;
812 AnsiString
.MaximumLength
= *lpcbClass
;
813 RtlUnicodeStringToAnsiString (&AnsiString
,
816 *lpcbClass
= AnsiString
.Length
;
819 return ERROR_SUCCESS
;
823 /************************************************************************
829 RegEnumKeyExW (HKEY hKey
,
836 PFILETIME lpftLastWriteTime
)
838 PKEY_NODE_INFORMATION KeyInfo
;
845 Status
= MapDefaultKey(&KeyHandle
,
847 if (!NT_SUCCESS(Status
))
849 ErrorCode
= RtlNtStatusToDosError (Status
);
850 SetLastError (ErrorCode
);
854 BufferSize
= sizeof (KEY_NODE_INFORMATION
) + *lpcbName
* sizeof(WCHAR
);
857 BufferSize
+= *lpcbClass
;
860 KeyInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
865 SetLastError (ERROR_OUTOFMEMORY
);
866 return ERROR_OUTOFMEMORY
;
869 /* We don't know the exact size of the data returned, so call
870 NtEnumerateKey() with a buffer size determined from parameters
871 to this function. If that call fails with a status code of
872 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
875 Status
= NtEnumerateKey (KeyHandle
,
881 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status
);
882 if (Status
== STATUS_BUFFER_OVERFLOW
)
884 BufferSize
= ResultSize
;
887 if (!NT_SUCCESS(Status
))
889 ErrorCode
= RtlNtStatusToDosError (Status
);
890 SetLastError (ErrorCode
);
895 if ((lpClass
!= NULL
) &&
897 (KeyInfo
->ClassLength
> *lpcbClass
))
899 ErrorCode
= ERROR_MORE_DATA
;
900 SetLastError (ErrorCode
);
903 RtlMoveMemory (lpName
,
905 KeyInfo
->NameLength
);
906 *lpcbName
= (DWORD
)(KeyInfo
->NameLength
/ sizeof(WCHAR
));
907 lpName
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
910 RtlMoveMemory (lpClass
,
911 (PVOID
)((ULONG_PTR
)KeyInfo
->Name
+ KeyInfo
->ClassOffset
),
912 KeyInfo
->ClassLength
);
913 *lpcbClass
= (DWORD
)(KeyInfo
->ClassLength
/ sizeof(WCHAR
));
915 if (lpftLastWriteTime
!= NULL
)
917 /* FIXME: Fill lpftLastWriteTime */
923 RtlFreeHeap (RtlGetProcessHeap (),
931 /************************************************************************
937 RegEnumValueA (HKEY hKey
,
940 LPDWORD lpcbValueName
,
946 WCHAR ValueName
[MAX_PATH
+1];
947 UNICODE_STRING UnicodeString
;
948 ANSI_STRING AnsiString
;
950 DWORD ValueNameLength
;
951 BYTE
* lpDataBuffer
= NULL
;
954 ANSI_STRING AnsiDataString
;
955 UNICODE_STRING UnicodeDataString
;
957 ErrorCode
= ERROR_SUCCESS
;
958 if (lpData
!= NULL
/*&& lpcbData != NULL*/)
960 cbData
= *lpcbData
; // this should always be valid if lpData is valid
961 lpDataBuffer
= RtlAllocateHeap (RtlGetProcessHeap (),
963 (*lpcbData
) * sizeof(WCHAR
));
964 if (lpDataBuffer
== NULL
)
966 SetLastError (ERROR_OUTOFMEMORY
);
967 return ERROR_OUTOFMEMORY
;
970 RtlInitUnicodeString (&UnicodeString
,
972 UnicodeString
.Buffer
= &ValueName
[0];
973 UnicodeString
.MaximumLength
= sizeof(ValueName
);
974 ValueNameLength
= *lpcbValueName
;
975 ErrorCode
= RegEnumValueW (hKey
,
977 UnicodeString
.Buffer
,
983 if (ErrorCode
!= ERROR_SUCCESS
)
985 if (lpDataBuffer
!= NULL
)
987 RtlFreeHeap (RtlGetProcessHeap (),
995 UnicodeString
.Length
= ValueNameLength
* sizeof(WCHAR
);
996 RtlInitAnsiString (&AnsiString
,
998 AnsiString
.Buffer
= lpValueName
;
999 AnsiString
.MaximumLength
= *lpcbValueName
;
1000 RtlUnicodeStringToAnsiString (&AnsiString
,
1003 *lpcbValueName
= AnsiString
.Length
;
1004 if (lpDataBuffer
!= NULL
)
1006 /* Did we use a temp buffer */
1007 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
))
1009 RtlInitUnicodeString (&UnicodeDataString
,
1011 UnicodeDataString
.Buffer
= (WCHAR
*)lpDataBuffer
;
1012 UnicodeDataString
.MaximumLength
= (*lpcbData
) * sizeof(WCHAR
);
1013 UnicodeDataString
.Length
= cbData
/* * sizeof(WCHAR)*/;
1014 RtlInitAnsiString (&AnsiDataString
,
1016 AnsiDataString
.Buffer
= lpData
;
1017 AnsiDataString
.MaximumLength
= *lpcbData
;
1018 RtlUnicodeStringToAnsiString (&AnsiDataString
,
1021 *lpcbData
= AnsiDataString
.Length
;
1025 RtlCopyMemory (lpData
,
1027 min(*lpcbData
, cbData
));
1030 RtlFreeHeap (RtlGetProcessHeap (),
1040 return ERROR_SUCCESS
;
1044 /************************************************************************
1050 RegEnumValueW (HKEY hKey
,
1053 LPDWORD lpcbValueName
,
1059 PKEY_VALUE_FULL_INFORMATION ValueInfo
;
1066 ErrorCode
= ERROR_SUCCESS
;
1067 Status
= MapDefaultKey (&KeyHandle
,
1069 if (!NT_SUCCESS(Status
))
1071 ErrorCode
= RtlNtStatusToDosError (Status
);
1072 SetLastError (ErrorCode
);
1076 BufferSize
= sizeof (KEY_VALUE_FULL_INFORMATION
) + *lpcbValueName
* sizeof(WCHAR
);
1079 BufferSize
+= *lpcbData
;
1082 /* We don't know the exact size of the data returned, so call
1083 NtEnumerateValueKey() with a buffer size determined from parameters
1084 to this function. If that call fails with a status code of
1085 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
1086 ValueInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
1089 if (ValueInfo
== NULL
)
1091 SetLastError (ERROR_OUTOFMEMORY
);
1092 return ERROR_OUTOFMEMORY
;
1097 Status
= NtEnumerateValueKey (KeyHandle
,
1099 KeyValueFullInformation
,
1103 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status
);
1104 if (Status
== STATUS_BUFFER_OVERFLOW
)
1106 BufferSize
= ResultSize
;
1109 if (!NT_SUCCESS(Status
))
1111 ErrorCode
= RtlNtStatusToDosError (Status
);
1112 SetLastError (ErrorCode
);
1117 if ((lpData
!= NULL
) &&
1119 (ValueInfo
->DataLength
> *lpcbData
))
1121 ErrorCode
= ERROR_MORE_DATA
;
1122 SetLastError (ErrorCode
);
1125 RtlCopyMemory (lpValueName
,
1127 ValueInfo
->NameLength
);
1128 *lpcbValueName
= (DWORD
)(ValueInfo
->NameLength
/ sizeof(WCHAR
));
1129 lpValueName
[ValueInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
1132 *lpType
= ValueInfo
->Type
;
1136 RtlCopyMemory (lpData
,
1137 (PVOID
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->DataOffset
),
1138 ValueInfo
->DataLength
);
1139 *lpcbData
= (DWORD
)ValueInfo
->DataLength
;
1145 RtlFreeHeap (RtlGetProcessHeap (),
1153 /************************************************************************
1159 RegFlushKey(HKEY hKey
)
1165 if (hKey
== HKEY_PERFORMANCE_DATA
)
1167 return ERROR_SUCCESS
;
1170 Status
= MapDefaultKey (&KeyHandle
,
1172 if (!NT_SUCCESS(Status
))
1174 ErrorCode
= RtlNtStatusToDosError (Status
);
1175 SetLastError (ErrorCode
);
1179 Status
= NtFlushKey (KeyHandle
);
1180 if (!NT_SUCCESS(Status
))
1182 ErrorCode
= RtlNtStatusToDosError (Status
);
1183 SetLastError (ErrorCode
);
1187 return ERROR_SUCCESS
;
1191 /************************************************************************
1197 RegGetKeySecurity (HKEY hKey
,
1198 SECURITY_INFORMATION SecurityInformation
,
1199 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1200 LPDWORD lpcbSecurityDescriptor
)
1207 if (hKey
= HKEY_PERFORMANCE_DATA
)
1209 return ERROR_INVALID_HANDLE
;
1212 Status
= MapDefaultKey (&KeyHandle
,
1214 if (!NT_SUCCESS(Status
))
1216 ErrorCode
= RtlNtStatusToDosError (Status
);
1217 SetLastError (ErrorCode
);
1221 Status
= NtQuerySecurityObject ()
1222 if (!NT_SUCCESS(Status
))
1224 ErrorCode
= RtlNtStatusToDosError (Status
);
1225 SetLastError (ErrorCode
);
1229 return ERROR_SUCCESS
;
1233 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1234 return ERROR_CALL_NOT_IMPLEMENTED
;
1238 /************************************************************************
1244 RegLoadKeyA (HKEY hKey
,
1248 UNICODE_STRING FileName
;
1249 UNICODE_STRING KeyName
;
1252 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
1254 RtlCreateUnicodeStringFromAsciiz (&FileName
,
1257 ErrorCode
= RegLoadKeyW (hKey
,
1261 RtlFreeUnicodeString (&FileName
);
1262 RtlFreeUnicodeString (&KeyName
);
1268 /************************************************************************
1274 RegLoadKeyW (HKEY hKey
,
1278 OBJECT_ATTRIBUTES FileObjectAttributes
;
1279 OBJECT_ATTRIBUTES KeyObjectAttributes
;
1280 UNICODE_STRING FileName
;
1281 UNICODE_STRING KeyName
;
1286 if (hKey
== HKEY_PERFORMANCE_DATA
)
1288 return ERROR_INVALID_HANDLE
;
1291 Status
= MapDefaultKey (&KeyHandle
,
1293 if (!NT_SUCCESS(Status
))
1295 ErrorCode
= RtlNtStatusToDosError (Status
);
1296 SetLastError (ErrorCode
);
1300 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
1305 SetLastError (ERROR_BAD_PATHNAME
);
1306 return ERROR_BAD_PATHNAME
;
1309 InitializeObjectAttributes (&FileObjectAttributes
,
1311 OBJ_CASE_INSENSITIVE
,
1315 RtlInitUnicodeString (&KeyName
,
1318 InitializeObjectAttributes (&KeyObjectAttributes
,
1320 OBJ_CASE_INSENSITIVE
,
1324 Status
= NtLoadKey (&KeyObjectAttributes
,
1325 &FileObjectAttributes
);
1327 RtlFreeUnicodeString (&FileName
);
1329 if (!NT_SUCCESS(Status
))
1331 ErrorCode
= RtlNtStatusToDosError (Status
);
1332 SetLastError (ErrorCode
);
1336 return ERROR_SUCCESS
;
1340 /************************************************************************
1341 * RegNotifyChangeKeyValue
1346 RegNotifyChangeKeyValue (HKEY hKey
,
1348 DWORD dwNotifyFilter
,
1352 IO_STATUS_BLOCK IoStatusBlock
;
1356 if (hKey
== HKEY_PERFORMANCE_DATA
)
1358 return ERROR_INVALID_HANDLE
;
1361 if (fAsynchronous
== TRUE
&& hEvent
== NULL
)
1363 return ERROR_INVALID_PARAMETER
;
1366 Status
= MapDefaultKey (&KeyHandle
,
1368 if (!NT_SUCCESS(Status
))
1370 return RtlNtStatusToDosError (Status
);
1373 /* FIXME: Remote key handles must fail */
1375 Status
= NtNotifyChangeKey (KeyHandle
,
1385 if (!NT_SUCCESS(Status
) && Status
!= STATUS_TIMEOUT
)
1387 return RtlNtStatusToDosError (Status
);
1390 return ERROR_SUCCESS
;
1395 /************************************************************************
1401 RegOpenKeyA (HKEY hKey
,
1405 OBJECT_ATTRIBUTES ObjectAttributes
;
1406 UNICODE_STRING SubKeyString
;
1411 Status
= MapDefaultKey (&KeyHandle
,
1413 if (!NT_SUCCESS(Status
))
1415 ErrorCode
= RtlNtStatusToDosError (Status
);
1416 SetLastError (ErrorCode
);
1420 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1422 InitializeObjectAttributes (&ObjectAttributes
,
1424 OBJ_CASE_INSENSITIVE
,
1427 Status
= NtOpenKey (phkResult
,
1430 RtlFreeUnicodeString (&SubKeyString
);
1431 if (!NT_SUCCESS(Status
))
1433 ErrorCode
= RtlNtStatusToDosError (Status
);
1434 SetLastError (ErrorCode
);
1438 return ERROR_SUCCESS
;
1442 /************************************************************************
1451 RegOpenKeyW (HKEY hKey
,
1455 OBJECT_ATTRIBUTES ObjectAttributes
;
1456 UNICODE_STRING SubKeyString
;
1461 Status
= MapDefaultKey (&KeyHandle
,
1463 if (!NT_SUCCESS(Status
))
1465 ErrorCode
= RtlNtStatusToDosError (Status
);
1466 SetLastError (ErrorCode
);
1470 RtlInitUnicodeString (&SubKeyString
,
1472 InitializeObjectAttributes (&ObjectAttributes
,
1474 OBJ_CASE_INSENSITIVE
,
1477 Status
= NtOpenKey (phkResult
,
1480 if (!NT_SUCCESS(Status
))
1482 ErrorCode
= RtlNtStatusToDosError (Status
);
1483 SetLastError(ErrorCode
);
1487 return ERROR_SUCCESS
;
1491 /************************************************************************
1497 RegOpenKeyExA (HKEY hKey
,
1503 OBJECT_ATTRIBUTES ObjectAttributes
;
1504 UNICODE_STRING SubKeyString
;
1509 Status
= MapDefaultKey (&KeyHandle
,
1511 if (!NT_SUCCESS(Status
))
1513 ErrorCode
= RtlNtStatusToDosError (Status
);
1514 SetLastError (ErrorCode
);
1518 RtlCreateUnicodeStringFromAsciiz (&SubKeyString
,
1520 InitializeObjectAttributes (&ObjectAttributes
,
1522 OBJ_CASE_INSENSITIVE
,
1525 Status
= NtOpenKey (phkResult
,
1528 RtlFreeUnicodeString (&SubKeyString
);
1529 if (!NT_SUCCESS(Status
))
1531 ErrorCode
= RtlNtStatusToDosError (Status
);
1532 SetLastError (ErrorCode
);
1536 return ERROR_SUCCESS
;
1540 /************************************************************************
1546 RegOpenKeyExW (HKEY hKey
,
1552 OBJECT_ATTRIBUTES ObjectAttributes
;
1553 UNICODE_STRING SubKeyString
;
1558 Status
= MapDefaultKey (&KeyHandle
,
1560 if (!NT_SUCCESS(Status
))
1562 ErrorCode
= RtlNtStatusToDosError (Status
);
1563 SetLastError (ErrorCode
);
1567 if (lpSubKey
!= NULL
)
1569 RtlInitUnicodeString (&SubKeyString
,
1574 RtlInitUnicodeString (&SubKeyString
,
1577 InitializeObjectAttributes (&ObjectAttributes
,
1579 OBJ_CASE_INSENSITIVE
,
1582 Status
= NtOpenKey (phkResult
,
1585 if (!NT_SUCCESS(Status
))
1587 ErrorCode
= RtlNtStatusToDosError (Status
);
1588 SetLastError (ErrorCode
);
1592 return ERROR_SUCCESS
;
1596 /************************************************************************
1602 RegQueryInfoKeyA (HKEY hKey
,
1607 LPDWORD lpcbMaxSubKeyLen
,
1608 LPDWORD lpcbMaxClassLen
,
1610 LPDWORD lpcbMaxValueNameLen
,
1611 LPDWORD lpcbMaxValueLen
,
1612 LPDWORD lpcbSecurityDescriptor
,
1613 PFILETIME lpftLastWriteTime
)
1615 WCHAR ClassName
[MAX_PATH
];
1616 UNICODE_STRING UnicodeString
;
1617 ANSI_STRING AnsiString
;
1620 RtlInitUnicodeString (&UnicodeString
,
1622 if (lpClass
!= NULL
)
1624 UnicodeString
.Buffer
= &ClassName
[0];
1625 UnicodeString
.MaximumLength
= sizeof(ClassName
);
1628 ErrorCode
= RegQueryInfoKeyW (hKey
,
1629 UnicodeString
.Buffer
,
1636 lpcbMaxValueNameLen
,
1638 lpcbSecurityDescriptor
,
1640 if ((ErrorCode
== ERROR_SUCCESS
) && (lpClass
!= NULL
))
1642 RtlInitAnsiString (&AnsiString
,
1644 AnsiString
.Buffer
= lpClass
;
1645 AnsiString
.MaximumLength
= *lpcbClass
;
1646 RtlUnicodeStringToAnsiString (&AnsiString
,
1649 *lpcbClass
= AnsiString
.Length
;
1656 /************************************************************************
1662 RegQueryInfoKeyW (HKEY hKey
,
1667 LPDWORD lpcbMaxSubKeyLen
,
1668 LPDWORD lpcbMaxClassLen
,
1670 LPDWORD lpcbMaxValueNameLen
,
1671 LPDWORD lpcbMaxValueLen
,
1672 LPDWORD lpcbSecurityDescriptor
,
1673 PFILETIME lpftLastWriteTime
)
1675 KEY_FULL_INFORMATION FullInfoBuffer
;
1676 PKEY_FULL_INFORMATION FullInfo
;
1683 if ((lpClass
) && (!lpcbClass
))
1685 SetLastError(ERROR_INVALID_PARAMETER
);
1686 return ERROR_INVALID_PARAMETER
;
1689 Status
= MapDefaultKey (&KeyHandle
,
1691 if (!NT_SUCCESS(Status
))
1693 ErrorCode
= RtlNtStatusToDosError (Status
);
1694 SetLastError (ErrorCode
);
1698 if (lpClass
!= NULL
)
1700 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
) + *lpcbClass
;
1701 FullInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
1704 if (FullInfo
== NULL
)
1706 SetLastError (ERROR_OUTOFMEMORY
);
1707 return ERROR_OUTOFMEMORY
;
1709 FullInfo
->ClassLength
= *lpcbClass
;
1713 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
);
1714 FullInfo
= &FullInfoBuffer
;
1715 FullInfo
->ClassLength
= 1;
1717 FullInfo
->ClassOffset
= FIELD_OFFSET(KEY_FULL_INFORMATION
, Class
);
1719 Status
= NtQueryKey (KeyHandle
,
1724 if (!NT_SUCCESS(Status
))
1726 if (lpClass
!= NULL
)
1728 RtlFreeHeap (RtlGetProcessHeap (),
1732 ErrorCode
= RtlNtStatusToDosError (Status
);
1733 SetLastError (ErrorCode
);
1737 if (lpcSubKeys
!= NULL
)
1739 *lpcSubKeys
= FullInfo
->SubKeys
;
1742 if (lpcbMaxSubKeyLen
!= NULL
)
1744 *lpcbMaxSubKeyLen
= FullInfo
->MaxNameLen
;
1747 if (lpcbMaxClassLen
!= NULL
)
1749 *lpcbMaxClassLen
= FullInfo
->MaxClassLen
;
1754 *lpcValues
= FullInfo
->Values
;
1757 if (lpcbMaxValueNameLen
)
1759 *lpcbMaxValueNameLen
= FullInfo
->MaxValueNameLen
;
1762 if (lpcbMaxValueLen
)
1764 *lpcbMaxValueLen
= FullInfo
->MaxValueDataLen
;
1767 if (lpcbSecurityDescriptor
)
1769 *lpcbSecurityDescriptor
= 0;
1773 if (lpftLastWriteTime
!= NULL
)
1775 lpftLastWriteTime
->dwLowDateTime
= FullInfo
->LastWriteTime
.u
.LowPart
;
1776 lpftLastWriteTime
->dwHighDateTime
= FullInfo
->LastWriteTime
.u
.HighPart
;
1779 if (lpClass
!= NULL
)
1784 RtlFreeHeap (RtlGetProcessHeap (),
1789 return ERROR_SUCCESS
;
1793 /************************************************************************
1794 * RegQueryMultipleValuesA
1799 RegQueryMultipleValuesA (HKEY hKey
,
1806 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1807 return ERROR_CALL_NOT_IMPLEMENTED
;
1811 /************************************************************************
1812 * RegQueryMultipleValuesW
1817 RegQueryMultipleValuesW (HKEY hKey
,
1824 DWORD maxBytes
= *ldwTotsize
;
1826 LPSTR bufptr
= (LPSTR
)lpValueBuf
;
1828 if ( maxBytes
>= (1024*1024) )
1829 return ERROR_TRANSFER_TOO_LONG
;
1833 //TRACE("(%p,%p,%ld,%p,%p=%ld)\n", hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
1835 for(i
=0; i
< num_vals
; ++i
)
1837 val_list
[i
].ve_valuelen
=0;
1838 status
= RegQueryValueExW(hKey
, val_list
[i
].ve_valuename
, NULL
, NULL
, NULL
, &val_list
[i
].ve_valuelen
);
1839 if(status
!= ERROR_SUCCESS
)
1844 if(lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
1846 status
= RegQueryValueExW(hKey
, val_list
[i
].ve_valuename
, NULL
, &val_list
[i
].ve_type
,
1847 bufptr
, &val_list
[i
].ve_valuelen
);
1848 if(status
!= ERROR_SUCCESS
)
1853 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
1855 bufptr
+= val_list
[i
].ve_valuelen
;
1858 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
1860 return lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
? ERROR_SUCCESS
: ERROR_MORE_DATA
;
1864 /************************************************************************
1870 RegQueryValueExW (HKEY hKey
,
1871 LPCWSTR lpValueName
,
1877 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
1878 UNICODE_STRING ValueName
;
1880 LONG ErrorCode
= ERROR_SUCCESS
;
1885 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
1886 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
1888 Status
= MapDefaultKey (&KeyHandle
,
1890 if (!NT_SUCCESS(Status
))
1892 ErrorCode
= RtlNtStatusToDosError (Status
);
1893 SetLastError (ErrorCode
);
1897 if (lpData
!= NULL
&& lpcbData
== NULL
)
1899 SetLastError (ERROR_INVALID_PARAMETER
);
1900 return ERROR_INVALID_PARAMETER
;
1903 RtlInitUnicodeString (&ValueName
,
1905 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + *lpcbData
;
1906 ValueInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
1909 if (ValueInfo
== NULL
)
1911 SetLastError(ERROR_OUTOFMEMORY
);
1912 return ERROR_OUTOFMEMORY
;
1915 Status
= NtQueryValueKey (hKey
,
1917 KeyValuePartialInformation
,
1921 DPRINT("Status 0x%X\n", Status
);
1922 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1924 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
1925 ErrorCode
= ERROR_SUCCESS
;
1927 else if (!NT_SUCCESS(Status
))
1929 ErrorCode
= RtlNtStatusToDosError (Status
);
1930 SetLastError (ErrorCode
);
1936 *lpType
= ValueInfo
->Type
;
1938 RtlMoveMemory (lpData
,
1940 ValueInfo
->DataLength
);
1941 if ((ValueInfo
->Type
== REG_SZ
) ||
1942 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
1943 (ValueInfo
->Type
== REG_EXPAND_SZ
))
1945 ((PWSTR
)lpData
)[ValueInfo
->DataLength
/ sizeof(WCHAR
)] = 0;
1948 DPRINT("Type %d Size %d\n", ValueInfo
->Type
, ValueInfo
->DataLength
);
1950 if (NULL
!= lpcbData
)
1952 *lpcbData
= (DWORD
)ValueInfo
->DataLength
;
1954 RtlFreeHeap (RtlGetProcessHeap (),
1962 /************************************************************************
1977 WCHAR ValueNameBuffer
[MAX_PATH
+1];
1978 UNICODE_STRING ValueName
;
1979 UNICODE_STRING ValueData
;
1980 ANSI_STRING AnsiString
;
1985 /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
1987 if ((lpData
) && (!lpcbData
)) {
1988 SetLastError(ERROR_INVALID_PARAMETER
);
1989 return ERROR_INVALID_PARAMETER
;
1991 RtlInitUnicodeString(&ValueData
, NULL
);
1993 ValueData
.MaximumLength
= *lpcbData
* sizeof(WCHAR
);
1994 ValueData
.Buffer
= RtlAllocateHeap(
1995 RtlGetProcessHeap(),
1997 ValueData
.MaximumLength
);
1998 if (!ValueData
.Buffer
) {
1999 SetLastError(ERROR_OUTOFMEMORY
);
2000 return ERROR_OUTOFMEMORY
;
2003 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpValueName
);
2004 RtlInitUnicodeString(&ValueName
, NULL
);
2005 ValueName
.Buffer
= &ValueNameBuffer
[0];
2006 ValueName
.MaximumLength
= sizeof(ValueNameBuffer
);
2007 RtlAnsiStringToUnicodeString(&ValueName
, &AnsiString
, FALSE
);
2009 ResultSize
= *lpcbData
;
2013 ErrorCode
= RegQueryValueExW(
2018 (LPBYTE
)ValueData
.Buffer
,
2020 if ((ErrorCode
== ERROR_SUCCESS
) && (ValueData
.Buffer
!= NULL
)) {
2024 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
)) {
2025 ValueData
.Length
= ResultSize
;
2026 RtlInitAnsiString(&AnsiString
, NULL
);
2027 AnsiString
.Buffer
= lpData
;
2028 AnsiString
.MaximumLength
= *lpcbData
;
2029 RtlUnicodeStringToAnsiString(&AnsiString
, &ValueData
, FALSE
);
2031 RtlMoveMemory(lpData
, ValueData
.Buffer
, ResultSize
);
2035 *lpcbData
= ResultSize
;
2037 if (ValueData
.Buffer
) {
2038 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData
.Buffer
);
2044 /************************************************************************
2050 RegQueryValueA (HKEY hKey
,
2055 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2056 UNICODE_STRING SubKeyName
;
2057 UNICODE_STRING Value
;
2058 ANSI_STRING AnsiString
;
2062 if (lpValue
!= NULL
&&
2065 SetLastError(ERROR_INVALID_PARAMETER
);
2066 return ERROR_INVALID_PARAMETER
;
2069 RtlInitUnicodeString (&SubKeyName
,
2071 RtlInitUnicodeString (&Value
,
2073 if (lpSubKey
!= NULL
&&
2074 strlen(lpSubKey
) != 0)
2076 RtlInitAnsiString (&AnsiString
,
2078 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2079 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2080 RtlAnsiStringToUnicodeString (&SubKeyName
,
2085 if (lpValue
!= NULL
)
2087 ValueSize
= *lpcbValue
* sizeof(WCHAR
);
2088 Value
.MaximumLength
= ValueSize
;
2089 Value
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
2092 if (Value
.Buffer
== NULL
)
2094 SetLastError(ERROR_OUTOFMEMORY
);
2095 return ERROR_OUTOFMEMORY
;
2103 ErrorCode
= RegQueryValueW (hKey
,
2104 (LPCWSTR
)SubKeyName
.Buffer
,
2107 if (ErrorCode
== ERROR_SUCCESS
)
2109 Value
.Length
= ValueSize
;
2110 RtlInitAnsiString (&AnsiString
,
2112 AnsiString
.Buffer
= lpValue
;
2113 AnsiString
.MaximumLength
= *lpcbValue
;
2114 RtlUnicodeStringToAnsiString (&AnsiString
,
2119 *lpcbValue
= ValueSize
;
2120 if (Value
.Buffer
!= NULL
)
2122 RtlFreeHeap (RtlGetProcessHeap (),
2131 /************************************************************************
2137 RegQueryValueW (HKEY hKey
,
2142 OBJECT_ATTRIBUTES ObjectAttributes
;
2143 UNICODE_STRING SubKeyString
;
2150 Status
= MapDefaultKey (&KeyHandle
,
2152 if (!NT_SUCCESS(Status
))
2154 ErrorCode
= RtlNtStatusToDosError (Status
);
2155 SetLastError (ErrorCode
);
2159 if (lpSubKey
!= NULL
&&
2160 wcslen(lpSubKey
) != 0)
2162 RtlInitUnicodeString (&SubKeyString
,
2164 InitializeObjectAttributes (&ObjectAttributes
,
2166 OBJ_CASE_INSENSITIVE
,
2169 Status
= NtOpenKey (&RealKey
,
2172 if (!NT_SUCCESS(Status
))
2174 ErrorCode
= RtlNtStatusToDosError (Status
);
2175 SetLastError (ErrorCode
);
2178 CloseRealKey
= TRUE
;
2183 CloseRealKey
= FALSE
;
2186 ErrorCode
= RegQueryValueExW (RealKey
,
2191 (LPDWORD
)lpcbValue
);
2201 /************************************************************************
2207 RegReplaceKeyA (HKEY hKey
,
2212 UNICODE_STRING lpSubKeyW
;
2213 UNICODE_STRING lpNewFileW
;
2214 UNICODE_STRING lpOldFileW
;
2217 RtlCreateUnicodeStringFromAsciiz( &lpSubKeyW
, (PCSZ
)lpSubKey
);
2218 RtlCreateUnicodeStringFromAsciiz( &lpOldFileW
, (PCSZ
)lpOldFile
);
2219 RtlCreateUnicodeStringFromAsciiz( &lpNewFileW
, (PCSZ
)lpNewFile
);
2220 ret
= RegReplaceKeyW( hKey
, lpSubKeyW
.Buffer
, lpNewFileW
.Buffer
, lpOldFileW
.Buffer
);
2221 RtlFreeUnicodeString( &lpOldFileW
);
2222 RtlFreeUnicodeString( &lpNewFileW
);
2223 RtlFreeUnicodeString( &lpSubKeyW
);
2228 /************************************************************************
2234 RegReplaceKeyW (HKEY hKey
,
2240 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2241 return ERROR_CALL_NOT_IMPLEMENTED
;
2245 /************************************************************************
2251 RegRestoreKeyA (HKEY hKey
,
2255 UNICODE_STRING lpFileW
;
2258 RtlCreateUnicodeStringFromAsciiz( &lpFileW
, (PCSZ
)lpFile
);
2259 ret
= RegRestoreKeyW( hKey
, lpFileW
.Buffer
, dwFlags
);
2260 RtlFreeUnicodeString( &lpFileW
);
2265 /************************************************************************
2271 RegRestoreKeyW (HKEY hKey
,
2276 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2277 return ERROR_CALL_NOT_IMPLEMENTED
;
2281 /************************************************************************
2287 RegSaveKeyA(HKEY hKey
,
2289 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2291 UNICODE_STRING FileName
;
2294 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2296 ErrorCode
= RegSaveKeyW (hKey
,
2298 lpSecurityAttributes
);
2299 RtlFreeUnicodeString (&FileName
);
2305 /************************************************************************
2311 RegSaveKeyW (HKEY hKey
,
2313 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2315 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
2316 OBJECT_ATTRIBUTES ObjectAttributes
;
2317 UNICODE_STRING NtName
;
2318 IO_STATUS_BLOCK IoStatusBlock
;
2324 Status
= MapDefaultKey (&KeyHandle
,
2326 if (!NT_SUCCESS(Status
))
2328 ErrorCode
= RtlNtStatusToDosError (Status
);
2329 SetLastError (ErrorCode
);
2333 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
2338 SetLastError (ERROR_INVALID_PARAMETER
);
2339 return ERROR_INVALID_PARAMETER
;
2342 if (lpSecurityAttributes
!= NULL
)
2344 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
2347 InitializeObjectAttributes (&ObjectAttributes
,
2349 OBJ_CASE_INSENSITIVE
,
2351 SecurityDescriptor
);
2352 Status
= NtCreateFile (&FileHandle
,
2353 GENERIC_WRITE
| SYNCHRONIZE
,
2357 FILE_ATTRIBUTE_NORMAL
,
2360 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT
,
2363 RtlFreeUnicodeString (&NtName
);
2364 if (!NT_SUCCESS(Status
))
2366 ErrorCode
= RtlNtStatusToDosError (Status
);
2367 SetLastError (ErrorCode
);
2371 Status
= NtSaveKey (KeyHandle
,
2373 NtClose (FileHandle
);
2374 if (!NT_SUCCESS(Status
))
2376 ErrorCode
= RtlNtStatusToDosError (Status
);
2377 SetLastError (ErrorCode
);
2381 return ERROR_SUCCESS
;
2385 /************************************************************************
2391 RegSetKeySecurity (HKEY hKey
,
2392 SECURITY_INFORMATION SecurityInformation
,
2393 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
2399 if (hKey
== HKEY_PERFORMANCE_DATA
)
2400 return ERROR_INVALID_HANDLE
;
2402 Status
= MapDefaultKey (&KeyHandle
,
2404 if (!NT_SUCCESS(Status
))
2406 ErrorCode
= RtlNtStatusToDosError (Status
);
2407 SetLastError (ErrorCode
);
2411 Status
= NtSetSecurityObject (KeyHandle
,
2412 SecurityInformation
,
2413 pSecurityDescriptor
);
2414 if (!NT_SUCCESS(Status
))
2416 ErrorCode
= RtlNtStatusToDosError (Status
);
2417 SetLastError (ErrorCode
);
2421 return ERROR_SUCCESS
;
2425 /************************************************************************
2431 RegSetValueExA (HKEY hKey
,
2438 UNICODE_STRING ValueName
;
2440 ANSI_STRING AnsiString
;
2441 UNICODE_STRING Data
;
2448 SetLastError (ERROR_INVALID_PARAMETER
);
2449 return ERROR_INVALID_PARAMETER
;
2452 if (lpValueName
!= NULL
&&
2453 strlen(lpValueName
) != 0)
2455 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
2456 (LPSTR
)lpValueName
);
2457 pValueName
= (LPWSTR
)ValueName
.Buffer
;
2464 if ((dwType
== REG_SZ
) ||
2465 (dwType
== REG_MULTI_SZ
) ||
2466 (dwType
== REG_EXPAND_SZ
))
2468 RtlInitAnsiString (&AnsiString
,
2470 AnsiString
.Buffer
= (LPSTR
)lpData
;
2471 AnsiString
.Length
= cbData
;
2472 AnsiString
.MaximumLength
= cbData
;
2473 RtlAnsiStringToUnicodeString (&Data
,
2476 pData
= (LPBYTE
)Data
.Buffer
;
2477 DataSize
= cbData
* sizeof(WCHAR
);
2481 RtlInitUnicodeString (&Data
,
2483 pData
= (LPBYTE
)lpData
;
2487 ErrorCode
= RegSetValueExW (hKey
,
2493 if (pValueName
!= NULL
)
2495 RtlFreeHeap (RtlGetProcessHeap (),
2500 if (Data
.Buffer
!= NULL
)
2502 RtlFreeHeap (RtlGetProcessHeap (),
2511 /************************************************************************
2517 RegSetValueExW (HKEY hKey
,
2518 LPCWSTR lpValueName
,
2524 UNICODE_STRING ValueName
;
2525 PUNICODE_STRING pValueName
;
2530 Status
= MapDefaultKey (&KeyHandle
,
2532 if (!NT_SUCCESS(Status
))
2534 ErrorCode
= RtlNtStatusToDosError (Status
);
2535 SetLastError (ErrorCode
);
2539 if (lpValueName
!= NULL
)
2541 RtlInitUnicodeString (&ValueName
,
2543 pValueName
= &ValueName
;
2550 Status
= NtSetValueKey (KeyHandle
,
2556 if (!NT_SUCCESS(Status
))
2558 ErrorCode
= RtlNtStatusToDosError (Status
);
2559 SetLastError (ErrorCode
);
2563 return ERROR_SUCCESS
;
2567 /************************************************************************
2573 RegSetValueA (HKEY hKey
,
2579 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2580 UNICODE_STRING SubKeyName
;
2581 UNICODE_STRING Data
;
2582 ANSI_STRING AnsiString
;
2588 SetLastError (ERROR_INVALID_PARAMETER
);
2589 return ERROR_INVALID_PARAMETER
;
2592 RtlInitUnicodeString (&SubKeyName
, NULL
);
2593 RtlInitUnicodeString (&Data
, NULL
);
2594 if (lpSubKey
!= NULL
&& (strlen(lpSubKey
) != 0))
2596 RtlInitAnsiString (&AnsiString
, (LPSTR
)lpSubKey
);
2597 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2598 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2599 RtlAnsiStringToUnicodeString (&SubKeyName
, &AnsiString
, FALSE
);
2602 DataSize
= cbData
* sizeof(WCHAR
);
2603 Data
.MaximumLength
= DataSize
;
2604 Data
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
2607 if (Data
.Buffer
== NULL
)
2609 SetLastError (ERROR_OUTOFMEMORY
);
2610 return ERROR_OUTOFMEMORY
;
2613 ErrorCode
= RegSetValueW (hKey
,
2614 (LPCWSTR
)SubKeyName
.Buffer
,
2618 RtlFreeHeap (RtlGetProcessHeap (),
2626 /************************************************************************
2632 RegSetValueW (HKEY hKey
,
2638 OBJECT_ATTRIBUTES ObjectAttributes
;
2639 UNICODE_STRING SubKeyString
;
2646 Status
= MapDefaultKey (&KeyHandle
,
2648 if (!NT_SUCCESS(Status
))
2650 ErrorCode
= RtlNtStatusToDosError (Status
);
2651 SetLastError (ErrorCode
);
2655 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
2657 RtlInitUnicodeString (&SubKeyString
,
2659 InitializeObjectAttributes (&ObjectAttributes
,
2661 OBJ_CASE_INSENSITIVE
,
2664 Status
= NtOpenKey (&RealKey
,
2667 if (!NT_SUCCESS(Status
))
2669 ErrorCode
= RtlNtStatusToDosError (Status
);
2670 SetLastError (ErrorCode
);
2673 CloseRealKey
= TRUE
;
2678 CloseRealKey
= FALSE
;
2681 ErrorCode
= RegSetValueExW (RealKey
,
2687 if (CloseRealKey
== TRUE
)
2696 /************************************************************************
2702 RegUnLoadKeyA (HKEY hKey
,
2705 UNICODE_STRING KeyName
;
2708 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
2711 ErrorCode
= RegUnLoadKeyW (hKey
,
2714 RtlFreeUnicodeString (&KeyName
);
2720 /************************************************************************
2726 RegUnLoadKeyW (HKEY hKey
,
2729 OBJECT_ATTRIBUTES ObjectAttributes
;
2730 UNICODE_STRING KeyName
;
2735 if (hKey
== HKEY_PERFORMANCE_DATA
)
2736 return ERROR_INVALID_HANDLE
;
2738 Status
= MapDefaultKey (&KeyHandle
, hKey
);
2739 if (!NT_SUCCESS(Status
))
2741 ErrorCode
= RtlNtStatusToDosError (Status
);
2742 SetLastError (ErrorCode
);
2746 RtlInitUnicodeString (&KeyName
,
2749 InitializeObjectAttributes (&ObjectAttributes
,
2751 OBJ_CASE_INSENSITIVE
,
2755 Status
= NtUnloadKey (&ObjectAttributes
);
2757 if (!NT_SUCCESS(Status
))
2759 ErrorCode
= RtlNtStatusToDosError (Status
);
2760 SetLastError (ErrorCode
);
2764 return ERROR_SUCCESS
;