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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -42,7 +42,7 @@ static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
|
||||||
BOOL
|
BOOL
|
||||||
RegInitialize (VOID)
|
RegInitialize (VOID)
|
||||||
{
|
{
|
||||||
DPRINT1("RegInitialize()\n");
|
DPRINT("RegInitialize()\n");
|
||||||
|
|
||||||
RtlZeroMemory (DefaultHandleTable,
|
RtlZeroMemory (DefaultHandleTable,
|
||||||
MAX_DEFAULT_HANDLES * sizeof(HANDLE));
|
MAX_DEFAULT_HANDLES * sizeof(HANDLE));
|
||||||
|
@ -58,7 +58,7 @@ RegInitialize (VOID)
|
||||||
BOOL
|
BOOL
|
||||||
RegCleanup(VOID)
|
RegCleanup(VOID)
|
||||||
{
|
{
|
||||||
DPRINT1("RegCleanup()\n");
|
DPRINT("RegCleanup()\n");
|
||||||
|
|
||||||
CloseDefaultKeys();
|
CloseDefaultKeys();
|
||||||
RtlDeleteCriticalSection(&HandleTableCS);
|
RtlDeleteCriticalSection(&HandleTableCS);
|
||||||
|
@ -67,24 +67,23 @@ RegCleanup(VOID)
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
MapDefaultKey (PHKEY ParentKey,
|
MapDefaultKey (PHKEY RealKey,
|
||||||
HKEY Key)
|
HKEY Key)
|
||||||
{
|
{
|
||||||
PHANDLE Handle;
|
PHANDLE Handle;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT1("MapDefaultKey (Key %x)\n", Key);
|
DPRINT("MapDefaultKey (Key %x)\n", Key);
|
||||||
|
|
||||||
if (((ULONG)Key & 0xF0000000) != 0x80000000)
|
if (((ULONG)Key & 0xF0000000) != 0x80000000)
|
||||||
{
|
{
|
||||||
*ParentKey = Key;
|
*RealKey = Key;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle special cases here */
|
/* Handle special cases here */
|
||||||
Index = (ULONG)Key & 0x0FFFFFFF;
|
Index = (ULONG)Key & 0x0FFFFFFF;
|
||||||
DPRINT1("Index %x\n", Index);
|
|
||||||
|
|
||||||
if (Index >= MAX_DEFAULT_HANDLES)
|
if (Index >= MAX_DEFAULT_HANDLES)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -102,18 +101,16 @@ DPRINT1("Index %x\n", Index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DPRINT1("MapDefaultHandle() no handle creator\n");
|
DPRINT("MapDefaultHandle() no handle creator\n");
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&HandleTableCS);
|
RtlLeaveCriticalSection(&HandleTableCS);
|
||||||
|
|
||||||
DPRINT1("Status %x\n", Status);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
*ParentKey = (HKEY)*Handle;
|
*RealKey = (HKEY)*Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -145,7 +142,7 @@ OpenLocalMachineKey (PHANDLE KeyHandle)
|
||||||
OBJECT_ATTRIBUTES Attributes;
|
OBJECT_ATTRIBUTES Attributes;
|
||||||
UNICODE_STRING KeyName;
|
UNICODE_STRING KeyName;
|
||||||
|
|
||||||
DPRINT1("OpenLocalMachineKey()\n");
|
DPRINT("OpenLocalMachineKey()\n");
|
||||||
|
|
||||||
RtlInitUnicodeString(&KeyName,
|
RtlInitUnicodeString(&KeyName,
|
||||||
L"\\Registry\\Machine");
|
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
|
* RegCreateKeyA
|
||||||
*/
|
*/
|
||||||
|
@ -297,7 +310,7 @@ RegCreateKeyExW(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HKEY ParentKey;
|
HKEY ParentKey;
|
||||||
|
|
||||||
DPRINT1("RegCreateKeyExW() called\n");
|
DPRINT("RegCreateKeyExW() called\n");
|
||||||
|
|
||||||
/* get the real parent key */
|
/* get the real parent key */
|
||||||
Status = MapDefaultKey (&ParentKey, hKey);
|
Status = MapDefaultKey (&ParentKey, hKey);
|
||||||
|
@ -309,7 +322,7 @@ RegCreateKeyExW(
|
||||||
return ErrorCode;
|
return ErrorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("ParentKey %x\n", (ULONG)ParentKey);
|
DPRINT("ParentKey %x\n", (ULONG)ParentKey);
|
||||||
|
|
||||||
RtlInitUnicodeString (&ClassString, lpClass);
|
RtlInitUnicodeString (&ClassString, lpClass);
|
||||||
RtlInitUnicodeString (&SubKeyString, lpSubKey);
|
RtlInitUnicodeString (&SubKeyString, lpSubKey);
|
||||||
|
@ -327,7 +340,7 @@ RegCreateKeyExW(
|
||||||
(lpClass == NULL)? NULL : &ClassString,
|
(lpClass == NULL)? NULL : &ClassString,
|
||||||
dwOptions,
|
dwOptions,
|
||||||
(PULONG)lpdwDisposition);
|
(PULONG)lpdwDisposition);
|
||||||
DPRINT1("Status %x\n", Status);
|
DPRINT("Status %x\n", Status);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
LONG ErrorCode = RtlNtStatusToDosError(Status);
|
LONG ErrorCode = RtlNtStatusToDosError(Status);
|
||||||
|
@ -335,7 +348,6 @@ RegCreateKeyExW(
|
||||||
SetLastError (ErrorCode);
|
SetLastError (ErrorCode);
|
||||||
return ErrorCode;
|
return ErrorCode;
|
||||||
}
|
}
|
||||||
DPRINT1("Returned handle %x\n", (ULONG)*phkResult);
|
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -366,8 +378,56 @@ RegDeleteKeyW(
|
||||||
LPCWSTR lpSubKey
|
LPCWSTR lpSubKey
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
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
|
LPCWSTR lpValueName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
UNICODE_STRING ValueName;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
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
|
* 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
|
* RegFlushKey
|
||||||
*/
|
*/
|
||||||
|
@ -477,7 +736,6 @@ RegFlushKey(
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegGetKeySecurity
|
* RegGetKeySecurity
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
LONG
|
LONG
|
||||||
STDCALL
|
STDCALL
|
||||||
RegGetKeySecurity (
|
RegGetKeySecurity (
|
||||||
|
@ -490,7 +748,6 @@ RegGetKeySecurity (
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -577,25 +834,39 @@ RegOpenKeyW (
|
||||||
NTSTATUS errCode;
|
NTSTATUS errCode;
|
||||||
UNICODE_STRING SubKeyString;
|
UNICODE_STRING SubKeyString;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
LONG ErrorCode;
|
||||||
|
|
||||||
SubKeyString.Buffer = (LPWSTR)lpSubKey;
|
errCode = MapDefaultKey(&KeyHandle,
|
||||||
SubKeyString.Length = wcslen(SubKeyString.Buffer);
|
hKey);
|
||||||
SubKeyString.MaximumLength = SubKeyString.Length;
|
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(
|
errCode = NtOpenKey(
|
||||||
phkResult,
|
phkResult,
|
||||||
GENERIC_ALL,
|
KEY_ALL_ACCESS,
|
||||||
& ObjectAttributes
|
& ObjectAttributes
|
||||||
);
|
);
|
||||||
if ( !NT_SUCCESS(errCode) )
|
if ( !NT_SUCCESS(errCode) )
|
||||||
{
|
{
|
||||||
LONG LastError = RtlNtStatusToDosError(errCode);
|
ErrorCode = RtlNtStatusToDosError(errCode);
|
||||||
|
|
||||||
SetLastError(LastError);
|
SetLastError(ErrorCode);
|
||||||
return LastError;
|
return ErrorCode;
|
||||||
}
|
}
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -632,8 +903,32 @@ RegOpenKeyExW(
|
||||||
PHKEY phkResult
|
PHKEY phkResult
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
NTSTATUS errCode;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
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
|
* RegQueryValueA
|
||||||
*/
|
*/
|
||||||
|
@ -754,6 +1067,62 @@ RegQueryValueExW(
|
||||||
LPBYTE lpData,
|
LPBYTE lpData,
|
||||||
LPDWORD lpcbData
|
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);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
return 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
|
* 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
|
* RegSaveKeyA
|
||||||
*/
|
*/
|
||||||
|
@ -801,7 +1203,23 @@ STDCALL
|
||||||
RegSaveKeyA(
|
RegSaveKeyA(
|
||||||
HKEY hKey,
|
HKEY hKey,
|
||||||
LPCSTR lpFile,
|
LPCSTR lpFile,
|
||||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* RegSaveKeyW
|
||||||
|
*/
|
||||||
|
LONG
|
||||||
|
STDCALL
|
||||||
|
RegSaveKeyW(
|
||||||
|
HKEY hKey,
|
||||||
|
LPCWSTR lpFile,
|
||||||
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
@ -812,7 +1230,6 @@ RegSaveKeyA(
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegSetKeySecurity
|
* RegSetKeySecurity
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
LONG
|
LONG
|
||||||
STDCALL
|
STDCALL
|
||||||
RegSetKeySecurity(
|
RegSetKeySecurity(
|
||||||
|
@ -824,7 +1241,7 @@ RegSetKeySecurity(
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegSetValueA
|
* RegSetValueA
|
||||||
|
@ -933,4 +1350,19 @@ RegUnLoadKeyA(
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* RegUnLoadKeyW
|
||||||
|
*/
|
||||||
|
LONG
|
||||||
|
STDCALL
|
||||||
|
RegUnLoadKeyW(
|
||||||
|
HKEY hKey,
|
||||||
|
LPCWSTR lpSubKey
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
#include <internal/ob.h>
|
#include <internal/ob.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
#define PROTO_REG 1 /* Comment out to disable */
|
#define PROTO_REG 1 /* Comment out to disable */
|
||||||
|
@ -227,6 +227,10 @@ static NTSTATUS CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PKEY_BLOCK KeyBlock,
|
IN PKEY_BLOCK KeyBlock,
|
||||||
IN PWSTR ValueName,
|
IN PWSTR ValueName,
|
||||||
OUT PVALUE_BLOCK *ValueBlock);
|
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,
|
static NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PKEY_BLOCK KeyBlock,
|
IN PKEY_BLOCK KeyBlock,
|
||||||
IN PWSTR ValueNameBuf,
|
IN PWSTR ValueNameBuf,
|
||||||
|
@ -364,7 +368,6 @@ CmInitializeRegistry(VOID)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
|
||||||
CmiReleaseBlock(CmiVolatileFile, KeyBlock);
|
CmiReleaseBlock(CmiVolatileFile, KeyBlock);
|
||||||
|
|
||||||
/* FIXME: create remaining structure needed for default handles */
|
/* FIXME: create remaining structure needed for default handles */
|
||||||
|
@ -373,6 +376,7 @@ CHECKPOINT;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
CmImportHive(PCHAR Chunk)
|
CmImportHive(PCHAR Chunk)
|
||||||
{
|
{
|
||||||
|
@ -380,7 +384,8 @@ CmImportHive(PCHAR Chunk)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtCreateKey (
|
NtCreateKey (
|
||||||
OUT PHANDLE KeyHandle,
|
OUT PHANDLE KeyHandle,
|
||||||
|
@ -432,7 +437,6 @@ NtCreateKey (
|
||||||
{
|
{
|
||||||
*Disposition = REG_OPENED_EXISTING_KEY;
|
*Disposition = REG_OPENED_EXISTING_KEY;
|
||||||
}
|
}
|
||||||
DPRINT1("KeyHandle (opened) %x\n", *KeyHandle);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +476,6 @@ DPRINT1("KeyHandle (opened) %x\n", *KeyHandle);
|
||||||
FALSE,
|
FALSE,
|
||||||
KeyHandle);
|
KeyHandle);
|
||||||
|
|
||||||
DPRINT1("Status %x KeyHandle (created) %x\n", Status, *KeyHandle);
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
*Disposition = REG_CREATED_NEW_KEY;
|
*Disposition = REG_CREATED_NEW_KEY;
|
||||||
|
@ -522,7 +525,48 @@ NtDeleteKey (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
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
|
STDCALL
|
||||||
NtEnumerateKey (
|
NtEnumerateKey (
|
||||||
IN HANDLE KeyHandle,
|
IN HANDLE KeyHandle,
|
||||||
|
@ -542,7 +586,7 @@ NtEnumerateKey (
|
||||||
PKEY_BASIC_INFORMATION BasicInformation;
|
PKEY_BASIC_INFORMATION BasicInformation;
|
||||||
PKEY_NODE_INFORMATION NodeInformation;
|
PKEY_NODE_INFORMATION NodeInformation;
|
||||||
PKEY_FULL_INFORMATION FullInformation;
|
PKEY_FULL_INFORMATION FullInformation;
|
||||||
|
|
||||||
/* Verify that the handle is valid and is a registry key */
|
/* Verify that the handle is valid and is a registry key */
|
||||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||||
KEY_ENUMERATE_SUB_KEYS,
|
KEY_ENUMERATE_SUB_KEYS,
|
||||||
|
@ -558,11 +602,11 @@ NtEnumerateKey (
|
||||||
/* Get pointer to KeyBlock */
|
/* Get pointer to KeyBlock */
|
||||||
KeyBlock = KeyObject->KeyBlock;
|
KeyBlock = KeyObject->KeyBlock;
|
||||||
RegistryFile = KeyObject->RegistryFile;
|
RegistryFile = KeyObject->RegistryFile;
|
||||||
|
|
||||||
/* Get pointer to SubKey */
|
/* Get pointer to SubKey */
|
||||||
HashTableBlock = CmiGetHashTableBlock(RegistryFile, KeyBlock->HashTableOffset);
|
HashTableBlock = CmiGetHashTableBlock(RegistryFile, KeyBlock->HashTableOffset);
|
||||||
SubKeyBlock = CmiGetKeyFromHashByIndex(RegistryFile,
|
SubKeyBlock = CmiGetKeyFromHashByIndex(RegistryFile,
|
||||||
HashTableBlock,
|
HashTableBlock,
|
||||||
Index);
|
Index);
|
||||||
if (SubKeyBlock == NULL)
|
if (SubKeyBlock == NULL)
|
||||||
{
|
{
|
||||||
|
@ -575,7 +619,7 @@ NtEnumerateKey (
|
||||||
case KeyBasicInformation:
|
case KeyBasicInformation:
|
||||||
/* Check size of buffer */
|
/* Check size of buffer */
|
||||||
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
||||||
SubKeyBlock->NameSize * sizeof(WCHAR))
|
(SubKeyBlock->NameSize + 1) * sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
Status = STATUS_BUFFER_OVERFLOW;
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
@ -585,7 +629,7 @@ NtEnumerateKey (
|
||||||
BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
|
BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
|
||||||
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
|
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
|
||||||
BasicInformation->TitleIndex = Index;
|
BasicInformation->TitleIndex = Index;
|
||||||
BasicInformation->NameLength = SubKeyBlock->NameSize;
|
BasicInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
|
||||||
wcsncpy(BasicInformation->Name,
|
wcsncpy(BasicInformation->Name,
|
||||||
SubKeyBlock->Name,
|
SubKeyBlock->Name,
|
||||||
SubKeyBlock->NameSize);
|
SubKeyBlock->NameSize);
|
||||||
|
@ -598,7 +642,7 @@ NtEnumerateKey (
|
||||||
case KeyNodeInformation:
|
case KeyNodeInformation:
|
||||||
/* Check size of buffer */
|
/* Check size of buffer */
|
||||||
if (Length < sizeof(KEY_NODE_INFORMATION) +
|
if (Length < sizeof(KEY_NODE_INFORMATION) +
|
||||||
SubKeyBlock->NameSize * sizeof(WCHAR) +
|
(SubKeyBlock->NameSize + 1) * sizeof(WCHAR) +
|
||||||
(SubKeyBlock->ClassSize + 1) * sizeof(WCHAR))
|
(SubKeyBlock->ClassSize + 1) * sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
Status = STATUS_BUFFER_OVERFLOW;
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
@ -612,7 +656,7 @@ NtEnumerateKey (
|
||||||
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
||||||
SubKeyBlock->NameSize * sizeof(WCHAR);
|
SubKeyBlock->NameSize * sizeof(WCHAR);
|
||||||
NodeInformation->ClassLength = SubKeyBlock->ClassSize;
|
NodeInformation->ClassLength = SubKeyBlock->ClassSize;
|
||||||
NodeInformation->NameLength = SubKeyBlock->NameSize;
|
NodeInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
|
||||||
wcsncpy(NodeInformation->Name,
|
wcsncpy(NodeInformation->Name,
|
||||||
SubKeyBlock->Name,
|
SubKeyBlock->Name,
|
||||||
SubKeyBlock->NameSize);
|
SubKeyBlock->NameSize);
|
||||||
|
@ -667,6 +711,7 @@ NtEnumerateKey (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CmiReleaseBlock(RegistryFile, SubKeyBlock);
|
CmiReleaseBlock(RegistryFile, SubKeyBlock);
|
||||||
|
ObDereferenceObject (KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
|
@ -675,26 +720,141 @@ NtEnumerateKey (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtEnumerateValueKey (
|
NtEnumerateValueKey (
|
||||||
IN HANDLE KeyHandle,
|
IN HANDLE KeyHandle,
|
||||||
IN ULONG Index,
|
IN ULONG Index,
|
||||||
IN KEY_VALUE_INFORMATION_CLASS KeyInformationClass,
|
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
|
||||||
OUT PVOID KeyInformation,
|
OUT PVOID KeyValueInformation,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG ResultLength
|
OUT PULONG ResultLength
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifdef PROTO_REG
|
#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
|
#else
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtFlushKey (
|
NtFlushKey (
|
||||||
IN HANDLE KeyHandle
|
IN HANDLE KeyHandle
|
||||||
|
@ -750,8 +910,6 @@ NtOpenKey (
|
||||||
KeyHandle);
|
KeyHandle);
|
||||||
ExFreePool(KeyNameBuf);
|
ExFreePool(KeyNameBuf);
|
||||||
|
|
||||||
DPRINT1("Status %x KeyHandle (opened) %x\n", Status, *KeyHandle);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,7 +952,6 @@ DPRINT1("Status %x KeyHandle (opened) %x\n", Status, *KeyHandle);
|
||||||
NewKey->RegistryFile = FileToUse;
|
NewKey->RegistryFile = FileToUse;
|
||||||
NewKey->KeyBlock = KeyBlock;
|
NewKey->KeyBlock = KeyBlock;
|
||||||
CmiAddKeyToList(NewKey);
|
CmiAddKeyToList(NewKey);
|
||||||
DPRINT1("KeyHandle (created) %x\n", *KeyHandle);
|
|
||||||
|
|
||||||
Status = ObCreateHandle(PsGetCurrentProcess(),
|
Status = ObCreateHandle(PsGetCurrentProcess(),
|
||||||
NewKey,
|
NewKey,
|
||||||
|
@ -802,7 +959,6 @@ DPRINT1("KeyHandle (created) %x\n", *KeyHandle);
|
||||||
FALSE,
|
FALSE,
|
||||||
KeyHandle);
|
KeyHandle);
|
||||||
|
|
||||||
DPRINT1("Status %x KeyHandle (created) %x\n", Status, *KeyHandle);
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -828,7 +984,7 @@ NtQueryKey (
|
||||||
PKEY_BASIC_INFORMATION BasicInformation;
|
PKEY_BASIC_INFORMATION BasicInformation;
|
||||||
PKEY_NODE_INFORMATION NodeInformation;
|
PKEY_NODE_INFORMATION NodeInformation;
|
||||||
PKEY_FULL_INFORMATION FullInformation;
|
PKEY_FULL_INFORMATION FullInformation;
|
||||||
|
|
||||||
/* Verify that the handle is valid and is a registry key */
|
/* Verify that the handle is valid and is a registry key */
|
||||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||||
KEY_READ,
|
KEY_READ,
|
||||||
|
@ -844,13 +1000,13 @@ NtQueryKey (
|
||||||
/* Get pointer to KeyBlock */
|
/* Get pointer to KeyBlock */
|
||||||
KeyBlock = KeyObject->KeyBlock;
|
KeyBlock = KeyObject->KeyBlock;
|
||||||
RegistryFile = KeyObject->RegistryFile;
|
RegistryFile = KeyObject->RegistryFile;
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
switch (KeyInformationClass)
|
switch (KeyInformationClass)
|
||||||
{
|
{
|
||||||
case KeyBasicInformation:
|
case KeyBasicInformation:
|
||||||
/* Check size of buffer */
|
/* Check size of buffer */
|
||||||
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
||||||
KeyBlock->NameSize * sizeof(WCHAR))
|
KeyBlock->NameSize * sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
Status = STATUS_BUFFER_OVERFLOW;
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
@ -862,11 +1018,11 @@ NtQueryKey (
|
||||||
BasicInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
BasicInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
||||||
BasicInformation->TitleIndex = 0;
|
BasicInformation->TitleIndex = 0;
|
||||||
BasicInformation->NameLength = KeyBlock->NameSize;
|
BasicInformation->NameLength = KeyBlock->NameSize;
|
||||||
wcsncpy(BasicInformation->Name,
|
wcsncpy(BasicInformation->Name,
|
||||||
KeyBlock->Name,
|
KeyBlock->Name,
|
||||||
KeyBlock->NameSize);
|
KeyBlock->NameSize);
|
||||||
BasicInformation->Name[KeyBlock->NameSize] = 0;
|
BasicInformation->Name[KeyBlock->NameSize] = 0;
|
||||||
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
|
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
|
||||||
KeyBlock->NameSize * sizeof(WCHAR);
|
KeyBlock->NameSize * sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -885,12 +1041,12 @@ NtQueryKey (
|
||||||
NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
|
NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
|
||||||
NodeInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
NodeInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
||||||
NodeInformation->TitleIndex = 0;
|
NodeInformation->TitleIndex = 0;
|
||||||
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
||||||
KeyBlock->NameSize * sizeof(WCHAR);
|
KeyBlock->NameSize * sizeof(WCHAR);
|
||||||
NodeInformation->ClassLength = KeyBlock->ClassSize;
|
NodeInformation->ClassLength = KeyBlock->ClassSize;
|
||||||
NodeInformation->NameLength = KeyBlock->NameSize;
|
NodeInformation->NameLength = KeyBlock->NameSize;
|
||||||
wcsncpy(NodeInformation->Name,
|
wcsncpy(NodeInformation->Name,
|
||||||
KeyBlock->Name,
|
KeyBlock->Name,
|
||||||
KeyBlock->NameSize);
|
KeyBlock->NameSize);
|
||||||
NodeInformation->Name[KeyBlock->NameSize] = 0;
|
NodeInformation->Name[KeyBlock->NameSize] = 0;
|
||||||
if (KeyBlock->ClassSize != 0)
|
if (KeyBlock->ClassSize != 0)
|
||||||
|
@ -920,7 +1076,7 @@ NtQueryKey (
|
||||||
FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
|
FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
|
||||||
FullInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
FullInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
||||||
FullInformation->TitleIndex = 0;
|
FullInformation->TitleIndex = 0;
|
||||||
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
|
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
|
||||||
sizeof(WCHAR);
|
sizeof(WCHAR);
|
||||||
FullInformation->ClassLength = KeyBlock->ClassSize;
|
FullInformation->ClassLength = KeyBlock->ClassSize;
|
||||||
FullInformation->SubKeys = KeyBlock->NumberOfSubKeys;
|
FullInformation->SubKeys = KeyBlock->NumberOfSubKeys;
|
||||||
|
@ -942,6 +1098,7 @@ NtQueryKey (
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ObDereferenceObject (KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
|
@ -950,7 +1107,7 @@ NtQueryKey (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtQueryValueKey (
|
NtQueryValueKey (
|
||||||
IN HANDLE KeyHandle,
|
IN HANDLE KeyHandle,
|
||||||
|
@ -1073,7 +1230,8 @@ NtQueryValueKey (
|
||||||
{
|
{
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -1147,58 +1305,27 @@ NtSetValueKey (
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
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
|
|
||||||
NtLoadKey (
|
NtLoadKey (
|
||||||
PHANDLE KeyHandle,
|
PHANDLE KeyHandle,
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes
|
OBJECT_ATTRIBUTES ObjectAttributes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
return NtLoadKey2(KeyHandle,
|
||||||
|
ObjectAttributes,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtLoadKey2(VOID)
|
NtLoadKey2 (
|
||||||
|
PHANDLE KeyHandle,
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
ULONG Unknown3
|
||||||
|
)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
@ -1209,11 +1336,11 @@ STDCALL
|
||||||
NtNotifyChangeKey (
|
NtNotifyChangeKey (
|
||||||
IN HANDLE KeyHandle,
|
IN HANDLE KeyHandle,
|
||||||
IN HANDLE Event,
|
IN HANDLE Event,
|
||||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||||
IN PVOID ApcContext OPTIONAL,
|
IN PVOID ApcContext OPTIONAL,
|
||||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
IN ULONG CompletionFilter,
|
IN ULONG CompletionFilter,
|
||||||
IN BOOLEAN Asynchroneous,
|
IN BOOLEAN Asynchroneous,
|
||||||
OUT PVOID ChangeBuffer,
|
OUT PVOID ChangeBuffer,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
IN BOOLEAN WatchSubtree
|
IN BOOLEAN WatchSubtree
|
||||||
|
@ -1287,7 +1414,7 @@ NtSetInformationKey (
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUnloadKey (
|
NtUnloadKey (
|
||||||
HANDLE KeyHandle
|
HANDLE KeyHandle
|
||||||
)
|
)
|
||||||
|
@ -1297,7 +1424,7 @@ NtUnloadKey (
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtInitializeRegistry (
|
NtInitializeRegistry (
|
||||||
BOOLEAN SetUpBoot
|
BOOLEAN SetUpBoot
|
||||||
)
|
)
|
||||||
|
@ -1408,7 +1535,7 @@ static NTSTATUS CmiObjectParse(PVOID ParsedObject,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurKeyBlock = CmiGetKeyBlock(RegistryFile,
|
CurKeyBlock = CmiGetKeyBlock(RegistryFile,
|
||||||
RegistryFile->HeaderBlock->RootKeyBlock);
|
RegistryFile->HeaderBlock->RootKeyBlock);
|
||||||
|
|
||||||
/* Loop through each key level and find the needed subkey */
|
/* Loop through each key level and find the needed subkey */
|
||||||
|
@ -1429,8 +1556,8 @@ static NTSTATUS CmiObjectParse(PVOID ParsedObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify existance of CurKeyName */
|
/* Verify existance of CurKeyName */
|
||||||
Status = CmiScanForSubKey(RegistryFile,
|
Status = CmiScanForSubKey(RegistryFile,
|
||||||
CurKeyBlock,
|
CurKeyBlock,
|
||||||
&SubKeyBlock,
|
&SubKeyBlock,
|
||||||
CurKeyName,
|
CurKeyName,
|
||||||
STANDARD_RIGHTS_REQUIRED);
|
STANDARD_RIGHTS_REQUIRED);
|
||||||
|
@ -1514,8 +1641,6 @@ CmiBuildKeyPath(PWSTR *KeyPath, POBJECT_ATTRIBUTES ObjectAttributes)
|
||||||
ObjectHeader = 0;
|
ObjectHeader = 0;
|
||||||
if (ObjectAttributes->RootDirectory != NULL)
|
if (ObjectAttributes->RootDirectory != NULL)
|
||||||
{
|
{
|
||||||
DbgPrint ("RootDirectory %x\n", ObjectAttributes->RootDirectory);
|
|
||||||
DbgPrint ("KeyName %wZ\n", ObjectAttributes->ObjectName);
|
|
||||||
/* FIXME: determine type of object for RootDirectory */
|
/* FIXME: determine type of object for RootDirectory */
|
||||||
Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
|
Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
|
||||||
KEY_READ,
|
KEY_READ,
|
||||||
|
@ -1525,7 +1650,6 @@ DbgPrint ("KeyName %wZ\n", ObjectAttributes->ObjectName);
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CHECKPOINT1;
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
||||||
|
@ -1650,7 +1774,7 @@ CmiAddKeyToList(PKEY_OBJECT NewKey)
|
||||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
|
CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
@ -2104,12 +2228,12 @@ CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
||||||
PKEY_BLOCK KeyBlock,
|
PKEY_BLOCK KeyBlock,
|
||||||
PKEY_BLOCK *SubKeyBlock,
|
PKEY_BLOCK *SubKeyBlock,
|
||||||
PWSTR NewSubKeyName,
|
PWSTR NewSubKeyName,
|
||||||
ULONG TitleIndex,
|
ULONG TitleIndex,
|
||||||
PWSTR Class,
|
PWSTR Class,
|
||||||
ULONG CreateOptions)
|
ULONG CreateOptions)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -2128,7 +2252,7 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
||||||
}
|
}
|
||||||
if (KeyBlock->HashTableOffset == 0)
|
if (KeyBlock->HashTableOffset == 0)
|
||||||
{
|
{
|
||||||
Status = CmiAllocateHashTableBlock(RegistryFile,
|
Status = CmiAllocateHashTableBlock(RegistryFile,
|
||||||
&HashBlock,
|
&HashBlock,
|
||||||
REG_INIT_HASH_TABLE_SIZE);
|
REG_INIT_HASH_TABLE_SIZE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -2175,7 +2299,7 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PKEY_BLOCK KeyBlock,
|
IN PKEY_BLOCK KeyBlock,
|
||||||
IN PWSTR ValueName,
|
IN PWSTR ValueName,
|
||||||
|
@ -2185,10 +2309,10 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||||
PVALUE_LIST_BLOCK ValueListBlock;
|
PVALUE_LIST_BLOCK ValueListBlock;
|
||||||
PVALUE_BLOCK CurValueBlock;
|
PVALUE_BLOCK CurValueBlock;
|
||||||
|
|
||||||
ValueListBlock = CmiGetBlock(RegistryFile,
|
ValueListBlock = CmiGetBlock(RegistryFile,
|
||||||
KeyBlock->ValuesOffset);
|
KeyBlock->ValuesOffset);
|
||||||
*ValueBlock = NULL;
|
*ValueBlock = NULL;
|
||||||
if (ValueListBlock == 0)
|
if (ValueListBlock == NULL)
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2210,6 +2334,40 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||||
return STATUS_SUCCESS;
|
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
|
static NTSTATUS
|
||||||
CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PKEY_BLOCK KeyBlock,
|
IN PKEY_BLOCK KeyBlock,
|
||||||
|
@ -2246,6 +2404,8 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
ValueBlock);
|
ValueBlock);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
KeyBlock->ValuesOffset = CmiGetBlockOffset(RegistryFile,
|
||||||
|
ValueListBlock);
|
||||||
}
|
}
|
||||||
else if (KeyBlock->NumberOfValues % REG_VALUE_LIST_BLOCK_MULTIPLE)
|
else if (KeyBlock->NumberOfValues % REG_VALUE_LIST_BLOCK_MULTIPLE)
|
||||||
{
|
{
|
||||||
|
@ -2268,6 +2428,7 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
CmiDestroyBlock(RegistryFile, ValueListBlock);
|
CmiDestroyBlock(RegistryFile, ValueListBlock);
|
||||||
ValueListBlock = NewValueListBlock;
|
ValueListBlock = NewValueListBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueListBlock->Values[KeyBlock->NumberOfValues] =
|
ValueListBlock->Values[KeyBlock->NumberOfValues] =
|
||||||
CmiGetBlockOffset(RegistryFile, ValueBlock);
|
CmiGetBlockOffset(RegistryFile, ValueBlock);
|
||||||
KeyBlock->NumberOfValues++;
|
KeyBlock->NumberOfValues++;
|
||||||
|
@ -2347,7 +2508,7 @@ CmiAllocateKeyBlock(IN PREGISTRY_FILE RegistryFile,
|
||||||
NewKeySize = sizeof(KEY_BLOCK) +
|
NewKeySize = sizeof(KEY_BLOCK) +
|
||||||
(wcslen(KeyName) + 1) * sizeof(WCHAR) +
|
(wcslen(KeyName) + 1) * sizeof(WCHAR) +
|
||||||
(Class != NULL ? (wcslen(Class) + 1) * sizeof(WCHAR) : 0);
|
(Class != NULL ? (wcslen(Class) + 1) * sizeof(WCHAR) : 0);
|
||||||
DPRINT ("NewKeySize: %lu\n", NewKeySize);
|
DPRINT ("NewKeySize: %lu\n", NewKeySize);
|
||||||
//CHECKPOINT;
|
//CHECKPOINT;
|
||||||
NewKeyBlock = ExAllocatePool(NonPagedPool, NewKeySize);
|
NewKeyBlock = ExAllocatePool(NonPagedPool, NewKeySize);
|
||||||
//CHECKPOINT;
|
//CHECKPOINT;
|
||||||
|
@ -2421,7 +2582,7 @@ CmiDestroyKeyBlock(PREGISTRY_FILE RegistryFile,
|
||||||
ExFreePool(KeyBlock);
|
ExFreePool(KeyBlock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2466,7 +2627,7 @@ CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PHASH_TABLE_BLOCK
|
static PHASH_TABLE_BLOCK
|
||||||
CmiGetHashTableBlock(PREGISTRY_FILE RegistryFile,
|
CmiGetHashTableBlock(PREGISTRY_FILE RegistryFile,
|
||||||
BLOCK_OFFSET HashBlockOffset)
|
BLOCK_OFFSET HashBlockOffset)
|
||||||
{
|
{
|
||||||
|
@ -2486,7 +2647,7 @@ CmiGetHashTableBlock(PREGISTRY_FILE RegistryFile,
|
||||||
return HashBlock;
|
return HashBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PKEY_BLOCK
|
static PKEY_BLOCK
|
||||||
CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
|
CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
|
||||||
PHASH_TABLE_BLOCK HashBlock,
|
PHASH_TABLE_BLOCK HashBlock,
|
||||||
ULONG Index)
|
ULONG Index)
|
||||||
|
@ -2506,7 +2667,7 @@ CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
|
||||||
return KeyBlock;
|
return KeyBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiAddKeyToHashTable(PREGISTRY_FILE RegistryFile,
|
CmiAddKeyToHashTable(PREGISTRY_FILE RegistryFile,
|
||||||
PHASH_TABLE_BLOCK HashBlock,
|
PHASH_TABLE_BLOCK HashBlock,
|
||||||
PKEY_BLOCK NewKeyBlock)
|
PKEY_BLOCK NewKeyBlock)
|
||||||
|
@ -2553,7 +2714,7 @@ static NTSTATUS
|
||||||
CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
|
CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
|
||||||
PVALUE_BLOCK *ValueBlock,
|
PVALUE_BLOCK *ValueBlock,
|
||||||
IN PWSTR ValueNameBuf,
|
IN PWSTR ValueNameBuf,
|
||||||
IN ULONG Type,
|
IN ULONG Type,
|
||||||
IN PVOID Data,
|
IN PVOID Data,
|
||||||
IN ULONG DataSize)
|
IN ULONG DataSize)
|
||||||
{
|
{
|
||||||
|
@ -2610,7 +2771,7 @@ CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiReplaceValueData(IN PREGISTRY_FILE RegistryFile,
|
CmiReplaceValueData(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PVALUE_BLOCK ValueBlock,
|
IN PVALUE_BLOCK ValueBlock,
|
||||||
IN ULONG Type,
|
IN ULONG Type,
|
||||||
IN PVOID Data,
|
IN PVOID Data,
|
||||||
IN ULONG DataSize)
|
IN ULONG DataSize)
|
||||||
{
|
{
|
||||||
|
@ -2652,8 +2813,7 @@ CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile,
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
CHECKPOINT1;
|
Status = CmiDestroyBlock(RegistryFile,
|
||||||
Status = CmiDestroyBlock(RegistryFile,
|
|
||||||
CmiGetBlock(RegistryFile,
|
CmiGetBlock(RegistryFile,
|
||||||
ValueBlock->DataOffset));
|
ValueBlock->DataOffset));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -2710,7 +2870,7 @@ CmiDestroyBlock(PREGISTRY_FILE RegistryFile,
|
||||||
ExFreePool(Block);
|
ExFreePool(Block);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2756,7 +2916,7 @@ CmiGetBlockOffset(PREGISTRY_FILE RegistryFile,
|
||||||
return BlockOffset;
|
return BlockOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
CmiLockBlock(PREGISTRY_FILE RegistryFile,
|
CmiLockBlock(PREGISTRY_FILE RegistryFile,
|
||||||
PVOID Block)
|
PVOID Block)
|
||||||
{
|
{
|
||||||
|
@ -2766,7 +2926,7 @@ CmiLockBlock(PREGISTRY_FILE RegistryFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
CmiReleaseBlock(PREGISTRY_FILE RegistryFile,
|
CmiReleaseBlock(PREGISTRY_FILE RegistryFile,
|
||||||
PVOID Block)
|
PVOID Block)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue