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)
14 #define NTOS_MODE_USER
16 #include <ddk/ntddk.h>
17 #include <ntdll/rtl.h>
24 #else /*WIN32_REGDBG*/
27 #define WINAPI __stdcall
28 #define WINAPIV __cdecl
29 #define APIENTRY __stdcall
30 #define DECLSPEC_IMPORT __declspec(dllimport)
31 #define DECLSPEC_EXPORT __declspec(dllexport)
32 #define DECLARE_HANDLE(n) typedef HANDLE n
33 #define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004)
34 #define ERROR_SUCCESS 0L
35 #define ERROR_INVALID_HANDLE 6L
36 #define ERROR_OUTOFMEMORY 14L
37 #define ERROR_INVALID_PARAMETER 87L
38 #define ERROR_CALL_NOT_IMPLEMENTED 120L
39 #define ERROR_MORE_DATA 234L
41 void WINAPI SetLastError(DWORD);
42 BOOLEAN STDCALL RtlDosPathNameToNtPathName_U(PWSTR dosname, PUNICODE_STRING ntname, PWSTR* shortname, PCURDIR nah);
43 NTSTATUS STDCALL RtlInitializeCriticalSection(LPCRITICAL_SECTION lpcs);
44 NTSTATUS STDCALL RtlDeleteCriticalSection(LPCRITICAL_SECTION lpcs);
45 NTSTATUS STDCALL RtlLeaveCriticalSection(LPCRITICAL_SECTION lpcs);
46 NTSTATUS STDCALL RtlEnterCriticalSection(LPCRITICAL_SECTION lpcs);
50 typedef ACCESS_MASK REGSAM;
52 typedef struct value_entA {
58 typedef struct value_entW {
66 #define STDCALL _stdcall
69 #undef RegQueryInfoKey
75 #endif /*WIN32_REGDBG*/
77 #define CHECK_STATUS \
79 if (!NT_SUCCESS(Status)) \
81 LONG _ErrorCode = RtlNtStatusToDosError(Status); \
82 SetLastError(_ErrorCode); \
87 /* GLOBALS *******************************************************************/
89 #define MAX_DEFAULT_HANDLES 6
91 static CRITICAL_SECTION HandleTableCS;
92 static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
95 /* PROTOTYPES ****************************************************************/
97 static NTSTATUS MapDefaultKey (PHKEY ParentKey, HKEY Key);
98 static VOID CloseDefaultKeys(VOID);
100 static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
101 static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
102 static NTSTATUS OpenUsersKey (PHANDLE KeyHandle);
103 static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle);
106 /* FUNCTIONS *****************************************************************/
108 inline void RegiTerminateWideString(LPWSTR String, DWORD Length)
110 LPWSTR AfterString = String + Length;
114 /************************************************************************
115 * RegInitDefaultHandles
121 DPRINT("RegInitialize()\n");
123 RtlZeroMemory (DefaultHandleTable,
124 MAX_DEFAULT_HANDLES * sizeof(HANDLE));
125 RtlInitializeCriticalSection(&HandleTableCS);
130 /************************************************************************
136 DPRINT("RegCleanup()\n");
139 RtlDeleteCriticalSection(&HandleTableCS);
145 MapDefaultKey(PHKEY RealKey,
150 NTSTATUS Status = STATUS_SUCCESS;
152 DPRINT("MapDefaultKey (Key %x)\n", Key);
154 if (((ULONG)Key & 0xF0000000) != 0x80000000) {
156 return STATUS_SUCCESS;
158 /* Handle special cases here */
159 Index = (ULONG)Key & 0x0FFFFFFF;
160 if (Index >= MAX_DEFAULT_HANDLES)
161 return STATUS_INVALID_PARAMETER;
162 RtlEnterCriticalSection(&HandleTableCS);
163 Handle = &DefaultHandleTable[Index];
164 if (*Handle == NULL) {
165 /* create/open the default handle */
167 case 0: /* HKEY_CLASSES_ROOT */
168 Status = OpenClassesRootKey(Handle);
170 case 1: /* HKEY_CURRENT_USER */
171 Status = RtlOpenCurrentUser(KEY_ALL_ACCESS, Handle);
173 case 2: /* HKEY_LOCAL_MACHINE */
174 Status = OpenLocalMachineKey(Handle);
176 case 3: /* HKEY_USERS */
177 Status = OpenUsersKey(Handle);
180 case 4: /* HKEY_PERFORMANCE_DATA */
181 Status = OpenPerformanceDataKey(Handle);
184 case 5: /* HKEY_CURRENT_CONFIG */
185 Status = OpenCurrentConfigKey(Handle);
188 DPRINT("MapDefaultHandle() no handle creator\n");
189 Status = STATUS_INVALID_PARAMETER;
192 RtlLeaveCriticalSection(&HandleTableCS);
193 if (NT_SUCCESS(Status)) {
194 *RealKey = (HKEY)*Handle;
201 CloseDefaultKeys(VOID)
205 RtlEnterCriticalSection(&HandleTableCS);
206 for (i = 0; i < MAX_DEFAULT_HANDLES; i++) {
207 if (DefaultHandleTable[i] != NULL) {
208 NtClose (DefaultHandleTable[i]);
209 DefaultHandleTable[i] = NULL;
212 RtlLeaveCriticalSection(&HandleTableCS);
217 OpenClassesRootKey(PHANDLE KeyHandle)
219 OBJECT_ATTRIBUTES Attributes;
220 UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\Software\\CLASSES");
222 DPRINT("OpenClassesRootKey()\n");
224 InitializeObjectAttributes(&Attributes,
226 OBJ_CASE_INSENSITIVE,
229 return(NtOpenKey(KeyHandle,
236 OpenLocalMachineKey(PHANDLE KeyHandle)
238 OBJECT_ATTRIBUTES Attributes;
239 UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine");
241 DPRINT("OpenLocalMachineKey()\n");
243 InitializeObjectAttributes(&Attributes,
245 OBJ_CASE_INSENSITIVE,
248 return(NtOpenKey(KeyHandle,
255 OpenUsersKey(PHANDLE KeyHandle)
257 OBJECT_ATTRIBUTES Attributes;
258 UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\User");
260 DPRINT("OpenUsersKey()\n");
262 InitializeObjectAttributes(&Attributes,
264 OBJ_CASE_INSENSITIVE,
267 return(NtOpenKey(KeyHandle,
274 OpenCurrentConfigKey(PHANDLE KeyHandle)
276 OBJECT_ATTRIBUTES Attributes;
277 UNICODE_STRING KeyName =
278 UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
280 DPRINT("OpenCurrentConfigKey()\n");
282 InitializeObjectAttributes(&Attributes,
284 OBJ_CASE_INSENSITIVE,
287 return(NtOpenKey(KeyHandle,
292 /************************************************************************
296 RegCloseKey(HKEY hKey)
300 /* don't close null handle or a pseudo handle */
301 if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000))
302 return ERROR_INVALID_HANDLE;
303 Status = NtClose (hKey);
304 if (!NT_SUCCESS(Status)) {
305 LONG ErrorCode = RtlNtStatusToDosError(Status);
306 SetLastError (ErrorCode);
309 return ERROR_SUCCESS;
313 /************************************************************************
314 * RegConnectRegistryA
317 RegConnectRegistryA(LPCSTR lpMachineName,
321 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
322 return ERROR_CALL_NOT_IMPLEMENTED;
326 /************************************************************************
327 * RegConnectRegistryW
330 RegConnectRegistryW(LPCWSTR lpMachineName,
334 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
335 return ERROR_CALL_NOT_IMPLEMENTED;
339 /************************************************************************
343 RegCreateKeyExA(HKEY hKey,
349 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
351 LPDWORD lpdwDisposition)
353 UNICODE_STRING SubKeyString;
354 UNICODE_STRING ClassString;
355 OBJECT_ATTRIBUTES Attributes;
359 DPRINT("RegCreateKeyExW() called\n");
361 /* get the real parent key */
362 Status = MapDefaultKey(&ParentKey, hKey);
363 if (!NT_SUCCESS(Status)) {
364 LONG ErrorCode = RtlNtStatusToDosError(Status);
365 SetLastError(ErrorCode);
368 DPRINT("ParentKey %x\n", (ULONG)ParentKey);
371 RtlCreateUnicodeStringFromAsciiz(&ClassString, lpClass);
372 RtlCreateUnicodeStringFromAsciiz(&SubKeyString, (LPSTR)lpSubKey);
373 InitializeObjectAttributes(&Attributes,
375 OBJ_CASE_INSENSITIVE,
377 (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
378 Status = NtCreateKey(phkResult,
382 (lpClass == NULL)? NULL : &ClassString,
384 (PULONG)lpdwDisposition);
385 RtlFreeUnicodeString(&SubKeyString);
387 RtlFreeUnicodeString(&ClassString);
388 DPRINT("Status %x\n", Status);
389 if (!NT_SUCCESS(Status)) {
390 LONG ErrorCode = RtlNtStatusToDosError(Status);
391 SetLastError (ErrorCode);
394 return(ERROR_SUCCESS);
398 /************************************************************************
402 RegCreateKeyExW(HKEY hKey,
408 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
410 LPDWORD lpdwDisposition)
412 UNICODE_STRING SubKeyString;
413 UNICODE_STRING ClassString;
414 OBJECT_ATTRIBUTES Attributes;
418 DPRINT("RegCreateKeyExW() called\n");
420 /* get the real parent key */
421 Status = MapDefaultKey (&ParentKey, hKey);
422 if (!NT_SUCCESS(Status)) {
423 LONG ErrorCode = RtlNtStatusToDosError(Status);
424 SetLastError (ErrorCode);
427 DPRINT("ParentKey %x\n", (ULONG)ParentKey);
428 RtlInitUnicodeString (&ClassString, lpClass);
429 RtlInitUnicodeString (&SubKeyString, lpSubKey);
430 InitializeObjectAttributes (&Attributes,
432 OBJ_CASE_INSENSITIVE,
434 (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
435 Status = NtCreateKey (phkResult,
439 (lpClass == NULL)? NULL : &ClassString,
441 (PULONG)lpdwDisposition);
442 DPRINT("Status %x\n", Status);
443 if (!NT_SUCCESS(Status)) {
444 LONG ErrorCode = RtlNtStatusToDosError(Status);
445 SetLastError (ErrorCode);
448 return ERROR_SUCCESS;
452 /************************************************************************
456 RegCreateKeyA(HKEY hKey,
460 return(RegCreateKeyExA(hKey,
472 /************************************************************************
476 RegCreateKeyW(HKEY hKey,
480 return(RegCreateKeyExW(hKey,
492 /************************************************************************
501 OBJECT_ATTRIBUTES ObjectAttributes;
502 UNICODE_STRING SubKeyStringW;
503 ANSI_STRING SubKeyStringA;
510 Status = MapDefaultKey(&ParentKey, hKey);
511 if (!NT_SUCCESS(Status)) {
512 ErrorCode = RtlNtStatusToDosError(Status);
513 SetLastError (ErrorCode);
516 RtlInitAnsiString(&SubKeyStringA, (LPSTR)lpSubKey);
517 RtlAnsiStringToUnicodeString(&SubKeyStringW, &SubKeyStringA, TRUE);
518 InitializeObjectAttributes (&ObjectAttributes,
520 OBJ_CASE_INSENSITIVE,
523 Status = NtOpenKey(&TargetKey, DELETE, &ObjectAttributes);
524 RtlFreeUnicodeString(&SubKeyStringW);
525 if (!NT_SUCCESS(Status)) {
526 ErrorCode = RtlNtStatusToDosError(Status);
527 SetLastError(ErrorCode);
530 Status = NtDeleteKey(TargetKey);
532 if (!NT_SUCCESS(Status)) {
533 ErrorCode = RtlNtStatusToDosError(Status);
534 SetLastError(ErrorCode);
537 return ERROR_SUCCESS;
541 /************************************************************************
550 OBJECT_ATTRIBUTES ObjectAttributes;
551 UNICODE_STRING SubKeyString;
557 Status = MapDefaultKey(&ParentKey, hKey);
558 if (!NT_SUCCESS(Status)) {
559 ErrorCode = RtlNtStatusToDosError(Status);
560 SetLastError (ErrorCode);
563 RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
565 InitializeObjectAttributes (&ObjectAttributes,
567 OBJ_CASE_INSENSITIVE,
570 Status = NtOpenKey(&TargetKey, DELETE, &ObjectAttributes);
571 if (!NT_SUCCESS(Status)) {
572 ErrorCode = RtlNtStatusToDosError(Status);
573 SetLastError (ErrorCode);
576 Status = NtDeleteKey(TargetKey);
578 if (!NT_SUCCESS(Status)) {
579 ErrorCode = RtlNtStatusToDosError(Status);
580 SetLastError (ErrorCode);
583 return ERROR_SUCCESS;
587 /************************************************************************
596 UNICODE_STRING ValueNameW;
597 ANSI_STRING ValueNameA;
602 Status = MapDefaultKey(&KeyHandle, hKey);
603 if (!NT_SUCCESS(Status)) {
604 ErrorCode = RtlNtStatusToDosError(Status);
605 SetLastError (ErrorCode);
608 RtlInitAnsiString(&ValueNameA, (LPSTR)lpValueName);
609 RtlAnsiStringToUnicodeString(&ValueNameW, &ValueNameA, TRUE);
610 Status = NtDeleteValueKey(KeyHandle, &ValueNameW);
611 RtlFreeUnicodeString (&ValueNameW);
612 if (!NT_SUCCESS(Status)) {
613 ErrorCode = RtlNtStatusToDosError(Status);
614 SetLastError (ErrorCode);
617 return ERROR_SUCCESS;
621 /************************************************************************
630 UNICODE_STRING ValueName;
635 Status = MapDefaultKey(&KeyHandle, hKey);
636 if (!NT_SUCCESS(Status))
638 ErrorCode = RtlNtStatusToDosError(Status);
639 SetLastError (ErrorCode);
642 RtlInitUnicodeString(&ValueName, (LPWSTR)lpValueName);
643 Status = NtDeleteValueKey(KeyHandle, &ValueName);
644 if (!NT_SUCCESS(Status)) {
645 ErrorCode = RtlNtStatusToDosError(Status);
646 SetLastError (ErrorCode);
649 return ERROR_SUCCESS;
653 /************************************************************************
666 PFILETIME lpftLastWriteTime)
668 PKEY_NODE_INFORMATION KeyInfo;
670 DWORD dwError = ERROR_SUCCESS;
675 Status = MapDefaultKey(&KeyHandle, hKey);
676 if (!NT_SUCCESS(Status)) {
677 dwError = RtlNtStatusToDosError(Status);
678 SetLastError (dwError);
682 BufferSize = sizeof (KEY_NODE_INFORMATION) + *lpcbName * sizeof(WCHAR);
684 BufferSize += *lpcbClass;
687 // I think this is a memory leak, always allocated again below ???
689 // KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
692 /* We don't know the exact size of the data returned, so call
693 NtEnumerateKey() with a buffer size determined from parameters
694 to this function. If that call fails with a status code of
695 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
697 KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
698 if (KeyInfo == NULL) {
699 SetLastError(ERROR_OUTOFMEMORY);
700 return ERROR_OUTOFMEMORY;
702 Status = NtEnumerateKey(
710 DPRINT("NtEnumerateKey() returned status 0x%X\n", Status);
712 if (Status == STATUS_BUFFER_OVERFLOW) {
713 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
714 BufferSize = ResultSize;
717 if (!NT_SUCCESS(Status)) {
718 dwError = RtlNtStatusToDosError(Status);
719 SetLastError(dwError);
722 if ((lpClass) && (*lpcbClass != 0) && (KeyInfo->ClassLength > *lpcbClass)) {
723 dwError = ERROR_MORE_DATA;
724 SetLastError(dwError);
727 RtlMoveMemory(lpName, KeyInfo->Name, KeyInfo->NameLength);
728 *lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR));
729 RegiTerminateWideString(lpName, *lpcbName);
731 RtlMoveMemory(lpClass,
732 (PVOID)((ULONG_PTR)KeyInfo->Name + KeyInfo->ClassOffset),
733 KeyInfo->ClassLength);
734 *lpcbClass = (DWORD)(KeyInfo->ClassLength / sizeof(WCHAR));
736 if (lpftLastWriteTime) {
737 /* FIXME: Fill lpftLastWriteTime */
742 RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo);
747 /************************************************************************
758 DWORD dwLength = cbName;
760 return RegEnumKeyExW(hKey,
771 /************************************************************************
784 PFILETIME lpftLastWriteTime)
786 WCHAR Name[MAX_PATH+1];
787 UNICODE_STRING UnicodeStringName;
788 WCHAR Class[MAX_PATH+1];
789 UNICODE_STRING UnicodeStringClass;
790 ANSI_STRING AnsiString;
795 DPRINT("hKey 0x%x dwIndex %d lpName 0x%x *lpcbName %d lpClass 0x%x lpcbClass %d\n",
796 hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass);
798 if ((lpClass) && (!lpcbClass)) {
799 SetLastError(ERROR_INVALID_PARAMETER);
800 return ERROR_INVALID_PARAMETER;
802 RtlInitUnicodeString(&UnicodeStringName, NULL);
803 UnicodeStringName.Buffer = &Name[0];
804 UnicodeStringName.MaximumLength = sizeof(Name);
805 RtlInitUnicodeString(&UnicodeStringClass, NULL);
807 UnicodeStringClass.Buffer = &Class[0];
808 UnicodeStringClass.MaximumLength = sizeof(Class);
809 ClassLength = *lpcbClass;
813 NameLength = *lpcbName;
814 ErrorCode = RegEnumKeyExW(
817 UnicodeStringName.Buffer,
820 UnicodeStringClass.Buffer,
824 if (ErrorCode != ERROR_SUCCESS)
827 UnicodeStringName.Length = NameLength * sizeof(WCHAR);
828 UnicodeStringClass.Length = ClassLength * sizeof(WCHAR);
829 RtlInitAnsiString(&AnsiString, NULL);
830 AnsiString.Buffer = lpName;
831 AnsiString.MaximumLength = *lpcbName;
832 RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringName, FALSE);
833 *lpcbName = AnsiString.Length;
835 DPRINT("Key Namea0 Length %d\n", UnicodeStringName.Length);
836 DPRINT("Key Namea1 Length %d\n", NameLength);
837 DPRINT("Key Namea Length %d\n", *lpcbName);
838 DPRINT("Key Namea %s\n", lpName);
841 RtlInitAnsiString(&AnsiString, NULL);
842 AnsiString.Buffer = lpClass;
843 AnsiString.MaximumLength = *lpcbClass;
844 RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringClass, FALSE);
845 *lpcbClass = AnsiString.Length;
847 return ERROR_SUCCESS;
851 /************************************************************************
862 DWORD dwLength = cbName;
864 return RegEnumKeyExA(hKey,
875 /************************************************************************
884 LPDWORD lpcbValueName,
890 PKEY_VALUE_FULL_INFORMATION ValueInfo;
892 DWORD dwError = ERROR_SUCCESS;
897 Status = MapDefaultKey(&KeyHandle, hKey);
898 if (!NT_SUCCESS(Status)) {
899 dwError = RtlNtStatusToDosError(Status);
900 SetLastError(dwError);
903 BufferSize = sizeof (KEY_VALUE_FULL_INFORMATION) + *lpcbValueName * sizeof(WCHAR);
905 BufferSize += *lpcbData;
907 /* We don't know the exact size of the data returned, so call
908 NtEnumerateValueKey() with a buffer size determined from parameters
909 to this function. If that call fails with a status code of
910 STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
912 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
913 if (ValueInfo == NULL) {
914 SetLastError(ERROR_OUTOFMEMORY);
915 return ERROR_OUTOFMEMORY;
917 Status = NtEnumerateValueKey(
920 KeyValueFullInformation,
925 DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status);
927 if (Status == STATUS_BUFFER_OVERFLOW) {
928 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
929 BufferSize = ResultSize;
932 if (!NT_SUCCESS(Status)) {
933 dwError = RtlNtStatusToDosError(Status);
934 SetLastError(dwError);
937 if ((lpData) && (*lpcbData != 0) && (ValueInfo->DataLength > *lpcbData)) {
938 dwError = ERROR_MORE_DATA;
939 SetLastError(dwError);
942 memcpy(lpValueName, ValueInfo->Name, ValueInfo->NameLength);
943 *lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR));
944 RegiTerminateWideString(lpValueName, *lpcbValueName);
946 *lpType = ValueInfo->Type;
949 //(PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset),
950 (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
951 ValueInfo->DataLength);
952 *lpcbData = (DWORD)ValueInfo->DataLength;
954 RtlCopyMemory((PCHAR) ValueFullInformation + ValueFullInformation->DataOffset,
956 ValueCell->DataSize & LONG_MAX);
962 RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo);
967 /************************************************************************
976 LPDWORD lpcbValueName,
982 WCHAR ValueName[MAX_PATH+1];
983 UNICODE_STRING UnicodeString;
984 ANSI_STRING AnsiString;
986 DWORD ValueNameLength;
987 BYTE* lpDataBuffer = NULL;
990 ANSI_STRING AnsiDataString;
991 UNICODE_STRING UnicodeDataString;
993 if (lpData != NULL /*&& lpcbData != NULL*/) {
994 cbData = *lpcbData; // this should always be valid if lpData is valid
995 lpDataBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, (*lpcbData) * sizeof(WCHAR));
996 if (lpDataBuffer == NULL) {
997 SetLastError(ERROR_OUTOFMEMORY);
998 return ERROR_OUTOFMEMORY;
1001 RtlInitUnicodeString(&UnicodeString, NULL);
1002 UnicodeString.Buffer = &ValueName[0];
1003 UnicodeString.MaximumLength = sizeof(ValueName);
1004 ValueNameLength = *lpcbValueName;
1005 ErrorCode = RegEnumValueW(
1008 UnicodeString.Buffer,
1014 if (ErrorCode != ERROR_SUCCESS)
1016 UnicodeString.Length = ValueNameLength * sizeof(WCHAR);
1017 RtlInitAnsiString(&AnsiString, NULL);
1018 AnsiString.Buffer = lpValueName;
1019 AnsiString.MaximumLength = *lpcbValueName;
1020 RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
1021 *lpcbValueName = AnsiString.Length;
1022 // if (lpData != lpDataBuffer) { // did we use a temp buffer
1023 if (lpDataBuffer) { // did we use a temp buffer
1024 if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) {
1025 RtlInitUnicodeString(&UnicodeDataString, NULL);
1026 UnicodeDataString.Buffer = (WCHAR*)lpDataBuffer;
1027 UnicodeDataString.MaximumLength = (*lpcbData) * sizeof(WCHAR);
1028 UnicodeDataString.Length = cbData /* * sizeof(WCHAR)*/;
1029 RtlInitAnsiString(&AnsiDataString, NULL);
1030 AnsiDataString.Buffer = lpData;
1031 AnsiDataString.MaximumLength = *lpcbData;
1032 RtlUnicodeStringToAnsiString(&AnsiDataString, &UnicodeDataString, FALSE);
1033 *lpcbData = AnsiDataString.Length;
1034 // else if (Type == REG_EXPAND_SZ) {
1036 memcpy(lpData, lpDataBuffer, min(*lpcbData, cbData));
1039 RtlFreeHeap(RtlGetProcessHeap(), 0, lpDataBuffer);
1041 if (lpType != NULL) {
1044 return ERROR_SUCCESS;
1048 /************************************************************************
1052 RegFlushKey(HKEY hKey)
1058 if (hKey == HKEY_PERFORMANCE_DATA)
1059 return(ERROR_SUCCESS);
1060 Status = MapDefaultKey(&KeyHandle, hKey);
1061 if (!NT_SUCCESS(Status)) {
1062 ErrorCode = RtlNtStatusToDosError(Status);
1063 SetLastError(ErrorCode);
1066 Status = NtFlushKey(KeyHandle);
1067 if (!NT_SUCCESS(Status)) {
1068 ErrorCode = RtlNtStatusToDosError(Status);
1069 SetLastError(ErrorCode);
1072 return(ERROR_SUCCESS);
1076 /************************************************************************
1083 SECURITY_INFORMATION SecurityInformation,
1084 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1085 LPDWORD lpcbSecurityDescriptor)
1088 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1089 return ERROR_CALL_NOT_IMPLEMENTED;
1093 /************************************************************************
1104 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1105 return ERROR_CALL_NOT_IMPLEMENTED;
1109 /************************************************************************
1119 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1120 return ERROR_CALL_NOT_IMPLEMENTED;
1124 /************************************************************************
1125 * RegNotifyChangeKeyValue
1129 RegNotifyChangeKeyValue(
1132 DWORD dwNotifyFilter,
1137 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1138 return ERROR_CALL_NOT_IMPLEMENTED;
1143 /************************************************************************
1147 RegOpenKeyA(HKEY hKey,
1151 OBJECT_ATTRIBUTES ObjectAttributes;
1152 UNICODE_STRING SubKeyString;
1157 Status = MapDefaultKey(&KeyHandle, hKey);
1158 if (!NT_SUCCESS(Status)) {
1159 ErrorCode = RtlNtStatusToDosError(Status);
1160 SetLastError(ErrorCode);
1163 RtlCreateUnicodeStringFromAsciiz(&SubKeyString, (LPSTR)lpSubKey);
1164 InitializeObjectAttributes(&ObjectAttributes,
1166 OBJ_CASE_INSENSITIVE,
1169 Status = NtOpenKey(phkResult, KEY_ALL_ACCESS, &ObjectAttributes);
1170 RtlFreeUnicodeString(&SubKeyString);
1171 if (!NT_SUCCESS(Status)) {
1172 ErrorCode = RtlNtStatusToDosError(Status);
1173 SetLastError(ErrorCode);
1176 return(ERROR_SUCCESS);
1180 /************************************************************************
1194 UNICODE_STRING SubKeyString;
1195 OBJECT_ATTRIBUTES ObjectAttributes;
1199 errCode = MapDefaultKey(&KeyHandle, hKey);
1200 if (!NT_SUCCESS(errCode)) {
1201 ErrorCode = RtlNtStatusToDosError(errCode);
1202 SetLastError (ErrorCode);
1205 RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
1206 InitializeObjectAttributes(&ObjectAttributes,
1208 OBJ_CASE_INSENSITIVE,
1211 errCode = NtOpenKey(phkResult, KEY_ALL_ACCESS, &ObjectAttributes);
1212 if (!NT_SUCCESS(errCode)) {
1213 ErrorCode = RtlNtStatusToDosError(errCode);
1214 SetLastError(ErrorCode);
1217 return ERROR_SUCCESS;
1221 /************************************************************************
1225 RegOpenKeyExA(HKEY hKey,
1231 OBJECT_ATTRIBUTES ObjectAttributes;
1232 UNICODE_STRING SubKeyString;
1237 Status = MapDefaultKey(&KeyHandle, hKey);
1238 if (!NT_SUCCESS(Status)) {
1239 ErrorCode = RtlNtStatusToDosError(Status);
1240 SetLastError(ErrorCode);
1243 RtlCreateUnicodeStringFromAsciiz(&SubKeyString, (LPSTR)lpSubKey);
1244 InitializeObjectAttributes(&ObjectAttributes,
1246 OBJ_CASE_INSENSITIVE,
1249 Status = NtOpenKey(phkResult, samDesired, &ObjectAttributes);
1250 RtlFreeUnicodeString(&SubKeyString);
1251 if (!NT_SUCCESS(Status)) {
1252 ErrorCode = RtlNtStatusToDosError(Status);
1253 SetLastError(ErrorCode);
1256 return(ERROR_SUCCESS);
1260 /************************************************************************
1264 RegOpenKeyExW(HKEY hKey,
1270 OBJECT_ATTRIBUTES ObjectAttributes;
1271 UNICODE_STRING SubKeyString;
1276 Status = MapDefaultKey(&KeyHandle, hKey);
1277 if (!NT_SUCCESS(Status)) {
1278 ErrorCode = RtlNtStatusToDosError(Status);
1279 SetLastError (ErrorCode);
1282 if (lpSubKey != NULL) {
1283 RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
1285 RtlInitUnicodeString(&SubKeyString, (LPWSTR)L"");
1287 InitializeObjectAttributes(&ObjectAttributes,
1289 OBJ_CASE_INSENSITIVE,
1292 Status = NtOpenKey(phkResult, samDesired, &ObjectAttributes);
1293 if (!NT_SUCCESS(Status)) {
1294 ErrorCode = RtlNtStatusToDosError(Status);
1295 SetLastError(ErrorCode);
1298 return(ERROR_SUCCESS);
1302 /************************************************************************
1313 LPDWORD lpcbMaxSubKeyLen,
1314 LPDWORD lpcbMaxClassLen,
1316 LPDWORD lpcbMaxValueNameLen,
1317 LPDWORD lpcbMaxValueLen,
1318 LPDWORD lpcbSecurityDescriptor,
1319 PFILETIME lpftLastWriteTime)
1321 KEY_FULL_INFORMATION FullInfoBuffer;
1322 PKEY_FULL_INFORMATION FullInfo;
1329 if ((lpClass) && (!lpcbClass)) {
1330 SetLastError(ERROR_INVALID_PARAMETER);
1331 return ERROR_INVALID_PARAMETER;
1334 Status = MapDefaultKey(&KeyHandle, hKey);
1338 FullInfoSize = sizeof(KEY_FULL_INFORMATION) + *lpcbClass;
1339 FullInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullInfoSize);
1341 SetLastError(ERROR_OUTOFMEMORY);
1342 return ERROR_OUTOFMEMORY;
1344 FullInfo->ClassLength = *lpcbClass;
1346 FullInfoSize = sizeof(KEY_FULL_INFORMATION);
1347 FullInfo = &FullInfoBuffer;
1348 FullInfo->ClassLength = 1;
1350 FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
1351 Status = NtQueryKey(
1357 if (!NT_SUCCESS(Status)) {
1359 RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo);
1361 ErrorCode = RtlNtStatusToDosError(Status);
1362 SetLastError(ErrorCode);
1366 *lpcSubKeys = FullInfo->SubKeys;
1368 if (lpcbMaxSubKeyLen) {
1369 *lpcbMaxSubKeyLen = FullInfo->MaxNameLen;
1371 if (lpcbMaxClassLen) {
1372 *lpcbMaxClassLen = FullInfo->MaxClassLen;
1375 *lpcValues = FullInfo->Values;
1377 if (lpcbMaxValueNameLen) {
1378 *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen;
1380 if (lpcbMaxValueLen) {
1381 *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
1383 if (lpcbSecurityDescriptor) {
1384 *lpcbSecurityDescriptor = 0;
1387 if (lpftLastWriteTime != NULL) {
1388 lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
1389 lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
1392 wcsncpy(lpClass, FullInfo->Class, *lpcbClass);
1393 RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo);
1395 SetLastError(ERROR_SUCCESS);
1396 return ERROR_SUCCESS;
1400 /************************************************************************
1411 LPDWORD lpcbMaxSubKeyLen,
1412 LPDWORD lpcbMaxClassLen,
1414 LPDWORD lpcbMaxValueNameLen,
1415 LPDWORD lpcbMaxValueLen,
1416 LPDWORD lpcbSecurityDescriptor,
1417 PFILETIME lpftLastWriteTime)
1419 WCHAR ClassName[MAX_PATH];
1420 UNICODE_STRING UnicodeString;
1421 ANSI_STRING AnsiString;
1424 RtlInitUnicodeString(&UnicodeString, NULL);
1426 UnicodeString.Buffer = &ClassName[0];
1427 UnicodeString.MaximumLength = sizeof(ClassName);
1429 ErrorCode = RegQueryInfoKeyW(
1431 UnicodeString.Buffer,
1438 lpcbMaxValueNameLen,
1440 lpcbSecurityDescriptor,
1443 if ((ErrorCode == ERROR_SUCCESS) && (lpClass)) {
1444 RtlInitAnsiString(&AnsiString, NULL);
1445 AnsiString.Buffer = lpClass;
1446 AnsiString.MaximumLength = *lpcbClass;
1447 RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
1448 *lpcbClass = AnsiString.Length;
1454 /************************************************************************
1455 * RegQueryMultipleValuesA
1459 RegQueryMultipleValuesA(
1467 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1468 return ERROR_CALL_NOT_IMPLEMENTED;
1472 /************************************************************************
1473 * RegQueryMultipleValuesW
1477 RegQueryMultipleValuesW(
1485 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1486 return ERROR_CALL_NOT_IMPLEMENTED;
1490 /************************************************************************
1497 LPCWSTR lpValueName,
1503 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
1504 UNICODE_STRING ValueName;
1506 DWORD dwError = ERROR_SUCCESS;
1511 DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
1512 hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
1513 Status = MapDefaultKey(&KeyHandle, hKey);
1514 if (!NT_SUCCESS(Status)) {
1515 dwError = RtlNtStatusToDosError(Status);
1516 SetLastError(dwError);
1519 if ((lpData) && (!lpcbData)) {
1520 SetLastError(ERROR_INVALID_PARAMETER);
1521 return ERROR_INVALID_PARAMETER;
1523 RtlInitUnicodeString (&ValueName, lpValueName);
1524 BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData;
1525 ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(),
1528 if (ValueInfo == NULL) {
1529 SetLastError(ERROR_OUTOFMEMORY);
1530 return ERROR_OUTOFMEMORY;
1532 Status = NtQueryValueKey (hKey,
1534 KeyValuePartialInformation,
1538 DPRINT("Status 0x%X\n", Status);
1539 if (Status == STATUS_BUFFER_TOO_SMALL) {
1540 /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
1541 dwError = ERROR_SUCCESS;
1543 else if (!NT_SUCCESS(Status)) {
1544 dwError = RtlNtStatusToDosError(Status);
1545 SetLastError(dwError);
1549 *lpType = ValueInfo->Type;
1551 RtlMoveMemory(lpData, ValueInfo->Data, ValueInfo->DataLength);
1552 if ((ValueInfo->Type == REG_SZ) ||
1553 (ValueInfo->Type == REG_MULTI_SZ) ||
1554 (ValueInfo->Type == REG_EXPAND_SZ)) {
1555 ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
1558 DPRINT("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
1559 if (NULL != lpcbData) {
1560 *lpcbData = (DWORD)ValueInfo->DataLength;
1562 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
1567 /************************************************************************
1580 WCHAR ValueNameBuffer[MAX_PATH+1];
1581 UNICODE_STRING ValueName;
1582 UNICODE_STRING ValueData;
1583 ANSI_STRING AnsiString;
1588 /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
1590 if ((lpData) && (!lpcbData)) {
1591 SetLastError(ERROR_INVALID_PARAMETER);
1592 return ERROR_INVALID_PARAMETER;
1594 RtlInitUnicodeString(&ValueData, NULL);
1596 ValueData.MaximumLength = *lpcbData * sizeof(WCHAR);
1597 ValueData.Buffer = RtlAllocateHeap(
1598 RtlGetProcessHeap(),
1600 ValueData.MaximumLength);
1601 if (!ValueData.Buffer) {
1602 SetLastError(ERROR_OUTOFMEMORY);
1603 return ERROR_OUTOFMEMORY;
1606 RtlInitAnsiString(&AnsiString, (LPSTR)lpValueName);
1607 RtlInitUnicodeString(&ValueName, NULL);
1608 ValueName.Buffer = &ValueNameBuffer[0];
1609 ValueName.MaximumLength = sizeof(ValueNameBuffer);
1610 RtlAnsiStringToUnicodeString(&ValueName, &AnsiString, FALSE);
1612 ResultSize = *lpcbData;
1616 ErrorCode = RegQueryValueExW(
1621 (LPBYTE)ValueData.Buffer,
1623 if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL)) {
1627 if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) {
1628 ValueData.Length = ResultSize;
1629 RtlInitAnsiString(&AnsiString, NULL);
1630 AnsiString.Buffer = lpData;
1631 AnsiString.MaximumLength = *lpcbData;
1632 RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
1634 RtlMoveMemory(lpData, ValueData.Buffer, ResultSize);
1638 *lpcbData = ResultSize;
1640 if (ValueData.Buffer) {
1641 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData.Buffer);
1647 /************************************************************************
1659 UNICODE_STRING SubKeyString;
1660 OBJECT_ATTRIBUTES ObjectAttributes;
1666 errCode = MapDefaultKey(&KeyHandle, hKey);
1667 if (!NT_SUCCESS(errCode)) {
1668 ErrorCode = RtlNtStatusToDosError(errCode);
1669 SetLastError (ErrorCode);
1672 if ((lpSubKey) && (wcslen(lpSubKey) != 0)) {
1673 RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
1674 InitializeObjectAttributes(&ObjectAttributes,
1676 OBJ_CASE_INSENSITIVE,
1679 errCode = NtOpenKey(
1682 & ObjectAttributes);
1683 if (!NT_SUCCESS(errCode)) {
1684 ErrorCode = RtlNtStatusToDosError(errCode);
1685 SetLastError(ErrorCode);
1688 CloseRealKey = TRUE;
1691 CloseRealKey = FALSE;
1693 ErrorCode = RegQueryValueExW(
1699 (LPDWORD)lpcbValue);
1707 /************************************************************************
1718 WCHAR SubKeyNameBuffer[MAX_PATH+1];
1719 UNICODE_STRING SubKeyName;
1720 UNICODE_STRING Value;
1721 ANSI_STRING AnsiString;
1725 if ((lpValue) && (!lpcbValue)) {
1726 SetLastError(ERROR_INVALID_PARAMETER);
1727 return ERROR_INVALID_PARAMETER;
1729 RtlInitUnicodeString(&SubKeyName, NULL);
1730 RtlInitUnicodeString(&Value, NULL);
1731 if ((lpSubKey) && (strlen(lpSubKey) != 0)) {
1732 RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
1733 SubKeyName.Buffer = &SubKeyNameBuffer[0];
1734 SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
1735 RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
1738 ValueSize = *lpcbValue * sizeof(WCHAR);
1739 Value.MaximumLength = ValueSize;
1740 Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize);
1741 if (!Value.Buffer) {
1742 SetLastError(ERROR_OUTOFMEMORY);
1743 return ERROR_OUTOFMEMORY;
1748 ErrorCode = RegQueryValueW(
1750 (LPCWSTR)SubKeyName.Buffer,
1753 if (ErrorCode == ERROR_SUCCESS) {
1754 Value.Length = ValueSize;
1755 RtlInitAnsiString(&AnsiString, NULL);
1756 AnsiString.Buffer = lpValue;
1757 AnsiString.MaximumLength = *lpcbValue;
1758 RtlUnicodeStringToAnsiString(&AnsiString, &Value, FALSE);
1760 *lpcbValue = ValueSize;
1762 RtlFreeHeap(RtlGetProcessHeap(), 0, Value.Buffer);
1768 /************************************************************************
1780 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1781 return ERROR_CALL_NOT_IMPLEMENTED;
1785 /************************************************************************
1797 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1798 return ERROR_CALL_NOT_IMPLEMENTED;
1802 /************************************************************************
1813 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1814 return ERROR_CALL_NOT_IMPLEMENTED;
1818 /************************************************************************
1829 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1830 return ERROR_CALL_NOT_IMPLEMENTED;
1834 /************************************************************************
1838 RegSaveKeyW(HKEY hKey,
1840 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
1842 PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
1843 OBJECT_ATTRIBUTES ObjectAttributes;
1844 UNICODE_STRING NtName;
1845 IO_STATUS_BLOCK IoStatusBlock;
1851 Status = MapDefaultKey(&KeyHandle, hKey);
1852 if (!NT_SUCCESS(Status)) {
1853 ErrorCode = RtlNtStatusToDosError(Status);
1854 SetLastError(ErrorCode);
1857 if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFile,
1858 &NtName, NULL, NULL)) {
1859 SetLastError(ERROR_INVALID_PARAMETER);
1860 return(ERROR_INVALID_PARAMETER);
1862 if (lpSecurityAttributes != NULL)
1863 SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
1864 InitializeObjectAttributes(&ObjectAttributes,
1866 OBJ_CASE_INSENSITIVE,
1868 SecurityDescriptor);
1869 Status = NtCreateFile(&FileHandle,
1870 GENERIC_WRITE | SYNCHRONIZE,
1874 FILE_ATTRIBUTE_NORMAL,
1877 FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
1880 RtlFreeUnicodeString(&NtName);
1881 if (!NT_SUCCESS(Status)) {
1882 ErrorCode = RtlNtStatusToDosError(Status);
1883 SetLastError(ErrorCode);
1886 Status = NtSaveKey(KeyHandle, FileHandle);
1887 NtClose(FileHandle);
1888 if (!NT_SUCCESS(Status)) {
1889 ErrorCode = RtlNtStatusToDosError(Status);
1890 SetLastError(ErrorCode);
1893 return(ERROR_SUCCESS);
1897 /************************************************************************
1901 RegSaveKeyA(HKEY hKey,
1903 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
1905 UNICODE_STRING FileName;
1908 RtlCreateUnicodeStringFromAsciiz(&FileName, (LPSTR)lpFile);
1909 ErrorCode = RegSaveKeyW(hKey, FileName.Buffer, lpSecurityAttributes);
1910 RtlFreeUnicodeString(&FileName);
1915 /************************************************************************
1922 SECURITY_INFORMATION SecurityInformation, /* FIXME: ULONG? */
1923 PSECURITY_DESCRIPTOR pSecurityDescriptor
1927 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1928 return ERROR_CALL_NOT_IMPLEMENTED;
1932 /************************************************************************
1939 LPCWSTR lpValueName,
1945 UNICODE_STRING ValueName;
1946 PUNICODE_STRING pValueName;
1951 Status = MapDefaultKey(&KeyHandle, hKey);
1952 if (!NT_SUCCESS(Status)) {
1953 ErrorCode = RtlNtStatusToDosError(Status);
1954 SetLastError(ErrorCode);
1958 RtlInitUnicodeString(&ValueName, lpValueName);
1959 pValueName = &ValueName;
1963 Status = NtSetValueKey(
1970 if (!NT_SUCCESS(Status)) {
1971 LONG ErrorCode = RtlNtStatusToDosError(Status);
1972 SetLastError (ErrorCode);
1975 return ERROR_SUCCESS;
1979 /************************************************************************
1992 UNICODE_STRING ValueName;
1994 ANSI_STRING AnsiString;
1995 UNICODE_STRING Data;
2001 SetLastError(ERROR_INVALID_PARAMETER);
2002 return ERROR_INVALID_PARAMETER;
2004 if ((lpValueName) && (strlen(lpValueName) != 0)) {
2005 RtlCreateUnicodeStringFromAsciiz(&ValueName, (LPSTR)lpValueName);
2006 pValueName = (LPWSTR)ValueName.Buffer;
2010 if ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ)) {
2011 RtlInitAnsiString(&AnsiString, NULL);
2012 AnsiString.Buffer = (LPSTR)lpData;
2013 AnsiString.Length = cbData;
2014 AnsiString.MaximumLength = cbData;
2015 RtlAnsiStringToUnicodeString(&Data, &AnsiString, TRUE);
2016 pData = (LPBYTE)Data.Buffer;
2017 DataSize = cbData * sizeof(WCHAR);
2019 RtlInitUnicodeString(&Data, NULL);
2020 pData = (LPBYTE)lpData;
2023 ErrorCode = RegSetValueExW(
2031 RtlFreeHeap(RtlGetProcessHeap(), 0, ValueName.Buffer);
2034 RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
2040 /************************************************************************
2053 UNICODE_STRING SubKeyString;
2054 OBJECT_ATTRIBUTES ObjectAttributes;
2060 errCode = MapDefaultKey(&KeyHandle, hKey);
2061 if (!NT_SUCCESS(errCode)) {
2062 ErrorCode = RtlNtStatusToDosError(errCode);
2063 SetLastError (ErrorCode);
2066 if ((lpSubKey) && (wcslen(lpSubKey) != 0)) {
2067 RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
2068 InitializeObjectAttributes(&ObjectAttributes,
2070 OBJ_CASE_INSENSITIVE,
2073 errCode = NtOpenKey(&RealKey, KEY_ALL_ACCESS, &ObjectAttributes);
2074 if (!NT_SUCCESS(errCode)) {
2075 ErrorCode = RtlNtStatusToDosError(errCode);
2076 SetLastError(ErrorCode);
2079 CloseRealKey = TRUE;
2082 CloseRealKey = FALSE;
2084 ErrorCode = RegSetValueExW(
2098 /************************************************************************
2110 WCHAR SubKeyNameBuffer[MAX_PATH+1];
2111 UNICODE_STRING SubKeyName;
2112 UNICODE_STRING Data;
2113 ANSI_STRING AnsiString;
2118 SetLastError(ERROR_INVALID_PARAMETER);
2119 return ERROR_INVALID_PARAMETER;
2121 RtlInitUnicodeString(&SubKeyName, NULL);
2122 RtlInitUnicodeString(&Data, NULL);
2123 if ((lpSubKey) && (strlen(lpSubKey) != 0)) {
2124 RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
2125 SubKeyName.Buffer = &SubKeyNameBuffer[0];
2126 SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
2127 RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
2129 DataSize = cbData * sizeof(WCHAR);
2130 Data.MaximumLength = DataSize;
2131 Data.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize);
2133 SetLastError(ERROR_OUTOFMEMORY);
2134 return ERROR_OUTOFMEMORY;
2136 ErrorCode = RegSetValueW(
2138 (LPCWSTR)SubKeyName.Buffer,
2142 RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
2147 /************************************************************************
2157 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2158 return ERROR_CALL_NOT_IMPLEMENTED;
2162 /************************************************************************
2172 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2173 return ERROR_CALL_NOT_IMPLEMENTED;