mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:56:26 +00:00
Implemented basic registry functions
svn path=/trunk/; revision=1346
This commit is contained in:
parent
16625529a2
commit
4b34e5c2de
2 changed files with 735 additions and 143 deletions
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue