1 /* $Id: reg.c,v 1.26 2003/07/12 00:03:42 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 *****************************************************************/
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 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1825 return ERROR_CALL_NOT_IMPLEMENTED
;
1829 /************************************************************************
1835 RegQueryValueExW (HKEY hKey
,
1836 LPCWSTR lpValueName
,
1842 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
1843 UNICODE_STRING ValueName
;
1845 LONG ErrorCode
= ERROR_SUCCESS
;
1850 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
1851 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
1853 Status
= MapDefaultKey (&KeyHandle
,
1855 if (!NT_SUCCESS(Status
))
1857 ErrorCode
= RtlNtStatusToDosError (Status
);
1858 SetLastError (ErrorCode
);
1862 if (lpData
!= NULL
&& lpcbData
== NULL
)
1864 SetLastError (ERROR_INVALID_PARAMETER
);
1865 return ERROR_INVALID_PARAMETER
;
1868 RtlInitUnicodeString (&ValueName
,
1870 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + *lpcbData
;
1871 ValueInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
1874 if (ValueInfo
== NULL
)
1876 SetLastError(ERROR_OUTOFMEMORY
);
1877 return ERROR_OUTOFMEMORY
;
1880 Status
= NtQueryValueKey (hKey
,
1882 KeyValuePartialInformation
,
1886 DPRINT("Status 0x%X\n", Status
);
1887 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1889 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
1890 ErrorCode
= ERROR_SUCCESS
;
1892 else if (!NT_SUCCESS(Status
))
1894 ErrorCode
= RtlNtStatusToDosError (Status
);
1895 SetLastError (ErrorCode
);
1901 *lpType
= ValueInfo
->Type
;
1903 RtlMoveMemory (lpData
,
1905 ValueInfo
->DataLength
);
1906 if ((ValueInfo
->Type
== REG_SZ
) ||
1907 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
1908 (ValueInfo
->Type
== REG_EXPAND_SZ
))
1910 ((PWSTR
)lpData
)[ValueInfo
->DataLength
/ sizeof(WCHAR
)] = 0;
1913 DPRINT("Type %d Size %d\n", ValueInfo
->Type
, ValueInfo
->DataLength
);
1915 if (NULL
!= lpcbData
)
1917 *lpcbData
= (DWORD
)ValueInfo
->DataLength
;
1919 RtlFreeHeap (RtlGetProcessHeap (),
1927 /************************************************************************
1942 WCHAR ValueNameBuffer
[MAX_PATH
+1];
1943 UNICODE_STRING ValueName
;
1944 UNICODE_STRING ValueData
;
1945 ANSI_STRING AnsiString
;
1950 /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
1952 if ((lpData
) && (!lpcbData
)) {
1953 SetLastError(ERROR_INVALID_PARAMETER
);
1954 return ERROR_INVALID_PARAMETER
;
1956 RtlInitUnicodeString(&ValueData
, NULL
);
1958 ValueData
.MaximumLength
= *lpcbData
* sizeof(WCHAR
);
1959 ValueData
.Buffer
= RtlAllocateHeap(
1960 RtlGetProcessHeap(),
1962 ValueData
.MaximumLength
);
1963 if (!ValueData
.Buffer
) {
1964 SetLastError(ERROR_OUTOFMEMORY
);
1965 return ERROR_OUTOFMEMORY
;
1968 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpValueName
);
1969 RtlInitUnicodeString(&ValueName
, NULL
);
1970 ValueName
.Buffer
= &ValueNameBuffer
[0];
1971 ValueName
.MaximumLength
= sizeof(ValueNameBuffer
);
1972 RtlAnsiStringToUnicodeString(&ValueName
, &AnsiString
, FALSE
);
1974 ResultSize
= *lpcbData
;
1978 ErrorCode
= RegQueryValueExW(
1983 (LPBYTE
)ValueData
.Buffer
,
1985 if ((ErrorCode
== ERROR_SUCCESS
) && (ValueData
.Buffer
!= NULL
)) {
1989 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
)) {
1990 ValueData
.Length
= ResultSize
;
1991 RtlInitAnsiString(&AnsiString
, NULL
);
1992 AnsiString
.Buffer
= lpData
;
1993 AnsiString
.MaximumLength
= *lpcbData
;
1994 RtlUnicodeStringToAnsiString(&AnsiString
, &ValueData
, FALSE
);
1996 RtlMoveMemory(lpData
, ValueData
.Buffer
, ResultSize
);
2000 *lpcbData
= ResultSize
;
2002 if (ValueData
.Buffer
) {
2003 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData
.Buffer
);
2009 /************************************************************************
2015 RegQueryValueA (HKEY hKey
,
2020 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2021 UNICODE_STRING SubKeyName
;
2022 UNICODE_STRING Value
;
2023 ANSI_STRING AnsiString
;
2027 if (lpValue
!= NULL
&&
2030 SetLastError(ERROR_INVALID_PARAMETER
);
2031 return ERROR_INVALID_PARAMETER
;
2034 RtlInitUnicodeString (&SubKeyName
,
2036 RtlInitUnicodeString (&Value
,
2038 if (lpSubKey
!= NULL
&&
2039 strlen(lpSubKey
) != 0)
2041 RtlInitAnsiString (&AnsiString
,
2043 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2044 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2045 RtlAnsiStringToUnicodeString (&SubKeyName
,
2050 if (lpValue
!= NULL
)
2052 ValueSize
= *lpcbValue
* sizeof(WCHAR
);
2053 Value
.MaximumLength
= ValueSize
;
2054 Value
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
2057 if (Value
.Buffer
== NULL
)
2059 SetLastError(ERROR_OUTOFMEMORY
);
2060 return ERROR_OUTOFMEMORY
;
2068 ErrorCode
= RegQueryValueW (hKey
,
2069 (LPCWSTR
)SubKeyName
.Buffer
,
2072 if (ErrorCode
== ERROR_SUCCESS
)
2074 Value
.Length
= ValueSize
;
2075 RtlInitAnsiString (&AnsiString
,
2077 AnsiString
.Buffer
= lpValue
;
2078 AnsiString
.MaximumLength
= *lpcbValue
;
2079 RtlUnicodeStringToAnsiString (&AnsiString
,
2084 *lpcbValue
= ValueSize
;
2085 if (Value
.Buffer
!= NULL
)
2087 RtlFreeHeap (RtlGetProcessHeap (),
2096 /************************************************************************
2102 RegQueryValueW (HKEY hKey
,
2107 OBJECT_ATTRIBUTES ObjectAttributes
;
2108 UNICODE_STRING SubKeyString
;
2115 Status
= MapDefaultKey (&KeyHandle
,
2117 if (!NT_SUCCESS(Status
))
2119 ErrorCode
= RtlNtStatusToDosError (Status
);
2120 SetLastError (ErrorCode
);
2124 if (lpSubKey
!= NULL
&&
2125 wcslen(lpSubKey
) != 0)
2127 RtlInitUnicodeString (&SubKeyString
,
2129 InitializeObjectAttributes (&ObjectAttributes
,
2131 OBJ_CASE_INSENSITIVE
,
2134 Status
= NtOpenKey (&RealKey
,
2137 if (!NT_SUCCESS(Status
))
2139 ErrorCode
= RtlNtStatusToDosError (Status
);
2140 SetLastError (ErrorCode
);
2143 CloseRealKey
= TRUE
;
2148 CloseRealKey
= FALSE
;
2151 ErrorCode
= RegQueryValueExW (RealKey
,
2156 (LPDWORD
)lpcbValue
);
2166 /************************************************************************
2172 RegReplaceKeyA (HKEY hKey
,
2178 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2179 return ERROR_CALL_NOT_IMPLEMENTED
;
2183 /************************************************************************
2189 RegReplaceKeyW (HKEY hKey
,
2195 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2196 return ERROR_CALL_NOT_IMPLEMENTED
;
2200 /************************************************************************
2206 RegRestoreKeyA (HKEY hKey
,
2211 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2212 return ERROR_CALL_NOT_IMPLEMENTED
;
2216 /************************************************************************
2222 RegRestoreKeyW (HKEY hKey
,
2227 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2228 return ERROR_CALL_NOT_IMPLEMENTED
;
2232 /************************************************************************
2238 RegSaveKeyA(HKEY hKey
,
2240 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2242 UNICODE_STRING FileName
;
2245 RtlCreateUnicodeStringFromAsciiz (&FileName
,
2247 ErrorCode
= RegSaveKeyW (hKey
,
2249 lpSecurityAttributes
);
2250 RtlFreeUnicodeString (&FileName
);
2256 /************************************************************************
2262 RegSaveKeyW (HKEY hKey
,
2264 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2266 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
2267 OBJECT_ATTRIBUTES ObjectAttributes
;
2268 UNICODE_STRING NtName
;
2269 IO_STATUS_BLOCK IoStatusBlock
;
2275 Status
= MapDefaultKey (&KeyHandle
,
2277 if (!NT_SUCCESS(Status
))
2279 ErrorCode
= RtlNtStatusToDosError (Status
);
2280 SetLastError (ErrorCode
);
2284 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFile
,
2289 SetLastError (ERROR_INVALID_PARAMETER
);
2290 return ERROR_INVALID_PARAMETER
;
2293 if (lpSecurityAttributes
!= NULL
)
2295 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
2298 InitializeObjectAttributes (&ObjectAttributes
,
2300 OBJ_CASE_INSENSITIVE
,
2302 SecurityDescriptor
);
2303 Status
= NtCreateFile (&FileHandle
,
2304 GENERIC_WRITE
| SYNCHRONIZE
,
2308 FILE_ATTRIBUTE_NORMAL
,
2311 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT
,
2314 RtlFreeUnicodeString (&NtName
);
2315 if (!NT_SUCCESS(Status
))
2317 ErrorCode
= RtlNtStatusToDosError (Status
);
2318 SetLastError (ErrorCode
);
2322 Status
= NtSaveKey (KeyHandle
,
2324 NtClose (FileHandle
);
2325 if (!NT_SUCCESS(Status
))
2327 ErrorCode
= RtlNtStatusToDosError (Status
);
2328 SetLastError (ErrorCode
);
2332 return ERROR_SUCCESS
;
2336 /************************************************************************
2342 RegSetKeySecurity (HKEY hKey
,
2343 SECURITY_INFORMATION SecurityInformation
,
2344 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
2350 if (hKey
== HKEY_PERFORMANCE_DATA
)
2351 return ERROR_INVALID_HANDLE
;
2353 Status
= MapDefaultKey (&KeyHandle
,
2355 if (!NT_SUCCESS(Status
))
2357 ErrorCode
= RtlNtStatusToDosError (Status
);
2358 SetLastError (ErrorCode
);
2362 Status
= NtSetSecurityObject (KeyHandle
,
2363 SecurityInformation
,
2364 pSecurityDescriptor
);
2365 if (!NT_SUCCESS(Status
))
2367 ErrorCode
= RtlNtStatusToDosError (Status
);
2368 SetLastError (ErrorCode
);
2372 return ERROR_SUCCESS
;
2376 /************************************************************************
2382 RegSetValueExA (HKEY hKey
,
2389 UNICODE_STRING ValueName
;
2391 ANSI_STRING AnsiString
;
2392 UNICODE_STRING Data
;
2399 SetLastError (ERROR_INVALID_PARAMETER
);
2400 return ERROR_INVALID_PARAMETER
;
2403 if (lpValueName
!= NULL
&&
2404 strlen(lpValueName
) != 0)
2406 RtlCreateUnicodeStringFromAsciiz (&ValueName
,
2407 (LPSTR
)lpValueName
);
2408 pValueName
= (LPWSTR
)ValueName
.Buffer
;
2415 if ((dwType
== REG_SZ
) ||
2416 (dwType
== REG_MULTI_SZ
) ||
2417 (dwType
== REG_EXPAND_SZ
))
2419 RtlInitAnsiString (&AnsiString
,
2421 AnsiString
.Buffer
= (LPSTR
)lpData
;
2422 AnsiString
.Length
= cbData
;
2423 AnsiString
.MaximumLength
= cbData
;
2424 RtlAnsiStringToUnicodeString (&Data
,
2427 pData
= (LPBYTE
)Data
.Buffer
;
2428 DataSize
= cbData
* sizeof(WCHAR
);
2432 RtlInitUnicodeString (&Data
,
2434 pData
= (LPBYTE
)lpData
;
2438 ErrorCode
= RegSetValueExW (hKey
,
2444 if (pValueName
!= NULL
)
2446 RtlFreeHeap (RtlGetProcessHeap (),
2451 if (Data
.Buffer
!= NULL
)
2453 RtlFreeHeap (RtlGetProcessHeap (),
2462 /************************************************************************
2468 RegSetValueExW (HKEY hKey
,
2469 LPCWSTR lpValueName
,
2475 UNICODE_STRING ValueName
;
2476 PUNICODE_STRING pValueName
;
2481 Status
= MapDefaultKey (&KeyHandle
,
2483 if (!NT_SUCCESS(Status
))
2485 ErrorCode
= RtlNtStatusToDosError (Status
);
2486 SetLastError (ErrorCode
);
2490 if (lpValueName
!= NULL
)
2492 RtlInitUnicodeString (&ValueName
,
2494 pValueName
= &ValueName
;
2501 Status
= NtSetValueKey (KeyHandle
,
2507 if (!NT_SUCCESS(Status
))
2509 ErrorCode
= RtlNtStatusToDosError (Status
);
2510 SetLastError (ErrorCode
);
2514 return ERROR_SUCCESS
;
2518 /************************************************************************
2524 RegSetValueA (HKEY hKey
,
2530 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2531 UNICODE_STRING SubKeyName
;
2532 UNICODE_STRING Data
;
2533 ANSI_STRING AnsiString
;
2539 SetLastError (ERROR_INVALID_PARAMETER
);
2540 return ERROR_INVALID_PARAMETER
;
2543 RtlInitUnicodeString (&SubKeyName
, NULL
);
2544 RtlInitUnicodeString (&Data
, NULL
);
2545 if (lpSubKey
!= NULL
&& (strlen(lpSubKey
) != 0))
2547 RtlInitAnsiString (&AnsiString
, (LPSTR
)lpSubKey
);
2548 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2549 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2550 RtlAnsiStringToUnicodeString (&SubKeyName
, &AnsiString
, FALSE
);
2553 DataSize
= cbData
* sizeof(WCHAR
);
2554 Data
.MaximumLength
= DataSize
;
2555 Data
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
2558 if (Data
.Buffer
== NULL
)
2560 SetLastError (ERROR_OUTOFMEMORY
);
2561 return ERROR_OUTOFMEMORY
;
2564 ErrorCode
= RegSetValueW (hKey
,
2565 (LPCWSTR
)SubKeyName
.Buffer
,
2569 RtlFreeHeap (RtlGetProcessHeap (),
2577 /************************************************************************
2583 RegSetValueW (HKEY hKey
,
2589 OBJECT_ATTRIBUTES ObjectAttributes
;
2590 UNICODE_STRING SubKeyString
;
2597 Status
= MapDefaultKey (&KeyHandle
,
2599 if (!NT_SUCCESS(Status
))
2601 ErrorCode
= RtlNtStatusToDosError (Status
);
2602 SetLastError (ErrorCode
);
2606 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
2608 RtlInitUnicodeString (&SubKeyString
,
2610 InitializeObjectAttributes (&ObjectAttributes
,
2612 OBJ_CASE_INSENSITIVE
,
2615 Status
= NtOpenKey (&RealKey
,
2618 if (!NT_SUCCESS(Status
))
2620 ErrorCode
= RtlNtStatusToDosError (Status
);
2621 SetLastError (ErrorCode
);
2624 CloseRealKey
= TRUE
;
2629 CloseRealKey
= FALSE
;
2632 ErrorCode
= RegSetValueExW (RealKey
,
2638 if (CloseRealKey
== TRUE
)
2647 /************************************************************************
2653 RegUnLoadKeyA (HKEY hKey
,
2656 UNICODE_STRING KeyName
;
2659 RtlCreateUnicodeStringFromAsciiz (&KeyName
,
2662 ErrorCode
= RegUnLoadKeyW (hKey
,
2665 RtlFreeUnicodeString (&KeyName
);
2671 /************************************************************************
2677 RegUnLoadKeyW (HKEY hKey
,
2680 OBJECT_ATTRIBUTES ObjectAttributes
;
2681 UNICODE_STRING KeyName
;
2686 if (hKey
== HKEY_PERFORMANCE_DATA
)
2687 return ERROR_INVALID_HANDLE
;
2689 Status
= MapDefaultKey (&KeyHandle
, hKey
);
2690 if (!NT_SUCCESS(Status
))
2692 ErrorCode
= RtlNtStatusToDosError (Status
);
2693 SetLastError (ErrorCode
);
2697 RtlInitUnicodeString (&KeyName
,
2700 InitializeObjectAttributes (&ObjectAttributes
,
2702 OBJ_CASE_INSENSITIVE
,
2706 Status
= NtUnloadKey (&ObjectAttributes
);
2708 if (!NT_SUCCESS(Status
))
2710 ErrorCode
= RtlNtStatusToDosError (Status
);
2711 SetLastError (ErrorCode
);
2715 return ERROR_SUCCESS
;