Implemented basic registry functions

svn path=/trunk/; revision=1346
This commit is contained in:
Eric Kohl 2000-09-08 22:55:14 +00:00
parent 16625529a2
commit 4b34e5c2de
2 changed files with 735 additions and 143 deletions

View file

@ -1,4 +1,4 @@
/* $Id: reg.c,v 1.9 2000/09/06 19:58:47 ekohl Exp $
/* $Id: reg.c,v 1.10 2000/09/08 22:54:13 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -42,7 +42,7 @@ static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
BOOL
RegInitialize (VOID)
{
DPRINT1("RegInitialize()\n");
DPRINT("RegInitialize()\n");
RtlZeroMemory (DefaultHandleTable,
MAX_DEFAULT_HANDLES * sizeof(HANDLE));
@ -58,7 +58,7 @@ RegInitialize (VOID)
BOOL
RegCleanup(VOID)
{
DPRINT1("RegCleanup()\n");
DPRINT("RegCleanup()\n");
CloseDefaultKeys();
RtlDeleteCriticalSection(&HandleTableCS);
@ -67,24 +67,23 @@ RegCleanup(VOID)
static NTSTATUS
MapDefaultKey (PHKEY ParentKey,
MapDefaultKey (PHKEY RealKey,
HKEY Key)
{
PHANDLE Handle;
ULONG Index;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT1("MapDefaultKey (Key %x)\n", Key);
DPRINT("MapDefaultKey (Key %x)\n", Key);
if (((ULONG)Key & 0xF0000000) != 0x80000000)
{
*ParentKey = Key;
*RealKey = Key;
return STATUS_SUCCESS;
}
/* Handle special cases here */
Index = (ULONG)Key & 0x0FFFFFFF;
DPRINT1("Index %x\n", Index);
if (Index >= MAX_DEFAULT_HANDLES)
return STATUS_INVALID_PARAMETER;
@ -102,18 +101,16 @@ DPRINT1("Index %x\n", Index);
break;
default:
DPRINT1("MapDefaultHandle() no handle creator\n");
DPRINT("MapDefaultHandle() no handle creator\n");
Status = STATUS_INVALID_PARAMETER;
}
}
RtlLeaveCriticalSection(&HandleTableCS);
DPRINT1("Status %x\n", Status);
if (NT_SUCCESS(Status))
{
*ParentKey = (HKEY)*Handle;
*RealKey = (HKEY)*Handle;
}
return Status;
@ -145,7 +142,7 @@ OpenLocalMachineKey (PHANDLE KeyHandle)
OBJECT_ATTRIBUTES Attributes;
UNICODE_STRING KeyName;
DPRINT1("OpenLocalMachineKey()\n");
DPRINT("OpenLocalMachineKey()\n");
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine");
@ -206,6 +203,22 @@ RegConnectRegistryA(
}
/************************************************************************
* RegConnectRegistryW
*/
LONG
STDCALL
RegConnectRegistryW(
LPWSTR lpMachineName,
HKEY hKey,
PHKEY phkResult
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
* RegCreateKeyA
*/
@ -297,7 +310,7 @@ RegCreateKeyExW(
NTSTATUS Status;
HKEY ParentKey;
DPRINT1("RegCreateKeyExW() called\n");
DPRINT("RegCreateKeyExW() called\n");
/* get the real parent key */
Status = MapDefaultKey (&ParentKey, hKey);
@ -309,7 +322,7 @@ RegCreateKeyExW(
return ErrorCode;
}
DPRINT1("ParentKey %x\n", (ULONG)ParentKey);
DPRINT("ParentKey %x\n", (ULONG)ParentKey);
RtlInitUnicodeString (&ClassString, lpClass);
RtlInitUnicodeString (&SubKeyString, lpSubKey);
@ -327,7 +340,7 @@ RegCreateKeyExW(
(lpClass == NULL)? NULL : &ClassString,
dwOptions,
(PULONG)lpdwDisposition);
DPRINT1("Status %x\n", Status);
DPRINT("Status %x\n", Status);
if (!NT_SUCCESS(Status))
{
LONG ErrorCode = RtlNtStatusToDosError(Status);
@ -335,7 +348,6 @@ RegCreateKeyExW(
SetLastError (ErrorCode);
return ErrorCode;
}
DPRINT1("Returned handle %x\n", (ULONG)*phkResult);
return ERROR_SUCCESS;
}
@ -366,8 +378,56 @@ RegDeleteKeyW(
LPCWSTR lpSubKey
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
HANDLE ParentKey;
HANDLE TargetKey;
NTSTATUS Status;
LONG ErrorCode;
Status = MapDefaultKey(&ParentKey,
hKey);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
RtlInitUnicodeString(&SubKeyString,
(LPWSTR)lpSubKey);
InitializeObjectAttributes (&ObjectAttributes,
&SubKeyString,
OBJ_CASE_INSENSITIVE,
(HANDLE)ParentKey,
NULL);
Status = NtOpenKey (&TargetKey,
DELETE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
Status = NtDeleteKey(TargetKey);
NtClose(TargetKey);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
}
@ -396,8 +456,35 @@ RegDeleteValueW(
LPCWSTR lpValueName
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
UNICODE_STRING ValueName;
NTSTATUS Status;
LONG ErrorCode;
HANDLE KeyHandle;
Status = MapDefaultKey(&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
RtlInitUnicodeString(&ValueName,
lpValueName);
Status = NtDeleteValueKey(KeyHandle,
&ValueName);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
}
@ -439,6 +526,111 @@ RegEnumKeyExA(
}
/************************************************************************
* RegEnumKeyExW
*/
LONG
STDCALL
RegEnumKeyExW(
HKEY hKey,
DWORD dwIndex,
LPWSTR lpName,
LPDWORD lpcbName,
LPDWORD lpReserved,
LPWSTR lpClass,
LPDWORD lpcbClass,
PFILETIME lpftLastWriteTime
)
{
PKEY_NODE_INFORMATION KeyInfo;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
ULONG BufferSize;
ULONG ResultSize;
HANDLE KeyHandle;
Status = MapDefaultKey(&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
SetLastError (dwError);
return dwError;
}
BufferSize = sizeof (KEY_NODE_INFORMATION) +
*lpcbName * sizeof(WCHAR);
if (lpClass)
BufferSize += *lpcbClass;
KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
0,
BufferSize);
if (KeyInfo == NULL)
return ERROR_OUTOFMEMORY;
Status = NtEnumerateKey (KeyHandle,
(ULONG)dwIndex,
KeyNodeInformation,
KeyInfo,
BufferSize,
&ResultSize);
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
SetLastError(dwError);
}
else
{
memcpy (lpName, KeyInfo->Name, KeyInfo->NameLength);
*lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR)) - 1;
if (lpClass)
{
memcpy (lpClass,
KeyInfo->Name + KeyInfo->ClassOffset,
KeyInfo->ClassLength);
*lpcbClass = (DWORD)(KeyInfo->ClassLength / sizeof(WCHAR)) - 1;
}
if (lpftLastWriteTime)
{
}
}
RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo);
return dwError;
}
/************************************************************************
* RegEnumKeyW
*/
LONG
STDCALL
RegEnumKeyW(
HKEY hKey,
DWORD dwIndex,
LPWSTR lpName,
DWORD cbName
)
{
DWORD dwLength = cbName;
return RegEnumKeyExW(hKey,
dwIndex,
lpName,
&dwLength,
NULL,
NULL,
NULL,
NULL);
}
/************************************************************************
* RegEnumValueA
*/
@ -460,6 +652,73 @@ RegEnumValueA(
}
/************************************************************************
* RegEnumValueW
*/
LONG
STDCALL
RegEnumValueW(
HKEY hKey,
DWORD dwIndex,
LPWSTR lpValueName,
LPDWORD lpcbValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
)
{
PKEY_VALUE_FULL_INFORMATION ValueInfo;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
ULONG BufferSize;
ULONG ResultSize;
BufferSize = sizeof (KEY_VALUE_FULL_INFORMATION) +
*lpcbValueName * sizeof(WCHAR);
if (lpcbData)
BufferSize += *lpcbData;
ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(),
0,
BufferSize);
if (ValueInfo == NULL)
return ERROR_OUTOFMEMORY;
Status = NtEnumerateValueKey (hKey,
(ULONG)dwIndex,
KeyValueFullInformation,
ValueInfo,
BufferSize,
&ResultSize);
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
SetLastError(dwError);
}
else
{
memcpy (lpValueName, ValueInfo->Name, ValueInfo->NameLength);
*lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR)) - 1;
if (lpType)
*lpType = ValueInfo->Type;
if (lpData)
{
memcpy (lpData,
ValueInfo->Name + ValueInfo->DataOffset,
ValueInfo->DataLength);
*lpcbValueName = (DWORD)ValueInfo->DataLength;
}
}
RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo);
return dwError;
}
/************************************************************************
* RegFlushKey
*/
@ -477,7 +736,6 @@ RegFlushKey(
/************************************************************************
* RegGetKeySecurity
*/
#if 0
LONG
STDCALL
RegGetKeySecurity (
@ -490,7 +748,6 @@ RegGetKeySecurity (
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
#endif
/************************************************************************
@ -577,25 +834,39 @@ RegOpenKeyW (
NTSTATUS errCode;
UNICODE_STRING SubKeyString;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE KeyHandle;
LONG ErrorCode;
SubKeyString.Buffer = (LPWSTR)lpSubKey;
SubKeyString.Length = wcslen(SubKeyString.Buffer);
SubKeyString.MaximumLength = SubKeyString.Length;
errCode = MapDefaultKey(&KeyHandle,
hKey);
if (!NT_SUCCESS(errCode))
{
ErrorCode = RtlNtStatusToDosError(errCode);
SetLastError (ErrorCode);
return ErrorCode;
}
RtlInitUnicodeString(&SubKeyString,
(LPWSTR)lpSubKey);
InitializeObjectAttributes(&ObjectAttributes,
&SubKeyString,
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
ObjectAttributes.RootDirectory = hKey;
ObjectAttributes.ObjectName = & SubKeyString;
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
errCode = NtOpenKey(
phkResult,
GENERIC_ALL,
KEY_ALL_ACCESS,
& ObjectAttributes
);
if ( !NT_SUCCESS(errCode) )
{
LONG LastError = RtlNtStatusToDosError(errCode);
ErrorCode = RtlNtStatusToDosError(errCode);
SetLastError(LastError);
return LastError;
SetLastError(ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
}
@ -632,8 +903,32 @@ RegOpenKeyExW(
PHKEY phkResult
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
NTSTATUS errCode;
UNICODE_STRING SubKeyString;
OBJECT_ATTRIBUTES ObjectAttributes;
RtlInitUnicodeString(&SubKeyString,
(LPWSTR)lpSubKey);
InitializeObjectAttributes(&ObjectAttributes,
&SubKeyString,
OBJ_CASE_INSENSITIVE,
(HANDLE)hKey,
NULL);
errCode = NtOpenKey(
phkResult,
samDesired,
& ObjectAttributes
);
if ( !NT_SUCCESS(errCode) )
{
LONG LastError = RtlNtStatusToDosError(errCode);
SetLastError(LastError);
return LastError;
}
return ERROR_SUCCESS;
}
@ -705,6 +1000,24 @@ RegQueryMultipleValuesA(
}
/************************************************************************
* RegQueryMultipleValuesW
*/
LONG
STDCALL
RegQueryMultipleValuesW(
HKEY hKey,
PVALENT val_list,
DWORD num_vals,
LPWSTR lpValueBuf,
LPDWORD ldwTotsize
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
* RegQueryValueA
*/
@ -754,6 +1067,62 @@ RegQueryValueExW(
LPBYTE lpData,
LPDWORD lpcbData
)
{
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
UNICODE_STRING ValueName;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
ULONG BufferSize;
ULONG ResultSize;
RtlInitUnicodeString (&ValueName,
lpValueName);
BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData;
ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(),
0,
BufferSize);
if (ValueInfo == NULL)
return ERROR_OUTOFMEMORY;
Status = NtQueryValueKey (hKey,
&ValueName,
KeyValuePartialInformation,
ValueInfo,
BufferSize,
&ResultSize);
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
SetLastError(dwError);
}
else
{
*lpType = ValueInfo->Type;
memcpy (lpData, ValueInfo->Data, ValueInfo->DataLength);
if (ValueInfo->Type == REG_SZ)
((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
}
*lpcbData = (DWORD)ResultSize;
RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo);
return dwError;
}
/************************************************************************
* RegQueryValueW
*/
LONG
STDCALL
RegQueryValueW(
HKEY hKey,
LPCWSTR lpSubKey,
LPWSTR lpValue,
PLONG lpcbValue
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
@ -777,6 +1146,23 @@ RegReplaceKeyA(
}
/************************************************************************
* RegReplaceKeyW
*/
LONG
STDCALL
RegReplaceKeyW(
HKEY hKey,
LPCWSTR lpSubKey,
LPCWSTR lpNewFile,
LPCWSTR lpOldFile
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
* RegRestoreKeyA
*/
@ -793,6 +1179,22 @@ RegRestoreKeyA(
}
/************************************************************************
* RegRestoreKeyW
*/
LONG
STDCALL
RegRestoreKeyW(
HKEY hKey,
LPCWSTR lpFile,
DWORD dwFlags
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
* RegSaveKeyA
*/
@ -809,10 +1211,25 @@ RegSaveKeyA(
}
/************************************************************************
* RegSaveKeyW
*/
LONG
STDCALL
RegSaveKeyW(
HKEY hKey,
LPCWSTR lpFile,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
* RegSetKeySecurity
*/
#if 0
LONG
STDCALL
RegSetKeySecurity(
@ -824,7 +1241,7 @@ RegSetKeySecurity(
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
#endif
/************************************************************************
* RegSetValueA
@ -933,4 +1350,19 @@ RegUnLoadKeyA(
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************
* RegUnLoadKeyW
*/
LONG
STDCALL
RegUnLoadKeyW(
HKEY hKey,
LPCWSTR lpSubKey
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.28 2000/09/06 19:59:54 ekohl Exp $
/* $Id: registry.c,v 1.29 2000/09/08 22:55:14 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -16,7 +16,7 @@
#include <internal/ob.h>
#include <wchar.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
#define PROTO_REG 1 /* Comment out to disable */
@ -227,6 +227,10 @@ static NTSTATUS CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN PWSTR ValueName,
OUT PVALUE_BLOCK *ValueBlock);
static NTSTATUS CmiGetValueFromKeyByIndex(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN ULONG Index,
OUT PVALUE_BLOCK *ValueBlock);
static NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN PWSTR ValueNameBuf,
@ -364,7 +368,6 @@ CmInitializeRegistry(VOID)
{
return;
}
CHECKPOINT;
CmiReleaseBlock(CmiVolatileFile, KeyBlock);
/* FIXME: create remaining structure needed for default handles */
@ -373,6 +376,7 @@ CHECKPOINT;
#endif
}
VOID
CmImportHive(PCHAR Chunk)
{
@ -380,6 +384,7 @@ CmImportHive(PCHAR Chunk)
return;
}
NTSTATUS
STDCALL
NtCreateKey (
@ -432,7 +437,6 @@ NtCreateKey (
{
*Disposition = REG_OPENED_EXISTING_KEY;
}
DPRINT1("KeyHandle (opened) %x\n", *KeyHandle);
return Status;
}
@ -472,7 +476,6 @@ DPRINT1("KeyHandle (opened) %x\n", *KeyHandle);
FALSE,
KeyHandle);
DPRINT1("Status %x KeyHandle (created) %x\n", Status, *KeyHandle);
if (NT_SUCCESS(Status))
{
*Disposition = REG_CREATED_NEW_KEY;
@ -522,6 +525,47 @@ NtDeleteKey (
}
NTSTATUS
STDCALL
NtDeleteValueKey (
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName
)
{
#ifdef PROTO_REG
NTSTATUS Status;
PKEY_OBJECT KeyObject;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock;
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Get pointer to KeyBlock */
KeyBlock = KeyObject->KeyBlock;
RegistryFile = KeyObject->RegistryFile;
Status = CmiDeleteValueFromKey(RegistryFile,
KeyBlock,
ValueName->Buffer);
ObDereferenceObject(KeyObject);
return Status;
#else
UNIMPLEMENTED;
#endif
}
NTSTATUS
STDCALL
NtEnumerateKey (
@ -575,7 +619,7 @@ NtEnumerateKey (
case KeyBasicInformation:
/* Check size of buffer */
if (Length < sizeof(KEY_BASIC_INFORMATION) +
SubKeyBlock->NameSize * sizeof(WCHAR))
(SubKeyBlock->NameSize + 1) * sizeof(WCHAR))
{
Status = STATUS_BUFFER_OVERFLOW;
}
@ -585,7 +629,7 @@ NtEnumerateKey (
BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
BasicInformation->TitleIndex = Index;
BasicInformation->NameLength = SubKeyBlock->NameSize;
BasicInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
wcsncpy(BasicInformation->Name,
SubKeyBlock->Name,
SubKeyBlock->NameSize);
@ -598,7 +642,7 @@ NtEnumerateKey (
case KeyNodeInformation:
/* Check size of buffer */
if (Length < sizeof(KEY_NODE_INFORMATION) +
SubKeyBlock->NameSize * sizeof(WCHAR) +
(SubKeyBlock->NameSize + 1) * sizeof(WCHAR) +
(SubKeyBlock->ClassSize + 1) * sizeof(WCHAR))
{
Status = STATUS_BUFFER_OVERFLOW;
@ -612,7 +656,7 @@ NtEnumerateKey (
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
SubKeyBlock->NameSize * sizeof(WCHAR);
NodeInformation->ClassLength = SubKeyBlock->ClassSize;
NodeInformation->NameLength = SubKeyBlock->NameSize;
NodeInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
wcsncpy(NodeInformation->Name,
SubKeyBlock->Name,
SubKeyBlock->NameSize);
@ -667,6 +711,7 @@ NtEnumerateKey (
break;
}
CmiReleaseBlock(RegistryFile, SubKeyBlock);
ObDereferenceObject (KeyObject);
return Status;
#else
@ -680,14 +725,129 @@ STDCALL
NtEnumerateValueKey (
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_VALUE_INFORMATION_CLASS KeyInformationClass,
OUT PVOID KeyInformation,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength
)
{
#ifdef PROTO_REG
UNIMPLEMENTED;
NTSTATUS Status;
PKEY_OBJECT KeyObject;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock;
PVALUE_BLOCK ValueBlock;
PVOID DataBlock;
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Get pointer to KeyBlock */
KeyBlock = KeyObject->KeyBlock;
RegistryFile = KeyObject->RegistryFile;
/* Get Value block of interest */
Status = CmiGetValueFromKeyByIndex(RegistryFile,
KeyBlock,
Index,
&ValueBlock);
if (!NT_SUCCESS(Status))
{
return Status;
}
else if (ValueBlock != NULL)
{
switch (KeyValueInformationClass)
{
case KeyValueBasicInformation:
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
(ValueBlock->NameSize + 1) * sizeof(WCHAR);
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
}
else
{
ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueBlock->DataType;
ValueBasicInformation->NameLength =
(ValueBlock->NameSize + 1) * sizeof(WCHAR);
wcscpy(ValueBasicInformation->Name, ValueBlock->Name);
}
break;
case KeyValuePartialInformation:
*ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
ValueBlock->DataSize;
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
}
else
{
ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
KeyValueInformation;
ValuePartialInformation->TitleIndex = 0;
ValuePartialInformation->Type = ValueBlock->DataType;
ValuePartialInformation->DataLength = ValueBlock->DataSize;
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset);
RtlCopyMemory(ValuePartialInformation->Data,
DataBlock,
ValueBlock->DataSize);
CmiReleaseBlock(RegistryFile, DataBlock);
}
break;
case KeyValueFullInformation:
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
(ValueBlock->NameSize + 1) * sizeof(WCHAR) + ValueBlock->DataSize;
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
}
else
{
ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueBlock->DataType;
ValueFullInformation->DataOffset =
sizeof(KEY_VALUE_FULL_INFORMATION) +
ValueBlock->NameSize * sizeof(WCHAR);
ValueFullInformation->DataLength = ValueBlock->DataSize;
ValueFullInformation->NameLength =
(ValueBlock->NameSize + 1) * sizeof(WCHAR);
wcscpy(ValueFullInformation->Name, ValueBlock->Name);
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset);
RtlCopyMemory(&ValueFullInformation->Name[ValueBlock->NameSize + 1],
DataBlock,
ValueBlock->DataSize);
CmiReleaseBlock(RegistryFile, DataBlock);
}
break;
}
}
else
{
Status = STATUS_UNSUCCESSFUL;
}
ObDereferenceObject(KeyObject);
return Status;
#else
UNIMPLEMENTED;
#endif
@ -750,8 +910,6 @@ NtOpenKey (
KeyHandle);
ExFreePool(KeyNameBuf);
DPRINT1("Status %x KeyHandle (opened) %x\n", Status, *KeyHandle);
return Status;
}
@ -794,7 +952,6 @@ DPRINT1("Status %x KeyHandle (opened) %x\n", Status, *KeyHandle);
NewKey->RegistryFile = FileToUse;
NewKey->KeyBlock = KeyBlock;
CmiAddKeyToList(NewKey);
DPRINT1("KeyHandle (created) %x\n", *KeyHandle);
Status = ObCreateHandle(PsGetCurrentProcess(),
NewKey,
@ -802,7 +959,6 @@ DPRINT1("KeyHandle (created) %x\n", *KeyHandle);
FALSE,
KeyHandle);
DPRINT1("Status %x KeyHandle (created) %x\n", Status, *KeyHandle);
return Status;
#else
UNIMPLEMENTED;
@ -942,6 +1098,7 @@ NtQueryKey (
}
break;
}
ObDereferenceObject (KeyObject);
return Status;
#else
@ -1073,6 +1230,7 @@ NtQueryValueKey (
{
Status = STATUS_UNSUCCESSFUL;
}
ObDereferenceObject(KeyObject);
return Status;
#else
@ -1147,43 +1305,6 @@ NtSetValueKey (
#endif
}
NTSTATUS
STDCALL
NtDeleteValueKey (
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName
)
{
#ifdef PROTO_REG
NTSTATUS Status;
PKEY_OBJECT KeyObject;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock;
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Get pointer to KeyBlock */
KeyBlock = KeyObject->KeyBlock;
RegistryFile = KeyObject->RegistryFile;
Status = CmiDeleteValueFromKey(RegistryFile,
KeyBlock,
ValueName->Buffer);
return Status;
#else
UNIMPLEMENTED;
#endif
}
NTSTATUS
STDCALL
@ -1192,13 +1313,19 @@ NtLoadKey (
OBJECT_ATTRIBUTES ObjectAttributes
)
{
UNIMPLEMENTED;
return NtLoadKey2(KeyHandle,
ObjectAttributes,
0);
}
NTSTATUS
STDCALL
NtLoadKey2(VOID)
NtLoadKey2 (
PHANDLE KeyHandle,
OBJECT_ATTRIBUTES ObjectAttributes,
ULONG Unknown3
)
{
UNIMPLEMENTED;
}
@ -1514,8 +1641,6 @@ CmiBuildKeyPath(PWSTR *KeyPath, POBJECT_ATTRIBUTES ObjectAttributes)
ObjectHeader = 0;
if (ObjectAttributes->RootDirectory != NULL)
{
DbgPrint ("RootDirectory %x\n", ObjectAttributes->RootDirectory);
DbgPrint ("KeyName %wZ\n", ObjectAttributes->ObjectName);
/* FIXME: determine type of object for RootDirectory */
Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
KEY_READ,
@ -1525,7 +1650,6 @@ DbgPrint ("KeyName %wZ\n", ObjectAttributes->ObjectName);
NULL);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
return Status;
}
ObjectHeader = BODY_TO_HEADER(ObjectBody);
@ -2188,7 +2312,7 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
ValueListBlock = CmiGetBlock(RegistryFile,
KeyBlock->ValuesOffset);
*ValueBlock = NULL;
if (ValueListBlock == 0)
if (ValueListBlock == NULL)
{
return STATUS_SUCCESS;
}
@ -2210,6 +2334,40 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
return STATUS_SUCCESS;
}
static NTSTATUS
CmiGetValueFromKeyByIndex(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN ULONG Index,
OUT PVALUE_BLOCK *ValueBlock)
{
PVALUE_LIST_BLOCK ValueListBlock;
PVALUE_BLOCK CurValueBlock;
ValueListBlock = CmiGetBlock(RegistryFile,
KeyBlock->ValuesOffset);
*ValueBlock = NULL;
if (ValueListBlock == NULL)
{
return STATUS_NO_MORE_ENTRIES;
}
if (Index >= KeyBlock->NumberOfValues)
{
return STATUS_NO_MORE_ENTRIES;
}
CurValueBlock = CmiGetBlock(RegistryFile,
ValueListBlock->Values[Index]);
if (CurValueBlock != NULL)
{
*ValueBlock = CurValueBlock;
}
CmiReleaseBlock(RegistryFile, CurValueBlock);
CmiReleaseBlock(RegistryFile, ValueListBlock);
return STATUS_SUCCESS;
}
static NTSTATUS
CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
@ -2246,6 +2404,8 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
ValueBlock);
return Status;
}
KeyBlock->ValuesOffset = CmiGetBlockOffset(RegistryFile,
ValueListBlock);
}
else if (KeyBlock->NumberOfValues % REG_VALUE_LIST_BLOCK_MULTIPLE)
{
@ -2268,6 +2428,7 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
CmiDestroyBlock(RegistryFile, ValueListBlock);
ValueListBlock = NewValueListBlock;
}
ValueListBlock->Values[KeyBlock->NumberOfValues] =
CmiGetBlockOffset(RegistryFile, ValueBlock);
KeyBlock->NumberOfValues++;
@ -2347,7 +2508,7 @@ CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile,
NewKeySize = sizeof(KEY_BLOCK) +
(wcslen(KeyName) + 1) * sizeof(WCHAR) +
(Class != NULL ? (wcslen(Class) + 1) * sizeof(WCHAR) : 0);
DPRINT ("NewKeySize: %lu\n", NewKeySize);
DPRINT ("NewKeySize: %lu\n", NewKeySize);
//CHECKPOINT;
NewKeyBlock = ExAllocatePool(NonPagedPool, NewKeySize);
//CHECKPOINT;
@ -2652,7 +2813,6 @@ CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile,
{
NTSTATUS Status;
CHECKPOINT1;
Status = CmiDestroyBlock(RegistryFile,
CmiGetBlock(RegistryFile,
ValueBlock->DataOffset));