1 /* $Id: reg.c,v 1.14 2001/09/03 23:11:59 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)
12 #include <ddk/ntddk.h>
13 #include <ntdll/rtl.h>
20 #define CHECK_STATUS \
22 if (!NT_SUCCESS(Status)) \
24 LONG _ErrorCode = RtlNtStatusToDosError(Status); \
25 SetLastError(_ErrorCode); \
30 /* GLOBALS *******************************************************************/
32 #define MAX_DEFAULT_HANDLES 6
34 static CRITICAL_SECTION HandleTableCS
;
35 static HANDLE DefaultHandleTable
[MAX_DEFAULT_HANDLES
];
38 /* PROTOTYPES ****************************************************************/
40 static NTSTATUS
MapDefaultKey (PHKEY ParentKey
, HKEY Key
);
41 static VOID
CloseDefaultKeys(VOID
);
43 static NTSTATUS
OpenClassesRootKey(PHANDLE KeyHandle
);
44 static NTSTATUS
OpenLocalMachineKey (PHANDLE KeyHandle
);
45 static NTSTATUS
OpenUsersKey (PHANDLE KeyHandle
);
46 static NTSTATUS
OpenCurrentConfigKey(PHANDLE KeyHandle
);
49 /* FUNCTIONS *****************************************************************/
51 inline RegiTerminateWideString(LPWSTR String
, DWORD Length
)
53 LPWSTR AfterString
= String
+ Length
;
57 /************************************************************************
58 * RegInitDefaultHandles
64 DPRINT("RegInitialize()\n");
66 RtlZeroMemory (DefaultHandleTable
,
67 MAX_DEFAULT_HANDLES
* sizeof(HANDLE
));
69 RtlInitializeCriticalSection(&HandleTableCS
);
74 /************************************************************************
80 DPRINT("RegCleanup()\n");
83 RtlDeleteCriticalSection(&HandleTableCS
);
89 MapDefaultKey(PHKEY RealKey
,
94 NTSTATUS Status
= STATUS_SUCCESS
;
96 DPRINT("MapDefaultKey (Key %x)\n", Key
);
98 if (((ULONG
)Key
& 0xF0000000) != 0x80000000)
101 return STATUS_SUCCESS
;
104 /* Handle special cases here */
105 Index
= (ULONG
)Key
& 0x0FFFFFFF;
107 if (Index
>= MAX_DEFAULT_HANDLES
)
108 return STATUS_INVALID_PARAMETER
;
110 RtlEnterCriticalSection(&HandleTableCS
);
112 Handle
= &DefaultHandleTable
[Index
];
115 /* create/open the default handle */
118 case 0: /* HKEY_CLASSES_ROOT */
119 Status
= OpenClassesRootKey(Handle
);
122 case 1: /* HKEY_CURRENT_USER */
123 Status
= RtlOpenCurrentUser(KEY_ALL_ACCESS
,
127 case 2: /* HKEY_LOCAL_MACHINE */
128 Status
= OpenLocalMachineKey(Handle
);
131 case 3: /* HKEY_USERS */
132 Status
= OpenUsersKey(Handle
);
135 case 4: /* HKEY_PERFORMANCE_DATA */
136 Status
= OpenPerformanceDataKey(Handle
);
139 case 5: /* HKEY_CURRENT_CONFIG */
140 Status
= OpenCurrentConfigKey(Handle
);
144 DPRINT("MapDefaultHandle() no handle creator\n");
145 Status
= STATUS_INVALID_PARAMETER
;
149 RtlLeaveCriticalSection(&HandleTableCS
);
151 if (NT_SUCCESS(Status
))
153 *RealKey
= (HKEY
)*Handle
;
161 CloseDefaultKeys(VOID
)
165 RtlEnterCriticalSection(&HandleTableCS
);
167 for (i
= 0; i
< MAX_DEFAULT_HANDLES
; i
++)
169 if (DefaultHandleTable
[i
] != NULL
)
171 NtClose (DefaultHandleTable
[i
]);
172 DefaultHandleTable
[i
] = NULL
;
176 RtlLeaveCriticalSection(&HandleTableCS
);
181 OpenClassesRootKey(PHANDLE KeyHandle
)
183 OBJECT_ATTRIBUTES Attributes
;
184 UNICODE_STRING KeyName
;
186 DPRINT("OpenClassesRootKey()\n");
188 RtlInitUnicodeString(&KeyName
,
189 L
"\\Registry\\Machine\\Software\\CLASSES");
191 InitializeObjectAttributes(&Attributes
,
193 OBJ_CASE_INSENSITIVE
,
197 return(NtOpenKey(KeyHandle
,
204 OpenLocalMachineKey(PHANDLE KeyHandle
)
206 OBJECT_ATTRIBUTES Attributes
;
207 UNICODE_STRING KeyName
;
209 DPRINT("OpenLocalMachineKey()\n");
211 RtlInitUnicodeString(&KeyName
,
212 L
"\\Registry\\Machine");
214 InitializeObjectAttributes(&Attributes
,
216 OBJ_CASE_INSENSITIVE
,
220 return(NtOpenKey(KeyHandle
,
227 OpenUsersKey(PHANDLE KeyHandle
)
229 OBJECT_ATTRIBUTES Attributes
;
230 UNICODE_STRING KeyName
;
232 DPRINT("OpenUsersKey()\n");
234 RtlInitUnicodeString(&KeyName
,
235 L
"\\Registry\\User");
237 InitializeObjectAttributes(&Attributes
,
239 OBJ_CASE_INSENSITIVE
,
243 return(NtOpenKey(KeyHandle
,
250 OpenCurrentConfigKey(PHANDLE KeyHandle
)
252 OBJECT_ATTRIBUTES Attributes
;
253 UNICODE_STRING KeyName
;
255 DPRINT("OpenCurrentConfigKey()\n");
257 RtlInitUnicodeString(&KeyName
,
258 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
260 InitializeObjectAttributes(&Attributes
,
262 OBJ_CASE_INSENSITIVE
,
266 return(NtOpenKey(KeyHandle
,
271 /************************************************************************
275 RegCloseKey(HKEY hKey
)
279 /* don't close null handle or a pseudo handle */
280 if ((!hKey
) || (((ULONG
)hKey
& 0xF0000000) == 0x80000000))
281 return ERROR_INVALID_HANDLE
;
283 Status
= NtClose (hKey
);
284 if (!NT_SUCCESS(Status
))
286 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
288 SetLastError (ErrorCode
);
292 return ERROR_SUCCESS
;
296 /************************************************************************
297 * RegConnectRegistryA
300 RegConnectRegistryA(LPSTR lpMachineName
,
304 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
305 return ERROR_CALL_NOT_IMPLEMENTED
;
309 /************************************************************************
310 * RegConnectRegistryW
313 RegConnectRegistryW(LPWSTR lpMachineName
,
317 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
318 return ERROR_CALL_NOT_IMPLEMENTED
;
322 /************************************************************************
326 RegCreateKeyA(HKEY hKey
,
330 return(RegCreateKeyExA(hKey
,
342 /************************************************************************
346 RegCreateKeyW(HKEY hKey
,
350 return(RegCreateKeyExW(hKey
,
362 /************************************************************************
366 RegCreateKeyExA(HKEY hKey
,
372 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
374 LPDWORD lpdwDisposition
)
376 UNICODE_STRING SubKeyString
;
377 UNICODE_STRING ClassString
;
378 OBJECT_ATTRIBUTES Attributes
;
382 DPRINT("RegCreateKeyExW() called\n");
384 /* get the real parent key */
385 Status
= MapDefaultKey(&ParentKey
,
387 if (!NT_SUCCESS(Status
))
389 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
391 SetLastError(ErrorCode
);
395 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
398 RtlCreateUnicodeStringFromAsciiz(&ClassString
,
400 RtlCreateUnicodeStringFromAsciiz(&SubKeyString
,
403 InitializeObjectAttributes(&Attributes
,
405 OBJ_CASE_INSENSITIVE
,
407 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
409 Status
= NtCreateKey(phkResult
,
413 (lpClass
== NULL
)? NULL
: &ClassString
,
415 (PULONG
)lpdwDisposition
);
417 RtlFreeUnicodeString(&SubKeyString
);
419 RtlFreeUnicodeString(&ClassString
);
421 DPRINT("Status %x\n", Status
);
422 if (!NT_SUCCESS(Status
))
424 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
426 SetLastError (ErrorCode
);
430 return(ERROR_SUCCESS
);
434 /************************************************************************
438 RegCreateKeyExW(HKEY hKey
,
444 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
446 LPDWORD lpdwDisposition
)
448 UNICODE_STRING SubKeyString
;
449 UNICODE_STRING ClassString
;
450 OBJECT_ATTRIBUTES Attributes
;
454 DPRINT("RegCreateKeyExW() called\n");
456 /* get the real parent key */
457 Status
= MapDefaultKey (&ParentKey
, hKey
);
458 if (!NT_SUCCESS(Status
))
460 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
462 SetLastError (ErrorCode
);
466 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
468 RtlInitUnicodeString (&ClassString
, lpClass
);
469 RtlInitUnicodeString (&SubKeyString
, lpSubKey
);
471 InitializeObjectAttributes (&Attributes
,
473 OBJ_CASE_INSENSITIVE
,
475 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
477 Status
= NtCreateKey (phkResult
,
481 (lpClass
== NULL
)? NULL
: &ClassString
,
483 (PULONG
)lpdwDisposition
);
484 DPRINT("Status %x\n", Status
);
485 if (!NT_SUCCESS(Status
))
487 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
489 SetLastError (ErrorCode
);
493 return ERROR_SUCCESS
;
497 /************************************************************************
507 OBJECT_ATTRIBUTES ObjectAttributes
;
508 UNICODE_STRING SubKeyStringW
;
509 ANSI_STRING SubKeyStringA
;
515 Status
= MapDefaultKey(&ParentKey
,
517 if (!NT_SUCCESS(Status
))
519 ErrorCode
= RtlNtStatusToDosError(Status
);
521 SetLastError (ErrorCode
);
525 RtlInitAnsiString(&SubKeyStringA
,
527 RtlAnsiStringToUnicodeString(&SubKeyStringW
,
531 InitializeObjectAttributes (&ObjectAttributes
,
533 OBJ_CASE_INSENSITIVE
,
537 Status
= NtOpenKey (&TargetKey
,
541 RtlFreeUnicodeString (&SubKeyStringW
);
543 if (!NT_SUCCESS(Status
))
545 ErrorCode
= RtlNtStatusToDosError(Status
);
547 SetLastError (ErrorCode
);
551 Status
= NtDeleteKey(TargetKey
);
555 if (!NT_SUCCESS(Status
))
557 ErrorCode
= RtlNtStatusToDosError(Status
);
559 SetLastError (ErrorCode
);
562 return ERROR_SUCCESS
;
566 /************************************************************************
576 OBJECT_ATTRIBUTES ObjectAttributes
;
577 UNICODE_STRING SubKeyString
;
583 Status
= MapDefaultKey(&ParentKey
,
585 if (!NT_SUCCESS(Status
))
587 ErrorCode
= RtlNtStatusToDosError(Status
);
589 SetLastError (ErrorCode
);
593 RtlInitUnicodeString(&SubKeyString
,
596 InitializeObjectAttributes (&ObjectAttributes
,
598 OBJ_CASE_INSENSITIVE
,
602 Status
= NtOpenKey (&TargetKey
,
605 if (!NT_SUCCESS(Status
))
607 ErrorCode
= RtlNtStatusToDosError(Status
);
609 SetLastError (ErrorCode
);
613 Status
= NtDeleteKey(TargetKey
);
617 if (!NT_SUCCESS(Status
))
619 ErrorCode
= RtlNtStatusToDosError(Status
);
621 SetLastError (ErrorCode
);
624 return ERROR_SUCCESS
;
628 /************************************************************************
638 UNICODE_STRING ValueNameW
;
639 ANSI_STRING ValueNameA
;
644 Status
= MapDefaultKey(&KeyHandle
,
646 if (!NT_SUCCESS(Status
))
648 ErrorCode
= RtlNtStatusToDosError(Status
);
650 SetLastError (ErrorCode
);
654 RtlInitAnsiString(&ValueNameA
,
656 RtlAnsiStringToUnicodeString(&ValueNameW
,
660 Status
= NtDeleteValueKey(KeyHandle
,
663 RtlFreeUnicodeString (&ValueNameW
);
665 if (!NT_SUCCESS(Status
))
667 ErrorCode
= RtlNtStatusToDosError(Status
);
669 SetLastError (ErrorCode
);
673 return ERROR_SUCCESS
;
677 /************************************************************************
687 UNICODE_STRING ValueName
;
692 Status
= MapDefaultKey(&KeyHandle
,
694 if (!NT_SUCCESS(Status
))
696 ErrorCode
= RtlNtStatusToDosError(Status
);
698 SetLastError (ErrorCode
);
702 RtlInitUnicodeString(&ValueName
,
703 (LPWSTR
)lpValueName
);
705 Status
= NtDeleteValueKey(KeyHandle
,
707 if (!NT_SUCCESS(Status
))
709 ErrorCode
= RtlNtStatusToDosError(Status
);
711 SetLastError (ErrorCode
);
715 return ERROR_SUCCESS
;
719 /************************************************************************
731 DWORD dwLength
= cbName
;
733 return RegEnumKeyExA(hKey
,
744 /************************************************************************
757 PFILETIME lpftLastWriteTime
760 WCHAR Name
[MAX_PATH
+1];
761 UNICODE_STRING UnicodeStringName
;
762 WCHAR Class
[MAX_PATH
+1];
763 UNICODE_STRING UnicodeStringClass
;
764 ANSI_STRING AnsiString
;
769 DPRINT("hKey 0x%x dwIndex %d lpName 0x%x *lpcbName %d lpClass 0x%x lpcbClass %d\n",
770 hKey
, dwIndex
, lpName
, *lpcbName
, lpClass
, lpcbClass
);
772 if ((lpClass
) && (!lpcbClass
))
774 SetLastError(ERROR_INVALID_PARAMETER
);
775 return ERROR_INVALID_PARAMETER
;
778 RtlInitUnicodeString(&UnicodeStringName
, NULL
);
779 UnicodeStringName
.Buffer
= &Name
[0];
780 UnicodeStringName
.MaximumLength
= sizeof(Name
);
782 RtlInitUnicodeString(&UnicodeStringClass
, NULL
);
786 UnicodeStringClass
.Buffer
= &Class
[0];
787 UnicodeStringClass
.MaximumLength
= sizeof(Class
);
788 ClassLength
= *lpcbClass
;
795 NameLength
= *lpcbName
;
797 ErrorCode
= RegEnumKeyExW(
800 UnicodeStringName
.Buffer
,
803 UnicodeStringClass
.Buffer
,
807 if (ErrorCode
!= ERROR_SUCCESS
)
810 UnicodeStringName
.Length
= NameLength
* sizeof(WCHAR
);
811 UnicodeStringClass
.Length
= ClassLength
* sizeof(WCHAR
);
813 RtlInitAnsiString(&AnsiString
, NULL
);
814 AnsiString
.Buffer
= lpName
;
815 AnsiString
.MaximumLength
= *lpcbName
;
816 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeStringName
, FALSE
);
817 *lpcbName
= AnsiString
.Length
;
819 DPRINT("Key Namea0 Length %d\n", UnicodeStringName
.Length
);
820 DPRINT("Key Namea1 Length %d\n", NameLength
);
821 DPRINT("Key Namea Length %d\n", *lpcbName
);
822 DPRINT("Key Namea %s\n", lpName
);
826 RtlInitAnsiString(&AnsiString
, NULL
);
827 AnsiString
.Buffer
= lpClass
;
828 AnsiString
.MaximumLength
= *lpcbClass
;
829 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeStringClass
, FALSE
);
830 *lpcbClass
= AnsiString
.Length
;
833 return ERROR_SUCCESS
;
837 /************************************************************************
850 PFILETIME lpftLastWriteTime
853 PKEY_NODE_INFORMATION KeyInfo
;
855 DWORD dwError
= ERROR_SUCCESS
;
860 Status
= MapDefaultKey(&KeyHandle
, hKey
);
861 if (!NT_SUCCESS(Status
))
863 dwError
= RtlNtStatusToDosError(Status
);
864 SetLastError (dwError
);
868 BufferSize
= sizeof (KEY_NODE_INFORMATION
) + *lpcbName
* sizeof(WCHAR
);
870 BufferSize
+= *lpcbClass
;
871 KeyInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize
);
873 /* We don't know the exact size of the data returned, so call
874 NtEnumerateKey() with a buffer size determined from parameters
875 to this function. If that call fails with a status code of
876 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
878 KeyInfo
= RtlAllocateHeap(
884 SetLastError(ERROR_OUTOFMEMORY
);
885 return ERROR_OUTOFMEMORY
;
888 Status
= NtEnumerateKey(
896 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status
);
898 if (Status
== STATUS_BUFFER_OVERFLOW
)
900 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
901 BufferSize
= ResultSize
;
905 if (!NT_SUCCESS(Status
))
907 dwError
= RtlNtStatusToDosError(Status
);
908 SetLastError(dwError
);
913 if ((lpClass
) && (*lpcbClass
!= 0) && (KeyInfo
->ClassLength
> *lpcbClass
))
915 dwError
= ERROR_MORE_DATA
;
916 SetLastError(dwError
);
920 RtlMoveMemory(lpName
, KeyInfo
->Name
, KeyInfo
->NameLength
);
921 *lpcbName
= (DWORD
)(KeyInfo
->NameLength
/ sizeof(WCHAR
));
922 RegiTerminateWideString(lpName
, *lpcbName
);
926 RtlMoveMemory(lpClass
,
927 (PVOID
)((ULONG_PTR
)KeyInfo
->Name
+ KeyInfo
->ClassOffset
),
928 KeyInfo
->ClassLength
);
929 *lpcbClass
= (DWORD
)(KeyInfo
->ClassLength
/ sizeof(WCHAR
));
932 if (lpftLastWriteTime
)
934 /* FIXME: Fill lpftLastWriteTime */
941 RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo
);
947 /************************************************************************
959 DWORD dwLength
= cbName
;
961 return RegEnumKeyExW(hKey
,
972 /************************************************************************
981 LPDWORD lpcbValueName
,
988 WCHAR ValueName
[MAX_PATH
+1];
989 UNICODE_STRING UnicodeString
;
990 ANSI_STRING AnsiString
;
992 DWORD ValueNameLength
;
994 RtlInitUnicodeString(&UnicodeString
, NULL
);
995 UnicodeString
.Buffer
= &ValueName
[0];
996 UnicodeString
.MaximumLength
= sizeof(ValueName
);
998 ValueNameLength
= *lpcbValueName
;
1000 ErrorCode
= RegEnumValueW(
1003 UnicodeString
.Buffer
,
1010 if (ErrorCode
!= ERROR_SUCCESS
)
1013 UnicodeString
.Length
= ValueNameLength
* sizeof(WCHAR
);
1015 RtlInitAnsiString(&AnsiString
, NULL
);
1016 AnsiString
.Buffer
= lpValueName
;
1017 AnsiString
.MaximumLength
= *lpcbValueName
;
1018 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeString
, FALSE
);
1019 *lpcbValueName
= AnsiString
.Length
;
1021 return ERROR_SUCCESS
;
1025 /************************************************************************
1034 LPDWORD lpcbValueName
,
1041 PKEY_VALUE_FULL_INFORMATION ValueInfo
;
1043 DWORD dwError
= ERROR_SUCCESS
;
1048 Status
= MapDefaultKey(&KeyHandle
, hKey
);
1049 if (!NT_SUCCESS(Status
))
1051 dwError
= RtlNtStatusToDosError(Status
);
1052 SetLastError(dwError
);
1056 BufferSize
= sizeof (KEY_VALUE_FULL_INFORMATION
) +
1057 *lpcbValueName
* sizeof(WCHAR
);
1059 BufferSize
+= *lpcbData
;
1061 /* We don't know the exact size of the data returned, so call
1062 NtEnumerateValueKey() with a buffer size determined from parameters
1063 to this function. If that call fails with a status code of
1064 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
1066 ValueInfo
= RtlAllocateHeap(
1067 RtlGetProcessHeap(),
1070 if (ValueInfo
== NULL
)
1072 SetLastError(ERROR_OUTOFMEMORY
);
1073 return ERROR_OUTOFMEMORY
;
1076 Status
= NtEnumerateValueKey(
1079 KeyValueFullInformation
,
1084 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status
);
1086 if (Status
== STATUS_BUFFER_OVERFLOW
)
1088 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo
);
1089 BufferSize
= ResultSize
;
1093 if (!NT_SUCCESS(Status
))
1095 dwError
= RtlNtStatusToDosError(Status
);
1096 SetLastError(dwError
);
1101 if ((lpData
) && (*lpcbData
!= 0) && (ValueInfo
->DataLength
> *lpcbData
))
1103 dwError
= ERROR_MORE_DATA
;
1104 SetLastError(dwError
);
1108 memcpy(lpValueName
, ValueInfo
->Name
, ValueInfo
->NameLength
);
1109 *lpcbValueName
= (DWORD
)(ValueInfo
->NameLength
/ sizeof(WCHAR
));
1110 RegiTerminateWideString(lpValueName
, *lpcbValueName
);
1113 *lpType
= ValueInfo
->Type
;
1118 (PVOID
)((ULONG_PTR
)ValueInfo
->Name
+ ValueInfo
->DataOffset
),
1119 ValueInfo
->DataLength
);
1120 *lpcbData
= (DWORD
)ValueInfo
->DataLength
;
1127 RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo
);
1133 /************************************************************************
1137 RegFlushKey(HKEY hKey
)
1143 if (hKey
== HKEY_PERFORMANCE_DATA
)
1144 return(ERROR_SUCCESS
);
1146 Status
= MapDefaultKey(&KeyHandle
,
1148 if (!NT_SUCCESS(Status
))
1150 ErrorCode
= RtlNtStatusToDosError(Status
);
1152 SetLastError(ErrorCode
);
1156 Status
= NtFlushKey(KeyHandle
);
1157 if (!NT_SUCCESS(Status
))
1159 ErrorCode
= RtlNtStatusToDosError(Status
);
1161 SetLastError(ErrorCode
);
1165 return(ERROR_SUCCESS
);
1169 /************************************************************************
1176 SECURITY_INFORMATION SecurityInformation
,
1177 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1178 LPDWORD lpcbSecurityDescriptor
1182 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1183 return ERROR_CALL_NOT_IMPLEMENTED
;
1187 /************************************************************************
1199 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1200 return ERROR_CALL_NOT_IMPLEMENTED
;
1204 /************************************************************************
1215 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1216 return ERROR_CALL_NOT_IMPLEMENTED
;
1220 /************************************************************************
1221 * RegNotifyChangeKeyValue
1225 RegNotifyChangeKeyValue(
1228 DWORD dwNotifyFilter
,
1234 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1235 return ERROR_CALL_NOT_IMPLEMENTED
;
1240 /************************************************************************
1244 RegOpenKeyA(HKEY hKey
,
1248 OBJECT_ATTRIBUTES ObjectAttributes
;
1249 UNICODE_STRING SubKeyString
;
1254 Status
= MapDefaultKey(&KeyHandle
,
1256 if (!NT_SUCCESS(Status
))
1258 ErrorCode
= RtlNtStatusToDosError(Status
);
1260 SetLastError(ErrorCode
);
1264 RtlCreateUnicodeStringFromAsciiz(&SubKeyString
,
1267 InitializeObjectAttributes(&ObjectAttributes
,
1269 OBJ_CASE_INSENSITIVE
,
1273 Status
= NtOpenKey(phkResult
,
1277 RtlFreeUnicodeString(&SubKeyString
);
1279 if (!NT_SUCCESS(Status
))
1281 ErrorCode
= RtlNtStatusToDosError(Status
);
1283 SetLastError(ErrorCode
);
1286 return(ERROR_SUCCESS
);
1290 /************************************************************************
1305 UNICODE_STRING SubKeyString
;
1306 OBJECT_ATTRIBUTES ObjectAttributes
;
1310 errCode
= MapDefaultKey(&KeyHandle
,
1312 if (!NT_SUCCESS(errCode
))
1314 ErrorCode
= RtlNtStatusToDosError(errCode
);
1316 SetLastError (ErrorCode
);
1320 RtlInitUnicodeString(&SubKeyString
,
1323 InitializeObjectAttributes(&ObjectAttributes
,
1325 OBJ_CASE_INSENSITIVE
,
1329 errCode
= NtOpenKey(
1334 if ( !NT_SUCCESS(errCode
) )
1336 ErrorCode
= RtlNtStatusToDosError(errCode
);
1338 SetLastError(ErrorCode
);
1341 return ERROR_SUCCESS
;
1345 /************************************************************************
1349 RegOpenKeyExA(HKEY hKey
,
1355 OBJECT_ATTRIBUTES ObjectAttributes
;
1356 UNICODE_STRING SubKeyString
;
1361 Status
= MapDefaultKey(&KeyHandle
,
1363 if (!NT_SUCCESS(Status
))
1365 ErrorCode
= RtlNtStatusToDosError(Status
);
1367 SetLastError(ErrorCode
);
1371 RtlCreateUnicodeStringFromAsciiz(&SubKeyString
,
1374 InitializeObjectAttributes(&ObjectAttributes
,
1376 OBJ_CASE_INSENSITIVE
,
1380 Status
= NtOpenKey(phkResult
,
1384 RtlFreeUnicodeString(&SubKeyString
);
1386 if (!NT_SUCCESS(Status
))
1388 ErrorCode
= RtlNtStatusToDosError(Status
);
1390 SetLastError(ErrorCode
);
1394 return(ERROR_SUCCESS
);
1398 /************************************************************************
1402 RegOpenKeyExW(HKEY hKey
,
1408 OBJECT_ATTRIBUTES ObjectAttributes
;
1409 UNICODE_STRING SubKeyString
;
1414 Status
= MapDefaultKey(&KeyHandle
,
1416 if (!NT_SUCCESS(Status
))
1418 ErrorCode
= RtlNtStatusToDosError(Status
);
1420 SetLastError (ErrorCode
);
1424 RtlInitUnicodeString(&SubKeyString
,
1427 InitializeObjectAttributes(&ObjectAttributes
,
1429 OBJ_CASE_INSENSITIVE
,
1433 Status
= NtOpenKey(phkResult
,
1436 if (!NT_SUCCESS(Status
))
1438 ErrorCode
= RtlNtStatusToDosError(Status
);
1440 SetLastError(ErrorCode
);
1443 return(ERROR_SUCCESS
);
1447 /************************************************************************
1458 LPDWORD lpcbMaxSubKeyLen
,
1459 LPDWORD lpcbMaxClassLen
,
1461 LPDWORD lpcbMaxValueNameLen
,
1462 LPDWORD lpcbMaxValueLen
,
1463 LPDWORD lpcbSecurityDescriptor
,
1464 PFILETIME lpftLastWriteTime
1467 WCHAR ClassName
[MAX_PATH
];
1468 UNICODE_STRING UnicodeString
;
1469 ANSI_STRING AnsiString
;
1472 RtlInitUnicodeString(&UnicodeString
, NULL
);
1476 UnicodeString
.Buffer
= &ClassName
[0];
1477 UnicodeString
.MaximumLength
= sizeof(ClassName
);
1480 ErrorCode
= RegQueryInfoKeyW(
1482 UnicodeString
.Buffer
,
1489 lpcbMaxValueNameLen
,
1491 lpcbSecurityDescriptor
,
1494 if ((ErrorCode
== ERROR_SUCCESS
) && (lpClass
))
1496 RtlInitAnsiString(&AnsiString
, NULL
);
1497 AnsiString
.Buffer
= lpClass
;
1498 AnsiString
.MaximumLength
= *lpcbClass
;
1499 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeString
, FALSE
);
1500 *lpcbClass
= AnsiString
.Length
;
1507 /************************************************************************
1518 LPDWORD lpcbMaxSubKeyLen
,
1519 LPDWORD lpcbMaxClassLen
,
1521 LPDWORD lpcbMaxValueNameLen
,
1522 LPDWORD lpcbMaxValueLen
,
1523 LPDWORD lpcbSecurityDescriptor
,
1524 PFILETIME lpftLastWriteTime
1527 KEY_FULL_INFORMATION FullInfoBuffer
;
1528 PKEY_FULL_INFORMATION FullInfo
;
1535 if ((lpClass
) && (!lpcbClass
))
1537 SetLastError(ERROR_INVALID_PARAMETER
);
1538 return ERROR_INVALID_PARAMETER
;
1541 Status
= MapDefaultKey(&KeyHandle
, hKey
);
1546 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
) + *lpcbClass
;
1547 FullInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, FullInfoSize
);
1550 SetLastError(ERROR_OUTOFMEMORY
);
1551 return ERROR_OUTOFMEMORY
;
1554 FullInfo
->ClassLength
= *lpcbClass
;
1558 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
);
1559 FullInfo
= &FullInfoBuffer
;
1560 FullInfo
->ClassLength
= 1;
1563 FullInfo
->ClassOffset
= FIELD_OFFSET(KEY_FULL_INFORMATION
, Class
);
1565 Status
= NtQueryKey(
1572 if (!NT_SUCCESS(Status
))
1576 RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo
);
1579 ErrorCode
= RtlNtStatusToDosError(Status
);
1580 SetLastError(ErrorCode
);
1586 *lpcSubKeys
= FullInfo
->SubKeys
;
1589 if (lpcbMaxSubKeyLen
)
1591 *lpcbMaxSubKeyLen
= FullInfo
->MaxNameLen
;
1594 if (lpcbMaxClassLen
)
1596 *lpcbMaxClassLen
= FullInfo
->MaxClassLen
;
1601 *lpcValues
= FullInfo
->Values
;
1604 if (lpcbMaxValueNameLen
)
1606 *lpcbMaxValueNameLen
= FullInfo
->MaxValueNameLen
;
1609 if (lpcbMaxValueLen
)
1611 *lpcbMaxValueLen
= FullInfo
->MaxValueDataLen
;
1614 if (lpcbSecurityDescriptor
)
1616 *lpcbSecurityDescriptor
= 0;
1620 if (lpftLastWriteTime
!= NULL
)
1622 lpftLastWriteTime
->dwLowDateTime
= FullInfo
->LastWriteTime
.u
.LowPart
;
1623 lpftLastWriteTime
->dwHighDateTime
= FullInfo
->LastWriteTime
.u
.HighPart
;
1628 wcsncpy(lpClass
, FullInfo
->Class
, *lpcbClass
);
1629 RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo
);
1632 SetLastError(ERROR_SUCCESS
);
1633 return ERROR_SUCCESS
;
1637 /************************************************************************
1638 * RegQueryMultipleValuesA
1642 RegQueryMultipleValuesA(
1651 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1652 return ERROR_CALL_NOT_IMPLEMENTED
;
1656 /************************************************************************
1657 * RegQueryMultipleValuesW
1661 RegQueryMultipleValuesW(
1670 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1671 return ERROR_CALL_NOT_IMPLEMENTED
;
1675 /************************************************************************
1687 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
1688 UNICODE_STRING SubKeyName
;
1689 UNICODE_STRING Value
;
1690 ANSI_STRING AnsiString
;
1694 if ((lpValue
) && (!lpcbValue
))
1696 SetLastError(ERROR_INVALID_PARAMETER
);
1697 return ERROR_INVALID_PARAMETER
;
1700 RtlInitUnicodeString(&SubKeyName
, NULL
);
1701 RtlInitUnicodeString(&Value
, NULL
);
1703 if ((lpSubKey
) && (strlen(lpSubKey
) != 0))
1705 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpSubKey
);
1706 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
1707 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
1708 RtlAnsiStringToUnicodeString(&SubKeyName
, &AnsiString
, FALSE
);
1713 ValueSize
= *lpcbValue
* sizeof(WCHAR
);
1714 Value
.MaximumLength
= ValueSize
;
1715 Value
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize
);
1718 SetLastError(ERROR_OUTOFMEMORY
);
1719 return ERROR_OUTOFMEMORY
;
1727 ErrorCode
= RegQueryValueW(
1729 (LPCWSTR
)SubKeyName
.Buffer
,
1733 if (ErrorCode
== ERROR_SUCCESS
)
1735 Value
.Length
= ValueSize
;
1736 RtlInitAnsiString(&AnsiString
, NULL
);
1737 AnsiString
.Buffer
= lpValue
;
1738 AnsiString
.MaximumLength
= *lpcbValue
;
1739 RtlUnicodeStringToAnsiString(&AnsiString
, &Value
, FALSE
);
1742 *lpcbValue
= ValueSize
;
1746 RtlFreeHeap(RtlGetProcessHeap(), 0, Value
.Buffer
);
1753 /************************************************************************
1767 WCHAR ValueNameBuffer
[MAX_PATH
+1];
1768 UNICODE_STRING ValueName
;
1769 UNICODE_STRING ValueData
;
1770 ANSI_STRING AnsiString
;
1775 /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
1777 if ((lpData
) && (!lpcbData
))
1779 SetLastError(ERROR_INVALID_PARAMETER
);
1780 return ERROR_INVALID_PARAMETER
;
1783 RtlInitUnicodeString(&ValueData
, NULL
);
1787 ValueData
.MaximumLength
= *lpcbData
* sizeof(WCHAR
);
1788 ValueData
.Buffer
= RtlAllocateHeap(
1789 RtlGetProcessHeap(),
1791 ValueData
.MaximumLength
);
1792 if (!ValueData
.Buffer
)
1794 SetLastError(ERROR_OUTOFMEMORY
);
1795 return ERROR_OUTOFMEMORY
;
1799 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpValueName
);
1800 RtlInitUnicodeString(&ValueName
, NULL
);
1801 ValueName
.Buffer
= &ValueNameBuffer
[0];
1802 ValueName
.MaximumLength
= sizeof(ValueNameBuffer
);
1803 RtlAnsiStringToUnicodeString(&ValueName
, &AnsiString
, FALSE
);
1807 ResultSize
= *lpcbData
;
1814 ErrorCode
= RegQueryValueExW(
1819 (LPBYTE
)ValueData
.Buffer
,
1822 if ((ErrorCode
== ERROR_SUCCESS
) && (ValueData
.Buffer
!= NULL
))
1829 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
))
1831 ValueData
.Length
= ResultSize
;
1832 RtlInitAnsiString(&AnsiString
, NULL
);
1833 AnsiString
.Buffer
= lpData
;
1834 AnsiString
.MaximumLength
= *lpcbData
;
1835 RtlUnicodeStringToAnsiString(&AnsiString
, &ValueData
, FALSE
);
1839 RtlMoveMemory(lpData
, ValueData
.Buffer
, ResultSize
);
1845 *lpcbData
= ResultSize
;
1848 if (ValueData
.Buffer
)
1850 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData
.Buffer
);
1857 /************************************************************************
1871 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
1872 UNICODE_STRING ValueName
;
1874 DWORD dwError
= ERROR_SUCCESS
;
1879 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
1880 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
1882 Status
= MapDefaultKey(&KeyHandle
, hKey
);
1883 if (!NT_SUCCESS(Status
))
1885 dwError
= RtlNtStatusToDosError(Status
);
1886 SetLastError(dwError
);
1890 if ((lpData
) && (!lpcbData
))
1892 SetLastError(ERROR_INVALID_PARAMETER
);
1893 return ERROR_INVALID_PARAMETER
;
1896 RtlInitUnicodeString (&ValueName
,
1899 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + *lpcbData
;
1900 ValueInfo
= RtlAllocateHeap (RtlGetProcessHeap(),
1903 if (ValueInfo
== NULL
)
1905 SetLastError(ERROR_OUTOFMEMORY
);
1906 return ERROR_OUTOFMEMORY
;
1909 Status
= NtQueryValueKey (hKey
,
1911 KeyValuePartialInformation
,
1916 DPRINT("Status 0x%X\n", Status
);
1918 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1920 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
1921 dwError
= ERROR_SUCCESS
;
1923 else if (!NT_SUCCESS(Status
))
1925 dwError
= RtlNtStatusToDosError(Status
);
1926 SetLastError(dwError
);
1932 *lpType
= ValueInfo
->Type
;
1935 RtlMoveMemory(lpData
, ValueInfo
->Data
, ValueInfo
->DataLength
);
1936 if ((ValueInfo
->Type
== REG_SZ
) ||
1937 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
1938 (ValueInfo
->Type
== REG_EXPAND_SZ
))
1940 ((PWSTR
)lpData
)[ValueInfo
->DataLength
/ sizeof(WCHAR
)] = 0;
1944 DPRINT("Type %d ResultSize %d\n", ValueInfo
->Type
, ResultSize
);
1946 *lpcbData
= (DWORD
)ResultSize
;
1948 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo
);
1954 /************************************************************************
1967 UNICODE_STRING SubKeyString
;
1968 OBJECT_ATTRIBUTES ObjectAttributes
;
1974 errCode
= MapDefaultKey(&KeyHandle
, hKey
);
1975 if (!NT_SUCCESS(errCode
))
1977 ErrorCode
= RtlNtStatusToDosError(errCode
);
1978 SetLastError (ErrorCode
);
1982 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
1985 RtlInitUnicodeString(&SubKeyString
,
1988 InitializeObjectAttributes(&ObjectAttributes
,
1990 OBJ_CASE_INSENSITIVE
,
1994 errCode
= NtOpenKey(
1999 if ( !NT_SUCCESS(errCode
) )
2001 ErrorCode
= RtlNtStatusToDosError(errCode
);
2002 SetLastError(ErrorCode
);
2005 CloseRealKey
= TRUE
;
2010 CloseRealKey
= FALSE
;
2013 ErrorCode
= RegQueryValueExW(
2019 (LPDWORD
)lpcbValue
);
2030 /************************************************************************
2043 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2044 return ERROR_CALL_NOT_IMPLEMENTED
;
2048 /************************************************************************
2061 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2062 return ERROR_CALL_NOT_IMPLEMENTED
;
2066 /************************************************************************
2078 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2079 return ERROR_CALL_NOT_IMPLEMENTED
;
2083 /************************************************************************
2095 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2096 return ERROR_CALL_NOT_IMPLEMENTED
;
2100 /************************************************************************
2104 RegSaveKeyA(HKEY hKey
,
2106 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2108 UNICODE_STRING FileName
;
2111 RtlCreateUnicodeStringFromAsciiz(&FileName
,
2113 ErrorCode
= RegSaveKeyW(hKey
,
2115 lpSecurityAttributes
);
2116 RtlFreeUnicodeString(&FileName
);
2122 /************************************************************************
2126 RegSaveKeyW(HKEY hKey
,
2128 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2130 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
2131 OBJECT_ATTRIBUTES ObjectAttributes
;
2132 UNICODE_STRING NtName
;
2133 IO_STATUS_BLOCK IoStatusBlock
;
2139 Status
= MapDefaultKey(&KeyHandle
,
2141 if (!NT_SUCCESS(Status
))
2143 ErrorCode
= RtlNtStatusToDosError(Status
);
2144 SetLastError(ErrorCode
);
2148 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFile
,
2153 SetLastError(ERROR_INVALID_PARAMETER
);
2154 return(ERROR_INVALID_PARAMETER
);
2157 if (lpSecurityAttributes
!= NULL
)
2158 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
2160 InitializeObjectAttributes(&ObjectAttributes
,
2162 OBJ_CASE_INSENSITIVE
,
2164 SecurityDescriptor
);
2166 Status
= NtCreateFile(&FileHandle
,
2167 GENERIC_WRITE
| SYNCHRONIZE
,
2171 FILE_ATTRIBUTE_NORMAL
,
2174 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT
,
2177 RtlFreeUnicodeString(&NtName
);
2178 if (!NT_SUCCESS(Status
))
2180 ErrorCode
= RtlNtStatusToDosError(Status
);
2181 SetLastError(ErrorCode
);
2185 Status
= NtSaveKey(KeyHandle
,
2187 NtClose(FileHandle
);
2188 if (!NT_SUCCESS(Status
))
2190 ErrorCode
= RtlNtStatusToDosError(Status
);
2191 SetLastError(ErrorCode
);
2195 return(ERROR_SUCCESS
);
2199 /************************************************************************
2206 SECURITY_INFORMATION SecurityInformation
, /* FIXME: ULONG? */
2207 PSECURITY_DESCRIPTOR pSecurityDescriptor
2211 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2212 return ERROR_CALL_NOT_IMPLEMENTED
;
2216 /************************************************************************
2229 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2230 UNICODE_STRING SubKeyName
;
2231 UNICODE_STRING Data
;
2232 ANSI_STRING AnsiString
;
2238 SetLastError(ERROR_INVALID_PARAMETER
);
2239 return ERROR_INVALID_PARAMETER
;
2242 RtlInitUnicodeString(&SubKeyName
, NULL
);
2243 RtlInitUnicodeString(&Data
, NULL
);
2245 if ((lpSubKey
) && (strlen(lpSubKey
) != 0))
2247 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpSubKey
);
2248 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2249 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2250 RtlAnsiStringToUnicodeString(&SubKeyName
, &AnsiString
, FALSE
);
2253 DataSize
= cbData
* sizeof(WCHAR
);
2254 Data
.MaximumLength
= DataSize
;
2255 Data
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize
);
2258 SetLastError(ERROR_OUTOFMEMORY
);
2259 return ERROR_OUTOFMEMORY
;
2262 ErrorCode
= RegSetValueW(
2264 (LPCWSTR
)SubKeyName
.Buffer
,
2269 RtlFreeHeap(RtlGetProcessHeap(), 0, Data
.Buffer
);
2275 /************************************************************************
2289 UNICODE_STRING ValueName
;
2291 ANSI_STRING AnsiString
;
2292 UNICODE_STRING Data
;
2299 SetLastError(ERROR_INVALID_PARAMETER
);
2300 return ERROR_INVALID_PARAMETER
;
2303 if ((lpValueName
) && (strlen(lpValueName
) != 0))
2305 RtlCreateUnicodeStringFromAsciiz(&ValueName
, (LPSTR
)lpValueName
);
2306 pValueName
= (LPWSTR
)ValueName
.Buffer
;
2313 if ((dwType
== REG_SZ
) || (dwType
== REG_MULTI_SZ
) || (dwType
== REG_EXPAND_SZ
))
2315 RtlInitAnsiString(&AnsiString
, NULL
);
2316 AnsiString
.Buffer
= (LPSTR
)lpData
;
2317 AnsiString
.Length
= cbData
;
2318 AnsiString
.MaximumLength
= cbData
;
2319 RtlAnsiStringToUnicodeString(&Data
, &AnsiString
, TRUE
);
2320 pData
= (LPBYTE
)Data
.Buffer
;
2321 DataSize
= cbData
* sizeof(WCHAR
);
2325 RtlInitUnicodeString(&Data
, NULL
);
2326 pData
= (LPBYTE
)lpData
;
2330 ErrorCode
= RegSetValueExW(
2340 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueName
.Buffer
);
2345 RtlFreeHeap(RtlGetProcessHeap(), 0, Data
.Buffer
);
2352 /************************************************************************
2359 LPCWSTR lpValueName
,
2366 UNICODE_STRING ValueName
;
2367 PUNICODE_STRING pValueName
;
2372 Status
= MapDefaultKey(&KeyHandle
, hKey
);
2373 if (!NT_SUCCESS(Status
))
2375 ErrorCode
= RtlNtStatusToDosError(Status
);
2376 SetLastError(ErrorCode
);
2382 RtlInitUnicodeString(&ValueName
, lpValueName
);
2383 pValueName
= &ValueName
;
2390 Status
= NtSetValueKey(
2397 if (!NT_SUCCESS(Status
))
2399 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
2400 SetLastError (ErrorCode
);
2404 return ERROR_SUCCESS
;
2408 /************************************************************************
2422 UNICODE_STRING SubKeyString
;
2423 OBJECT_ATTRIBUTES ObjectAttributes
;
2429 errCode
= MapDefaultKey(&KeyHandle
, hKey
);
2430 if (!NT_SUCCESS(errCode
))
2432 ErrorCode
= RtlNtStatusToDosError(errCode
);
2433 SetLastError (ErrorCode
);
2437 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
2440 RtlInitUnicodeString(&SubKeyString
,
2443 InitializeObjectAttributes(&ObjectAttributes
,
2445 OBJ_CASE_INSENSITIVE
,
2449 errCode
= NtOpenKey(
2454 if ( !NT_SUCCESS(errCode
) )
2456 ErrorCode
= RtlNtStatusToDosError(errCode
);
2457 SetLastError(ErrorCode
);
2460 CloseRealKey
= TRUE
;
2465 CloseRealKey
= FALSE
;
2468 ErrorCode
= RegSetValueExW(
2485 /************************************************************************
2496 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2497 return ERROR_CALL_NOT_IMPLEMENTED
;
2501 /************************************************************************
2512 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2513 return ERROR_CALL_NOT_IMPLEMENTED
;