mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 19:05:52 +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
|
||||
*/
|
||||
|
@ -801,7 +1203,23 @@ STDCALL
|
|||
RegSaveKeyA(
|
||||
HKEY hKey,
|
||||
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);
|
||||
|
@ -812,7 +1230,6 @@ RegSaveKeyA(
|
|||
/************************************************************************
|
||||
* 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,7 +384,8 @@ CmImportHive(PCHAR Chunk)
|
|||
return;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtCreateKey (
|
||||
OUT PHANDLE KeyHandle,
|
||||
|
@ -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,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
|
||||
NtEnumerateKey (
|
||||
IN HANDLE KeyHandle,
|
||||
|
@ -542,7 +586,7 @@ NtEnumerateKey (
|
|||
PKEY_BASIC_INFORMATION BasicInformation;
|
||||
PKEY_NODE_INFORMATION NodeInformation;
|
||||
PKEY_FULL_INFORMATION FullInformation;
|
||||
|
||||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
KEY_ENUMERATE_SUB_KEYS,
|
||||
|
@ -558,11 +602,11 @@ NtEnumerateKey (
|
|||
/* Get pointer to KeyBlock */
|
||||
KeyBlock = KeyObject->KeyBlock;
|
||||
RegistryFile = KeyObject->RegistryFile;
|
||||
|
||||
|
||||
/* Get pointer to SubKey */
|
||||
HashTableBlock = CmiGetHashTableBlock(RegistryFile, KeyBlock->HashTableOffset);
|
||||
SubKeyBlock = CmiGetKeyFromHashByIndex(RegistryFile,
|
||||
HashTableBlock,
|
||||
SubKeyBlock = CmiGetKeyFromHashByIndex(RegistryFile,
|
||||
HashTableBlock,
|
||||
Index);
|
||||
if (SubKeyBlock == NULL)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -675,26 +720,141 @@ NtEnumerateKey (
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTSTATUS
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtFlushKey (
|
||||
IN HANDLE KeyHandle
|
||||
|
@ -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;
|
||||
|
@ -828,7 +984,7 @@ NtQueryKey (
|
|||
PKEY_BASIC_INFORMATION BasicInformation;
|
||||
PKEY_NODE_INFORMATION NodeInformation;
|
||||
PKEY_FULL_INFORMATION FullInformation;
|
||||
|
||||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
KEY_READ,
|
||||
|
@ -844,13 +1000,13 @@ NtQueryKey (
|
|||
/* Get pointer to KeyBlock */
|
||||
KeyBlock = KeyObject->KeyBlock;
|
||||
RegistryFile = KeyObject->RegistryFile;
|
||||
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
switch (KeyInformationClass)
|
||||
{
|
||||
case KeyBasicInformation:
|
||||
/* Check size of buffer */
|
||||
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
||||
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
||||
KeyBlock->NameSize * sizeof(WCHAR))
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
|
@ -862,11 +1018,11 @@ NtQueryKey (
|
|||
BasicInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
||||
BasicInformation->TitleIndex = 0;
|
||||
BasicInformation->NameLength = KeyBlock->NameSize;
|
||||
wcsncpy(BasicInformation->Name,
|
||||
KeyBlock->Name,
|
||||
wcsncpy(BasicInformation->Name,
|
||||
KeyBlock->Name,
|
||||
KeyBlock->NameSize);
|
||||
BasicInformation->Name[KeyBlock->NameSize] = 0;
|
||||
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
|
||||
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
|
||||
KeyBlock->NameSize * sizeof(WCHAR);
|
||||
}
|
||||
break;
|
||||
|
@ -885,12 +1041,12 @@ NtQueryKey (
|
|||
NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
|
||||
NodeInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
||||
NodeInformation->TitleIndex = 0;
|
||||
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
||||
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
||||
KeyBlock->NameSize * sizeof(WCHAR);
|
||||
NodeInformation->ClassLength = KeyBlock->ClassSize;
|
||||
NodeInformation->NameLength = KeyBlock->NameSize;
|
||||
wcsncpy(NodeInformation->Name,
|
||||
KeyBlock->Name,
|
||||
wcsncpy(NodeInformation->Name,
|
||||
KeyBlock->Name,
|
||||
KeyBlock->NameSize);
|
||||
NodeInformation->Name[KeyBlock->NameSize] = 0;
|
||||
if (KeyBlock->ClassSize != 0)
|
||||
|
@ -920,7 +1076,7 @@ NtQueryKey (
|
|||
FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
|
||||
FullInformation->LastWriteTime = KeyBlock->LastWriteTime;
|
||||
FullInformation->TitleIndex = 0;
|
||||
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
|
||||
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
|
||||
sizeof(WCHAR);
|
||||
FullInformation->ClassLength = KeyBlock->ClassSize;
|
||||
FullInformation->SubKeys = KeyBlock->NumberOfSubKeys;
|
||||
|
@ -942,6 +1098,7 @@ NtQueryKey (
|
|||
}
|
||||
break;
|
||||
}
|
||||
ObDereferenceObject (KeyObject);
|
||||
|
||||
return Status;
|
||||
#else
|
||||
|
@ -950,7 +1107,7 @@ NtQueryKey (
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtQueryValueKey (
|
||||
IN HANDLE KeyHandle,
|
||||
|
@ -1073,7 +1230,8 @@ NtQueryValueKey (
|
|||
{
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
ObDereferenceObject(KeyObject);
|
||||
|
||||
return Status;
|
||||
#else
|
||||
UNIMPLEMENTED;
|
||||
|
@ -1147,58 +1305,27 @@ 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
|
||||
NtLoadKey (
|
||||
PHANDLE KeyHandle,
|
||||
OBJECT_ATTRIBUTES ObjectAttributes
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NtLoadKey2(KeyHandle,
|
||||
ObjectAttributes,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtLoadKey2(VOID)
|
||||
NtLoadKey2 (
|
||||
PHANDLE KeyHandle,
|
||||
OBJECT_ATTRIBUTES ObjectAttributes,
|
||||
ULONG Unknown3
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
@ -1209,11 +1336,11 @@ STDCALL
|
|||
NtNotifyChangeKey (
|
||||
IN HANDLE KeyHandle,
|
||||
IN HANDLE Event,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG CompletionFilter,
|
||||
IN BOOLEAN Asynchroneous,
|
||||
IN BOOLEAN Asynchroneous,
|
||||
OUT PVOID ChangeBuffer,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN WatchSubtree
|
||||
|
@ -1287,7 +1414,7 @@ NtSetInformationKey (
|
|||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
STDCALL
|
||||
NtUnloadKey (
|
||||
HANDLE KeyHandle
|
||||
)
|
||||
|
@ -1297,7 +1424,7 @@ NtUnloadKey (
|
|||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
STDCALL
|
||||
NtInitializeRegistry (
|
||||
BOOLEAN SetUpBoot
|
||||
)
|
||||
|
@ -1408,7 +1535,7 @@ static NTSTATUS CmiObjectParse(PVOID ParsedObject,
|
|||
return Status;
|
||||
}
|
||||
|
||||
CurKeyBlock = CmiGetKeyBlock(RegistryFile,
|
||||
CurKeyBlock = CmiGetKeyBlock(RegistryFile,
|
||||
RegistryFile->HeaderBlock->RootKeyBlock);
|
||||
|
||||
/* Loop through each key level and find the needed subkey */
|
||||
|
@ -1429,8 +1556,8 @@ static NTSTATUS CmiObjectParse(PVOID ParsedObject,
|
|||
}
|
||||
|
||||
/* Verify existance of CurKeyName */
|
||||
Status = CmiScanForSubKey(RegistryFile,
|
||||
CurKeyBlock,
|
||||
Status = CmiScanForSubKey(RegistryFile,
|
||||
CurKeyBlock,
|
||||
&SubKeyBlock,
|
||||
CurKeyName,
|
||||
STANDARD_RIGHTS_REQUIRED);
|
||||
|
@ -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);
|
||||
|
@ -1650,7 +1774,7 @@ CmiAddKeyToList(PKEY_OBJECT NewKey)
|
|||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
}
|
||||
|
||||
static VOID
|
||||
static VOID
|
||||
CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
@ -2104,12 +2228,12 @@ CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
|
|||
}
|
||||
|
||||
static NTSTATUS
|
||||
CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
||||
CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
||||
PKEY_BLOCK KeyBlock,
|
||||
PKEY_BLOCK *SubKeyBlock,
|
||||
PWSTR NewSubKeyName,
|
||||
ULONG TitleIndex,
|
||||
PWSTR Class,
|
||||
PWSTR Class,
|
||||
ULONG CreateOptions)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
@ -2128,7 +2252,7 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
|||
}
|
||||
if (KeyBlock->HashTableOffset == 0)
|
||||
{
|
||||
Status = CmiAllocateHashTableBlock(RegistryFile,
|
||||
Status = CmiAllocateHashTableBlock(RegistryFile,
|
||||
&HashBlock,
|
||||
REG_INIT_HASH_TABLE_SIZE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -2175,7 +2299,7 @@ CmiAddSubKey(PREGISTRY_FILE RegistryFile,
|
|||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
static NTSTATUS
|
||||
CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PKEY_BLOCK KeyBlock,
|
||||
IN PWSTR ValueName,
|
||||
|
@ -2185,10 +2309,10 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
|||
PVALUE_LIST_BLOCK ValueListBlock;
|
||||
PVALUE_BLOCK CurValueBlock;
|
||||
|
||||
ValueListBlock = CmiGetBlock(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;
|
||||
|
@ -2421,7 +2582,7 @@ CmiDestroyKeyBlock(PREGISTRY_FILE RegistryFile,
|
|||
ExFreePool(KeyBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -2466,7 +2627,7 @@ CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile,
|
|||
return Status;
|
||||
}
|
||||
|
||||
static PHASH_TABLE_BLOCK
|
||||
static PHASH_TABLE_BLOCK
|
||||
CmiGetHashTableBlock(PREGISTRY_FILE RegistryFile,
|
||||
BLOCK_OFFSET HashBlockOffset)
|
||||
{
|
||||
|
@ -2486,7 +2647,7 @@ CmiGetHashTableBlock(PREGISTRY_FILE RegistryFile,
|
|||
return HashBlock;
|
||||
}
|
||||
|
||||
static PKEY_BLOCK
|
||||
static PKEY_BLOCK
|
||||
CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
|
||||
PHASH_TABLE_BLOCK HashBlock,
|
||||
ULONG Index)
|
||||
|
@ -2506,7 +2667,7 @@ CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
|
|||
return KeyBlock;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
static NTSTATUS
|
||||
CmiAddKeyToHashTable(PREGISTRY_FILE RegistryFile,
|
||||
PHASH_TABLE_BLOCK HashBlock,
|
||||
PKEY_BLOCK NewKeyBlock)
|
||||
|
@ -2553,7 +2714,7 @@ static NTSTATUS
|
|||
CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVALUE_BLOCK *ValueBlock,
|
||||
IN PWSTR ValueNameBuf,
|
||||
IN ULONG Type,
|
||||
IN ULONG Type,
|
||||
IN PVOID Data,
|
||||
IN ULONG DataSize)
|
||||
{
|
||||
|
@ -2610,7 +2771,7 @@ CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
|
|||
static NTSTATUS
|
||||
CmiReplaceValueData(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PVALUE_BLOCK ValueBlock,
|
||||
IN ULONG Type,
|
||||
IN ULONG Type,
|
||||
IN PVOID Data,
|
||||
IN ULONG DataSize)
|
||||
{
|
||||
|
@ -2652,8 +2813,7 @@ CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile,
|
|||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
CHECKPOINT1;
|
||||
Status = CmiDestroyBlock(RegistryFile,
|
||||
Status = CmiDestroyBlock(RegistryFile,
|
||||
CmiGetBlock(RegistryFile,
|
||||
ValueBlock->DataOffset));
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -2710,7 +2870,7 @@ CmiDestroyBlock(PREGISTRY_FILE RegistryFile,
|
|||
ExFreePool(Block);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -2756,7 +2916,7 @@ CmiGetBlockOffset(PREGISTRY_FILE RegistryFile,
|
|||
return BlockOffset;
|
||||
}
|
||||
|
||||
static VOID
|
||||
static VOID
|
||||
CmiLockBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVOID Block)
|
||||
{
|
||||
|
@ -2766,7 +2926,7 @@ CmiLockBlock(PREGISTRY_FILE RegistryFile,
|
|||
}
|
||||
}
|
||||
|
||||
static VOID
|
||||
static VOID
|
||||
CmiReleaseBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVOID Block)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue