Sweden-Number/dlls/ntdll/reg.c

710 lines
21 KiB
C

/*
* registry functions
*
* NOTES:
* HKEY_LOCAL_MACHINE \\REGISTRY\\MACHINE
* HKEY_USERS \\REGISTRY\\USER
* HKEY_CURRENT_CONFIG \\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\HARDWARE PROFILES\\CURRENT
* HKEY_CLASSES \\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES
*/
#include "debugtools.h"
#include "winreg.h"
#include "winerror.h"
#include "file.h"
#include "server.h"
#include "ntddk.h"
#include "crtdll.h"
#include "ntdll_misc.h"
DEFAULT_DEBUG_CHANNEL(ntdll);
/* copy a key name into the request buffer */
static inline NTSTATUS copy_nameU( LPWSTR Dest, PUNICODE_STRING Name, UINT Offset )
{
if (Name->Buffer)
{
if ((Name->Length-Offset) > MAX_PATH) return STATUS_BUFFER_OVERFLOW;
lstrcpyW( Dest, Name->Buffer+Offset );
}
else Dest[0] = 0;
return STATUS_SUCCESS;
}
/* translates predefined paths to HKEY_ constants */
static BOOLEAN _NtKeyToWinKey(
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT UINT * Offset, /* offset within ObjectName */
OUT HKEY * KeyHandle) /* translated handle */
{
static const WCHAR KeyPath_HKLM[] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','M','A','C','H','I','N','E',0};
static const WCHAR KeyPath_HKU [] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','U','S','E','R',0};
static const WCHAR KeyPath_HCC [] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','M','A','C','H','I','N','E',
'\\','S','Y','S','T','E','M',
'\\','C','U','R','R','E','N','T','C','O','N','T','R','O','L','S','E','T',
'\\','H','A','R','D','W','A','R','E','P','R','O','F','I','L','E','S',
'\\','C','U','R','R','E','N','T',0};
static const WCHAR KeyPath_HCR [] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','M','A','C','H','I','N','E',
'\\','S','O','F','T','W','A','R','E',
'\\','C','L','A','S','S','E','S',0};
int len;
PUNICODE_STRING ObjectName = ObjectAttributes->ObjectName;
if((ObjectName->Length > (len=lstrlenW(KeyPath_HKLM)))
&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HKLM,len)))
{ *KeyHandle = HKEY_LOCAL_MACHINE;
}
else if((ObjectName->Length > (len=lstrlenW(KeyPath_HKU)))
&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HKU,len)))
{ *KeyHandle = HKEY_USERS;
}
else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCR)))
&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HCR,len)))
{ *KeyHandle = HKEY_CLASSES_ROOT;
}
else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCC)))
&& (0==CRTDLL_wcsncmp(ObjectName->Buffer,KeyPath_HCC,len)))
{ *KeyHandle = HKEY_CURRENT_CONFIG;
}
else
{
*KeyHandle = ObjectAttributes->RootDirectory;
*Offset = 0;
return FALSE;
}
if (ObjectName->Buffer[len] == (WCHAR)'\\') len++;
*Offset = len;
TRACE("off=%u hkey=0x%08x\n", *Offset, *KeyHandle);
return TRUE;
}
/******************************************************************************
* NtCreateKey [NTDLL]
* ZwCreateKey
*/
NTSTATUS WINAPI NtCreateKey(
PHANDLE KeyHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions,
PULONG Disposition)
{
struct create_key_request *req = get_req_buffer();
UINT ObjectNameOffset;
HKEY RootDirectory;
NTSTATUS ret;
TRACE("(%p,0x%08lx,0x%08lx,%p(%s),0x%08lx,%p)\n",
KeyHandle, DesiredAccess, TitleIndex, Class, debugstr_us(Class), CreateOptions, Disposition);
dump_ObjectAttributes(ObjectAttributes);
if (!KeyHandle)
return STATUS_INVALID_PARAMETER;
_NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory);
req->parent = RootDirectory;
req->access = DesiredAccess;
req->options = CreateOptions;
req->modif = time(NULL);
if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS)
return STATUS_INVALID_PARAMETER;
if (Class)
{
int ClassLen = Class->Length+1;
if ( ClassLen*sizeof(WCHAR) > server_remaining(req->class)) return STATUS_BUFFER_OVERFLOW;
lstrcpynW( req->class, Class->Buffer, ClassLen);
}
else
req->class[0] = 0x0000;
if (!(ret = server_call_noerr(REQ_CREATE_KEY)))
{
*KeyHandle = req->hkey;
if (Disposition) *Disposition = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
}
return ret;
}
/******************************************************************************
* NtOpenKey [NTDLL.129]
* ZwOpenKey
* OUT PHANDLE KeyHandle (returns 0 when failure)
* IN ACCESS_MASK DesiredAccess
* IN POBJECT_ATTRIBUTES ObjectAttributes
*/
NTSTATUS WINAPI NtOpenKey(
PHANDLE KeyHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes)
{
struct open_key_request *req = get_req_buffer();
UINT ObjectNameOffset;
HKEY RootDirectory;
NTSTATUS ret;
TRACE("(%p,0x%08lx)\n", KeyHandle, DesiredAccess);
dump_ObjectAttributes(ObjectAttributes);
if (!KeyHandle) return STATUS_INVALID_PARAMETER;
*KeyHandle = 0;
_NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory);
req->parent = RootDirectory;
req->access = DesiredAccess;
if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS)
return STATUS_INVALID_PARAMETER;
if (!(ret = server_call_noerr(REQ_OPEN_KEY)))
{
*KeyHandle = req->hkey;
}
return ret;
}
/******************************************************************************
* NtDeleteKey [NTDLL]
* ZwDeleteKey
*/
NTSTATUS WINAPI NtDeleteKey(HANDLE KeyHandle)
{
FIXME("(0x%08x) stub!\n",
KeyHandle);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtDeleteValueKey [NTDLL]
* ZwDeleteValueKey
*/
NTSTATUS WINAPI NtDeleteValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName)
{
FIXME("(0x%08x,%p(%s)) stub!\n",
KeyHandle, ValueName,debugstr_us(ValueName));
return STATUS_SUCCESS;
}
/******************************************************************************
* NtEnumerateKey [NTDLL]
* ZwEnumerateKey
*
* NOTES
* the name copied into the buffer is NOT 0-terminated
*/
NTSTATUS WINAPI NtEnumerateKey(
HANDLE KeyHandle,
ULONG Index,
KEY_INFORMATION_CLASS KeyInformationClass,
PVOID KeyInformation,
ULONG Length,
PULONG ResultLength)
{
struct enum_key_request *req = get_req_buffer();
NTSTATUS ret;
TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
req->hkey = KeyHandle;
req->index = Index;
if ((ret = server_call_noerr(REQ_ENUM_KEY)) != STATUS_SUCCESS) return ret;
switch (KeyInformationClass)
{
case KeyBasicInformation:
{
PKEY_BASIC_INFORMATION kbi = KeyInformation;
UINT NameLength = lstrlenW(req->name) * sizeof(WCHAR);
*ResultLength = sizeof(KEY_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
DOSFS_UnixTimeToFileTime(req->modif, &kbi->LastWriteTime, 0);
kbi->TitleIndex = 0;
kbi->NameLength = NameLength;
memcpy (kbi->Name, req->name, NameLength);
}
break;
case KeyFullInformation:
{
PKEY_FULL_INFORMATION kfi = KeyInformation;
kfi->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
kfi->ClassOffset = (kfi->ClassLength) ?
sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) : 0xffffffff;
*ResultLength = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) + kfi->ClassLength;
if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
DOSFS_UnixTimeToFileTime(req->modif, &kfi->LastWriteTime, 0);
kfi->TitleIndex = 0;
/* kfi->SubKeys = req->subkeys;
kfi->MaxNameLength = req->max_subkey;
kfi->MaxClassLength = req->max_class;
kfi->Values = req->values;
kfi->MaxValueNameLen = req->max_value;
kfi->MaxValueDataLen = req->max_data;
*/
FIXME("incomplete\n");
if (kfi->ClassLength) memcpy (kfi->Class, req->class, kfi->ClassLength);
}
break;
case KeyNodeInformation:
{
PKEY_NODE_INFORMATION kni = KeyInformation;
kni->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
kni->NameLength = lstrlenW(req->name) * sizeof(WCHAR);
kni->ClassOffset = (kni->ClassLength) ?
sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength : 0xffffffff;
*ResultLength = sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength + kni->ClassLength;
if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
DOSFS_UnixTimeToFileTime(req->modif, &kni->LastWriteTime, 0);
kni->TitleIndex = 0;
memcpy (kni->Name, req->name, kni->NameLength);
if (kni->ClassLength) memcpy (KeyInformation+kni->ClassOffset, req->class, kni->ClassLength);
}
break;
default:
FIXME("KeyInformationClass not implemented\n");
return STATUS_UNSUCCESSFUL;
}
TRACE("buf=%lu len=%lu\n", Length, *ResultLength);
return ret;
}
/******************************************************************************
* NtQueryKey [NTDLL]
* ZwQueryKey
*/
NTSTATUS WINAPI NtQueryKey(
HANDLE KeyHandle,
KEY_INFORMATION_CLASS KeyInformationClass,
PVOID KeyInformation,
ULONG Length,
PULONG ResultLength)
{
struct query_key_info_request *req = get_req_buffer();
NTSTATUS ret;
TRACE("(0x%08x,0x%08x,%p,0x%08lx,%p) stub\n",
KeyHandle, KeyInformationClass, KeyInformation, Length, ResultLength);
req->hkey = KeyHandle;
if ((ret = server_call_noerr(REQ_QUERY_KEY_INFO)) != STATUS_SUCCESS) return ret;
switch (KeyInformationClass)
{
case KeyBasicInformation:
{
PKEY_BASIC_INFORMATION kbi = KeyInformation;
UINT NameLength = lstrlenW(req->name) * sizeof(WCHAR);
*ResultLength = sizeof(KEY_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
DOSFS_UnixTimeToFileTime(req->modif, &kbi->LastWriteTime, 0);
kbi->TitleIndex = 0;
kbi->NameLength = NameLength;
memcpy (kbi->Name, req->name, NameLength);
}
break;
case KeyFullInformation:
{
PKEY_FULL_INFORMATION kfi = KeyInformation;
kfi->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
kfi->ClassOffset = (kfi->ClassLength) ?
sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) : 0xffffffff;
*ResultLength = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) + kfi->ClassLength;
if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
DOSFS_UnixTimeToFileTime(req->modif, &kfi->LastWriteTime, 0);
kfi->TitleIndex = 0;
kfi->SubKeys = req->subkeys;
kfi->MaxNameLen = req->max_subkey;
kfi->MaxClassLen = req->max_class;
kfi->Values = req->values;
kfi->MaxValueNameLen = req->max_value;
kfi->MaxValueDataLen = req->max_data;
if(kfi->ClassLength) memcpy (KeyInformation+kfi->ClassOffset, req->class, kfi->ClassLength);
}
break;
case KeyNodeInformation:
{
PKEY_NODE_INFORMATION kni = KeyInformation;
kni->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
kni->NameLength = lstrlenW(req->name) * sizeof(WCHAR);
kni->ClassOffset = (kni->ClassLength) ?
sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength : 0xffffffff;
*ResultLength = sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength + kni->ClassLength;
if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
DOSFS_UnixTimeToFileTime(req->modif, &kni->LastWriteTime, 0);
kni->TitleIndex = 0;
memcpy (kni->Name, req->name, kni->NameLength);
if(kni->ClassLength) memcpy (KeyInformation+kni->ClassOffset, req->class, kni->ClassLength);
}
break;
default:
FIXME("KeyInformationClass not implemented\n");
return STATUS_UNSUCCESSFUL;
}
return ret;
}
/******************************************************************************
* NtEnumerateValueKey [NTDLL]
* ZwEnumerateValueKey
*/
NTSTATUS WINAPI NtEnumerateValueKey(
HANDLE KeyHandle,
ULONG Index,
KEY_VALUE_INFORMATION_CLASS KeyInformationClass,
PVOID KeyInformation,
ULONG Length,
PULONG ResultLength)
{
struct enum_key_value_request *req = get_req_buffer();
UINT NameLength;
NTSTATUS ret;
TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
req->hkey = KeyHandle;
req->index = Index;
if ((ret = server_call_noerr(REQ_ENUM_KEY_VALUE)) != STATUS_SUCCESS) return ret;
switch (KeyInformationClass)
{
case KeyBasicInformation:
{
PKEY_VALUE_BASIC_INFORMATION kbi = KeyInformation;
NameLength = lstrlenW(req->name) * sizeof(WCHAR);
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
kbi->TitleIndex = 0;
kbi->Type = req->type;
kbi->NameLength = NameLength;
memcpy(kbi->Name, req->name, kbi->NameLength);
}
break;
case KeyValueFullInformation:
{
PKEY_VALUE_FULL_INFORMATION kbi = KeyInformation;
UINT DataOffset;
NameLength = lstrlenW(req->name) * sizeof(WCHAR);
DataOffset = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR) + NameLength;
*ResultLength = DataOffset + req->len;
if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
kbi->TitleIndex = 0;
kbi->Type = req->type;
kbi->DataOffset = DataOffset;
kbi->DataLength = req->len;
kbi->NameLength = NameLength;
memcpy(kbi->Name, req->name, kbi->NameLength);
memcpy(((LPBYTE)kbi) + DataOffset, req->data, req->len);
}
break;
case KeyValuePartialInformation:
{
PKEY_VALUE_PARTIAL_INFORMATION kbi = KeyInformation;
*ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(WCHAR) + req->len;
if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
kbi->TitleIndex = 0;
kbi->Type = req->type;
kbi->DataLength = req->len;
memcpy(kbi->Data, req->data, req->len);
}
break;
default:
FIXME("not implemented\n");
}
return STATUS_SUCCESS;
}
/******************************************************************************
* NtFlushKey [NTDLL]
* ZwFlushKey
*/
NTSTATUS WINAPI NtFlushKey(HANDLE KeyHandle)
{
FIXME("(0x%08x) stub!\n",
KeyHandle);
return 1;
}
/******************************************************************************
* NtLoadKey [NTDLL]
* ZwLoadKey
*/
NTSTATUS WINAPI NtLoadKey(
PHANDLE KeyHandle,
POBJECT_ATTRIBUTES ObjectAttributes)
{
FIXME("(%p),stub!\n", KeyHandle);
dump_ObjectAttributes(ObjectAttributes);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtNotifyChangeKey [NTDLL]
* ZwNotifyChangeKey
*/
NTSTATUS WINAPI NtNotifyChangeKey(
IN HANDLE KeyHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG CompletionFilter,
IN BOOLEAN Asynchroneous,
OUT PVOID ChangeBuffer,
IN ULONG Length,
IN BOOLEAN WatchSubtree)
{
FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
Asynchroneous, ChangeBuffer, Length, WatchSubtree);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtQueryMultipleValueKey [NTDLL]
* ZwQueryMultipleValueKey
*/
NTSTATUS WINAPI NtQueryMultipleValueKey(
HANDLE KeyHandle,
PVALENTW ListOfValuesToQuery,
ULONG NumberOfItems,
PVOID MultipleValueInformation,
ULONG Length,
PULONG ReturnLength)
{
FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
Length,ReturnLength);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtQueryValueKey [NTDLL]
* ZwQueryValueKey
*
* NOTES
* the name in the KeyValueInformation is never set
*/
NTSTATUS WINAPI NtQueryValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength)
{
struct get_key_value_request *req = get_req_buffer();
NTSTATUS ret;
TRACE("(0x%08x,%s,0x%08x,%p,0x%08lx,%p)\n",
KeyHandle, debugstr_us(ValueName), KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
req->hkey = KeyHandle;
if (copy_nameU(req->name, ValueName, 0) != STATUS_SUCCESS) return STATUS_BUFFER_OVERFLOW;
if ((ret = server_call_noerr(REQ_GET_KEY_VALUE)) != STATUS_SUCCESS) return ret;
switch(KeyValueInformationClass)
{
case KeyValueBasicInformation:
{
PKEY_VALUE_BASIC_INFORMATION kbi = (PKEY_VALUE_BASIC_INFORMATION) KeyValueInformation;
kbi->Type = req->type;
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION)-sizeof(WCHAR);
if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
kbi->NameLength = 0;
}
break;
case KeyValueFullInformation:
{
PKEY_VALUE_FULL_INFORMATION kfi = (PKEY_VALUE_FULL_INFORMATION) KeyValueInformation;
ULONG DataOffset;
kfi->Type = req->type;
DataOffset = sizeof(KEY_VALUE_FULL_INFORMATION)-sizeof(WCHAR);
*ResultLength = DataOffset + req->len;
if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
kfi->NameLength = 0;
kfi->DataOffset = DataOffset;
kfi->DataLength = req->len;
memcpy(KeyValueInformation+DataOffset, req->data, req->len);
}
break;
case KeyValuePartialInformation:
{
PKEY_VALUE_PARTIAL_INFORMATION kpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;
kpi->Type = req->type;
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)-sizeof(UCHAR)+req->len;
if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
kpi->DataLength = req->len;
memcpy(kpi->Data, req->data, req->len);
}
break;
default:
FIXME("KeyValueInformationClass not implemented\n");
return STATUS_UNSUCCESSFUL;
}
return ret;
}
/******************************************************************************
* NtReplaceKey [NTDLL]
* ZwReplaceKey
*/
NTSTATUS WINAPI NtReplaceKey(
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN HANDLE Key,
IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
{
FIXME("(0x%08x),stub!\n", Key);
dump_ObjectAttributes(ObjectAttributes);
dump_ObjectAttributes(ReplacedObjectAttributes);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtRestoreKey [NTDLL]
* ZwRestoreKey
*/
NTSTATUS WINAPI NtRestoreKey(
HANDLE KeyHandle,
HANDLE FileHandle,
ULONG RestoreFlags)
{
FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
KeyHandle, FileHandle, RestoreFlags);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtSaveKey [NTDLL]
* ZwSaveKey
*/
NTSTATUS WINAPI NtSaveKey(
IN HANDLE KeyHandle,
IN HANDLE FileHandle)
{
FIXME("(0x%08x,0x%08x) stub\n",
KeyHandle, FileHandle);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtSetInformationKey [NTDLL]
* ZwSetInformationKey
*/
NTSTATUS WINAPI NtSetInformationKey(
IN HANDLE KeyHandle,
IN const int KeyInformationClass,
IN PVOID KeyInformation,
IN ULONG KeyInformationLength)
{
FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtSetValueKey [NTDLL]
* ZwSetValueKey
*/
NTSTATUS WINAPI NtSetValueKey(
HANDLE KeyHandle,
PUNICODE_STRING ValueName,
ULONG TitleIndex,
ULONG Type,
PVOID Data,
ULONG DataSize)
{
FIXME("(0x%08x,%p(%s), 0x%08lx, 0x%08lx, %p, 0x%08lx) stub!\n",
KeyHandle, ValueName,debugstr_us(ValueName), TitleIndex, Type, Data, DataSize);
return STATUS_SUCCESS;
}
/******************************************************************************
* NtUnloadKey [NTDLL]
* ZwUnloadKey
*/
NTSTATUS WINAPI NtUnloadKey(
IN HANDLE KeyHandle)
{
FIXME("(0x%08x) stub\n",
KeyHandle);
return STATUS_SUCCESS;
}
/******************************************************************************
* RtlFormatCurrentUserKeyPath [NTDLL.371]
*/
NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
IN OUT PUNICODE_STRING KeyPath)
{
/* LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
ANSI_STRING AnsiPath;
FIXME("(%p) stub\n",KeyPath);
RtlInitAnsiString(&AnsiPath, Path);
return RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
}
/******************************************************************************
* RtlOpenCurrentUser [NTDLL]
*
* if we return just HKEY_CURRENT_USER the advapi try's to find a remote
* registry (odd handle) and fails
*
*/
DWORD WINAPI RtlOpenCurrentUser(
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE KeyHandle) /* handle of HKEY_CURRENT_USER */
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ObjectName;
NTSTATUS ret;
TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
RtlFormatCurrentUserKeyPath(&ObjectName);
InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
RtlFreeUnicodeString(&ObjectName);
return ret;
}