Share duplicated Rtl code. I've taken care to use the most recent code, so now ntoskrnl can also do environment string expansion.
Modified: trunk/reactos/lib/ntdll/makefile
Deleted: trunk/reactos/lib/ntdll/rtl/registry.c
Modified: trunk/reactos/lib/rtl/makefile
Added: trunk/reactos/lib/rtl/registry.c
Modified: trunk/reactos/ntoskrnl/Makefile
Deleted: trunk/reactos/ntoskrnl/cm/rtlfunc.c

Modified: trunk/reactos/lib/ntdll/makefile
--- trunk/reactos/lib/ntdll/makefile	2005-01-18 04:25:27 UTC (rev 13112)
+++ trunk/reactos/lib/ntdll/makefile	2005-01-18 04:33:31 UTC (rev 13113)
@@ -77,7 +77,6 @@
 	rtl/process.o \
 	rtl/propvar.o \
 	rtl/rangelist.o \
-	rtl/registry.o \
 	rtl/resource.o \
 	rtl/teb.o \
 	rtl/thread.o \

Deleted: trunk/reactos/lib/ntdll/rtl/registry.c
--- trunk/reactos/lib/ntdll/rtl/registry.c	2005-01-18 04:25:27 UTC (rev 13112)
+++ trunk/reactos/lib/ntdll/rtl/registry.c	2005-01-18 04:33:31 UTC (rev 13113)
@@ -1,1125 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS kernel
- * PURPOSE:           Rtl registry functions
- * FILE:              lib/ntdll/rtl/registry.c
- * PROGRAMER:         Eric Kohl
- * REVISION HISTORY:
- *                    2000/08/11: Created
- */
-
-/*
- * TODO:
- *   - finish RtlQueryRegistryValues()
- *	- support RTL_QUERY_REGISTRY_DELETE
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
-#include <ntos/minmax.h>
-
-#define NDEBUG
-#include <ntdll/ntdll.h>
-
-
-/* FUNCTIONS ***************************************************************/
-
-static NTSTATUS
-RtlpGetRegistryHandle(ULONG RelativeTo,
-		      PWSTR Path,
-		      BOOLEAN Create,
-		      PHANDLE KeyHandle)
-{
-  UNICODE_STRING KeyPath;
-  UNICODE_STRING KeyName;
-  WCHAR KeyBuffer[MAX_PATH];
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  NTSTATUS Status;
-
-  DPRINT("RtlpGetRegistryHandle()\n");
-
-  if (RelativeTo & RTL_REGISTRY_HANDLE)
-    {
-      Status = NtDuplicateObject(NtCurrentProcess(),
-				 (HANDLE)Path,
-				 NtCurrentProcess(),
-				 KeyHandle,
-				 0,
-				 FALSE,
-				 DUPLICATE_SAME_ACCESS);
-      return(Status);
-    }
-
-  if (RelativeTo & RTL_REGISTRY_OPTIONAL)
-    RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
-
-  if (RelativeTo >= RTL_REGISTRY_MAXIMUM)
-    return(STATUS_INVALID_PARAMETER);
-
-  KeyName.Length = 0;
-  KeyName.MaximumLength = MAX_PATH;
-  KeyName.Buffer = KeyBuffer;
-  KeyBuffer[0] = 0;
-
-  switch (RelativeTo)
-    {
-      case RTL_REGISTRY_ABSOLUTE:
-	RtlAppendUnicodeToString(&KeyName,
-				 L"\\");
-	break;
-
-      case RTL_REGISTRY_SERVICES:
-	RtlAppendUnicodeToString(&KeyName,
-				 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
-	break;
-
-      case RTL_REGISTRY_CONTROL:
-	RtlAppendUnicodeToString(&KeyName,
-				 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
-	break;
-
-      case RTL_REGISTRY_WINDOWS_NT:
-	RtlAppendUnicodeToString(&KeyName,
-				 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");
-	break;
-
-      case RTL_REGISTRY_DEVICEMAP:
-	RtlAppendUnicodeToString(&KeyName,
-				 L"\\Registry\\Machine\\Hardware\\DeviceMap\\");
-	break;
-
-      case RTL_REGISTRY_USER:
-	Status = RtlFormatCurrentUserKeyPath (&KeyPath);
-	if (!NT_SUCCESS(Status))
-	  return(Status);
-	RtlAppendUnicodeStringToString (&KeyName,
-					&KeyPath);
-	RtlFreeUnicodeString (&KeyPath);
-	RtlAppendUnicodeToString (&KeyName,
-				  L"\\");
-	break;
-
-      /* ReactOS specific */
-      case RTL_REGISTRY_ENUM:
-	RtlAppendUnicodeToString(&KeyName,
-				 L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
-	break;
-    }
-
-  DPRINT("KeyName %wZ\n", &KeyName);
-
-  if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE)
-    {
-      Path++;
-    }
-  RtlAppendUnicodeToString(&KeyName,
-			   Path);
-
-  DPRINT("KeyName %wZ\n", &KeyName);
-
-  InitializeObjectAttributes(&ObjectAttributes,
-			     &KeyName,
-			     OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
-			     NULL,
-			     NULL);
-
-  if (Create == TRUE)
-    {
-      Status = NtCreateKey(KeyHandle,
-			   KEY_ALL_ACCESS,
-			   &ObjectAttributes,
-			   0,
-			   NULL,
-			   0,
-			   NULL);
-    }
-  else
-    {
-      Status = NtOpenKey(KeyHandle,
-			 KEY_ALL_ACCESS,
-			 &ObjectAttributes);
-    }
-
-  return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlCheckRegistryKey(IN ULONG RelativeTo,
-		    IN PWSTR Path)
-{
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-
-  Status = RtlpGetRegistryHandle(RelativeTo,
-				 Path,
-				 FALSE,
-				 &KeyHandle);
-  if (!NT_SUCCESS(Status))
-    return(Status);
-
-  NtClose(KeyHandle);
-
-  return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlCreateRegistryKey(IN ULONG RelativeTo,
-		     IN PWSTR Path)
-{
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-
-  Status = RtlpGetRegistryHandle(RelativeTo,
-				 Path,
-				 TRUE,
-				 &KeyHandle);
-  if (!NT_SUCCESS(Status))
-    return(Status);
-
-  NtClose(KeyHandle);
-
-  return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlDeleteRegistryValue(IN ULONG RelativeTo,
-		       IN PCWSTR Path,
-		       IN PCWSTR ValueName)
-{
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  UNICODE_STRING Name;
-
-  Status = RtlpGetRegistryHandle(RelativeTo,
-				 (PWSTR)Path,
-				 FALSE,
-				 &KeyHandle);
-  if (!NT_SUCCESS(Status))
-    return(Status);
-
-  RtlInitUnicodeString(&Name,
-		       ValueName);
-
-  Status = NtDeleteValueKey(KeyHandle,
-			    &Name);
-
-  NtClose(KeyHandle);
-
-  return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath)
-{
-  HANDLE TokenHandle;
-  UCHAR Buffer[256];
-  PSID_AND_ATTRIBUTES SidBuffer;
-  ULONG Length;
-  UNICODE_STRING SidString;
-  NTSTATUS Status;
-
-  DPRINT ("RtlFormatCurrentUserKeyPath() called\n");
-
-  Status = NtOpenThreadToken (NtCurrentThread (),
-			      TOKEN_READ,
-			      TRUE,
-			      &TokenHandle);
-  if (!NT_SUCCESS (Status))
-    {
-      if (Status != STATUS_NO_TOKEN)
-	{
-	  DPRINT1 ("NtOpenThreadToken() failed (Status %lx)\n", Status);
-	  return Status;
-	}
-
-      Status = NtOpenProcessToken (NtCurrentProcess (),
-				   TOKEN_READ,
-				   &TokenHandle);
-      if (!NT_SUCCESS (Status))
-	{
-	  DPRINT1 ("NtOpenProcessToken() failed (Status %lx)\n", Status);
-	  return Status;
-	}
-    }
-
-  SidBuffer = (PSID_AND_ATTRIBUTES)Buffer;
-  Status = NtQueryInformationToken (TokenHandle,
-				    TokenUser,
-				    (PVOID)SidBuffer,
-				    256,
-				    &Length);
-  NtClose (TokenHandle);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1 ("NtQueryInformationToken() failed (Status %lx)\n", Status);
-      return Status;
-    }
-
-  Status = RtlConvertSidToUnicodeString (&SidString,
-					 SidBuffer[0].Sid,
-					 TRUE);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1 ("RtlConvertSidToUnicodeString() failed (Status %lx)\n", Status);
-      return Status;
-    }
-
-  DPRINT ("SidString: '%wZ'\n", &SidString);
-
-  Length = SidString.Length + sizeof(L"\\Registry\\User\\");
-  DPRINT ("Length: %lu\n", Length);
-
-  KeyPath->Length = 0;
-  KeyPath->MaximumLength = Length;
-  KeyPath->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
-				     0,
-				     KeyPath->MaximumLength);
-  if (KeyPath->Buffer == NULL)
-    {
-      DPRINT1 ("RtlAllocateHeap() failed\n");
-      RtlFreeUnicodeString (&SidString);
-      return STATUS_NO_TOKEN;
-    }
-
-  RtlAppendUnicodeToString (KeyPath,
-			    L"\\Registry\\User\\");
-  RtlAppendUnicodeStringToString (KeyPath,
-				  &SidString);
-  RtlFreeUnicodeString (&SidString);
-
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess,
-		   OUT PHANDLE KeyHandle)
-{
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING KeyPath;
-  NTSTATUS Status;
-
-  Status = RtlFormatCurrentUserKeyPath(&KeyPath);
-  if (NT_SUCCESS(Status))
-    {
-      InitializeObjectAttributes(&ObjectAttributes,
-				 &KeyPath,
-				 OBJ_CASE_INSENSITIVE,
-				 NULL,
-				 NULL);
-      Status = NtOpenKey(KeyHandle,
-			 DesiredAccess,
-			 &ObjectAttributes);
-      RtlFreeUnicodeString(&KeyPath);
-      if (NT_SUCCESS(Status))
-	{
-	  return STATUS_SUCCESS;
-	}
-    }
-
-  RtlInitUnicodeString (&KeyPath,
-			L"\\Registry\\User\\.Default");
-  InitializeObjectAttributes(&ObjectAttributes,
-			     &KeyPath,
-			     OBJ_CASE_INSENSITIVE,
-			     NULL,
-			     NULL);
-  Status = NtOpenKey(KeyHandle,
-		     DesiredAccess,
-		     &ObjectAttributes);
-
-  return Status;
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-RtlQueryRegistryValues(IN ULONG RelativeTo,
-		       IN PCWSTR Path,
-		       IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
-		       IN PVOID Context,
-		       IN PVOID Environment)
-{
-  NTSTATUS Status;
-  HANDLE BaseKeyHandle;
-  HANDLE CurrentKeyHandle;
-  PRTL_QUERY_REGISTRY_TABLE QueryEntry;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING KeyName;
-  PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
-  PKEY_VALUE_FULL_INFORMATION FullValueInfo;
-  ULONG BufferSize;
-  ULONG ResultSize;
-  ULONG Index;
-  ULONG StringLen;
-  ULONG ValueNameSize;
-  PWSTR StringPtr;
-  PWSTR ExpandBuffer;
-  PWSTR ValueName;
-  UNICODE_STRING EnvValue;
-  UNICODE_STRING EnvExpandedValue;
-
-  DPRINT("RtlQueryRegistryValues() called\n");
-
-  Status = RtlpGetRegistryHandle(RelativeTo,
-				 (PWSTR)Path,
-				 FALSE,
-				 &BaseKeyHandle);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("RtlpGetRegistryHandle() failed (Status %lx)\n", Status);
-      return(Status);
-    }
-
-  CurrentKeyHandle = BaseKeyHandle;
-  QueryEntry = QueryTable;
-  while ((QueryEntry->QueryRoutine != NULL) ||
-	 (QueryEntry->Name != NULL))
-    {
-      if (((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_TOPKEY)) != 0) &&
-	  (BaseKeyHandle != CurrentKeyHandle))
-	{
-	  NtClose(CurrentKeyHandle);
-	  CurrentKeyHandle = BaseKeyHandle;
-	}
-
-      if (QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY)
-	{
-	  DPRINT("Open new subkey: %S\n", QueryEntry->Name);
-
-	  RtlInitUnicodeString(&KeyName,
-			       QueryEntry->Name);
-	  InitializeObjectAttributes(&ObjectAttributes,
-				     &KeyName,
-				     OBJ_CASE_INSENSITIVE,
-				     BaseKeyHandle,
-				     NULL);
-	  Status = NtOpenKey(&CurrentKeyHandle,
-			     KEY_ALL_ACCESS,
-			     &ObjectAttributes);
-	  if (!NT_SUCCESS(Status))
-	    break;
-	}
-      else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DIRECT)
-	{
-	  DPRINT("Query value directly: %S\n", QueryEntry->Name);
-
-	  RtlInitUnicodeString(&KeyName,
-			       QueryEntry->Name);
-
-	  BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + 4096;
-	  ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
-				      0,
-				      BufferSize);
-	  if (ValueInfo == NULL)
-	    {
-	      Status = STATUS_NO_MEMORY;
-	      break;
-	    }
-
-	  Status = NtQueryValueKey(CurrentKeyHandle,
-				   &KeyName,
-				   KeyValuePartialInformation,
-				   ValueInfo,
-				   BufferSize,
-				   &ResultSize);
-	  if (!NT_SUCCESS(Status))
-	    {
-	      if (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED)
-		{
-		  RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
-		  Status = STATUS_OBJECT_NAME_NOT_FOUND;
-		  break;
-		}
-	
-	      if (QueryEntry->DefaultType == REG_SZ)
-		{
-		  PUNICODE_STRING ValueString;
-		  PUNICODE_STRING SourceString;
-
-		  SourceString = (PUNICODE_STRING)QueryEntry->DefaultData;
-		  ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
-		  if (ValueString->Buffer == NULL)
-		    {
-		      ValueString->Length = SourceString->Length;
-		      ValueString->MaximumLength = SourceString->MaximumLength;
-		      ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
-							    0,
-							    ValueString->MaximumLength);
-		      if (!ValueString->Buffer)
-			break;
-		      ValueString->Buffer[0] = 0;
-		      memcpy(ValueString->Buffer,
-			     SourceString->Buffer,
-			     SourceString->MaximumLength);
-		    }
-		  else
-		    {
-		      ValueString->Length = min(SourceString->Length,
-						ValueString->MaximumLength - sizeof(WCHAR));
-		      memcpy(ValueString->Buffer,
-			     SourceString->Buffer,
-			     ValueString->Length);
-		      ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
-		    }
-		}
-	      else
-		{
-		  memcpy(QueryEntry->EntryContext,
-			 QueryEntry->DefaultData,
-			 QueryEntry->DefaultLength);
-		}
-	      Status = STATUS_SUCCESS;
-	    }
-	  else
-	    {
-	      if ((ValueInfo->Type == REG_SZ) ||
-		  (ValueInfo->Type == REG_MULTI_SZ) ||
-		  (ValueInfo->Type == REG_EXPAND_SZ && (QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND)))
-		{
-		  PUNICODE_STRING ValueString;
-
-		  ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
-		  if (ValueString->Buffer == NULL)
-		    {
-		      ValueString->MaximumLength = ValueInfo->DataLength;
-		      ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
-							    0,
-							    ValueString->MaximumLength);
-		      if (ValueString->Buffer == NULL)
-			{
-			  Status = STATUS_INSUFFICIENT_RESOURCES;
-			  break;
-			}
-		      ValueString->Buffer[0] = 0;
-		     }
-		  ValueString->Length = min(ValueInfo->DataLength,
-					    ValueString->MaximumLength) - sizeof(WCHAR);
-		  memcpy(ValueString->Buffer,
-			 ValueInfo->Data,
-			 ValueString->Length);
-		  ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
-		}
-	      else if (ValueInfo->Type == REG_EXPAND_SZ)
-		{
-		  PUNICODE_STRING ValueString;
-
-		  DPRINT("Expand REG_EXPAND_SZ type\n");
-
-		  ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
-
-		  ExpandBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
-						 0,
-						 ValueInfo->DataLength * 2);
-		  if (ExpandBuffer == NULL)
-		    {
-		      Status = STATUS_NO_MEMORY;
-		      break;
-		    }
-
-		  RtlInitUnicodeString(&EnvValue,
-				       (PWSTR)ValueInfo->Data);
-		  EnvExpandedValue.Length = 0;
-		  EnvExpandedValue.MaximumLength = ValueInfo->DataLength * 2;
-		  EnvExpandedValue.Buffer = ExpandBuffer;
-		  *ExpandBuffer = 0;
-
-		  RtlExpandEnvironmentStrings_U(Environment,
-						&EnvValue,
-						&EnvExpandedValue,
-						&StringLen);
-
-		  if (ValueString->Buffer == NULL)
-		    {
-		      ValueString->MaximumLength = EnvExpandedValue.Length + sizeof(WCHAR);
-		      ValueString->Length = EnvExpandedValue.Length;
-		      ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
-							    0,
-							    ValueString->MaximumLength);
-		      if (ValueString->Buffer == NULL)
-			{
-			  Status = STATUS_INSUFFICIENT_RESOURCES;
-			  break;
-			}
-		    }
-		  else
-		    {
-		      ValueString->Length = min(EnvExpandedValue.Length,
-						ValueString->MaximumLength - sizeof(WCHAR));
-		    }
-
-		  memcpy(ValueString->Buffer,
-			 EnvExpandedValue.Buffer,
-			 ValueString->Length);
-		  ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
-
-		  RtlFreeHeap(RtlGetProcessHeap(),
-			      0,
-			      ExpandBuffer);
-		}
-	      else
-		{
-		  memcpy(QueryEntry->EntryContext,
-			 ValueInfo->Data,
-			 ValueInfo->DataLength);
-		}
-	    }
-
-	  if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
-	    {
-	      DPRINT1("FIXME: Delete value: %S\n", QueryEntry->Name);
-
-	    }
-
-	  RtlFreeHeap(RtlGetProcessHeap(),
-		      0,
-		      ValueInfo);
-	}
-      else
-	{
-	  DPRINT("Query value via query routine: %S\n", QueryEntry->Name);
-	  if (QueryEntry->Name != NULL)
-	    {
-	      RtlInitUnicodeString(&KeyName,
-				   QueryEntry->Name);
-
-	      BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + 4096;
-	      ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
-					  0,
-					  BufferSize);
-	      if (ValueInfo == NULL)
-		{
-		  Status = STATUS_NO_MEMORY;
-		  break;
-		}
-
-	      Status = NtQueryValueKey(CurrentKeyHandle,
-				       &KeyName,
-				       KeyValuePartialInformation,
-				       ValueInfo,
-				       BufferSize,
-				       &ResultSize);
-	      if (!NT_SUCCESS(Status))
-		{
-		  if (!(QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED))
-		    {
-		      Status = QueryEntry->QueryRoutine(QueryEntry->Name,
-							QueryEntry->DefaultType,
-							QueryEntry->DefaultData,
-							QueryEntry->DefaultLength,
-							Context,
-							QueryEntry->EntryContext);
-		    }
-		}
-	      else if ((ValueInfo->Type == REG_MULTI_SZ) &&
-		       !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
-		{
-		  DPRINT("Expand REG_MULTI_SZ type\n");
-		  StringPtr = (PWSTR)ValueInfo->Data;
-		  while (*StringPtr != 0)
-		    {
-		      StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);
-		      Status = QueryEntry->QueryRoutine(QueryEntry->Name,
-							REG_SZ,
-							(PVOID)StringPtr,
-							StringLen,
-							Context,
-							QueryEntry->EntryContext);
-		      if(!NT_SUCCESS(Status))
-			break;
-		      StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);
-		    }
-		}
-	      else if ((ValueInfo->Type == REG_EXPAND_SZ) &&
-		       !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
-		{
-		  DPRINT("Expand REG_EXPAND_SZ type\n");
-
-		  ExpandBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
-						 0,
-						 ValueInfo->DataLength * 2);
-		  if (ExpandBuffer == NULL)
-		    {
-		      Status = STATUS_NO_MEMORY;
-		      break;
-		    }
-
-		  RtlInitUnicodeString(&EnvValue,
-				       (PWSTR)ValueInfo->Data);
-		  EnvExpandedValue.Length = 0;
-		  EnvExpandedValue.MaximumLength = ValueInfo->DataLength * 2 * sizeof(WCHAR);
-		  EnvExpandedValue.Buffer = ExpandBuffer;
-		  *ExpandBuffer = 0;
-
-		  RtlExpandEnvironmentStrings_U(Environment,
-						&EnvValue,
-						&EnvExpandedValue,
-						&StringLen);
-
-		  StringLen = (wcslen(ExpandBuffer) + 1) * sizeof(WCHAR);
-		  Status = QueryEntry->QueryRoutine(QueryEntry->Name,
-						    REG_SZ,
-						    (PVOID)ExpandBuffer,
-						    StringLen,
-						    Context,
-						    QueryEntry->EntryContext);
-
-		  RtlFreeHeap(RtlGetProcessHeap(),
-			      0,
-			      ExpandBuffer);
-		}
-	      else
-		{
-		  Status = QueryEntry->QueryRoutine(QueryEntry->Name,
-						    ValueInfo->Type,
-						    ValueInfo->Data,
-						    ValueInfo->DataLength,
-						    Context,
-						    QueryEntry->EntryContext);
-		}
-
-	      if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
-		{
-		  DPRINT1("FIXME: Delete value: %S\n", QueryEntry->Name);
-
-		}
-
-	      RtlFreeHeap(RtlGetProcessHeap(),
-			  0,
-			  ValueInfo);
-	      if (!NT_SUCCESS(Status))
-		break;
-	    }
-	  else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_NOVALUE)
-	    {
-	      DPRINT("Simple callback\n");
-	      Status = QueryEntry->QueryRoutine(NULL,
-						REG_NONE,
-						NULL,
-						0,
-						Context,
-						QueryEntry->EntryContext);
-	      if (!NT_SUCCESS(Status))
-		break;
-	    }
-	  else
-	    {
-	      DPRINT("Enumerate values\n");
-
-	      BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + 4096;
-	      FullValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
-					      0,
-					      BufferSize);
-	      if (FullValueInfo == NULL)
-		{
-		  Status = STATUS_NO_MEMORY;
-		  break;
-		}
-	      ValueNameSize = 256 * sizeof(WCHAR);
-	      ValueName = RtlAllocateHeap(RtlGetProcessHeap(),
-					  0,
-					  ValueNameSize);
-	      if (ValueName == NULL)
-	        {
-		  Status = STATUS_NO_MEMORY;
-		  break;
-		}
-	      Index = 0;
-	      while (TRUE)
-		{
-		  Status = NtEnumerateValueKey(CurrentKeyHandle,
-					       Index,
-					       KeyValueFullInformation,
-					       FullValueInfo,
-					       BufferSize,
-					       &ResultSize);
-		  if (!NT_SUCCESS(Status))
-		    {
-		      if ((Status == STATUS_NO_MORE_ENTRIES) &&
-			  (Index == 0) &&
-			  (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED))
-			{
-			  Status = STATUS_OBJECT_NAME_NOT_FOUND;
-			}
-		      else if (Status == STATUS_NO_MORE_ENTRIES)
-			{
-			  Status = STATUS_SUCCESS;
-			}
-		      break;
-		    }
-
-		  if (FullValueInfo->NameLength > ValueNameSize - sizeof(WCHAR))
-		    {
-		      /* Should not happen, because the name length is limited to 255 characters */
-		      RtlFreeHeap(RtlGetProcessHeap(),
-			          0,
-				  ValueName);
-		      ValueNameSize = FullValueInfo->NameLength + sizeof(WCHAR);
-		      ValueName = RtlAllocateHeap(RtlGetProcessHeap(),
-						  0,
-						  ValueNameSize);
-		      if (ValueName == NULL)
-		        {
-		          Status = STATUS_NO_MEMORY;
-		          break;
-		        }
-		    }
-
-		  memcpy(ValueName,
-			 FullValueInfo->Name,
-			 FullValueInfo->NameLength);
-		  ValueName[FullValueInfo->NameLength / sizeof(WCHAR)] = 0;
-
-		  DPRINT("FullValueInfo->Type: %lu\n", FullValueInfo->Type);
-		  if ((FullValueInfo->Type == REG_MULTI_SZ) &&
-		      !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
-		    {
-		      DPRINT("Expand REG_MULTI_SZ type\n");
-		      StringPtr = (PWSTR)((PVOID)FullValueInfo + FullValueInfo->DataOffset);
-		      while (*StringPtr != 0)
-			{
-			  StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);
-			  Status = QueryEntry->QueryRoutine(ValueName,
-							    REG_SZ,
-							    (PVOID)StringPtr,
-							    StringLen,
-							    Context,
-							    QueryEntry->EntryContext);
-			  if(!NT_SUCCESS(Status))
-			    break;
-			  StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);
-			}
-		    }
-		  else if ((FullValueInfo->Type == REG_EXPAND_SZ) &&
-			   !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
-		    {
-		      DPRINT("Expand REG_EXPAND_SZ type\n");
-
-		      StringPtr = (PWSTR)((PVOID)FullValueInfo + FullValueInfo->DataOffset);
-		      ExpandBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
-						     0,
-						     FullValueInfo->DataLength * 2);
-		      if (ExpandBuffer == NULL)
-			{
-			  Status = STATUS_NO_MEMORY;
-			  break;
-			}
-
-		      RtlInitUnicodeString(&EnvValue,
-					   StringPtr);
-		      EnvExpandedValue.Length = 0;
-		      EnvExpandedValue.MaximumLength = FullValueInfo->DataLength * 2;
-		      EnvExpandedValue.Buffer = ExpandBuffer;
-		      *ExpandBuffer = 0;
-
-		      RtlExpandEnvironmentStrings_U(Environment,
-						    &EnvValue,
-						    &EnvExpandedValue,
-						    &StringLen);
-
-		      StringLen = (wcslen(ExpandBuffer) + 1) * sizeof(WCHAR);
-		      Status = QueryEntry->QueryRoutine(ValueName,
-							REG_SZ,
-							(PVOID)ExpandBuffer,
-							StringLen,
-							Context,
-							QueryEntry->EntryContext);
-
-		      RtlFreeHeap(RtlGetProcessHeap(),
-				  0,
-				  ExpandBuffer);
-		    }
-		  else
-		    {
-		      Status = QueryEntry->QueryRoutine(ValueName,
-							FullValueInfo->Type,
-							(PVOID)FullValueInfo + FullValueInfo->DataOffset,
-							FullValueInfo->DataLength,
-							Context,
-							QueryEntry->EntryContext);
-		    }
-
-		  if (!NT_SUCCESS(Status))
-		    break;
-
-		  /* FIXME: How will these be deleted? */
-
-		  Index++;
-		}
-
-	      RtlFreeHeap(RtlGetProcessHeap(),
-			  0,
-			  FullValueInfo);
-	      RtlFreeHeap(RtlGetProcessHeap(),
-		          0,
-			  ValueName);
-	      if (!NT_SUCCESS(Status))
-		break;
-	    }
-	}
-
-      QueryEntry++;
-    }
-
-  if (CurrentKeyHandle != BaseKeyHandle)
-    NtClose(CurrentKeyHandle);
-
-  NtClose(BaseKeyHandle);
-
-  return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlWriteRegistryValue(IN ULONG RelativeTo,
-		      IN PCWSTR Path,
-		      IN PCWSTR ValueName,
-		      IN ULONG ValueType,
-		      IN PVOID ValueData,
-		      IN ULONG ValueLength)
-{
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  UNICODE_STRING Name;
-
-  Status = RtlpGetRegistryHandle(RelativeTo,
-				 (PWSTR)Path,
-				 TRUE,
-				 &KeyHandle);
-  if (!NT_SUCCESS(Status))
-    return(Status);
-
-  RtlInitUnicodeString(&Name,
-		       ValueName);
-
-  Status = NtSetValueKey(KeyHandle,
-			 &Name,
-			 0,
-			 ValueType,
-			 ValueData,
-			 ValueLength);
-  if (NT_SUCCESS(Status))
-    NtClose(KeyHandle);
-
-  return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlpNtCreateKey(OUT HANDLE KeyHandle,
-		IN ACCESS_MASK DesiredAccess,
-		IN POBJECT_ATTRIBUTES ObjectAttributes,
-		IN ULONG Unused1,
-		OUT PULONG Disposition,
-		IN ULONG Unused2)
-{
-  if (ObjectAttributes != NULL)
-    ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
-
-  return(NtCreateKey(KeyHandle,
-		     DesiredAccess,
-		     ObjectAttributes,
-		     0,
-		     NULL,
-		     0,
-		     Disposition));
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlpNtEnumerateSubKey(IN HANDLE KeyHandle,
-		      OUT PUNICODE_STRING SubKeyName,
-		      IN ULONG Index,
-		      IN ULONG Unused)
-{
-  PKEY_BASIC_INFORMATION KeyInfo = NULL;
-  ULONG BufferLength = 0;
-  ULONG ReturnedLength;
-  NTSTATUS Status;
-
-  if (SubKeyName->MaximumLength != 0)
-    {
-      BufferLength = SubKeyName->MaximumLength +
-		     sizeof(KEY_BASIC_INFORMATION);
-      KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(),
-				0,
-				BufferLength);
-      if (KeyInfo == NULL)
-	return(STATUS_NO_MEMORY);
-    }
-
[truncated at 1000 lines; 2023 more skipped]