Author: khornicek
Date: Mon Jul 20 03:08:50 2009
New Revision: 42094
URL:
http://svn.reactos.org/svn/reactos?rev=42094&view=rev
Log:
- add regglue.c for now, it contains APIs needed by freetype
Added:
branches/arwinss/reactos/dll/win32/gdi32/regglue.c (with props)
Modified:
branches/arwinss/reactos/dll/win32/gdi32/gdi32.rbuild
Modified: branches/arwinss/reactos/dll/win32/gdi32/gdi32.rbuild
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/gdi32…
==============================================================================
--- branches/arwinss/reactos/dll/win32/gdi32/gdi32.rbuild [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/gdi32/gdi32.rbuild [iso-8859-1] Mon Jul 20 03:08:50
2009
@@ -41,6 +41,7 @@
<file>pen.c</file>
<file>printdrv.c</file>
<file>region.c</file>
+ <file>regglue.c</file>
<file>gdi32.rc</file>
</module>
Added: branches/arwinss/reactos/dll/win32/gdi32/regglue.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/gdi32…
==============================================================================
--- branches/arwinss/reactos/dll/win32/gdi32/regglue.c (added)
+++ branches/arwinss/reactos/dll/win32/gdi32/regglue.c [iso-8859-1] Mon Jul 20 03:08:50
2009
@@ -1,0 +1,1606 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/advapi32/reg/reg.c
+ * PURPOSE: Registry functions
+ * PROGRAMMER: Ariadne ( ariadne(a)xs4all.nl)
+ * Thomas Weidenmueller <w3seek(a)reactos.com>
+ * UPDATE HISTORY:
+ * Created 01/11/98
+ * 19990309 EA Stubs
+ * 20050502 Fireball imported some stuff from WINE
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <stdio.h>
+#define WIN32_NO_STATUS
+#define _WMI_SOURCE_
+#include <windows.h>
+#include <string.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gdi);
+
+#define ClosePredefKey(Handle) \
+ if ((ULONG_PTR)Handle & 0x1) { \
+ NtClose(Handle); \
+ }
+#define IsPredefKey(HKey) \
+ (((ULONG)(HKey) & 0xF0000000) == 0x80000000)
+#define GetPredefKeyIndex(HKey) \
+ ((ULONG)(HKey) & 0x0FFFFFFF)
+
+#define MAX_DEFAULT_HANDLES 6
+#define REG_MAX_NAME_SIZE 256
+#define REG_MAX_DATA_SIZE 2048
+
+static NTSTATUS MapDefaultKey(OUT PHANDLE, IN HKEY);
+static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
+static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
+static NTSTATUS OpenUsersKey (PHANDLE KeyHandle);
+static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle);
+
+LONG WINAPI RegOpenKeyA(HKEY, LPCSTR, PHKEY);
+LONG WINAPI RegOpenKeyW(HKEY, LPCWSTR, PHKEY);
+LONG WINAPI RegOpenKeyExA(HKEY, LPCSTR, DWORD, REGSAM, PHKEY);
+LONG WINAPI RegOpenKeyExW(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY);
+
+static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
+static BOOLEAN DefaultHandlesDisabled = FALSE;
+static BOOLEAN DefaultHandleHKUDisabled = FALSE;
+
+
+__inline static int is_string( DWORD type )
+{
+ return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
+}
+
+static NTSTATUS
+OpenPredefinedKey(IN ULONG Index,
+ OUT HANDLE Handle)
+{
+ NTSTATUS Status;
+
+ switch (Index)
+ {
+ case 0: /* HKEY_CLASSES_ROOT */
+ Status = OpenClassesRootKey (Handle);
+ break;
+
+ case 1: /* HKEY_CURRENT_USER */
+ Status = RtlOpenCurrentUser (MAXIMUM_ALLOWED,
+ Handle);
+ break;
+
+ case 2: /* HKEY_LOCAL_MACHINE */
+ Status = OpenLocalMachineKey (Handle);
+ break;
+
+ case 3: /* HKEY_USERS */
+ Status = OpenUsersKey (Handle);
+ break;
+
+ case 5: /* HKEY_CURRENT_CONFIG */
+ Status = OpenCurrentConfigKey (Handle);
+ break;
+
+ case 6: /* HKEY_DYN_DATA */
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ WARN("MapDefaultHandle() no handle creator\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+MapDefaultKey(PHANDLE RealKey,
+ HKEY Key)
+{
+ PHANDLE Handle;
+ ULONG Index;
+ BOOLEAN DoOpen, DefDisabled;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ TRACE("MapDefaultKey (Key %x)\n", Key);
+
+ if (!IsPredefKey(Key))
+ {
+ *RealKey = (HANDLE)((ULONG_PTR)Key & ~0x1);
+ return STATUS_SUCCESS;
+ }
+
+ /* Handle special cases here */
+ Index = GetPredefKeyIndex(Key);
+ if (Index >= MAX_DEFAULT_HANDLES)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (Key == HKEY_CURRENT_USER)
+ DefDisabled = DefaultHandleHKUDisabled;
+ else
+ DefDisabled = DefaultHandlesDisabled;
+
+ if (!DefDisabled)
+ {
+ Handle = &DefaultHandleTable[Index];
+ DoOpen = (*Handle == NULL);
+ }
+ else
+ {
+ Handle = RealKey;
+ DoOpen = TRUE;
+ }
+
+ if (DoOpen)
+ {
+ /* create/open the default handle */
+ Status = OpenPredefinedKey(Index,
+ Handle);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ if (!DefDisabled)
+ *RealKey = *Handle;
+ else
+ *(PULONG_PTR)Handle |= 0x1;
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+OpenClassesRootKey(PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\CLASSES");
+
+ TRACE("OpenClassesRootKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ return NtOpenKey(KeyHandle,
+ MAXIMUM_ALLOWED,
+ &Attributes);
+}
+
+
+static NTSTATUS
+OpenLocalMachineKey(PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine");
+ NTSTATUS Status;
+
+ TRACE("OpenLocalMachineKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenKey(KeyHandle,
+ MAXIMUM_ALLOWED,
+ &Attributes);
+
+ TRACE("NtOpenKey(%wZ) => %08x\n", &KeyName, Status);
+
+ return Status;
+}
+
+
+static NTSTATUS
+OpenUsersKey(PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\User");
+
+ TRACE("OpenUsersKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ return NtOpenKey(KeyHandle,
+ MAXIMUM_ALLOWED,
+ &Attributes);
+}
+
+
+static NTSTATUS
+OpenCurrentConfigKey (PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES Attributes;
+ UNICODE_STRING KeyName =
+
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware
Profiles\\Current");
+
+ TRACE("OpenCurrentConfigKey()\n");
+
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ return NtOpenKey(KeyHandle,
+ MAXIMUM_ALLOWED,
+ &Attributes);
+}
+
+LONG WINAPI
+RegCloseKey(HKEY hKey)
+{
+ NTSTATUS Status;
+
+ /* don't close null handle or a pseudo handle */
+ if ((!hKey) || (((ULONG_PTR)hKey & 0xF0000000) == 0x80000000))
+ {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ Status = NtClose(hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static NTSTATUS
+CreateNestedKey(PHKEY KeyHandle,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PUNICODE_STRING ClassString,
+ DWORD dwOptions,
+ REGSAM samDesired,
+ DWORD *lpdwDisposition)
+{
+ OBJECT_ATTRIBUTES LocalObjectAttributes;
+ UNICODE_STRING LocalKeyName;
+ ULONG Disposition;
+ NTSTATUS Status;
+ ULONG FullNameLength;
+ ULONG Length;
+ PWCHAR Ptr;
+ HANDLE LocalKeyHandle;
+
+ Status = NtCreateKey((PHANDLE) KeyHandle,
+ samDesired,
+ ObjectAttributes,
+ 0,
+ ClassString,
+ dwOptions,
+ (PULONG)lpdwDisposition);
+ TRACE("NtCreateKey(%wZ) called (Status %lx)\n",
ObjectAttributes->ObjectName, Status);
+ if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
+ return Status;
+
+ /* Copy object attributes */
+ RtlCopyMemory(&LocalObjectAttributes,
+ ObjectAttributes,
+ sizeof(OBJECT_ATTRIBUTES));
+ RtlCreateUnicodeString(&LocalKeyName,
+ ObjectAttributes->ObjectName->Buffer);
+ LocalObjectAttributes.ObjectName = &LocalKeyName;
+ FullNameLength = LocalKeyName.Length / sizeof(WCHAR);
+
+ LocalKeyHandle = NULL;
+
+ /* Remove the last part of the key name and try to create the key again. */
+ while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ Ptr = wcsrchr(LocalKeyName.Buffer, '\\');
+ if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ *Ptr = (WCHAR)0;
+ LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
+
+ Status = NtCreateKey(&LocalKeyHandle,
+ KEY_CREATE_SUB_KEY,
+ &LocalObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ &Disposition);
+ TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&LocalKeyName);
+ return Status;
+ }
+
+ /* Add removed parts of the key name and create them too. */
+ Length = wcslen(LocalKeyName.Buffer);
+ while (TRUE)
+ {
+ if (LocalKeyHandle)
+ NtClose (LocalKeyHandle);
+
+ LocalKeyName.Buffer[Length] = L'\\';
+ Length = wcslen (LocalKeyName.Buffer);
+ LocalKeyName.Length = Length * sizeof(WCHAR);
+
+ if (Length == FullNameLength)
+ {
+ Status = NtCreateKey((PHANDLE) KeyHandle,
+ samDesired,
+ ObjectAttributes,
+ 0,
+ ClassString,
+ dwOptions,
+ (PULONG)lpdwDisposition);
+ break;
+ }
+
+ Status = NtCreateKey(&LocalKeyHandle,
+ KEY_CREATE_SUB_KEY,
+ &LocalObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ &Disposition);
+ TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+
+ RtlFreeUnicodeString(&LocalKeyName);
+
+ return Status;
+}
+
+LONG WINAPI
+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;
+ HANDLE ParentKey;
+ NTSTATUS Status;
+
+ TRACE("RegCreateKeyExA() called\n");
+
+ if (lpSecurityAttributes && lpSecurityAttributes->nLength !=
sizeof(SECURITY_ATTRIBUTES))
+ return ERROR_INVALID_USER_BUFFER;
+
+ /* get the real parent key */
+ Status = MapDefaultKey(&ParentKey,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ TRACE("ParentKey %p\n", ParentKey);
+
+ if (lpClass != NULL)
+ {
+ RtlCreateUnicodeStringFromAsciiz(&ClassString,
+ lpClass);
+ }
+
+ RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
+ (LPSTR)lpSubKey);
+ InitializeObjectAttributes(&Attributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)ParentKey,
+ lpSecurityAttributes ?
(PSECURITY_DESCRIPTOR)lpSecurityAttributes->lpSecurityDescriptor : NULL);
+ Status = CreateNestedKey(phkResult,
+ &Attributes,
+ (lpClass == NULL)? NULL : &ClassString,
+ dwOptions,
+ samDesired,
+ lpdwDisposition);
+ RtlFreeUnicodeString(&SubKeyString);
+ if (lpClass != NULL)
+ {
+ RtlFreeUnicodeString(&ClassString);
+ }
+
+ ClosePredefKey(ParentKey);
+
+ TRACE("Status %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+LONG WINAPI
+RegCreateKeyA(HKEY hKey,
+ LPCSTR lpSubKey,
+ PHKEY phkResult)
+{
+ return RegCreateKeyExA(hKey,
+ lpSubKey,
+ 0,
+ NULL,
+ 0,
+ MAXIMUM_ALLOWED,
+ NULL,
+ phkResult,
+ NULL);
+}
+
+LONG WINAPI
+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;
+ HANDLE ParentKey;
+ NTSTATUS Status;
+
+ TRACE("RegCreateKeyExW() called\n");
+
+ if (lpSecurityAttributes && lpSecurityAttributes->nLength !=
sizeof(SECURITY_ATTRIBUTES))
+ return ERROR_INVALID_USER_BUFFER;
+
+ /* get the real parent key */
+ Status = MapDefaultKey(&ParentKey,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ TRACE("ParentKey %p\n", ParentKey);
+
+ RtlInitUnicodeString(&ClassString,
+ lpClass);
+ RtlInitUnicodeString(&SubKeyString,
+ lpSubKey);
+ InitializeObjectAttributes(&Attributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)ParentKey,
+ lpSecurityAttributes ?
(PSECURITY_DESCRIPTOR)lpSecurityAttributes->lpSecurityDescriptor : NULL);
+ Status = CreateNestedKey(phkResult,
+ &Attributes,
+ (lpClass == NULL)? NULL : &ClassString,
+ dwOptions,
+ samDesired,
+ lpdwDisposition);
+
+ ClosePredefKey(ParentKey);
+
+ TRACE("Status %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+LONG WINAPI
+RegCreateKeyW(HKEY hKey,
+ LPCWSTR lpSubKey,
+ PHKEY phkResult)
+{
+ return RegCreateKeyExW(hKey,
+ lpSubKey,
+ 0,
+ NULL,
+ 0,
+ MAXIMUM_ALLOWED,
+ NULL,
+ phkResult,
+ NULL);
+}
+
+LONG WINAPI
+RegDeleteKeyW(HKEY hKey,
+ LPCWSTR lpSubKey)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyName;
+ HANDLE ParentKey;
+ HANDLE TargetKey;
+ NTSTATUS Status;
+
+ /* Make sure we got a subkey */
+ if (!lpSubKey)
+ {
+ /* Fail */
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ Status = MapDefaultKey(&ParentKey,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ RtlInitUnicodeString(&SubKeyName,
+ (LPWSTR)lpSubKey);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyName,
+ OBJ_CASE_INSENSITIVE,
+ ParentKey,
+ NULL);
+ Status = NtOpenKey(&TargetKey,
+ DELETE,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+
+ Status = NtDeleteKey(TargetKey);
+ NtClose(TargetKey);
+
+Cleanup:
+ ClosePredefKey(ParentKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+LONG WINAPI
+RegDeleteValueA(HKEY hKey,
+ LPCSTR lpValueName)
+{
+ UNICODE_STRING ValueName;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ RtlCreateUnicodeStringFromAsciiz(&ValueName,
+ (LPSTR)lpValueName);
+ Status = NtDeleteValueKey(KeyHandle,
+ &ValueName);
+ RtlFreeUnicodeString (&ValueName);
+
+ ClosePredefKey(KeyHandle);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+LONG WINAPI
+RegDeleteValueW(HKEY hKey,
+ LPCWSTR lpValueName)
+{
+ UNICODE_STRING ValueName;
+ NTSTATUS Status;
+ HANDLE KeyHandle;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ RtlInitUnicodeString(&ValueName,
+ (LPWSTR)lpValueName);
+
+ Status = NtDeleteValueKey(KeyHandle,
+ &ValueName);
+
+ ClosePredefKey(KeyHandle);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+LONG WINAPI
+RegEnumValueA(HKEY hKey,
+ DWORD index,
+ LPSTR value,
+ LPDWORD val_count,
+ LPDWORD reserved,
+ LPDWORD type,
+ LPBYTE data,
+ LPDWORD count)
+{
+ HANDLE KeyHandle;
+ NTSTATUS status;
+ ULONG total_size;
+ char buffer[256], *buf_ptr = buffer;
+ KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
+ static const int info_size = FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name );
+
+ //TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n",
+ // hkey, index, value, val_count, reserved, type, data, count );
+
+ /* NT only checks count, not val_count */
+ if ((data && !count) || reserved)
+ return ERROR_INVALID_PARAMETER;
+
+ status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(status))
+ {
+ return RtlNtStatusToDosError(status);
+ }
+
+ total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
+ if (data) total_size += *count;
+ total_size = min( sizeof(buffer), total_size );
+
+ status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
+ buffer, total_size, &total_size );
+ if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+
+ /* we need to fetch the contents for a string type even if not requested,
+ * because we need to compute the length of the ASCII string. */
+ if (value || data || is_string(info->Type))
+ {
+ /* retry with a dynamically allocated buffer */
+ while (status == STATUS_BUFFER_OVERFLOW)
+ {
+ if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+ info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr;
+ status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
+ buf_ptr, total_size, &total_size );
+ }
+
+ if (status) goto done;
+
+ if (is_string(info->Type))
+ {
+ ULONG len;
+ RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr +
info->DataOffset),
+ total_size - info->DataOffset );
+ if (data && len)
+ {
+ if (len > *count) status = STATUS_BUFFER_OVERFLOW;
+ else
+ {
+ RtlUnicodeToMultiByteN( (PCHAR)data, len, NULL, (WCHAR *)(buf_ptr +
info->DataOffset),
+ total_size - info->DataOffset );
+ /* if the type is REG_SZ and data is not 0-terminated
+ * and there is enough space in the buffer NT appends a \0 */
+ if (len < *count && data[len-1]) data[len] = 0;
+ }
+ }
+ info->DataLength = len;
+ }
+ else if (data)
+ {
+ if (total_size - info->DataOffset > *count) status =
STATUS_BUFFER_OVERFLOW;
+ else memcpy( data, buf_ptr + info->DataOffset, total_size -
info->DataOffset );
+ }
+
+ if (value && !status)
+ {
+ ULONG len;
+
+ RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
+ if (len >= *val_count)
+ {
+ status = STATUS_BUFFER_OVERFLOW;
+ if (*val_count)
+ {
+ len = *val_count - 1;
+ RtlUnicodeToMultiByteN( value, len, NULL, info->Name,
info->NameLength );
+ value[len] = 0;
+ }
+ }
+ else
+ {
+ RtlUnicodeToMultiByteN( value, len, NULL, info->Name,
info->NameLength );
+ value[len] = 0;
+ *val_count = len;
+ }
+ }
+ }
+ else status = STATUS_SUCCESS;
+
+ if (type) *type = info->Type;
+ if (count) *count = info->DataLength;
+
+ done:
+ if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ ClosePredefKey(KeyHandle);
+ return RtlNtStatusToDosError(status);
+}
+
+LONG WINAPI
+RegEnumValueW(HKEY hKey,
+ DWORD index,
+ LPWSTR value,
+ PDWORD val_count,
+ PDWORD reserved,
+ PDWORD type,
+ LPBYTE data,
+ PDWORD count)
+{
+ HANDLE KeyHandle;
+ NTSTATUS status;
+ ULONG total_size;
+ char buffer[256], *buf_ptr = buffer;
+ KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
+ static const int info_size = FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name );
+
+ //TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n",
+ // hkey, index, value, val_count, reserved, type, data, count );
+
+ /* NT only checks count, not val_count */
+ if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
+
+ status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(status))
+ {
+ return RtlNtStatusToDosError(status);
+ }
+
+ total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
+ if (data) total_size += *count;
+ total_size = min( sizeof(buffer), total_size );
+
+ status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
+ buffer, total_size, &total_size );
+ if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+
+ if (value || data)
+ {
+ /* retry with a dynamically allocated buffer */
+ while (status == STATUS_BUFFER_OVERFLOW)
+ {
+ if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+ {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+ info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr;
+ status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
+ buf_ptr, total_size, &total_size );
+ }
+
+ if (status) goto done;
+
+ if (value)
+ {
+ if (info->NameLength/sizeof(WCHAR) >= *val_count)
+ {
+ status = STATUS_BUFFER_OVERFLOW;
+ goto overflow;
+ }
+ memcpy( value, info->Name, info->NameLength );
+ *val_count = info->NameLength / sizeof(WCHAR);
+ value[*val_count] = 0;
+ }
+
+ if (data)
+ {
+ if (total_size - info->DataOffset > *count)
+ {
+ status = STATUS_BUFFER_OVERFLOW;
+ goto overflow;
+ }
+ memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset
);
+ if (total_size - info->DataOffset <= *count-sizeof(WCHAR) &&
is_string(info->Type))
+ {
+ /* if the type is REG_SZ and data is not 0-terminated
+ * and there is enough space in the buffer NT appends a \0 */
+ WCHAR *ptr = (WCHAR *)(data + total_size - info->DataOffset);
+ if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
+ }
+ }
+ }
+ else status = STATUS_SUCCESS;
+
+ overflow:
+ if (type) *type = info->Type;
+ if (count) *count = info->DataLength;
+
+ done:
+ if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ ClosePredefKey(KeyHandle);
+ return RtlNtStatusToDosError(status);
+}
+
+LONG WINAPI
+RegOpenKeyA(HKEY hKey,
+ LPCSTR lpSubKey,
+ PHKEY phkResult)
+{
+ TRACE("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n",
+ hKey, lpSubKey, phkResult);
+
+ if (!hKey && lpSubKey && phkResult)
+ {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!lpSubKey || !*lpSubKey)
+ {
+ *phkResult = hKey;
+ return ERROR_SUCCESS;
+ }
+
+ return RegOpenKeyExA(hKey,
+ lpSubKey,
+ 0,
+ MAXIMUM_ALLOWED,
+ phkResult);
+}
+
+LONG WINAPI
+RegOpenKeyW(HKEY hKey,
+ LPCWSTR lpSubKey,
+ PHKEY phkResult)
+{
+ TRACE("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n",
+ hKey, lpSubKey, phkResult);
+
+ if (!hKey && lpSubKey && phkResult)
+ {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!lpSubKey || !*lpSubKey)
+ {
+ *phkResult = hKey;
+ return ERROR_SUCCESS;
+ }
+
+ return RegOpenKeyExW(hKey,
+ lpSubKey,
+ 0,
+ MAXIMUM_ALLOWED,
+ phkResult);
+}
+
+LONG WINAPI
+RegOpenKeyExA(HKEY hKey,
+ LPCSTR lpSubKey,
+ DWORD ulOptions,
+ REGSAM samDesired,
+ PHKEY phkResult)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyString;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
+
+ TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x
phkResult %p\n",
+ hKey, lpSubKey, ulOptions, samDesired, phkResult);
+ if (!phkResult)
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
+ (LPSTR)lpSubKey);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ Status = NtOpenKey((PHANDLE)phkResult,
+ samDesired,
+ &ObjectAttributes);
+ RtlFreeUnicodeString(&SubKeyString);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+ }
+
+ ClosePredefKey(KeyHandle);
+
+ return ErrorCode;
+}
+
+LONG WINAPI
+RegOpenKeyExW(HKEY hKey,
+ LPCWSTR lpSubKey,
+ DWORD ulOptions,
+ REGSAM samDesired,
+ PHKEY phkResult)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyString;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
+
+ TRACE("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x
phkResult %p\n",
+ hKey, lpSubKey, ulOptions, samDesired, phkResult);
+ if (!phkResult)
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ if (lpSubKey != NULL)
+ RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
+ else
+ RtlInitUnicodeString(&SubKeyString, (LPWSTR)L"");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ Status = NtOpenKey((PHANDLE)phkResult,
+ samDesired,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+ }
+
+ ClosePredefKey(KeyHandle);
+
+ return ErrorCode;
+}
+
+LONG WINAPI
+RegQueryInfoKeyA(HKEY hKey,
+ LPSTR lpClass,
+ LPDWORD lpcbClass,
+ LPDWORD lpReserved,
+ LPDWORD lpcSubKeys,
+ LPDWORD lpcbMaxSubKeyLen,
+ LPDWORD lpcbMaxClassLen,
+ LPDWORD lpcValues,
+ LPDWORD lpcbMaxValueNameLen,
+ LPDWORD lpcbMaxValueLen,
+ LPDWORD lpcbSecurityDescriptor,
+ PFILETIME lpftLastWriteTime)
+{
+ WCHAR ClassName[MAX_PATH];
+ UNICODE_STRING UnicodeString;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+
+ RtlInitUnicodeString(&UnicodeString,
+ NULL);
+ if (lpClass != NULL)
+ {
+ UnicodeString.Buffer = &ClassName[0];
+ UnicodeString.MaximumLength = sizeof(ClassName);
+ AnsiString.MaximumLength = *lpcbClass;
+ }
+
+ ErrorCode = RegQueryInfoKeyW(hKey,
+ UnicodeString.Buffer,
+ lpcbClass,
+ lpReserved,
+ lpcSubKeys,
+ lpcbMaxSubKeyLen,
+ lpcbMaxClassLen,
+ lpcValues,
+ lpcbMaxValueNameLen,
+ lpcbMaxValueLen,
+ lpcbSecurityDescriptor,
+ lpftLastWriteTime);
+ if ((ErrorCode == ERROR_SUCCESS) && (lpClass != NULL))
+ {
+ AnsiString.Buffer = lpClass;
+ AnsiString.Length = 0;
+ UnicodeString.Length = *lpcbClass * sizeof(WCHAR);
+ RtlUnicodeStringToAnsiString(&AnsiString,
+ &UnicodeString,
+ FALSE);
+ *lpcbClass = AnsiString.Length;
+ lpClass[AnsiString.Length] = 0;
+ }
+
+ return ErrorCode;
+}
+
+LONG WINAPI
+RegQueryInfoKeyW(HKEY hKey,
+ LPWSTR lpClass,
+ LPDWORD lpcbClass,
+ LPDWORD lpReserved,
+ LPDWORD lpcSubKeys,
+ LPDWORD lpcbMaxSubKeyLen,
+ LPDWORD lpcbMaxClassLen,
+ LPDWORD lpcValues,
+ LPDWORD lpcbMaxValueNameLen,
+ LPDWORD lpcbMaxValueLen,
+ LPDWORD lpcbSecurityDescriptor,
+ PFILETIME lpftLastWriteTime)
+{
+ KEY_FULL_INFORMATION FullInfoBuffer;
+ PKEY_FULL_INFORMATION FullInfo;
+ ULONG FullInfoSize;
+ ULONG ClassLength = 0;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ ULONG Length;
+ LONG ErrorCode = ERROR_SUCCESS;
+
+ if ((lpClass) && (!lpcbClass))
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ if (lpClass != NULL)
+ {
+ if (*lpcbClass > 0)
+ {
+ ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+ }
+ else
+ {
+ ClassLength = 0;
+ }
+
+ FullInfoSize = sizeof(KEY_FULL_INFORMATION) + ((ClassLength + 3) & ~3);
+ FullInfo = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ FullInfoSize);
+ if (FullInfo == NULL)
+ {
+ ErrorCode = ERROR_OUTOFMEMORY;
+ goto Cleanup;
+ }
+
+ FullInfo->ClassLength = ClassLength;
+ }
+ else
+ {
+ FullInfoSize = sizeof(KEY_FULL_INFORMATION);
+ FullInfo = &FullInfoBuffer;
+ FullInfo->ClassLength = 0;
+ }
+ FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+
+ Status = NtQueryKey(KeyHandle,
+ KeyFullInformation,
+ FullInfo,
+ FullInfoSize,
+ &Length);
+ TRACE("NtQueryKey() returned status 0x%X\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ if (lpClass != NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ FullInfo);
+ }
+
+ ErrorCode = RtlNtStatusToDosError(Status);
+ goto Cleanup;
+ }
+
+ TRACE("SubKeys %d\n", FullInfo->SubKeys);
+ if (lpcSubKeys != NULL)
+ {
+ *lpcSubKeys = FullInfo->SubKeys;
+ }
+
+ TRACE("MaxNameLen %lu\n", FullInfo->MaxNameLen);
+ if (lpcbMaxSubKeyLen != NULL)
+ {
+ *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
+ }
+
+ TRACE("MaxClassLen %lu\n", FullInfo->MaxClassLen);
+ if (lpcbMaxClassLen != NULL)
+ {
+ *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
+ }
+
+ TRACE("Values %lu\n", FullInfo->Values);
+ if (lpcValues != NULL)
+ {
+ *lpcValues = FullInfo->Values;
+ }
+
+ TRACE("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
+ if (lpcbMaxValueNameLen != NULL)
+ {
+ *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
+ }
+
+ TRACE("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
+ if (lpcbMaxValueLen != NULL)
+ {
+ *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
+ }
+
+ if (lpftLastWriteTime != NULL)
+ {
+ lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
+ lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
+ }
+
+ if (lpClass != NULL)
+ {
+ if (FullInfo->ClassLength > ClassLength)
+ {
+ ErrorCode = ERROR_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ RtlCopyMemory(lpClass,
+ FullInfo->Class,
+ FullInfo->ClassLength);
+ *lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
+ lpClass[*lpcbClass] = 0;
+ }
+
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ FullInfo);
+ }
+
+Cleanup:
+ ClosePredefKey(KeyHandle);
+
+ return ErrorCode;
+}
+
+LONG WINAPI
+RegQueryValueExA(HKEY hKey,
+ LPCSTR lpValueName,
+ LPDWORD lpReserved,
+ LPDWORD lpType,
+ LPBYTE lpData,
+ LPDWORD lpcbData)
+{
+ UNICODE_STRING ValueName;
+ UNICODE_STRING ValueData;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+ DWORD Length;
+ DWORD Type;
+
+ TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
+ hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
+
+ if (lpData != NULL && lpcbData == NULL)
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if (lpData)
+ {
+ ValueData.Length = 0;
+ ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
+ ValueData.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ ValueData.MaximumLength);
+ if (!ValueData.Buffer)
+ {
+ return ERROR_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ ValueData.Buffer = NULL;
+ ValueData.Length = 0;
+ ValueData.MaximumLength = 0;
+
+ if (lpcbData)
+ *lpcbData = 0;
+ }
+
+ RtlCreateUnicodeStringFromAsciiz(&ValueName,
+ (LPSTR)lpValueName);
+
+ Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
+ ErrorCode = RegQueryValueExW(hKey,
+ ValueName.Buffer,
+ lpReserved,
+ &Type,
+ (lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer,
+ &Length);
+ TRACE("ErrorCode %lu\n", ErrorCode);
+ RtlFreeUnicodeString(&ValueName);
+
+ if (ErrorCode == ERROR_SUCCESS ||
+ ErrorCode == ERROR_MORE_DATA)
+ {
+
+ if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
+ {
+ if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = (LPSTR)lpData;
+ AnsiString.MaximumLength = *lpcbData;
+ ValueData.Length = Length;
+ ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
+ RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
+ }
+
+ Length = Length / sizeof(WCHAR);
+ }
+ else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+ {
+ if (*lpcbData < Length)
+ {
+ ErrorCode = ERROR_MORE_DATA;
+ }
+ else
+ {
+ RtlMoveMemory(lpData, ValueData.Buffer, Length);
+ }
+ }
+
+ if (lpcbData != NULL)
+ {
+ *lpcbData = Length;
+ }
+ }
+
+ if (lpType != NULL)
+ {
+ *lpType = Type;
+ }
+
+ if (ValueData.Buffer != NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData.Buffer);
+ }
+
+ return ErrorCode;
+}
+
+LONG
+WINAPI
+RegQueryValueExW(HKEY hkeyorg,
+ LPCWSTR name,
+ LPDWORD reserved,
+ LPDWORD type,
+ LPBYTE data,
+ LPDWORD count)
+{
+ HANDLE hkey;
+ NTSTATUS status;
+ UNICODE_STRING name_str;
+ DWORD total_size;
+ char buffer[256], *buf_ptr = buffer;
+ KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
+ static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
+
+ TRACE("(%p,%s,%p,%p,%p,%p=%d)\n",
+ hkey, debugstr_w(name), reserved, type, data, count,
+ (count && data) ? *count : 0 );
+
+ if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
+
+ status = MapDefaultKey(&hkey, hkeyorg);
+ if (!NT_SUCCESS(status))
+ {
+ return RtlNtStatusToDosError(status);
+ }
+
+ RtlInitUnicodeString( &name_str, name );
+
+ if (data) total_size = min( sizeof(buffer), *count + info_size );
+ else
+ {
+ total_size = info_size;
+ if (count) *count = 0;
+ }
+
+ /* this matches Win9x behaviour - NT sets *type to a random value */
+ if (type) *type = REG_NONE;
+
+ status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
+ buffer, total_size, &total_size );
+ if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+
+ if (data)
+ {
+ /* retry with a dynamically allocated buffer */
+ while (status == STATUS_BUFFER_OVERFLOW && total_size - info_size <=
*count)
+ {
+ if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+ {
+ ClosePredefKey(hkey);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
+ status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
+ buf_ptr, total_size, &total_size );
+ }
+
+ if (!status)
+ {
+ memcpy( data, buf_ptr + info_size, total_size - info_size );
+ /* if the type is REG_SZ and data is not 0-terminated
+ * and there is enough space in the buffer NT appends a \0 */
+ if (total_size - info_size <= *count-sizeof(WCHAR) &&
is_string(info->Type))
+ {
+ WCHAR *ptr = (WCHAR *)(data + total_size - info_size);
+ if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
+ }
+ }
+ else if (status != STATUS_BUFFER_OVERFLOW) goto done;
+ }
+ else status = STATUS_SUCCESS;
+
+ if (type) *type = info->Type;
+ if (count) *count = total_size - info_size;
+
+ done:
+ if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ ClosePredefKey(hkey);
+ return RtlNtStatusToDosError(status);
+}
+
+LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG count )
+{
+ DWORD ret;
+ HKEY subkey = hkey;
+
+ TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_a(name), data, count ? *count : 0
);
+
+ if (name && name[0])
+ {
+ if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
+ }
+ ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
+ if (subkey != hkey) RegCloseKey( subkey );
+ if (ret == ERROR_FILE_NOT_FOUND)
+ {
+ /* return empty string if default value not found */
+ if (data) *data = 0;
+ if (count) *count = 1;
+ ret = ERROR_SUCCESS;
+ }
+ return ret;
+}
+
+LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count )
+{
+ DWORD ret;
+ HKEY subkey = hkey;
+
+ TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_w(name), data, count ? *count : 0
);
+ if (hkey == NULL)
+ {
+ return ERROR_INVALID_HANDLE;
+ }
+ if (name && name[0])
+ {
+ ret = RegOpenKeyW( hkey, name, &subkey);
+ if (ret != ERROR_SUCCESS)
+ {
+ return ret;
+ }
+ }
+
+ ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
+
+ if (subkey != hkey)
+ {
+ RegCloseKey( subkey );
+ }
+
+ if (ret == ERROR_FILE_NOT_FOUND)
+ {
+ /* return empty string if default value not found */
+ if (data)
+ *data = 0;
+ if (count)
+ *count = sizeof(WCHAR);
+ ret = ERROR_SUCCESS;
+ }
+ return ret;
+}
+
+LONG WINAPI
+RegSetValueExA(HKEY hKey,
+ LPCSTR lpValueName,
+ DWORD Reserved,
+ DWORD dwType,
+ CONST BYTE* lpData,
+ DWORD cbData)
+{
+ UNICODE_STRING ValueName;
+ LPWSTR pValueName;
+ ANSI_STRING AnsiString;
+ UNICODE_STRING Data;
+ LONG ErrorCode;
+ LPBYTE pData;
+ DWORD DataSize;
+
+ if (lpValueName != NULL &&
+ strlen(lpValueName) != 0)
+ {
+ RtlCreateUnicodeStringFromAsciiz(&ValueName,
+ (PSTR)lpValueName);
+ }
+ else
+ {
+ ValueName.Buffer = NULL;
+ }
+
+ pValueName = (LPWSTR)ValueName.Buffer;
+
+ if (((dwType == REG_SZ) ||
+ (dwType == REG_MULTI_SZ) ||
+ (dwType == REG_EXPAND_SZ)) &&
+ (cbData != 0))
+ {
+ /* NT adds one if the caller forgot the NULL-termination character */
+ if (lpData[cbData - 1] != '\0')
+ {
+ cbData++;
+ }
+
+ RtlInitAnsiString(&AnsiString,
+ NULL);
+ AnsiString.Buffer = (PSTR)lpData;
+ AnsiString.Length = cbData - 1;
+ 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 != NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ ValueName.Buffer);
+ }
+
+ if (Data.Buffer != NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ Data.Buffer);
+ }
+
+ return ErrorCode;
+}
+
+LONG WINAPI
+RegSetValueExW(HKEY hKey,
+ LPCWSTR lpValueName,
+ DWORD Reserved,
+ DWORD dwType,
+ CONST BYTE* lpData,
+ DWORD cbData)
+{
+ UNICODE_STRING ValueName;
+ PUNICODE_STRING pValueName;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ if (lpValueName != NULL)
+ {
+ RtlInitUnicodeString(&ValueName,
+ lpValueName);
+ }
+ else
+ {
+ RtlInitUnicodeString(&ValueName, L"");
+ }
+ pValueName = &ValueName;
+
+ if (((dwType == REG_SZ) ||
+ (dwType == REG_MULTI_SZ) ||
+ (dwType == REG_EXPAND_SZ)) &&
+ (cbData != 0) && (*(((PWCHAR)lpData) + (cbData / sizeof(WCHAR)) - 1) !=
L'\0'))
+ {
+ /* NT adds one if the caller forgot the NULL-termination character */
+ cbData += sizeof(WCHAR);
+ }
+
+ Status = NtSetValueKey(KeyHandle,
+ pValueName,
+ 0,
+ dwType,
+ (PVOID)lpData,
+ (ULONG)cbData);
+
+ ClosePredefKey(KeyHandle);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ return ERROR_SUCCESS;
+}
Propchange: branches/arwinss/reactos/dll/win32/gdi32/regglue.c
------------------------------------------------------------------------------
svn:eol-style = native