reactos/subsystems/win32/win32k/misc/registry.c
Jérôme Gardou 88c9e7c6e8 Sync with trunk (r47116), hopefully without breaking anything.
svn path=/branches/reactos-yarotows/; revision=47117
2010-05-07 07:41:13 +00:00

302 lines
8 KiB
C

/*
* COPYRIGHT: GPL, see COPYING in the top level directory
* PROJECT: ReactOS win32 kernel mode subsystem server
* PURPOSE: Registry loading and storing
* FILE: subsystem/win32/win32k/misc/registry.c
* PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include <win32k.h>
#define NDEBUG
#include <debug.h>
NTSTATUS
NTAPI
RegOpenKey(
LPCWSTR pwszKeyName,
PHKEY phkey)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ustrKeyName;
HKEY hkey;
/* Initialize the key name */
RtlInitUnicodeString(&ustrKeyName, pwszKeyName);
/* Initialize object attributes */
InitializeObjectAttributes(&ObjectAttributes,
&ustrKeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Open the key */
Status = ZwOpenKey(&hkey, KEY_READ, &ObjectAttributes);
if (NT_SUCCESS(Status))
{
*phkey = hkey;
}
return Status;
}
NTSTATUS
NTAPI
RegQueryValue(
IN HKEY hkey,
IN PCWSTR pwszValueName,
IN ULONG ulType,
OUT PVOID pvData,
IN OUT PULONG pcbValue)
{
NTSTATUS Status;
UNICODE_STRING ustrValueName;
BYTE ajBuffer[100];
PKEY_VALUE_PARTIAL_INFORMATION pInfo;
ULONG cbInfoSize;
/* Check if the local buffer is sufficient */
cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue;
if (cbInfoSize <= sizeof(ajBuffer))
{
pInfo = (PVOID)ajBuffer;
}
else
{
/* It's not, allocate a sufficient buffer */
pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
if (!pInfo)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
}
/* Query the value */
RtlInitUnicodeString(&ustrValueName, pwszValueName);
Status = ZwQueryValueKey(hkey,
&ustrValueName,
KeyValuePartialInformation,
(PVOID)pInfo,
cbInfoSize,
&cbInfoSize);
if (NT_SUCCESS(Status))
{
/* Did we get the right type */
if (pInfo->Type == ulType)
{
/* Copy the contents to the caller */
RtlCopyMemory(pvData, pInfo->Data, *pcbValue);
}
else
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
/* Return the data size to the caller */
*pcbValue = cbInfoSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
/* Cleanup */
if (pInfo != (PVOID)ajBuffer)
ExFreePoolWithTag(pInfo, TAG_TEMP);
return Status;
}
BOOL
NTAPI
RegReadUserSetting(
IN PCWSTR pwszKeyName,
IN PCWSTR pwszValueName,
IN ULONG ulType,
OUT PVOID pvData,
IN ULONG cbDataSize)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING usCurrentUserKey, usKeyName, usValueName;
WCHAR awcBuffer[MAX_PATH];
HKEY hkey;
PKEY_VALUE_PARTIAL_INFORMATION pInfo;
ULONG cbInfoSize, cbReqSize;
/* Get the path of the current user's profile */
Status = RtlFormatCurrentUserKeyPath(&usCurrentUserKey);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
/* Initialize empty key name */
RtlInitEmptyUnicodeString(&usKeyName, awcBuffer, sizeof(awcBuffer));
/* Append the current user key name */
Status = RtlAppendUnicodeStringToString(&usKeyName, &usCurrentUserKey);
/* Free the current user key name */
RtlFreeUnicodeString(&usCurrentUserKey);
/* Check for success */
if (!NT_SUCCESS(Status))
{
return FALSE;
}
/* Append a '\', we can trust in enough space left. */
usKeyName.Buffer[usKeyName.Length / sizeof(WCHAR)] = '\\';
usKeyName.Length += sizeof(WCHAR);
/* Append the subkey name */
Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
/* Initialize object attributes */
InitializeObjectAttributes(&ObjectAttributes,
&usKeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Open the key */
Status = ZwOpenKey(&hkey, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
/* Check if the local buffer is sufficient */
cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + cbDataSize;
if (cbInfoSize <= sizeof(awcBuffer))
{
pInfo = (PVOID)awcBuffer;
}
else
{
/* It's not, allocate a sufficient buffer */
pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
if (!pInfo)
{
ZwClose(hkey);
return FALSE;
}
}
/* Query the value */
RtlInitUnicodeString(&usValueName, pwszValueName);
Status = ZwQueryValueKey(hkey,
&usValueName,
KeyValuePartialInformation,
(PVOID)pInfo,
cbInfoSize,
&cbReqSize);
if (NT_SUCCESS(Status))
{
/* Did we get the right type */
if (pInfo->Type == ulType)
{
/* Copy the contents to the caller */
RtlCopyMemory(pvData, pInfo->Data, cbDataSize);
}
}
/* Cleanup */
ZwClose(hkey);
if (pInfo != (PVOID)awcBuffer)
ExFreePoolWithTag(pInfo, TAG_TEMP);
return NT_SUCCESS(Status);
}
BOOL
NTAPI
RegWriteUserSetting(
IN PCWSTR pwszKeyName,
IN PCWSTR pwszValueName,
IN ULONG ulType,
OUT PVOID pvData,
IN ULONG cbDataSize)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING usCurrentUserKey, usKeyName, usValueName;
WCHAR awcBuffer[MAX_PATH];
HKEY hkey;
// FIXME: logged in user versus current process user?
/* Get the path of the current user's profile */
Status = RtlFormatCurrentUserKeyPath(&usCurrentUserKey);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlFormatCurrentUserKeyPath failed\n");
return FALSE;
}
/* Initialize empty key name */
RtlInitEmptyUnicodeString(&usKeyName, awcBuffer, sizeof(awcBuffer));
/* Append the current user key name */
Status = RtlAppendUnicodeStringToString(&usKeyName, &usCurrentUserKey);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
/* Free the current user key name */
RtlFreeUnicodeString(&usCurrentUserKey);
/* Append a '\', we can trust in enough space left. */
usKeyName.Buffer[usKeyName.Length / sizeof(WCHAR)] = '\\';
usKeyName.Length += sizeof(WCHAR);
/* Append the subkey name */
Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n",
Status, usKeyName.Length, usKeyName.MaximumLength);
return FALSE;
}
/* Initialize object attributes */
InitializeObjectAttributes(&ObjectAttributes,
&usKeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Open or create the key */
Status = ZwCreateKey(&hkey,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
NULL);
if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to create key: 0x%x\n", Status);
return FALSE;
}
/* Initialize the value name string */
RtlInitUnicodeString(&usValueName, pwszValueName);
Status = ZwSetValueKey(hkey, &usValueName, 0, ulType, pvData, cbDataSize);
if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to write reg key '%S' value '%S', Status = %lx\n",
pwszKeyName, pwszValueName, Status);
}
/* Cleanup */
ZwClose(hkey);
return NT_SUCCESS(Status);
}