-/*
+/* $Id: reg.c,v 1.19 2002/11/10 13:44:48 robd Exp $
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/advapi32/reg/reg.c
* Created 01/11/98
* 19990309 EA Stubs
*/
-#include <windows.h>
+
+#ifdef WIN32_REGDBG
+#include "cm_win32.h"
+
+#ifdef __GNUC__
+#define WINAPI __stdcall
+#define WINAPIV __cdecl
+#define APIENTRY __stdcall
+#define DECLSPEC_IMPORT __declspec(dllimport)
+#define DECLSPEC_EXPORT __declspec(dllexport)
+#define DECLARE_HANDLE(n) typedef HANDLE n
+#define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004)
+
+#define ERROR_SUCCESS 0L
+#define ERROR_INVALID_HANDLE 6L
+#define ERROR_OUTOFMEMORY 14L
+#define ERROR_INVALID_PARAMETER 87L
+#define ERROR_CALL_NOT_IMPLEMENTED 120L
+#define ERROR_MORE_DATA 234L
+
+void WINAPI SetLastError(DWORD);
+
+BOOLEAN
+STDCALL
+RtlDosPathNameToNtPathName_U (
+ PWSTR dosname,
+ PUNICODE_STRING ntname,
+ PWSTR *shortname,
+ PCURDIR nah);
+
+NTSTATUS
+STDCALL
+RtlInitializeCriticalSection(LPCRITICAL_SECTION lpcs);
+
+NTSTATUS
+STDCALL
+RtlDeleteCriticalSection(LPCRITICAL_SECTION lpcs);
+
+NTSTATUS
+STDCALL
+RtlLeaveCriticalSection(LPCRITICAL_SECTION lpcs);
+
+NTSTATUS
+STDCALL
+RtlEnterCriticalSection(LPCRITICAL_SECTION lpcs);
+
+DECLARE_HANDLE(HKEY);
+typedef HKEY *PHKEY;
+typedef ACCESS_MASK REGSAM;
+
+typedef struct value_entA {
+ LPSTR ve_valuename;
+ DWORD ve_valuelen;
+ DWORD ve_valueptr;
+ DWORD ve_type;
+} VALENTA,*PVALENTA;
+typedef struct value_entW {
+ LPWSTR ve_valuename;
+ DWORD ve_valuelen;
+ DWORD ve_valueptr;
+ DWORD ve_type;
+} VALENTW,*PVALENTW;
+#endif
+
+#undef STDCALL
+#define STDCALL _stdcall
+#undef RegSetValueEx
+#undef RegCreateKeyEx
+#undef RegQueryInfoKey
+#undef RegDeleteKey
+#undef RegOpenKey
+#undef RegOpenKeyEx
+#undef RegEnumKeyEx
+#undef RegEnumValue
+#else
#include <ddk/ntddk.h>
+#include <ntdll/rtl.h>
+#include <windows.h>
#include <wchar.h>
+#define NDEBUG
+#include <debug.h>
+#endif
+
+#define CHECK_STATUS \
+{ \
+ if (!NT_SUCCESS(Status)) \
+ { \
+ LONG _ErrorCode = RtlNtStatusToDosError(Status); \
+ SetLastError(_ErrorCode); \
+ return _ErrorCode; \
+ } \
+}
+
+/* GLOBALS *******************************************************************/
+
+#define MAX_DEFAULT_HANDLES 6
+
+static CRITICAL_SECTION HandleTableCS;
+static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
+
+
+/* PROTOTYPES ****************************************************************/
+
+static NTSTATUS MapDefaultKey (PHKEY ParentKey, HKEY Key);
+static VOID CloseDefaultKeys(VOID);
+
+static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
+static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
+static NTSTATUS OpenUsersKey (PHANDLE KeyHandle);
+static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle);
+
+
+/* FUNCTIONS *****************************************************************/
+
+inline RegiTerminateWideString(LPWSTR String, DWORD Length)
+{
+ LPWSTR AfterString = String + Length;
+ *AfterString = 0;
+}
+
+/************************************************************************
+ * RegInitDefaultHandles
+ */
+
+BOOL
+RegInitialize (VOID)
+{
+ DPRINT("RegInitialize()\n");
+
+ RtlZeroMemory (DefaultHandleTable,
+ MAX_DEFAULT_HANDLES * sizeof(HANDLE));
+
+ RtlInitializeCriticalSection(&HandleTableCS);
+ return TRUE;
+}
+
+
+/************************************************************************
+ * RegInit
+ */
+BOOL
+RegCleanup(VOID)
+{
+ DPRINT("RegCleanup()\n");
+
+ CloseDefaultKeys();
+ RtlDeleteCriticalSection(&HandleTableCS);
+ return TRUE;
+}
+
+
+static NTSTATUS
+MapDefaultKey(PHKEY RealKey,
+ HKEY Key)
+{
+ PHANDLE Handle;
+ ULONG Index;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("MapDefaultKey (Key %x)\n", Key);
+
+ if (((ULONG)Key & 0xF0000000) != 0x80000000)
+ {
+ *RealKey = Key;
+ return STATUS_SUCCESS;
+ }
+
+ /* Handle special cases here */
+ Index = (ULONG)Key & 0x0FFFFFFF;
+
+ if (Index >= MAX_DEFAULT_HANDLES)
+ return STATUS_INVALID_PARAMETER;
+
+ RtlEnterCriticalSection(&HandleTableCS);
+
+ Handle = &DefaultHandleTable[Index];
+ if (*Handle == NULL)
+ {
+ /* create/open the default handle */
+ switch (Index)
+ {
+ case 0: /* HKEY_CLASSES_ROOT */
+ Status = OpenClassesRootKey(Handle);
+ break;
+
+ case 1: /* HKEY_CURRENT_USER */
+ Status = RtlOpenCurrentUser(KEY_ALL_ACCESS,
+ Handle);
+ break;
+
+ case 2: /* HKEY_LOCAL_MACHINE */
+ Status = OpenLocalMachineKey(Handle);
+ break;
+
+ case 3: /* HKEY_USERS */
+ Status = OpenUsersKey(Handle);
+ break;
+#if 0
+ case 4: /* HKEY_PERFORMANCE_DATA */
+ Status = OpenPerformanceDataKey(Handle);
+ break;
+#endif
+ case 5: /* HKEY_CURRENT_CONFIG */
+ Status = OpenCurrentConfigKey(Handle);
+ break;
+
+ default:
+ DPRINT("MapDefaultHandle() no handle creator\n");
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+
+ RtlLeaveCriticalSection(&HandleTableCS);
+
+ if (NT_SUCCESS(Status))
+ {
+ *RealKey = (HKEY)*Handle;
+ }
+
+ return Status;
+}
+
+
+static VOID
+CloseDefaultKeys(VOID)
+{
+ ULONG i;
+
+ RtlEnterCriticalSection(&HandleTableCS);
+
+ for (i = 0; i < MAX_DEFAULT_HANDLES; i++)
+ {
+ if (DefaultHandleTable[i] != NULL)
+ {
+ NtClose (DefaultHandleTable[i]);
+ DefaultHandleTable[i] = NULL;
+ }
+ }
+
+ RtlLeaveCriticalSection(&HandleTableCS);
+}
+
+
+static NTSTATUS
+OpenClassesRootKey(PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\Software\\CLASSES");
+
+ DPRINT("OpenClassesRootKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ return(NtOpenKey(KeyHandle,
+ KEY_ALL_ACCESS,
+ &Attributes));
+}
+
+
+static NTSTATUS
+OpenLocalMachineKey(PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine");
+
+ DPRINT("OpenLocalMachineKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ return(NtOpenKey(KeyHandle,
+ KEY_ALL_ACCESS,
+ &Attributes));
+}
+
+
+static NTSTATUS
+OpenUsersKey(PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\User");
+
+ DPRINT("OpenUsersKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ return(NtOpenKey(KeyHandle,
+ KEY_ALL_ACCESS,
+ &Attributes));
+}
+
+
+static NTSTATUS
+OpenCurrentConfigKey(PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName =
+ UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
+
+ DPRINT("OpenCurrentConfigKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ return(NtOpenKey(KeyHandle,
+ KEY_ALL_ACCESS,
+ &Attributes));
+}
+
/************************************************************************
* RegCloseKey
*/
-LONG
-STDCALL
-RegCloseKey(
- HKEY hKey
- )
+LONG STDCALL
+RegCloseKey(HKEY hKey)
{
- if (!hKey)
- return ERROR_INVALID_HANDLE;
+ NTSTATUS Status;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ /* don't close null handle or a pseudo handle */
+ if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000))
+ return ERROR_INVALID_HANDLE;
+
+ Status = NtClose (hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ LONG ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return ERROR_SUCCESS;
}
/************************************************************************
* RegConnectRegistryA
*/
-LONG
-STDCALL
-RegConnectRegistryA(
- LPSTR lpMachineName,
- HKEY hKey,
- PHKEY phkResult
- )
+LONG STDCALL
+RegConnectRegistryA(LPCSTR lpMachineName,
+ HKEY hKey,
+ PHKEY phkResult)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/************************************************************************
+ * RegConnectRegistryW
+ */
+LONG STDCALL
+RegConnectRegistryW(LPCWSTR lpMachineName,
+ HKEY hKey,
+ PHKEY phkResult)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/************************************************************************
+ * RegCreateKeyExA
+ */
+LONG STDCALL
+RegCreateKeyExA(HKEY hKey,
+ LPCSTR lpSubKey,
+ DWORD Reserved,
+ LPSTR lpClass,
+ DWORD dwOptions,
+ REGSAM samDesired,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ PHKEY phkResult,
+ LPDWORD lpdwDisposition)
+{
+ UNICODE_STRING SubKeyString;
+ UNICODE_STRING ClassString;
+ OBJECT_ATTRIBUTES Attributes;
+ NTSTATUS Status;
+ HKEY ParentKey;
+
+ DPRINT("RegCreateKeyExW() called\n");
+
+ /* get the real parent key */
+ Status = MapDefaultKey(&ParentKey,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ LONG ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ DPRINT("ParentKey %x\n", (ULONG)ParentKey);
+
+ if (lpClass != NULL)
+ RtlCreateUnicodeStringFromAsciiz(&ClassString,
+ lpClass);
+ RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
+ (LPSTR)lpSubKey);
+
+ InitializeObjectAttributes(&Attributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)ParentKey,
+ (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
+
+ Status = NtCreateKey(phkResult,
+ samDesired,
+ &Attributes,
+ 0,
+ (lpClass == NULL)? NULL : &ClassString,
+ dwOptions,
+ (PULONG)lpdwDisposition);
+
+ RtlFreeUnicodeString(&SubKeyString);
+ if (lpClass != NULL)
+ RtlFreeUnicodeString(&ClassString);
+
+ DPRINT("Status %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ LONG ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return(ERROR_SUCCESS);
+}
+
+
+/************************************************************************
+ * RegCreateKeyExW
+ */
+LONG STDCALL
+RegCreateKeyExW(HKEY hKey,
+ LPCWSTR lpSubKey,
+ DWORD Reserved,
+ LPWSTR lpClass,
+ DWORD dwOptions,
+ REGSAM samDesired,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ PHKEY phkResult,
+ LPDWORD lpdwDisposition)
+{
+ UNICODE_STRING SubKeyString;
+ UNICODE_STRING ClassString;
+ OBJECT_ATTRIBUTES Attributes;
+ NTSTATUS Status;
+ HKEY ParentKey;
+
+ DPRINT("RegCreateKeyExW() called\n");
+
+ /* get the real parent key */
+ Status = MapDefaultKey (&ParentKey, hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ LONG ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ DPRINT("ParentKey %x\n", (ULONG)ParentKey);
+ RtlInitUnicodeString (&ClassString, lpClass);
+ RtlInitUnicodeString (&SubKeyString, lpSubKey);
+
+ InitializeObjectAttributes (&Attributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)ParentKey,
+ (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
+
+ Status = NtCreateKey (phkResult,
+ samDesired,
+ &Attributes,
+ 0,
+ (lpClass == NULL)? NULL : &ClassString,
+ dwOptions,
+ (PULONG)lpdwDisposition);
+ DPRINT("Status %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ LONG ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return ERROR_SUCCESS;
}
/************************************************************************
* RegCreateKeyA
*/
+LONG STDCALL
+RegCreateKeyA(HKEY hKey,
+ LPCSTR lpSubKey,
+ PHKEY phkResult)
+{
+ return(RegCreateKeyExA(hKey,
+ lpSubKey,
+ 0,
+ NULL,
+ 0,
+ KEY_ALL_ACCESS,
+ NULL,
+ phkResult,
+ NULL));
+}
+
+
+/************************************************************************
+ * RegCreateKeyW
+ */
+LONG STDCALL
+RegCreateKeyW(HKEY hKey,
+ LPCWSTR lpSubKey,
+ PHKEY phkResult)
+{
+ return(RegCreateKeyExW(hKey,
+ lpSubKey,
+ 0,
+ NULL,
+ 0,
+ KEY_ALL_ACCESS,
+ NULL,
+ phkResult,
+ NULL));
+}
+
+
+/************************************************************************
+ * RegDeleteKeyA
+ */
LONG
STDCALL
-RegCreateKeyA(
+RegDeleteKeyA(
HKEY hKey,
- LPCSTR lpSubKey,
- PHKEY phkResult
+ LPCSTR lpSubKey
)
{
- return RegCreateKeyExA(hKey,
- lpSubKey,
- 0,
- NULL,
- 0,
- MAXIMUM_ALLOWED,
- NULL,
- phkResult,
- NULL);
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyStringW;
+ ANSI_STRING SubKeyStringA;
+// HANDLE ParentKey;
+ HKEY ParentKey;
+ HANDLE TargetKey;
+ NTSTATUS Status;
+ LONG ErrorCode;
+
+ Status = MapDefaultKey(&ParentKey,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ RtlInitAnsiString(&SubKeyStringA,
+ (LPSTR)lpSubKey);
+ RtlAnsiStringToUnicodeString(&SubKeyStringW,
+ &SubKeyStringA,
+ TRUE);
+
+ InitializeObjectAttributes (&ObjectAttributes,
+ &SubKeyStringW,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)ParentKey,
+ NULL);
+
+ Status = NtOpenKey (&TargetKey,
+ DELETE,
+ &ObjectAttributes);
+
+ RtlFreeUnicodeString (&SubKeyStringW);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ Status = NtDeleteKey(TargetKey);
+
+ NtClose(TargetKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+ return ERROR_SUCCESS;
}
/************************************************************************
- * RegCreateKeyW
+ * RegDeleteKeyW
*/
LONG
STDCALL
-RegCreateKeyW(
+RegDeleteKeyW(
HKEY hKey,
- LPCWSTR lpSubKey,
- PHKEY phkResult
+ LPCWSTR lpSubKey
)
{
- return RegCreateKeyExW(hKey,
- lpSubKey,
- 0,
- NULL,
- 0,
- MAXIMUM_ALLOWED,
- NULL,
- phkResult,
- NULL);
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyString;
+ HKEY ParentKey;
+ HANDLE TargetKey;
+ NTSTATUS Status;
+ LONG ErrorCode;
+
+ Status = MapDefaultKey(&ParentKey,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)lpSubKey);
+
+ InitializeObjectAttributes (&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)ParentKey,
+ NULL);
+
+ Status = NtOpenKey (&TargetKey,
+ DELETE,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ Status = NtDeleteKey(TargetKey);
+
+ NtClose(TargetKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+ return ERROR_SUCCESS;
}
/************************************************************************
- * RegCreateKeyExA
+ * RegDeleteValueA
*/
LONG
STDCALL
-RegCreateKeyExA(
- HKEY hKey,
- LPCSTR lpSubKey,
- DWORD Reserved,
- LPSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition
+RegDeleteValueA(
+ HKEY hKey,
+ LPCSTR lpValueName
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ UNICODE_STRING ValueNameW;
+ ANSI_STRING ValueNameA;
+ NTSTATUS Status;
+ LONG ErrorCode;
+ HKEY KeyHandle;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ RtlInitAnsiString(&ValueNameA,
+ (LPSTR)lpValueName);
+ RtlAnsiStringToUnicodeString(&ValueNameW,
+ &ValueNameA,
+ TRUE);
+
+ Status = NtDeleteValueKey(KeyHandle,
+ &ValueNameW);
+
+ RtlFreeUnicodeString (&ValueNameW);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return ERROR_SUCCESS;
}
/************************************************************************
- * RegCreateKeyExW
+ * RegDeleteValueW
*/
LONG
STDCALL
-RegCreateKeyExW(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD Reserved,
- LPWSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition
+RegDeleteValueW(
+ HKEY hKey,
+ LPCWSTR lpValueName
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ UNICODE_STRING ValueName;
+ NTSTATUS Status;
+ LONG ErrorCode;
+ HKEY KeyHandle;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ RtlInitUnicodeString(&ValueName,
+ (LPWSTR)lpValueName);
+
+ Status = NtDeleteValueKey(KeyHandle,
+ &ValueName);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return ERROR_SUCCESS;
}
/************************************************************************
- * RegDeleteKeyA
+ * RegEnumKeyExW
*/
LONG
STDCALL
-RegDeleteKeyA(
- HKEY hKey,
- LPCSTR lpSubKey
+RegEnumKeyExW(
+ HKEY hKey,
+ DWORD dwIndex,
+ LPWSTR lpName,
+ LPDWORD lpcbName,
+ LPDWORD lpReserved,
+ LPWSTR lpClass,
+ LPDWORD lpcbClass,
+ PFILETIME lpftLastWriteTime
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PKEY_NODE_INFORMATION KeyInfo;
+ NTSTATUS Status;
+ DWORD dwError = ERROR_SUCCESS;
+ ULONG BufferSize;
+ ULONG ResultSize;
+ HKEY KeyHandle;
+
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError (dwError);
+ return dwError;
+ }
+
+ BufferSize = sizeof (KEY_NODE_INFORMATION) + *lpcbName * sizeof(WCHAR);
+ if (lpClass)
+ BufferSize += *lpcbClass;
+
+ //
+ // I think this is a memory leak, always allocated again below ???
+ //
+ // KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
+ //
+
+ /* We don't know the exact size of the data returned, so call
+ NtEnumerateKey() with a buffer size determined from parameters
+ to this function. If that call fails with a status code of
+ STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
+ while (TRUE) {
+ KeyInfo = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ 0,
+ BufferSize);
+ if (KeyInfo == NULL)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ Status = NtEnumerateKey(
+ KeyHandle,
+ (ULONG)dwIndex,
+ KeyNodeInformation,
+ KeyInfo,
+ BufferSize,
+ &ResultSize);
+
+ DPRINT("NtEnumerateKey() returned status 0x%X\n", Status);
+
+ if (Status == STATUS_BUFFER_OVERFLOW)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+ BufferSize = ResultSize;
+ continue;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError(dwError);
+ break;
+ }
+ else
+ {
+ if ((lpClass) && (*lpcbClass != 0) && (KeyInfo->ClassLength > *lpcbClass))
+ {
+ dwError = ERROR_MORE_DATA;
+ SetLastError(dwError);
+ break;
+ }
+
+ RtlMoveMemory(lpName, KeyInfo->Name, KeyInfo->NameLength);
+ *lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR));
+ RegiTerminateWideString(lpName, *lpcbName);
+
+ if (lpClass)
+ {
+ RtlMoveMemory(lpClass,
+ (PVOID)((ULONG_PTR)KeyInfo->Name + KeyInfo->ClassOffset),
+ KeyInfo->ClassLength);
+ *lpcbClass = (DWORD)(KeyInfo->ClassLength / sizeof(WCHAR));
+ }
+
+ if (lpftLastWriteTime)
+ {
+ /* FIXME: Fill lpftLastWriteTime */
+ }
+
+ break;
+ }
+ }
+
+ RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo);
+
+ return dwError;
}
/************************************************************************
- * RegDeleteKeyW
+ * RegEnumKeyW
*/
LONG
STDCALL
-RegDeleteKeyW(
+RegEnumKeyW(
HKEY hKey,
- LPCWSTR lpSubKey
+ DWORD dwIndex,
+ LPWSTR lpName,
+ DWORD cbName
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ DWORD dwLength = cbName;
+
+ return RegEnumKeyExW(hKey,
+ dwIndex,
+ lpName,
+ &dwLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
/************************************************************************
- * RegDeleteValueA
+ * RegEnumKeyExA
*/
LONG
STDCALL
-RegDeleteValueA(
- HKEY hKey,
- LPCSTR lpValueName
+RegEnumKeyExA(
+ HKEY hKey,
+ DWORD dwIndex,
+ LPSTR lpName,
+ LPDWORD lpcbName,
+ LPDWORD lpReserved,
+ LPSTR lpClass,
+ LPDWORD lpcbClass,
+ PFILETIME lpftLastWriteTime
)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+{
+ WCHAR Name[MAX_PATH+1];
+ UNICODE_STRING UnicodeStringName;
+ WCHAR Class[MAX_PATH+1];
+ UNICODE_STRING UnicodeStringClass;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+ DWORD NameLength;
+ DWORD ClassLength;
+
+ DPRINT("hKey 0x%x dwIndex %d lpName 0x%x *lpcbName %d lpClass 0x%x lpcbClass %d\n",
+ hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass);
+
+ if ((lpClass) && (!lpcbClass))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&UnicodeStringName, NULL);
+ UnicodeStringName.Buffer = &Name[0];
+ UnicodeStringName.MaximumLength = sizeof(Name);
+
+ RtlInitUnicodeString(&UnicodeStringClass, NULL);
+
+ if (lpClass)
+ {
+ UnicodeStringClass.Buffer = &Class[0];
+ UnicodeStringClass.MaximumLength = sizeof(Class);
+ ClassLength = *lpcbClass;
+ }
+ else
+ {
+ ClassLength = 0;
+ }
+
+ NameLength = *lpcbName;
+
+ ErrorCode = RegEnumKeyExW(
+ hKey,
+ dwIndex,
+ UnicodeStringName.Buffer,
+ &NameLength,
+ lpReserved,
+ UnicodeStringClass.Buffer,
+ &ClassLength,
+ lpftLastWriteTime);
+
+ if (ErrorCode != ERROR_SUCCESS)
+ return ErrorCode;
+
+ UnicodeStringName.Length = NameLength * sizeof(WCHAR);
+ UnicodeStringClass.Length = ClassLength * sizeof(WCHAR);
+
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpName;
+ AnsiString.MaximumLength = *lpcbName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringName, FALSE);
+ *lpcbName = AnsiString.Length;
+
+ DPRINT("Key Namea0 Length %d\n", UnicodeStringName.Length);
+ DPRINT("Key Namea1 Length %d\n", NameLength);
+ DPRINT("Key Namea Length %d\n", *lpcbName);
+ DPRINT("Key Namea %s\n", lpName);
+
+ if (lpClass)
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpClass;
+ AnsiString.MaximumLength = *lpcbClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringClass, FALSE);
+ *lpcbClass = AnsiString.Length;
+ }
+
+ return ERROR_SUCCESS;
}
DWORD cbName
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ DWORD dwLength = cbName;
+
+ return RegEnumKeyExA(hKey,
+ dwIndex,
+ lpName,
+ &dwLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
/************************************************************************
- * RegEnumKeyExA
+ * RegEnumValueW
*/
LONG
STDCALL
-RegEnumKeyExA(
- HKEY hKey,
- DWORD dwIndex,
- LPSTR lpName,
- LPDWORD lpcbName,
- LPDWORD lpReserved,
- LPSTR lpClass,
- LPDWORD lpcbClass,
- PFILETIME lpftLastWriteTime
+RegEnumValueW(
+ HKEY hKey,
+ DWORD dwIndex,
+ LPWSTR lpValueName,
+ LPDWORD lpcbValueName,
+ LPDWORD lpReserved,
+ LPDWORD lpType,
+ LPBYTE lpData,
+ LPDWORD lpcbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PKEY_VALUE_FULL_INFORMATION ValueInfo;
+ NTSTATUS Status;
+ DWORD dwError = ERROR_SUCCESS;
+ ULONG BufferSize;
+ ULONG ResultSize;
+ HKEY KeyHandle;
+
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError(dwError);
+ return(dwError);
+ }
+
+ BufferSize = sizeof (KEY_VALUE_FULL_INFORMATION) +
+ *lpcbValueName * sizeof(WCHAR);
+ if (lpcbData)
+ BufferSize += *lpcbData;
+
+ /* We don't know the exact size of the data returned, so call
+ NtEnumerateValueKey() with a buffer size determined from parameters
+ to this function. If that call fails with a status code of
+ STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
+ while (TRUE) {
+ ValueInfo = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ 0,
+ BufferSize);
+ if (ValueInfo == NULL)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ Status = NtEnumerateValueKey(
+ KeyHandle,
+ (ULONG)dwIndex,
+ KeyValueFullInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+
+ DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status);
+
+ if (Status == STATUS_BUFFER_OVERFLOW)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
+ BufferSize = ResultSize;
+ continue;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError(dwError);
+ break;
+ }
+ else
+ {
+ if ((lpData) && (*lpcbData != 0) && (ValueInfo->DataLength > *lpcbData))
+ {
+ dwError = ERROR_MORE_DATA;
+ SetLastError(dwError);
+ break;
+ }
+
+ memcpy(lpValueName, ValueInfo->Name, ValueInfo->NameLength);
+ *lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR));
+ RegiTerminateWideString(lpValueName, *lpcbValueName);
+
+ if (lpType)
+ *lpType = ValueInfo->Type;
+
+ if (lpData)
+ {
+ memcpy(lpData,
+ //(PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset),
+ (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
+ ValueInfo->DataLength);
+ *lpcbData = (DWORD)ValueInfo->DataLength;
+/*
+ RtlCopyMemory((PCHAR) ValueFullInformation + ValueFullInformation->DataOffset,
+ DataCell->Data,
+ ValueCell->DataSize & LONG_MAX);
+ */
+ }
+
+ break;
+ }
+ }
+
+ RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo);
+
+ return dwError;
}
LPDWORD lpcbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR ValueName[MAX_PATH+1];
+ UNICODE_STRING UnicodeString;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+ DWORD ValueNameLength;
+ BYTE* lpDataBuffer = NULL;
+ DWORD cbData = 0;
+ DWORD Type;
+ ANSI_STRING AnsiDataString;
+ UNICODE_STRING UnicodeDataString;
+
+ if (lpData != NULL /*&& lpcbData != NULL*/) {
+ cbData = *lpcbData; // this should always be valid if lpData is valid
+ lpDataBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, (*lpcbData) * sizeof(WCHAR));
+ if (lpDataBuffer == NULL) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+ }
+
+ RtlInitUnicodeString(&UnicodeString, NULL);
+ UnicodeString.Buffer = &ValueName[0];
+ UnicodeString.MaximumLength = sizeof(ValueName);
+
+ ValueNameLength = *lpcbValueName;
+
+ ErrorCode = RegEnumValueW(
+ hKey,
+ dwIndex,
+ UnicodeString.Buffer,
+ &ValueNameLength,
+ lpReserved,
+ &Type,
+ lpDataBuffer,
+ &cbData);
+
+ if (ErrorCode != ERROR_SUCCESS)
+ return ErrorCode;
+
+ UnicodeString.Length = ValueNameLength * sizeof(WCHAR);
+
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpValueName;
+ AnsiString.MaximumLength = *lpcbValueName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
+ *lpcbValueName = AnsiString.Length;
+
+// if (lpData != lpDataBuffer) { // did we use a temp buffer
+ if (lpDataBuffer) { // did we use a temp buffer
+ if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) {
+ RtlInitUnicodeString(&UnicodeDataString, NULL);
+ UnicodeDataString.Buffer = lpDataBuffer;
+ UnicodeDataString.MaximumLength = (*lpcbData) * sizeof(WCHAR);
+ UnicodeDataString.Length = cbData /* * sizeof(WCHAR)*/;
+ RtlInitAnsiString(&AnsiDataString, NULL);
+ AnsiDataString.Buffer = lpData;
+ AnsiDataString.MaximumLength = *lpcbData;
+ RtlUnicodeStringToAnsiString(&AnsiDataString, &UnicodeDataString, FALSE);
+ *lpcbData = AnsiDataString.Length;
+// else if (Type == REG_EXPAND_SZ) {
+ } else {
+ memcpy(lpData, lpDataBuffer, min(*lpcbData, cbData));
+ *lpcbData = cbData;
+ }
+ RtlFreeHeap(RtlGetProcessHeap(), 0, lpDataBuffer);
+ }
+ if (lpType != NULL) {
+ *lpType = Type;
+ }
+ return ERROR_SUCCESS;
}
/************************************************************************
* RegFlushKey
*/
-LONG
-STDCALL
-RegFlushKey(
- HKEY hKey
- )
+LONG STDCALL
+RegFlushKey(HKEY hKey)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ HKEY KeyHandle;
+ NTSTATUS Status;
+ LONG ErrorCode;
+
+ if (hKey == HKEY_PERFORMANCE_DATA)
+ return(ERROR_SUCCESS);
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ Status = NtFlushKey(KeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ return(ERROR_SUCCESS);
}
/************************************************************************
* RegGetKeySecurity
*/
-#if 0
LONG
STDCALL
RegGetKeySecurity (
HKEY hKey,
- SECURITY_INFORMATION SecurityInformation, /* FIXME: ULONG ? */
+ SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor,
LPDWORD lpcbSecurityDescriptor
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
-#endif
/************************************************************************
*/
LONG
STDCALL
-RegLoadKey(
+RegLoadKeyA(
HKEY hKey,
LPCSTR lpSubKey,
LPCSTR lpFile
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
BOOL fAsynchronous
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
* RegOpenKeyA
*/
-LONG
-STDCALL
-RegOpenKeyA(
- HKEY hKey,
- LPCSTR lpSubKey,
- PHKEY phkResult
- )
+LONG STDCALL
+RegOpenKeyA(HKEY hKey,
+ LPCSTR lpSubKey,
+ PHKEY phkResult)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyString;
+ HKEY KeyHandle;
+ LONG ErrorCode;
+ NTSTATUS Status;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
+ (LPSTR)lpSubKey);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ Status = NtOpenKey(phkResult,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes);
+
+ RtlFreeUnicodeString(&SubKeyString);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+ return(ERROR_SUCCESS);
}
NTSTATUS errCode;
UNICODE_STRING SubKeyString;
OBJECT_ATTRIBUTES ObjectAttributes;
+ HKEY KeyHandle;
+ LONG ErrorCode;
+
+ errCode = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(errCode))
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)lpSubKey);
- SubKeyString.Buffer = (LPWSTR)lpSubKey;
- SubKeyString.Length = wcslen(lpSubKey);
- SubKeyString.MaximumLength = SubKeyString.Length;
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
- ObjectAttributes.RootDirectory = hKey;
- ObjectAttributes.ObjectName = & SubKeyString;
- ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
errCode = NtOpenKey(
phkResult,
- GENERIC_ALL,
+ KEY_ALL_ACCESS,
& ObjectAttributes
);
if ( !NT_SUCCESS(errCode) )
{
- LONG LastError = RtlNtStatusToDosError(errCode);
+ ErrorCode = RtlNtStatusToDosError(errCode);
- SetLastError(LastError);
- return LastError;
+ SetLastError(ErrorCode);
+ return ErrorCode;
}
return ERROR_SUCCESS;
}
/************************************************************************
* RegOpenKeyExA
*/
-LONG
-STDCALL
-RegOpenKeyExA(
- HKEY hKey,
- LPCSTR lpSubKey,
- DWORD ulOptions,
- REGSAM samDesired,
- PHKEY phkResult
- )
+LONG STDCALL
+RegOpenKeyExA(HKEY hKey,
+ LPCSTR lpSubKey,
+ DWORD ulOptions,
+ REGSAM samDesired,
+ PHKEY phkResult)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyString;
+ HKEY KeyHandle;
+ LONG ErrorCode;
+ NTSTATUS Status;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
+ (LPSTR)lpSubKey);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ Status = NtOpenKey(phkResult,
+ samDesired,
+ &ObjectAttributes);
+
+ RtlFreeUnicodeString(&SubKeyString);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ return(ERROR_SUCCESS);
}
/************************************************************************
* RegOpenKeyExW
*/
-LONG
-STDCALL
-RegOpenKeyExW(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD ulOptions,
- REGSAM samDesired,
- PHKEY phkResult
- )
+LONG STDCALL
+RegOpenKeyExW(HKEY hKey,
+ LPCWSTR lpSubKey,
+ DWORD ulOptions,
+ REGSAM samDesired,
+ PHKEY phkResult)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyString;
+ HKEY KeyHandle;
+ LONG ErrorCode;
+ NTSTATUS Status;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError (ErrorCode);
+ return(ErrorCode);
+ }
+
+ if (lpSubKey != NULL) {
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)lpSubKey);
+ } else {
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)L"");
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ Status = NtOpenKey(phkResult,
+ samDesired,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+ return(ERROR_SUCCESS);
}
/************************************************************************
- * RegQueryInfoKeyA
+ * RegQueryInfoKeyW
*/
LONG
STDCALL
-RegQueryInfoKeyA(
+RegQueryInfoKeyW(
HKEY hKey,
- LPSTR lpClass,
+ LPWSTR lpClass,
LPDWORD lpcbClass,
LPDWORD lpReserved,
LPDWORD lpcSubKeys,
PFILETIME lpftLastWriteTime
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ KEY_FULL_INFORMATION FullInfoBuffer;
+ PKEY_FULL_INFORMATION FullInfo;
+ ULONG FullInfoSize;
+ HKEY KeyHandle;
+ NTSTATUS Status;
+ LONG ErrorCode;
+ ULONG Length;
+
+ if ((lpClass) && (!lpcbClass))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ CHECK_STATUS;
+
+ if (lpClass)
+ {
+ FullInfoSize = sizeof(KEY_FULL_INFORMATION) + *lpcbClass;
+ FullInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullInfoSize);
+ if (!FullInfo)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ FullInfo->ClassLength = *lpcbClass;
+ }
+ else
+ {
+ FullInfoSize = sizeof(KEY_FULL_INFORMATION);
+ FullInfo = &FullInfoBuffer;
+ FullInfo->ClassLength = 1;
+ }
+
+ FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+
+ Status = NtQueryKey(
+ KeyHandle,
+ KeyFullInformation,
+ FullInfo,
+ FullInfoSize,
+ &Length);
+
+ if (!NT_SUCCESS(Status))
+ {
+ if (lpClass)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo);
+ }
+
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
+
+ if (lpcSubKeys)
+ {
+ *lpcSubKeys = FullInfo->SubKeys;
+ }
+
+ if (lpcbMaxSubKeyLen)
+ {
+ *lpcbMaxSubKeyLen = FullInfo->MaxNameLen;
+ }
+
+ if (lpcbMaxClassLen)
+ {
+ *lpcbMaxClassLen = FullInfo->MaxClassLen;
+ }
+
+ if (lpcValues)
+ {
+ *lpcValues = FullInfo->Values;
+ }
+
+ if (lpcbMaxValueNameLen)
+ {
+ *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen;
+ }
+
+ if (lpcbMaxValueLen)
+ {
+ *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
+ }
+
+ if (lpcbSecurityDescriptor)
+ {
+ *lpcbSecurityDescriptor = 0;
+ /* FIXME */
+ }
+
+ if (lpftLastWriteTime != NULL)
+ {
+ lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
+ lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
+ }
+
+ if (lpClass)
+ {
+ wcsncpy(lpClass, FullInfo->Class, *lpcbClass);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo);
+ }
+
+ SetLastError(ERROR_SUCCESS);
+ return ERROR_SUCCESS;
}
/************************************************************************
- * RegQueryInfoKeyW
+ * RegQueryInfoKeyA
*/
LONG
STDCALL
-RegQueryInfoKeyW(
+RegQueryInfoKeyA(
HKEY hKey,
- LPWSTR lpClass,
+ LPSTR lpClass,
LPDWORD lpcbClass,
LPDWORD lpReserved,
LPDWORD lpcSubKeys,
PFILETIME lpftLastWriteTime
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR ClassName[MAX_PATH];
+ UNICODE_STRING UnicodeString;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+
+ RtlInitUnicodeString(&UnicodeString, NULL);
+
+ if (lpClass)
+ {
+ UnicodeString.Buffer = &ClassName[0];
+ UnicodeString.MaximumLength = sizeof(ClassName);
+ }
+
+ ErrorCode = RegQueryInfoKeyW(
+ hKey,
+ UnicodeString.Buffer,
+ lpcbClass,
+ lpReserved,
+ lpcSubKeys,
+ lpcbMaxSubKeyLen,
+ lpcbMaxClassLen,
+ lpcValues,
+ lpcbMaxValueNameLen,
+ lpcbMaxValueLen,
+ lpcbSecurityDescriptor,
+ lpftLastWriteTime);
+
+ if ((ErrorCode == ERROR_SUCCESS) && (lpClass))
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpClass;
+ AnsiString.MaximumLength = *lpcbClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
+ *lpcbClass = AnsiString.Length;
+ }
+
+ return ErrorCode;
}
LONG
STDCALL
RegQueryMultipleValuesA(
- HKEY hKey,
- PVALENT val_list,
- DWORD num_vals,
- LPSTR lpValueBuf,
- LPDWORD ldwTotsize
+ HKEY hKey,
+ PVALENTA val_list,
+ DWORD num_vals,
+ LPSTR lpValueBuf,
+ LPDWORD ldwTotsize
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
- * RegQueryValueA
+ * RegQueryMultipleValuesW
*/
LONG
STDCALL
-RegQueryValueA(
- HKEY hKey,
- LPCSTR lpSubKey,
- LPSTR lpValue,
- PLONG lpcbValue
+RegQueryMultipleValuesW(
+ HKEY hKey,
+ PVALENTW val_list,
+ DWORD num_vals,
+ LPWSTR lpValueBuf,
+ LPDWORD ldwTotsize
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
- * RegQueryValueExA
+ * RegQueryValueExW
*/
LONG
STDCALL
-RegQueryValueExA(
+RegQueryValueExW(
HKEY hKey,
- LPSTR lpValueName,
+ LPCWSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+ UNICODE_STRING ValueName;
+ NTSTATUS Status;
+ DWORD dwError = ERROR_SUCCESS;
+ ULONG BufferSize;
+ ULONG ResultSize;
+ HKEY KeyHandle;
+
+ DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
+ hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
+
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError(dwError);
+ return(dwError);
+ }
+
+ if ((lpData) && (!lpcbData))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString (&ValueName,
+ lpValueName);
+
+ BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData;
+ ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(),
+ 0,
+ BufferSize);
+ if (ValueInfo == NULL)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ Status = NtQueryValueKey (hKey,
+ &ValueName,
+ KeyValuePartialInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+
+ DPRINT("Status 0x%X\n", Status);
+
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
+ dwError = ERROR_SUCCESS;
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError(dwError);
+ }
+ else
+ {
+ if (lpType)
+ {
+ *lpType = ValueInfo->Type;
+ }
+
+ RtlMoveMemory(lpData, ValueInfo->Data, ValueInfo->DataLength);
+ if ((ValueInfo->Type == REG_SZ) ||
+ (ValueInfo->Type == REG_MULTI_SZ) ||
+ (ValueInfo->Type == REG_EXPAND_SZ))
+ {
+ ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
+ }
+ }
+
+ DPRINT("Type %d ResultSize %d\n", ValueInfo->Type, ResultSize);
+
+ *lpcbData = (DWORD)ResultSize;
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
+
+ return dwError;
}
/************************************************************************
- * RegQueryValueExW
+ * RegQueryValueExA
*/
LONG
STDCALL
-RegQueryValueExW(
+RegQueryValueExA(
HKEY hKey,
- LPWSTR lpValueName,
+ LPCSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR ValueNameBuffer[MAX_PATH+1];
+ UNICODE_STRING ValueName;
+ UNICODE_STRING ValueData;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+ DWORD ResultSize;
+ DWORD Type;
+
+ /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
+
+ if ((lpData) && (!lpcbData))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&ValueData, NULL);
+
+ if (lpData)
+ {
+ ValueData.MaximumLength = *lpcbData * sizeof(WCHAR);
+ ValueData.Buffer = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ 0,
+ ValueData.MaximumLength);
+ if (!ValueData.Buffer)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+ }
+
+ RtlInitAnsiString(&AnsiString, (LPSTR)lpValueName);
+ RtlInitUnicodeString(&ValueName, NULL);
+ ValueName.Buffer = &ValueNameBuffer[0];
+ ValueName.MaximumLength = sizeof(ValueNameBuffer);
+ RtlAnsiStringToUnicodeString(&ValueName, &AnsiString, FALSE);
+
+ if (lpcbData)
+ {
+ ResultSize = *lpcbData;
+ }
+ else
+ {
+ ResultSize = 0;
+ }
+
+ ErrorCode = RegQueryValueExW(
+ hKey,
+ ValueName.Buffer,
+ lpReserved,
+ &Type,
+ (LPBYTE)ValueData.Buffer,
+ &ResultSize);
+
+ if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL))
+ {
+ if (lpType)
+ {
+ *lpType = Type;
+ }
+
+ if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
+ {
+ ValueData.Length = ResultSize;
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpData;
+ AnsiString.MaximumLength = *lpcbData;
+ RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
+ }
+ else
+ {
+ RtlMoveMemory(lpData, ValueData.Buffer, ResultSize);
+ }
+ }
+
+ if (lpcbData)
+ {
+ *lpcbData = ResultSize;
+ }
+
+ if (ValueData.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData.Buffer);
+ }
+
+ return ErrorCode;
+}
+
+
+/************************************************************************
+ * RegQueryValueW
+ */
+LONG
+STDCALL
+RegQueryValueW(
+ HKEY hKey,
+ LPCWSTR lpSubKey,
+ LPWSTR lpValue,
+ PLONG lpcbValue
+ )
+{
+ NTSTATUS errCode;
+ UNICODE_STRING SubKeyString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HKEY KeyHandle;
+ HANDLE RealKey;
+ LONG ErrorCode;
+ BOOL CloseRealKey;
+
+ errCode = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(errCode))
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ if ((lpSubKey) && (wcslen(lpSubKey) != 0))
+ {
+
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)lpSubKey);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ errCode = NtOpenKey(
+ &RealKey,
+ KEY_ALL_ACCESS,
+ & ObjectAttributes
+ );
+ if ( !NT_SUCCESS(errCode) )
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
+ CloseRealKey = TRUE;
+ }
+ else
+ {
+ RealKey = hKey;
+ CloseRealKey = FALSE;
+ }
+
+ ErrorCode = RegQueryValueExW(
+ RealKey,
+ NULL,
+ NULL,
+ NULL,
+ (LPBYTE)lpValue,
+ (LPDWORD)lpcbValue);
+
+ if (CloseRealKey)
+ {
+ NtClose(RealKey);
+ }
+
+ return ErrorCode;
+}
+
+
+/************************************************************************
+ * RegQueryValueA
+ */
+LONG
+STDCALL
+RegQueryValueA(
+ HKEY hKey,
+ LPCSTR lpSubKey,
+ LPSTR lpValue,
+ PLONG lpcbValue
+ )
+{
+ WCHAR SubKeyNameBuffer[MAX_PATH+1];
+ UNICODE_STRING SubKeyName;
+ UNICODE_STRING Value;
+ ANSI_STRING AnsiString;
+ LONG ValueSize;
+ LONG ErrorCode;
+
+ if ((lpValue) && (!lpcbValue))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&SubKeyName, NULL);
+ RtlInitUnicodeString(&Value, NULL);
+
+ if ((lpSubKey) && (strlen(lpSubKey) != 0))
+ {
+ RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
+ SubKeyName.Buffer = &SubKeyNameBuffer[0];
+ SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
+ RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+ }
+
+ if (lpValue)
+ {
+ ValueSize = *lpcbValue * sizeof(WCHAR);
+ Value.MaximumLength = ValueSize;
+ Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize);
+ if (!Value.Buffer)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ ValueSize = 0;
+ }
+
+ ErrorCode = RegQueryValueW(
+ hKey,
+ (LPCWSTR)SubKeyName.Buffer,
+ Value.Buffer,
+ &ValueSize);
+
+ if (ErrorCode == ERROR_SUCCESS)
+ {
+ Value.Length = ValueSize;
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpValue;
+ AnsiString.MaximumLength = *lpcbValue;
+ RtlUnicodeStringToAnsiString(&AnsiString, &Value, FALSE);
+ }
+
+ *lpcbValue = ValueSize;
+
+ if (Value.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Value.Buffer);
+ }
+
+ return ErrorCode;
}
LPCSTR lpOldFile
)
{
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/************************************************************************
+ * RegReplaceKeyW
+ */
+LONG
+STDCALL
+RegReplaceKeyW(
+ HKEY hKey,
+ LPCWSTR lpSubKey,
+ LPCWSTR lpNewFile,
+ LPCWSTR lpOldFile
+ )
+{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
DWORD dwFlags
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
- * RegSaveKeyA
+ * RegRestoreKeyW
*/
LONG
STDCALL
-RegSaveKeyA(
- HKEY hKey,
- LPCSTR lpFile,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes
+RegRestoreKeyW(
+ HKEY hKey,
+ LPCWSTR lpFile,
+ DWORD dwFlags
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
+/************************************************************************
+ * RegSaveKeyW
+ */
+LONG STDCALL
+RegSaveKeyW(HKEY hKey,
+ LPCWSTR lpFile,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes)
+{
+ PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING NtName;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle;
+ HKEY KeyHandle;
+ NTSTATUS Status;
+ LONG ErrorCode;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFile,
+ &NtName,
+ NULL,
+ NULL))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return(ERROR_INVALID_PARAMETER);
+ }
+
+ if (lpSecurityAttributes != NULL)
+ SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NtName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ SecurityDescriptor);
+
+ Status = NtCreateFile(&FileHandle,
+ GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ FILE_CREATE,
+ FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+ RtlFreeUnicodeString(&NtName);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ Status = NtSaveKey(KeyHandle,
+ FileHandle);
+ NtClose(FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
+ return(ErrorCode);
+ }
+
+ return(ERROR_SUCCESS);
+}
+
+
+/************************************************************************
+ * RegSaveKeyA
+ */
+LONG STDCALL
+RegSaveKeyA(HKEY hKey,
+ LPCSTR lpFile,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes)
+{
+ UNICODE_STRING FileName;
+ LONG ErrorCode;
+
+ RtlCreateUnicodeStringFromAsciiz(&FileName,
+ (LPSTR)lpFile);
+ ErrorCode = RegSaveKeyW(hKey,
+ FileName.Buffer,
+ lpSecurityAttributes);
+ RtlFreeUnicodeString(&FileName);
+
+ return(ErrorCode);
+}
+
+
/************************************************************************
* RegSetKeySecurity
*/
-#if 0
LONG
STDCALL
RegSetKeySecurity(
PSECURITY_DESCRIPTOR pSecurityDescriptor
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
-#endif
+
/************************************************************************
- * RegSetValueA
+ * RegSetValueExW
*/
LONG
STDCALL
-RegSetValueA(
- HKEY hKey,
- LPCSTR lpSubKey,
- DWORD dwType,
- LPCSTR lpData,
- DWORD cbData
+RegSetValueExW(
+ HKEY hKey,
+ LPCWSTR lpValueName,
+ DWORD Reserved,
+ DWORD dwType,
+ CONST BYTE *lpData,
+ DWORD cbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ UNICODE_STRING ValueName;
+ PUNICODE_STRING pValueName;
+ HKEY KeyHandle;
+ NTSTATUS Status;
+ LONG ErrorCode;
+
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
+
+ if (lpValueName)
+ {
+ RtlInitUnicodeString(&ValueName, lpValueName);
+ pValueName = &ValueName;
+ }
+ else
+ {
+ pValueName = NULL;
+ }
+
+ Status = NtSetValueKey(
+ KeyHandle,
+ pValueName,
+ 0,
+ dwType,
+ (PVOID)lpData,
+ (ULONG)cbData);
+ if (!NT_SUCCESS(Status))
+ {
+ LONG ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return ERROR_SUCCESS;
}
DWORD cbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ UNICODE_STRING ValueName;
+ LPWSTR pValueName;
+ ANSI_STRING AnsiString;
+ UNICODE_STRING Data;
+ LONG ErrorCode;
+ LPBYTE pData;
+ DWORD DataSize;
+
+ if (!lpData)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if ((lpValueName) && (strlen(lpValueName) != 0))
+ {
+ RtlCreateUnicodeStringFromAsciiz(&ValueName, (LPSTR)lpValueName);
+ pValueName = (LPWSTR)ValueName.Buffer;
+ }
+ else
+ {
+ pValueName = NULL;
+ }
+
+ if ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ))
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = (LPSTR)lpData;
+ AnsiString.Length = cbData;
+ AnsiString.MaximumLength = cbData;
+ RtlAnsiStringToUnicodeString(&Data, &AnsiString, TRUE);
+ pData = (LPBYTE)Data.Buffer;
+ DataSize = cbData * sizeof(WCHAR);
+ }
+ else
+ {
+ RtlInitUnicodeString(&Data, NULL);
+ pData = (LPBYTE)lpData;
+ DataSize = cbData;
+ }
+
+ ErrorCode = RegSetValueExW(
+ hKey,
+ pValueName,
+ Reserved,
+ dwType,
+ pData,
+ DataSize);
+
+ if (pValueName)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueName.Buffer);
+ }
+
+ if (Data.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
+ }
+
+ return ErrorCode;
+}
+
+
+/************************************************************************
+ * RegSetValueW
+ */
+LONG
+STDCALL
+RegSetValueW(
+ HKEY hKey,
+ LPCWSTR lpSubKey,
+ DWORD dwType,
+ LPCWSTR lpData,
+ DWORD cbData
+ )
+{
+ NTSTATUS errCode;
+ UNICODE_STRING SubKeyString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HKEY KeyHandle;
+ HANDLE RealKey;
+ LONG ErrorCode;
+ BOOL CloseRealKey;
+
+ errCode = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(errCode))
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ if ((lpSubKey) && (wcslen(lpSubKey) != 0))
+ {
+
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)lpSubKey);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ errCode = NtOpenKey(
+ &RealKey,
+ KEY_ALL_ACCESS,
+ & ObjectAttributes
+ );
+ if ( !NT_SUCCESS(errCode) )
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
+ CloseRealKey = TRUE;
+ }
+ else
+ {
+ RealKey = hKey;
+ CloseRealKey = FALSE;
+ }
+
+ ErrorCode = RegSetValueExW(
+ RealKey,
+ NULL,
+ 0,
+ dwType,
+ (LPBYTE)lpData,
+ cbData);
+
+ if (CloseRealKey)
+ {
+ NtClose(RealKey);
+ }
+
+ return ErrorCode;
+}
+
+
+/************************************************************************
+ * RegSetValueA
+ */
+LONG
+STDCALL
+RegSetValueA(
+ HKEY hKey,
+ LPCSTR lpSubKey,
+ DWORD dwType,
+ LPCSTR lpData,
+ DWORD cbData
+ )
+{
+ WCHAR SubKeyNameBuffer[MAX_PATH+1];
+ UNICODE_STRING SubKeyName;
+ UNICODE_STRING Data;
+ ANSI_STRING AnsiString;
+ LONG DataSize;
+ LONG ErrorCode;
+
+ if (!lpData)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&SubKeyName, NULL);
+ RtlInitUnicodeString(&Data, NULL);
+
+ if ((lpSubKey) && (strlen(lpSubKey) != 0))
+ {
+ RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
+ SubKeyName.Buffer = &SubKeyNameBuffer[0];
+ SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
+ RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+ }
+
+ DataSize = cbData * sizeof(WCHAR);
+ Data.MaximumLength = DataSize;
+ Data.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize);
+ if (!Data.Buffer)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ ErrorCode = RegSetValueW(
+ hKey,
+ (LPCWSTR)SubKeyName.Buffer,
+ dwType,
+ Data.Buffer,
+ DataSize);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
+
+ return ErrorCode;
}
LPCSTR lpSubKey
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
+/************************************************************************
+ * RegUnLoadKeyW
+ */
+LONG
+STDCALL
+RegUnLoadKeyW(
+ HKEY hKey,
+ LPCWSTR lpSubKey
+ )
+{
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
/* EOF */