1 /* $Id: reg.c,v 1.20 2002/11/14 18:21:04 chorns 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 #define NTOS_MODE_USER
19 #define WINAPI __stdcall
20 #define WINAPIV __cdecl
21 #define APIENTRY __stdcall
22 #define DECLSPEC_IMPORT __declspec(dllimport)
23 #define DECLSPEC_EXPORT __declspec(dllexport)
24 #define DECLARE_HANDLE(n) typedef HANDLE n
25 #define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004)
27 #define ERROR_SUCCESS 0L
28 #define ERROR_INVALID_HANDLE 6L
29 #define ERROR_OUTOFMEMORY 14L
30 #define ERROR_INVALID_PARAMETER 87L
31 #define ERROR_CALL_NOT_IMPLEMENTED 120L
32 #define ERROR_MORE_DATA 234L
34 void WINAPI
SetLastError(DWORD
);
38 RtlDosPathNameToNtPathName_U (
40 PUNICODE_STRING ntname
,
46 RtlInitializeCriticalSection(LPCRITICAL_SECTION lpcs
);
50 RtlDeleteCriticalSection(LPCRITICAL_SECTION lpcs
);
54 RtlLeaveCriticalSection(LPCRITICAL_SECTION lpcs
);
58 RtlEnterCriticalSection(LPCRITICAL_SECTION lpcs
);
62 typedef ACCESS_MASK REGSAM
;
64 typedef struct value_entA
{
70 typedef struct value_entW
{
79 #define STDCALL _stdcall
82 #undef RegQueryInfoKey
89 #include <ddk/ntddk.h>
90 #include <ntdll/rtl.h>
98 #define CHECK_STATUS \
100 if (!NT_SUCCESS(Status)) \
102 LONG _ErrorCode = RtlNtStatusToDosError(Status); \
103 SetLastError(_ErrorCode); \
108 /* GLOBALS *******************************************************************/
110 #define MAX_DEFAULT_HANDLES 6
112 static CRITICAL_SECTION HandleTableCS
;
113 static HANDLE DefaultHandleTable
[MAX_DEFAULT_HANDLES
];
116 /* PROTOTYPES ****************************************************************/
118 static NTSTATUS
MapDefaultKey (PHKEY ParentKey
, HKEY Key
);
119 static VOID
CloseDefaultKeys(VOID
);
121 static NTSTATUS
OpenClassesRootKey(PHANDLE KeyHandle
);
122 static NTSTATUS
OpenLocalMachineKey (PHANDLE KeyHandle
);
123 static NTSTATUS
OpenUsersKey (PHANDLE KeyHandle
);
124 static NTSTATUS
OpenCurrentConfigKey(PHANDLE KeyHandle
);
127 /* FUNCTIONS *****************************************************************/
129 inline RegiTerminateWideString(LPWSTR String
, DWORD Length
)
131 LPWSTR AfterString
= String
+ Length
;
135 /************************************************************************
136 * RegInitDefaultHandles
142 DPRINT("RegInitialize()\n");
144 RtlZeroMemory (DefaultHandleTable
,
145 MAX_DEFAULT_HANDLES
* sizeof(HANDLE
));
147 RtlInitializeCriticalSection(&HandleTableCS
);
152 /************************************************************************
158 DPRINT("RegCleanup()\n");
161 RtlDeleteCriticalSection(&HandleTableCS
);
167 MapDefaultKey(PHKEY RealKey
,
172 NTSTATUS Status
= STATUS_SUCCESS
;
174 DPRINT("MapDefaultKey (Key %x)\n", Key
);
176 if (((ULONG
)Key
& 0xF0000000) != 0x80000000)
179 return STATUS_SUCCESS
;
182 /* Handle special cases here */
183 Index
= (ULONG
)Key
& 0x0FFFFFFF;
185 if (Index
>= MAX_DEFAULT_HANDLES
)
186 return STATUS_INVALID_PARAMETER
;
188 RtlEnterCriticalSection(&HandleTableCS
);
190 Handle
= &DefaultHandleTable
[Index
];
193 /* create/open the default handle */
196 case 0: /* HKEY_CLASSES_ROOT */
197 Status
= OpenClassesRootKey(Handle
);
200 case 1: /* HKEY_CURRENT_USER */
201 Status
= RtlOpenCurrentUser(KEY_ALL_ACCESS
,
205 case 2: /* HKEY_LOCAL_MACHINE */
206 Status
= OpenLocalMachineKey(Handle
);
209 case 3: /* HKEY_USERS */
210 Status
= OpenUsersKey(Handle
);
213 case 4: /* HKEY_PERFORMANCE_DATA */
214 Status
= OpenPerformanceDataKey(Handle
);
217 case 5: /* HKEY_CURRENT_CONFIG */
218 Status
= OpenCurrentConfigKey(Handle
);
222 DPRINT("MapDefaultHandle() no handle creator\n");
223 Status
= STATUS_INVALID_PARAMETER
;
227 RtlLeaveCriticalSection(&HandleTableCS
);
229 if (NT_SUCCESS(Status
))
231 *RealKey
= (HKEY
)*Handle
;
239 CloseDefaultKeys(VOID
)
243 RtlEnterCriticalSection(&HandleTableCS
);
245 for (i
= 0; i
< MAX_DEFAULT_HANDLES
; i
++)
247 if (DefaultHandleTable
[i
] != NULL
)
249 NtClose (DefaultHandleTable
[i
]);
250 DefaultHandleTable
[i
] = NULL
;
254 RtlLeaveCriticalSection(&HandleTableCS
);
259 OpenClassesRootKey(PHANDLE KeyHandle
)
261 OBJECT_ATTRIBUTES Attributes
;
262 UNICODE_STRING KeyName
= UNICODE_STRING_INITIALIZER(L
"\\Registry\\Machine\\Software\\CLASSES");
264 DPRINT("OpenClassesRootKey()\n");
266 InitializeObjectAttributes(&Attributes
,
268 OBJ_CASE_INSENSITIVE
,
272 return(NtOpenKey(KeyHandle
,
279 OpenLocalMachineKey(PHANDLE KeyHandle
)
281 OBJECT_ATTRIBUTES Attributes
;
282 UNICODE_STRING KeyName
= UNICODE_STRING_INITIALIZER(L
"\\Registry\\Machine");
284 DPRINT("OpenLocalMachineKey()\n");
286 InitializeObjectAttributes(&Attributes
,
288 OBJ_CASE_INSENSITIVE
,
292 return(NtOpenKey(KeyHandle
,
299 OpenUsersKey(PHANDLE KeyHandle
)
301 OBJECT_ATTRIBUTES Attributes
;
302 UNICODE_STRING KeyName
= UNICODE_STRING_INITIALIZER(L
"\\Registry\\User");
304 DPRINT("OpenUsersKey()\n");
306 InitializeObjectAttributes(&Attributes
,
308 OBJ_CASE_INSENSITIVE
,
312 return(NtOpenKey(KeyHandle
,
319 OpenCurrentConfigKey(PHANDLE KeyHandle
)
321 OBJECT_ATTRIBUTES Attributes
;
322 UNICODE_STRING KeyName
=
323 UNICODE_STRING_INITIALIZER(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
325 DPRINT("OpenCurrentConfigKey()\n");
327 InitializeObjectAttributes(&Attributes
,
329 OBJ_CASE_INSENSITIVE
,
333 return(NtOpenKey(KeyHandle
,
338 /************************************************************************
342 RegCloseKey(HKEY hKey
)
346 /* don't close null handle or a pseudo handle */
347 if ((!hKey
) || (((ULONG
)hKey
& 0xF0000000) == 0x80000000))
348 return ERROR_INVALID_HANDLE
;
350 Status
= NtClose (hKey
);
351 if (!NT_SUCCESS(Status
))
353 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
355 SetLastError (ErrorCode
);
359 return ERROR_SUCCESS
;
363 /************************************************************************
364 * RegConnectRegistryA
367 RegConnectRegistryA(LPCSTR lpMachineName
,
371 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
372 return ERROR_CALL_NOT_IMPLEMENTED
;
376 /************************************************************************
377 * RegConnectRegistryW
380 RegConnectRegistryW(LPCWSTR lpMachineName
,
384 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
385 return ERROR_CALL_NOT_IMPLEMENTED
;
389 /************************************************************************
393 RegCreateKeyExA(HKEY hKey
,
399 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
401 LPDWORD lpdwDisposition
)
403 UNICODE_STRING SubKeyString
;
404 UNICODE_STRING ClassString
;
405 OBJECT_ATTRIBUTES Attributes
;
409 DPRINT("RegCreateKeyExW() called\n");
411 /* get the real parent key */
412 Status
= MapDefaultKey(&ParentKey
,
414 if (!NT_SUCCESS(Status
))
416 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
418 SetLastError(ErrorCode
);
422 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
425 RtlCreateUnicodeStringFromAsciiz(&ClassString
,
427 RtlCreateUnicodeStringFromAsciiz(&SubKeyString
,
430 InitializeObjectAttributes(&Attributes
,
432 OBJ_CASE_INSENSITIVE
,
434 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
436 Status
= NtCreateKey(phkResult
,
440 (lpClass
== NULL
)? NULL
: &ClassString
,
442 (PULONG
)lpdwDisposition
);
444 RtlFreeUnicodeString(&SubKeyString
);
446 RtlFreeUnicodeString(&ClassString
);
448 DPRINT("Status %x\n", Status
);
449 if (!NT_SUCCESS(Status
))
451 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
453 SetLastError (ErrorCode
);
457 return(ERROR_SUCCESS
);
461 /************************************************************************
465 RegCreateKeyExW(HKEY hKey
,
471 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
473 LPDWORD lpdwDisposition
)
475 UNICODE_STRING SubKeyString
;
476 UNICODE_STRING ClassString
;
477 OBJECT_ATTRIBUTES Attributes
;
481 DPRINT("RegCreateKeyExW() called\n");
483 /* get the real parent key */
484 Status
= MapDefaultKey (&ParentKey
, hKey
);
485 if (!NT_SUCCESS(Status
))
487 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
489 SetLastError (ErrorCode
);
493 DPRINT("ParentKey %x\n", (ULONG
)ParentKey
);
494 RtlInitUnicodeString (&ClassString
, lpClass
);
495 RtlInitUnicodeString (&SubKeyString
, lpSubKey
);
497 InitializeObjectAttributes (&Attributes
,
499 OBJ_CASE_INSENSITIVE
,
501 (PSECURITY_DESCRIPTOR
)lpSecurityAttributes
);
503 Status
= NtCreateKey (phkResult
,
507 (lpClass
== NULL
)? NULL
: &ClassString
,
509 (PULONG
)lpdwDisposition
);
510 DPRINT("Status %x\n", Status
);
511 if (!NT_SUCCESS(Status
))
513 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
515 SetLastError (ErrorCode
);
519 return ERROR_SUCCESS
;
523 /************************************************************************
527 RegCreateKeyA(HKEY hKey
,
531 return(RegCreateKeyExA(hKey
,
543 /************************************************************************
547 RegCreateKeyW(HKEY hKey
,
551 return(RegCreateKeyExW(hKey
,
563 /************************************************************************
573 OBJECT_ATTRIBUTES ObjectAttributes
;
574 UNICODE_STRING SubKeyStringW
;
575 ANSI_STRING SubKeyStringA
;
582 Status
= MapDefaultKey(&ParentKey
,
584 if (!NT_SUCCESS(Status
))
586 ErrorCode
= RtlNtStatusToDosError(Status
);
588 SetLastError (ErrorCode
);
592 RtlInitAnsiString(&SubKeyStringA
,
594 RtlAnsiStringToUnicodeString(&SubKeyStringW
,
598 InitializeObjectAttributes (&ObjectAttributes
,
600 OBJ_CASE_INSENSITIVE
,
604 Status
= NtOpenKey (&TargetKey
,
608 RtlFreeUnicodeString (&SubKeyStringW
);
610 if (!NT_SUCCESS(Status
))
612 ErrorCode
= RtlNtStatusToDosError(Status
);
614 SetLastError (ErrorCode
);
618 Status
= NtDeleteKey(TargetKey
);
622 if (!NT_SUCCESS(Status
))
624 ErrorCode
= RtlNtStatusToDosError(Status
);
626 SetLastError (ErrorCode
);
629 return ERROR_SUCCESS
;
633 /************************************************************************
643 OBJECT_ATTRIBUTES ObjectAttributes
;
644 UNICODE_STRING SubKeyString
;
650 Status
= MapDefaultKey(&ParentKey
,
652 if (!NT_SUCCESS(Status
))
654 ErrorCode
= RtlNtStatusToDosError(Status
);
656 SetLastError (ErrorCode
);
660 RtlInitUnicodeString(&SubKeyString
,
663 InitializeObjectAttributes (&ObjectAttributes
,
665 OBJ_CASE_INSENSITIVE
,
669 Status
= NtOpenKey (&TargetKey
,
672 if (!NT_SUCCESS(Status
))
674 ErrorCode
= RtlNtStatusToDosError(Status
);
676 SetLastError (ErrorCode
);
680 Status
= NtDeleteKey(TargetKey
);
684 if (!NT_SUCCESS(Status
))
686 ErrorCode
= RtlNtStatusToDosError(Status
);
688 SetLastError (ErrorCode
);
691 return ERROR_SUCCESS
;
695 /************************************************************************
705 UNICODE_STRING ValueNameW
;
706 ANSI_STRING ValueNameA
;
711 Status
= MapDefaultKey(&KeyHandle
,
713 if (!NT_SUCCESS(Status
))
715 ErrorCode
= RtlNtStatusToDosError(Status
);
717 SetLastError (ErrorCode
);
721 RtlInitAnsiString(&ValueNameA
,
723 RtlAnsiStringToUnicodeString(&ValueNameW
,
727 Status
= NtDeleteValueKey(KeyHandle
,
730 RtlFreeUnicodeString (&ValueNameW
);
732 if (!NT_SUCCESS(Status
))
734 ErrorCode
= RtlNtStatusToDosError(Status
);
736 SetLastError (ErrorCode
);
740 return ERROR_SUCCESS
;
744 /************************************************************************
754 UNICODE_STRING ValueName
;
759 Status
= MapDefaultKey(&KeyHandle
,
761 if (!NT_SUCCESS(Status
))
763 ErrorCode
= RtlNtStatusToDosError(Status
);
765 SetLastError (ErrorCode
);
769 RtlInitUnicodeString(&ValueName
,
770 (LPWSTR
)lpValueName
);
772 Status
= NtDeleteValueKey(KeyHandle
,
774 if (!NT_SUCCESS(Status
))
776 ErrorCode
= RtlNtStatusToDosError(Status
);
778 SetLastError (ErrorCode
);
782 return ERROR_SUCCESS
;
786 /************************************************************************
799 PFILETIME lpftLastWriteTime
802 PKEY_NODE_INFORMATION KeyInfo
;
804 DWORD dwError
= ERROR_SUCCESS
;
809 Status
= MapDefaultKey(&KeyHandle
, hKey
);
810 if (!NT_SUCCESS(Status
))
812 dwError
= RtlNtStatusToDosError(Status
);
813 SetLastError (dwError
);
817 BufferSize
= sizeof (KEY_NODE_INFORMATION
) + *lpcbName
* sizeof(WCHAR
);
819 BufferSize
+= *lpcbClass
;
822 // I think this is a memory leak, always allocated again below ???
824 // KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
827 /* We don't know the exact size of the data returned, so call
828 NtEnumerateKey() with a buffer size determined from parameters
829 to this function. If that call fails with a status code of
830 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
832 KeyInfo
= RtlAllocateHeap(
838 SetLastError(ERROR_OUTOFMEMORY
);
839 return ERROR_OUTOFMEMORY
;
842 Status
= NtEnumerateKey(
850 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status
);
852 if (Status
== STATUS_BUFFER_OVERFLOW
)
854 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
855 BufferSize
= ResultSize
;
859 if (!NT_SUCCESS(Status
))
861 dwError
= RtlNtStatusToDosError(Status
);
862 SetLastError(dwError
);
867 if ((lpClass
) && (*lpcbClass
!= 0) && (KeyInfo
->ClassLength
> *lpcbClass
))
869 dwError
= ERROR_MORE_DATA
;
870 SetLastError(dwError
);
874 RtlMoveMemory(lpName
, KeyInfo
->Name
, KeyInfo
->NameLength
);
875 *lpcbName
= (DWORD
)(KeyInfo
->NameLength
/ sizeof(WCHAR
));
876 RegiTerminateWideString(lpName
, *lpcbName
);
880 RtlMoveMemory(lpClass
,
881 (PVOID
)((ULONG_PTR
)KeyInfo
->Name
+ KeyInfo
->ClassOffset
),
882 KeyInfo
->ClassLength
);
883 *lpcbClass
= (DWORD
)(KeyInfo
->ClassLength
/ sizeof(WCHAR
));
886 if (lpftLastWriteTime
)
888 /* FIXME: Fill lpftLastWriteTime */
895 RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo
);
901 /************************************************************************
913 DWORD dwLength
= cbName
;
915 return RegEnumKeyExW(hKey
,
926 /************************************************************************
939 PFILETIME lpftLastWriteTime
942 WCHAR Name
[MAX_PATH
+1];
943 UNICODE_STRING UnicodeStringName
;
944 WCHAR Class
[MAX_PATH
+1];
945 UNICODE_STRING UnicodeStringClass
;
946 ANSI_STRING AnsiString
;
951 DPRINT("hKey 0x%x dwIndex %d lpName 0x%x *lpcbName %d lpClass 0x%x lpcbClass %d\n",
952 hKey
, dwIndex
, lpName
, *lpcbName
, lpClass
, lpcbClass
);
954 if ((lpClass
) && (!lpcbClass
))
956 SetLastError(ERROR_INVALID_PARAMETER
);
957 return ERROR_INVALID_PARAMETER
;
960 RtlInitUnicodeString(&UnicodeStringName
, NULL
);
961 UnicodeStringName
.Buffer
= &Name
[0];
962 UnicodeStringName
.MaximumLength
= sizeof(Name
);
964 RtlInitUnicodeString(&UnicodeStringClass
, NULL
);
968 UnicodeStringClass
.Buffer
= &Class
[0];
969 UnicodeStringClass
.MaximumLength
= sizeof(Class
);
970 ClassLength
= *lpcbClass
;
977 NameLength
= *lpcbName
;
979 ErrorCode
= RegEnumKeyExW(
982 UnicodeStringName
.Buffer
,
985 UnicodeStringClass
.Buffer
,
989 if (ErrorCode
!= ERROR_SUCCESS
)
992 UnicodeStringName
.Length
= NameLength
* sizeof(WCHAR
);
993 UnicodeStringClass
.Length
= ClassLength
* sizeof(WCHAR
);
995 RtlInitAnsiString(&AnsiString
, NULL
);
996 AnsiString
.Buffer
= lpName
;
997 AnsiString
.MaximumLength
= *lpcbName
;
998 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeStringName
, FALSE
);
999 *lpcbName
= AnsiString
.Length
;
1001 DPRINT("Key Namea0 Length %d\n", UnicodeStringName
.Length
);
1002 DPRINT("Key Namea1 Length %d\n", NameLength
);
1003 DPRINT("Key Namea Length %d\n", *lpcbName
);
1004 DPRINT("Key Namea %s\n", lpName
);
1008 RtlInitAnsiString(&AnsiString
, NULL
);
1009 AnsiString
.Buffer
= lpClass
;
1010 AnsiString
.MaximumLength
= *lpcbClass
;
1011 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeStringClass
, FALSE
);
1012 *lpcbClass
= AnsiString
.Length
;
1015 return ERROR_SUCCESS
;
1019 /************************************************************************
1031 DWORD dwLength
= cbName
;
1033 return RegEnumKeyExA(hKey
,
1044 /************************************************************************
1053 LPDWORD lpcbValueName
,
1060 PKEY_VALUE_FULL_INFORMATION ValueInfo
;
1062 DWORD dwError
= ERROR_SUCCESS
;
1067 Status
= MapDefaultKey(&KeyHandle
, hKey
);
1068 if (!NT_SUCCESS(Status
))
1070 dwError
= RtlNtStatusToDosError(Status
);
1071 SetLastError(dwError
);
1075 BufferSize
= sizeof (KEY_VALUE_FULL_INFORMATION
) +
1076 *lpcbValueName
* sizeof(WCHAR
);
1078 BufferSize
+= *lpcbData
;
1080 /* We don't know the exact size of the data returned, so call
1081 NtEnumerateValueKey() with a buffer size determined from parameters
1082 to this function. If that call fails with a status code of
1083 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
1085 ValueInfo
= RtlAllocateHeap(
1086 RtlGetProcessHeap(),
1089 if (ValueInfo
== NULL
)
1091 SetLastError(ERROR_OUTOFMEMORY
);
1092 return ERROR_OUTOFMEMORY
;
1095 Status
= NtEnumerateValueKey(
1098 KeyValueFullInformation
,
1103 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status
);
1105 if (Status
== STATUS_BUFFER_OVERFLOW
)
1107 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo
);
1108 BufferSize
= ResultSize
;
1112 if (!NT_SUCCESS(Status
))
1114 dwError
= RtlNtStatusToDosError(Status
);
1115 SetLastError(dwError
);
1120 if ((lpData
) && (*lpcbData
!= 0) && (ValueInfo
->DataLength
> *lpcbData
))
1122 dwError
= ERROR_MORE_DATA
;
1123 SetLastError(dwError
);
1127 memcpy(lpValueName
, ValueInfo
->Name
, ValueInfo
->NameLength
);
1128 *lpcbValueName
= (DWORD
)(ValueInfo
->NameLength
/ sizeof(WCHAR
));
1129 RegiTerminateWideString(lpValueName
, *lpcbValueName
);
1132 *lpType
= ValueInfo
->Type
;
1137 //(PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset),
1138 (PVOID
)((ULONG_PTR
)ValueInfo
+ ValueInfo
->DataOffset
),
1139 ValueInfo
->DataLength
);
1140 *lpcbData
= (DWORD
)ValueInfo
->DataLength
;
1142 RtlCopyMemory((PCHAR) ValueFullInformation + ValueFullInformation->DataOffset,
1144 ValueCell->DataSize & LONG_MAX);
1152 RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo
);
1158 /************************************************************************
1167 LPDWORD lpcbValueName
,
1174 WCHAR ValueName
[MAX_PATH
+1];
1175 UNICODE_STRING UnicodeString
;
1176 ANSI_STRING AnsiString
;
1178 DWORD ValueNameLength
;
1179 BYTE
* lpDataBuffer
= NULL
;
1182 ANSI_STRING AnsiDataString
;
1183 UNICODE_STRING UnicodeDataString
;
1185 if (lpData
!= NULL
/*&& lpcbData != NULL*/) {
1186 cbData
= *lpcbData
; // this should always be valid if lpData is valid
1187 lpDataBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, (*lpcbData
) * sizeof(WCHAR
));
1188 if (lpDataBuffer
== NULL
) {
1189 SetLastError(ERROR_OUTOFMEMORY
);
1190 return ERROR_OUTOFMEMORY
;
1194 RtlInitUnicodeString(&UnicodeString
, NULL
);
1195 UnicodeString
.Buffer
= &ValueName
[0];
1196 UnicodeString
.MaximumLength
= sizeof(ValueName
);
1198 ValueNameLength
= *lpcbValueName
;
1200 ErrorCode
= RegEnumValueW(
1203 UnicodeString
.Buffer
,
1210 if (ErrorCode
!= ERROR_SUCCESS
)
1213 UnicodeString
.Length
= ValueNameLength
* sizeof(WCHAR
);
1215 RtlInitAnsiString(&AnsiString
, NULL
);
1216 AnsiString
.Buffer
= lpValueName
;
1217 AnsiString
.MaximumLength
= *lpcbValueName
;
1218 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeString
, FALSE
);
1219 *lpcbValueName
= AnsiString
.Length
;
1221 // if (lpData != lpDataBuffer) { // did we use a temp buffer
1222 if (lpDataBuffer
) { // did we use a temp buffer
1223 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
)) {
1224 RtlInitUnicodeString(&UnicodeDataString
, NULL
);
1225 UnicodeDataString
.Buffer
= lpDataBuffer
;
1226 UnicodeDataString
.MaximumLength
= (*lpcbData
) * sizeof(WCHAR
);
1227 UnicodeDataString
.Length
= cbData
/* * sizeof(WCHAR)*/;
1228 RtlInitAnsiString(&AnsiDataString
, NULL
);
1229 AnsiDataString
.Buffer
= lpData
;
1230 AnsiDataString
.MaximumLength
= *lpcbData
;
1231 RtlUnicodeStringToAnsiString(&AnsiDataString
, &UnicodeDataString
, FALSE
);
1232 *lpcbData
= AnsiDataString
.Length
;
1233 // else if (Type == REG_EXPAND_SZ) {
1235 memcpy(lpData
, lpDataBuffer
, min(*lpcbData
, cbData
));
1238 RtlFreeHeap(RtlGetProcessHeap(), 0, lpDataBuffer
);
1240 if (lpType
!= NULL
) {
1243 return ERROR_SUCCESS
;
1247 /************************************************************************
1251 RegFlushKey(HKEY hKey
)
1257 if (hKey
== HKEY_PERFORMANCE_DATA
)
1258 return(ERROR_SUCCESS
);
1260 Status
= MapDefaultKey(&KeyHandle
,
1262 if (!NT_SUCCESS(Status
))
1264 ErrorCode
= RtlNtStatusToDosError(Status
);
1266 SetLastError(ErrorCode
);
1270 Status
= NtFlushKey(KeyHandle
);
1271 if (!NT_SUCCESS(Status
))
1273 ErrorCode
= RtlNtStatusToDosError(Status
);
1275 SetLastError(ErrorCode
);
1279 return(ERROR_SUCCESS
);
1283 /************************************************************************
1290 SECURITY_INFORMATION SecurityInformation
,
1291 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1292 LPDWORD lpcbSecurityDescriptor
1296 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1297 return ERROR_CALL_NOT_IMPLEMENTED
;
1301 /************************************************************************
1313 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1314 return ERROR_CALL_NOT_IMPLEMENTED
;
1318 /************************************************************************
1329 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1330 return ERROR_CALL_NOT_IMPLEMENTED
;
1334 /************************************************************************
1335 * RegNotifyChangeKeyValue
1339 RegNotifyChangeKeyValue(
1342 DWORD dwNotifyFilter
,
1348 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1349 return ERROR_CALL_NOT_IMPLEMENTED
;
1354 /************************************************************************
1358 RegOpenKeyA(HKEY hKey
,
1362 OBJECT_ATTRIBUTES ObjectAttributes
;
1363 UNICODE_STRING SubKeyString
;
1368 Status
= MapDefaultKey(&KeyHandle
,
1370 if (!NT_SUCCESS(Status
))
1372 ErrorCode
= RtlNtStatusToDosError(Status
);
1374 SetLastError(ErrorCode
);
1378 RtlCreateUnicodeStringFromAsciiz(&SubKeyString
,
1381 InitializeObjectAttributes(&ObjectAttributes
,
1383 OBJ_CASE_INSENSITIVE
,
1387 Status
= NtOpenKey(phkResult
,
1391 RtlFreeUnicodeString(&SubKeyString
);
1393 if (!NT_SUCCESS(Status
))
1395 ErrorCode
= RtlNtStatusToDosError(Status
);
1397 SetLastError(ErrorCode
);
1400 return(ERROR_SUCCESS
);
1404 /************************************************************************
1419 UNICODE_STRING SubKeyString
;
1420 OBJECT_ATTRIBUTES ObjectAttributes
;
1424 errCode
= MapDefaultKey(&KeyHandle
,
1426 if (!NT_SUCCESS(errCode
))
1428 ErrorCode
= RtlNtStatusToDosError(errCode
);
1430 SetLastError (ErrorCode
);
1434 RtlInitUnicodeString(&SubKeyString
,
1437 InitializeObjectAttributes(&ObjectAttributes
,
1439 OBJ_CASE_INSENSITIVE
,
1443 errCode
= NtOpenKey(
1448 if ( !NT_SUCCESS(errCode
) )
1450 ErrorCode
= RtlNtStatusToDosError(errCode
);
1452 SetLastError(ErrorCode
);
1455 return ERROR_SUCCESS
;
1459 /************************************************************************
1463 RegOpenKeyExA(HKEY hKey
,
1469 OBJECT_ATTRIBUTES ObjectAttributes
;
1470 UNICODE_STRING SubKeyString
;
1475 Status
= MapDefaultKey(&KeyHandle
,
1477 if (!NT_SUCCESS(Status
))
1479 ErrorCode
= RtlNtStatusToDosError(Status
);
1481 SetLastError(ErrorCode
);
1485 RtlCreateUnicodeStringFromAsciiz(&SubKeyString
,
1488 InitializeObjectAttributes(&ObjectAttributes
,
1490 OBJ_CASE_INSENSITIVE
,
1494 Status
= NtOpenKey(phkResult
,
1498 RtlFreeUnicodeString(&SubKeyString
);
1500 if (!NT_SUCCESS(Status
))
1502 ErrorCode
= RtlNtStatusToDosError(Status
);
1504 SetLastError(ErrorCode
);
1508 return(ERROR_SUCCESS
);
1512 /************************************************************************
1516 RegOpenKeyExW(HKEY hKey
,
1522 OBJECT_ATTRIBUTES ObjectAttributes
;
1523 UNICODE_STRING SubKeyString
;
1528 Status
= MapDefaultKey(&KeyHandle
,
1530 if (!NT_SUCCESS(Status
))
1532 ErrorCode
= RtlNtStatusToDosError(Status
);
1534 SetLastError (ErrorCode
);
1538 if (lpSubKey
!= NULL
) {
1539 RtlInitUnicodeString(&SubKeyString
,
1542 RtlInitUnicodeString(&SubKeyString
,
1546 InitializeObjectAttributes(&ObjectAttributes
,
1548 OBJ_CASE_INSENSITIVE
,
1552 Status
= NtOpenKey(phkResult
,
1555 if (!NT_SUCCESS(Status
))
1557 ErrorCode
= RtlNtStatusToDosError(Status
);
1559 SetLastError(ErrorCode
);
1562 return(ERROR_SUCCESS
);
1566 /************************************************************************
1577 LPDWORD lpcbMaxSubKeyLen
,
1578 LPDWORD lpcbMaxClassLen
,
1580 LPDWORD lpcbMaxValueNameLen
,
1581 LPDWORD lpcbMaxValueLen
,
1582 LPDWORD lpcbSecurityDescriptor
,
1583 PFILETIME lpftLastWriteTime
1586 KEY_FULL_INFORMATION FullInfoBuffer
;
1587 PKEY_FULL_INFORMATION FullInfo
;
1594 if ((lpClass
) && (!lpcbClass
))
1596 SetLastError(ERROR_INVALID_PARAMETER
);
1597 return ERROR_INVALID_PARAMETER
;
1600 Status
= MapDefaultKey(&KeyHandle
, hKey
);
1605 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
) + *lpcbClass
;
1606 FullInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, FullInfoSize
);
1609 SetLastError(ERROR_OUTOFMEMORY
);
1610 return ERROR_OUTOFMEMORY
;
1613 FullInfo
->ClassLength
= *lpcbClass
;
1617 FullInfoSize
= sizeof(KEY_FULL_INFORMATION
);
1618 FullInfo
= &FullInfoBuffer
;
1619 FullInfo
->ClassLength
= 1;
1622 FullInfo
->ClassOffset
= FIELD_OFFSET(KEY_FULL_INFORMATION
, Class
);
1624 Status
= NtQueryKey(
1631 if (!NT_SUCCESS(Status
))
1635 RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo
);
1638 ErrorCode
= RtlNtStatusToDosError(Status
);
1639 SetLastError(ErrorCode
);
1645 *lpcSubKeys
= FullInfo
->SubKeys
;
1648 if (lpcbMaxSubKeyLen
)
1650 *lpcbMaxSubKeyLen
= FullInfo
->MaxNameLen
;
1653 if (lpcbMaxClassLen
)
1655 *lpcbMaxClassLen
= FullInfo
->MaxClassLen
;
1660 *lpcValues
= FullInfo
->Values
;
1663 if (lpcbMaxValueNameLen
)
1665 *lpcbMaxValueNameLen
= FullInfo
->MaxValueNameLen
;
1668 if (lpcbMaxValueLen
)
1670 *lpcbMaxValueLen
= FullInfo
->MaxValueDataLen
;
1673 if (lpcbSecurityDescriptor
)
1675 *lpcbSecurityDescriptor
= 0;
1679 if (lpftLastWriteTime
!= NULL
)
1681 lpftLastWriteTime
->dwLowDateTime
= FullInfo
->LastWriteTime
.u
.LowPart
;
1682 lpftLastWriteTime
->dwHighDateTime
= FullInfo
->LastWriteTime
.u
.HighPart
;
1687 wcsncpy(lpClass
, FullInfo
->Class
, *lpcbClass
);
1688 RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo
);
1691 SetLastError(ERROR_SUCCESS
);
1692 return ERROR_SUCCESS
;
1696 /************************************************************************
1707 LPDWORD lpcbMaxSubKeyLen
,
1708 LPDWORD lpcbMaxClassLen
,
1710 LPDWORD lpcbMaxValueNameLen
,
1711 LPDWORD lpcbMaxValueLen
,
1712 LPDWORD lpcbSecurityDescriptor
,
1713 PFILETIME lpftLastWriteTime
1716 WCHAR ClassName
[MAX_PATH
];
1717 UNICODE_STRING UnicodeString
;
1718 ANSI_STRING AnsiString
;
1721 RtlInitUnicodeString(&UnicodeString
, NULL
);
1725 UnicodeString
.Buffer
= &ClassName
[0];
1726 UnicodeString
.MaximumLength
= sizeof(ClassName
);
1729 ErrorCode
= RegQueryInfoKeyW(
1731 UnicodeString
.Buffer
,
1738 lpcbMaxValueNameLen
,
1740 lpcbSecurityDescriptor
,
1743 if ((ErrorCode
== ERROR_SUCCESS
) && (lpClass
))
1745 RtlInitAnsiString(&AnsiString
, NULL
);
1746 AnsiString
.Buffer
= lpClass
;
1747 AnsiString
.MaximumLength
= *lpcbClass
;
1748 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeString
, FALSE
);
1749 *lpcbClass
= AnsiString
.Length
;
1756 /************************************************************************
1757 * RegQueryMultipleValuesA
1761 RegQueryMultipleValuesA(
1770 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1771 return ERROR_CALL_NOT_IMPLEMENTED
;
1775 /************************************************************************
1776 * RegQueryMultipleValuesW
1780 RegQueryMultipleValuesW(
1789 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1790 return ERROR_CALL_NOT_IMPLEMENTED
;
1794 /************************************************************************
1801 LPCWSTR lpValueName
,
1808 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
1809 UNICODE_STRING ValueName
;
1811 DWORD dwError
= ERROR_SUCCESS
;
1816 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
1817 hKey
, lpValueName
, lpData
, lpcbData
? *lpcbData
: 0);
1819 Status
= MapDefaultKey(&KeyHandle
, hKey
);
1820 if (!NT_SUCCESS(Status
))
1822 dwError
= RtlNtStatusToDosError(Status
);
1823 SetLastError(dwError
);
1827 if ((lpData
) && (!lpcbData
))
1829 SetLastError(ERROR_INVALID_PARAMETER
);
1830 return ERROR_INVALID_PARAMETER
;
1833 RtlInitUnicodeString (&ValueName
,
1836 BufferSize
= sizeof (KEY_VALUE_PARTIAL_INFORMATION
) + *lpcbData
;
1837 ValueInfo
= RtlAllocateHeap (RtlGetProcessHeap(),
1840 if (ValueInfo
== NULL
)
1842 SetLastError(ERROR_OUTOFMEMORY
);
1843 return ERROR_OUTOFMEMORY
;
1846 Status
= NtQueryValueKey (hKey
,
1848 KeyValuePartialInformation
,
1853 DPRINT("Status 0x%X\n", Status
);
1855 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1857 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
1858 dwError
= ERROR_SUCCESS
;
1860 else if (!NT_SUCCESS(Status
))
1862 dwError
= RtlNtStatusToDosError(Status
);
1863 SetLastError(dwError
);
1869 *lpType
= ValueInfo
->Type
;
1872 RtlMoveMemory(lpData
, ValueInfo
->Data
, ValueInfo
->DataLength
);
1873 if ((ValueInfo
->Type
== REG_SZ
) ||
1874 (ValueInfo
->Type
== REG_MULTI_SZ
) ||
1875 (ValueInfo
->Type
== REG_EXPAND_SZ
))
1877 ((PWSTR
)lpData
)[ValueInfo
->DataLength
/ sizeof(WCHAR
)] = 0;
1881 DPRINT("Type %d ResultSize %d\n", ValueInfo
->Type
, ResultSize
);
1883 *lpcbData
= (DWORD
)ResultSize
;
1885 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo
);
1891 /************************************************************************
1905 WCHAR ValueNameBuffer
[MAX_PATH
+1];
1906 UNICODE_STRING ValueName
;
1907 UNICODE_STRING ValueData
;
1908 ANSI_STRING AnsiString
;
1913 /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
1915 if ((lpData
) && (!lpcbData
))
1917 SetLastError(ERROR_INVALID_PARAMETER
);
1918 return ERROR_INVALID_PARAMETER
;
1921 RtlInitUnicodeString(&ValueData
, NULL
);
1925 ValueData
.MaximumLength
= *lpcbData
* sizeof(WCHAR
);
1926 ValueData
.Buffer
= RtlAllocateHeap(
1927 RtlGetProcessHeap(),
1929 ValueData
.MaximumLength
);
1930 if (!ValueData
.Buffer
)
1932 SetLastError(ERROR_OUTOFMEMORY
);
1933 return ERROR_OUTOFMEMORY
;
1937 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpValueName
);
1938 RtlInitUnicodeString(&ValueName
, NULL
);
1939 ValueName
.Buffer
= &ValueNameBuffer
[0];
1940 ValueName
.MaximumLength
= sizeof(ValueNameBuffer
);
1941 RtlAnsiStringToUnicodeString(&ValueName
, &AnsiString
, FALSE
);
1945 ResultSize
= *lpcbData
;
1952 ErrorCode
= RegQueryValueExW(
1957 (LPBYTE
)ValueData
.Buffer
,
1960 if ((ErrorCode
== ERROR_SUCCESS
) && (ValueData
.Buffer
!= NULL
))
1967 if ((Type
== REG_SZ
) || (Type
== REG_MULTI_SZ
) || (Type
== REG_EXPAND_SZ
))
1969 ValueData
.Length
= ResultSize
;
1970 RtlInitAnsiString(&AnsiString
, NULL
);
1971 AnsiString
.Buffer
= lpData
;
1972 AnsiString
.MaximumLength
= *lpcbData
;
1973 RtlUnicodeStringToAnsiString(&AnsiString
, &ValueData
, FALSE
);
1977 RtlMoveMemory(lpData
, ValueData
.Buffer
, ResultSize
);
1983 *lpcbData
= ResultSize
;
1986 if (ValueData
.Buffer
)
1988 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData
.Buffer
);
1995 /************************************************************************
2008 UNICODE_STRING SubKeyString
;
2009 OBJECT_ATTRIBUTES ObjectAttributes
;
2015 errCode
= MapDefaultKey(&KeyHandle
, hKey
);
2016 if (!NT_SUCCESS(errCode
))
2018 ErrorCode
= RtlNtStatusToDosError(errCode
);
2019 SetLastError (ErrorCode
);
2023 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
2026 RtlInitUnicodeString(&SubKeyString
,
2029 InitializeObjectAttributes(&ObjectAttributes
,
2031 OBJ_CASE_INSENSITIVE
,
2035 errCode
= NtOpenKey(
2040 if ( !NT_SUCCESS(errCode
) )
2042 ErrorCode
= RtlNtStatusToDosError(errCode
);
2043 SetLastError(ErrorCode
);
2046 CloseRealKey
= TRUE
;
2051 CloseRealKey
= FALSE
;
2054 ErrorCode
= RegQueryValueExW(
2060 (LPDWORD
)lpcbValue
);
2071 /************************************************************************
2083 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2084 UNICODE_STRING SubKeyName
;
2085 UNICODE_STRING Value
;
2086 ANSI_STRING AnsiString
;
2090 if ((lpValue
) && (!lpcbValue
))
2092 SetLastError(ERROR_INVALID_PARAMETER
);
2093 return ERROR_INVALID_PARAMETER
;
2096 RtlInitUnicodeString(&SubKeyName
, NULL
);
2097 RtlInitUnicodeString(&Value
, NULL
);
2099 if ((lpSubKey
) && (strlen(lpSubKey
) != 0))
2101 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpSubKey
);
2102 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2103 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2104 RtlAnsiStringToUnicodeString(&SubKeyName
, &AnsiString
, FALSE
);
2109 ValueSize
= *lpcbValue
* sizeof(WCHAR
);
2110 Value
.MaximumLength
= ValueSize
;
2111 Value
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize
);
2114 SetLastError(ERROR_OUTOFMEMORY
);
2115 return ERROR_OUTOFMEMORY
;
2123 ErrorCode
= RegQueryValueW(
2125 (LPCWSTR
)SubKeyName
.Buffer
,
2129 if (ErrorCode
== ERROR_SUCCESS
)
2131 Value
.Length
= ValueSize
;
2132 RtlInitAnsiString(&AnsiString
, NULL
);
2133 AnsiString
.Buffer
= lpValue
;
2134 AnsiString
.MaximumLength
= *lpcbValue
;
2135 RtlUnicodeStringToAnsiString(&AnsiString
, &Value
, FALSE
);
2138 *lpcbValue
= ValueSize
;
2142 RtlFreeHeap(RtlGetProcessHeap(), 0, Value
.Buffer
);
2149 /************************************************************************
2162 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2163 return ERROR_CALL_NOT_IMPLEMENTED
;
2167 /************************************************************************
2180 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2181 return ERROR_CALL_NOT_IMPLEMENTED
;
2185 /************************************************************************
2197 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2198 return ERROR_CALL_NOT_IMPLEMENTED
;
2202 /************************************************************************
2214 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2215 return ERROR_CALL_NOT_IMPLEMENTED
;
2219 /************************************************************************
2223 RegSaveKeyW(HKEY hKey
,
2225 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2227 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
2228 OBJECT_ATTRIBUTES ObjectAttributes
;
2229 UNICODE_STRING NtName
;
2230 IO_STATUS_BLOCK IoStatusBlock
;
2236 Status
= MapDefaultKey(&KeyHandle
,
2238 if (!NT_SUCCESS(Status
))
2240 ErrorCode
= RtlNtStatusToDosError(Status
);
2241 SetLastError(ErrorCode
);
2245 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFile
,
2250 SetLastError(ERROR_INVALID_PARAMETER
);
2251 return(ERROR_INVALID_PARAMETER
);
2254 if (lpSecurityAttributes
!= NULL
)
2255 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
2257 InitializeObjectAttributes(&ObjectAttributes
,
2259 OBJ_CASE_INSENSITIVE
,
2261 SecurityDescriptor
);
2263 Status
= NtCreateFile(&FileHandle
,
2264 GENERIC_WRITE
| SYNCHRONIZE
,
2268 FILE_ATTRIBUTE_NORMAL
,
2271 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT
,
2274 RtlFreeUnicodeString(&NtName
);
2275 if (!NT_SUCCESS(Status
))
2277 ErrorCode
= RtlNtStatusToDosError(Status
);
2278 SetLastError(ErrorCode
);
2282 Status
= NtSaveKey(KeyHandle
,
2284 NtClose(FileHandle
);
2285 if (!NT_SUCCESS(Status
))
2287 ErrorCode
= RtlNtStatusToDosError(Status
);
2288 SetLastError(ErrorCode
);
2292 return(ERROR_SUCCESS
);
2296 /************************************************************************
2300 RegSaveKeyA(HKEY hKey
,
2302 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
2304 UNICODE_STRING FileName
;
2307 RtlCreateUnicodeStringFromAsciiz(&FileName
,
2309 ErrorCode
= RegSaveKeyW(hKey
,
2311 lpSecurityAttributes
);
2312 RtlFreeUnicodeString(&FileName
);
2318 /************************************************************************
2325 SECURITY_INFORMATION SecurityInformation
, /* FIXME: ULONG? */
2326 PSECURITY_DESCRIPTOR pSecurityDescriptor
2330 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2331 return ERROR_CALL_NOT_IMPLEMENTED
;
2335 /************************************************************************
2342 LPCWSTR lpValueName
,
2349 UNICODE_STRING ValueName
;
2350 PUNICODE_STRING pValueName
;
2355 Status
= MapDefaultKey(&KeyHandle
, hKey
);
2356 if (!NT_SUCCESS(Status
))
2358 ErrorCode
= RtlNtStatusToDosError(Status
);
2359 SetLastError(ErrorCode
);
2365 RtlInitUnicodeString(&ValueName
, lpValueName
);
2366 pValueName
= &ValueName
;
2373 Status
= NtSetValueKey(
2380 if (!NT_SUCCESS(Status
))
2382 LONG ErrorCode
= RtlNtStatusToDosError(Status
);
2383 SetLastError (ErrorCode
);
2387 return ERROR_SUCCESS
;
2391 /************************************************************************
2405 UNICODE_STRING ValueName
;
2407 ANSI_STRING AnsiString
;
2408 UNICODE_STRING Data
;
2415 SetLastError(ERROR_INVALID_PARAMETER
);
2416 return ERROR_INVALID_PARAMETER
;
2419 if ((lpValueName
) && (strlen(lpValueName
) != 0))
2421 RtlCreateUnicodeStringFromAsciiz(&ValueName
, (LPSTR
)lpValueName
);
2422 pValueName
= (LPWSTR
)ValueName
.Buffer
;
2429 if ((dwType
== REG_SZ
) || (dwType
== REG_MULTI_SZ
) || (dwType
== REG_EXPAND_SZ
))
2431 RtlInitAnsiString(&AnsiString
, NULL
);
2432 AnsiString
.Buffer
= (LPSTR
)lpData
;
2433 AnsiString
.Length
= cbData
;
2434 AnsiString
.MaximumLength
= cbData
;
2435 RtlAnsiStringToUnicodeString(&Data
, &AnsiString
, TRUE
);
2436 pData
= (LPBYTE
)Data
.Buffer
;
2437 DataSize
= cbData
* sizeof(WCHAR
);
2441 RtlInitUnicodeString(&Data
, NULL
);
2442 pData
= (LPBYTE
)lpData
;
2446 ErrorCode
= RegSetValueExW(
2456 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueName
.Buffer
);
2461 RtlFreeHeap(RtlGetProcessHeap(), 0, Data
.Buffer
);
2468 /************************************************************************
2482 UNICODE_STRING SubKeyString
;
2483 OBJECT_ATTRIBUTES ObjectAttributes
;
2489 errCode
= MapDefaultKey(&KeyHandle
, hKey
);
2490 if (!NT_SUCCESS(errCode
))
2492 ErrorCode
= RtlNtStatusToDosError(errCode
);
2493 SetLastError (ErrorCode
);
2497 if ((lpSubKey
) && (wcslen(lpSubKey
) != 0))
2500 RtlInitUnicodeString(&SubKeyString
,
2503 InitializeObjectAttributes(&ObjectAttributes
,
2505 OBJ_CASE_INSENSITIVE
,
2509 errCode
= NtOpenKey(
2514 if ( !NT_SUCCESS(errCode
) )
2516 ErrorCode
= RtlNtStatusToDosError(errCode
);
2517 SetLastError(ErrorCode
);
2520 CloseRealKey
= TRUE
;
2525 CloseRealKey
= FALSE
;
2528 ErrorCode
= RegSetValueExW(
2545 /************************************************************************
2558 WCHAR SubKeyNameBuffer
[MAX_PATH
+1];
2559 UNICODE_STRING SubKeyName
;
2560 UNICODE_STRING Data
;
2561 ANSI_STRING AnsiString
;
2567 SetLastError(ERROR_INVALID_PARAMETER
);
2568 return ERROR_INVALID_PARAMETER
;
2571 RtlInitUnicodeString(&SubKeyName
, NULL
);
2572 RtlInitUnicodeString(&Data
, NULL
);
2574 if ((lpSubKey
) && (strlen(lpSubKey
) != 0))
2576 RtlInitAnsiString(&AnsiString
, (LPSTR
)lpSubKey
);
2577 SubKeyName
.Buffer
= &SubKeyNameBuffer
[0];
2578 SubKeyName
.MaximumLength
= sizeof(SubKeyNameBuffer
);
2579 RtlAnsiStringToUnicodeString(&SubKeyName
, &AnsiString
, FALSE
);
2582 DataSize
= cbData
* sizeof(WCHAR
);
2583 Data
.MaximumLength
= DataSize
;
2584 Data
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize
);
2587 SetLastError(ERROR_OUTOFMEMORY
);
2588 return ERROR_OUTOFMEMORY
;
2591 ErrorCode
= RegSetValueW(
2593 (LPCWSTR
)SubKeyName
.Buffer
,
2598 RtlFreeHeap(RtlGetProcessHeap(), 0, Data
.Buffer
);
2604 /************************************************************************
2615 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2616 return ERROR_CALL_NOT_IMPLEMENTED
;
2620 /************************************************************************
2631 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2632 return ERROR_CALL_NOT_IMPLEMENTED
;