/*
 *	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(ObjectAttributes->RootDirectory)
	{
	  len = 0;
	  *KeyHandle = ObjectAttributes->RootDirectory;
	}
	else if((ObjectName->Length > (len=lstrlenW(KeyPath_HKLM)))
	&& (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HKLM,len)))
	{  *KeyHandle = HKEY_LOCAL_MACHINE;
	}
	else if((ObjectName->Length > (len=lstrlenW(KeyPath_HKU)))
	&& (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HKU,len)))
	{  *KeyHandle = HKEY_USERS;
	}
	else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCR)))
	&& (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HCR,len)))
	{  *KeyHandle = HKEY_CLASSES_ROOT;
	}
	else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCC)))
	&& (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HCC,len)))
	{  *KeyHandle = HKEY_CURRENT_CONFIG;
	}
	else
	{
	  *KeyHandle = 0;
	  *Offset = 0;
	  return FALSE;
	}

	if (len > 0 && 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 ((char *) 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 ((char *) 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 ((char *) 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((char *) 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;
}
