mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
Added hive flushing.
- Only keys are supported (create / delete). - No log-file support yet. - Still a little buggy. svn path=/trunk/; revision=4122
This commit is contained in:
parent
652669005d
commit
8a23cc7a5b
5 changed files with 504 additions and 238 deletions
|
@ -55,7 +55,7 @@
|
|||
#define MAX_REG_STD_HANDLE_NAME 19
|
||||
|
||||
// BLOCK_OFFSET = offset in file after header block
|
||||
typedef DWORD BLOCK_OFFSET;
|
||||
typedef ULONG BLOCK_OFFSET;
|
||||
|
||||
/* header for registry hive file : */
|
||||
typedef struct _HIVE_HEADER
|
||||
|
@ -256,6 +256,9 @@ typedef struct _REGISTRY_HIVE
|
|||
BLOCK_OFFSET *FreeListOffset;
|
||||
ERESOURCE HiveResource;
|
||||
|
||||
RTL_BITMAP DirtyBitMap;
|
||||
BOOLEAN HiveDirty;
|
||||
|
||||
// NTSTATUS (*Extend)(ULONG NewSize);
|
||||
// PVOID (*Flush)(VOID);
|
||||
} REGISTRY_HIVE, *PREGISTRY_HIVE;
|
||||
|
@ -396,6 +399,9 @@ CmiCreateRegistryHive(PWSTR Filename,
|
|||
NTSTATUS
|
||||
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
|
||||
|
||||
NTSTATUS
|
||||
CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
|
||||
|
||||
ULONG
|
||||
CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell);
|
||||
|
@ -473,6 +479,11 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
|||
PKEY_CELL NewKeyCell,
|
||||
BLOCK_OFFSET NKBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
|
||||
PHASH_TABLE_CELL HashBlock,
|
||||
BLOCK_OFFSET NKBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
|
||||
OUT PVALUE_CELL *ValueCell,
|
||||
|
@ -497,8 +508,8 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
PVOID
|
||||
CmiGetBlock(PREGISTRY_HIVE RegistryHive,
|
||||
BLOCK_OFFSET BlockOffset,
|
||||
OUT PHBIN * ppBin);
|
||||
BLOCK_OFFSET BlockOffset,
|
||||
OUT PHBIN * ppBin);
|
||||
|
||||
VOID
|
||||
CmiLockBlock(PREGISTRY_HIVE RegistryHive,
|
||||
|
@ -506,7 +517,11 @@ CmiLockBlock(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
VOID
|
||||
CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID Block);
|
||||
PVOID Block);
|
||||
|
||||
VOID
|
||||
CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
|
||||
BLOCK_OFFSET BlockOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiAddFree(PREGISTRY_HIVE RegistryHive,
|
||||
|
|
|
@ -112,7 +112,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
|||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&KeyObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
|
@ -142,7 +141,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
|||
TitleIndex,
|
||||
Class,
|
||||
CreateOptions);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
@ -200,15 +198,14 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
|||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
KEY_WRITE,
|
||||
CmiKeyType,
|
||||
UserMode,
|
||||
(PVOID *) &KeyObject,
|
||||
NULL);
|
||||
|
||||
KEY_WRITE,
|
||||
CmiKeyType,
|
||||
UserMode,
|
||||
(PVOID *)&KeyObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Acquire hive lock */
|
||||
|
@ -219,21 +216,26 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
|||
/* Set the marked for delete bit in the key object */
|
||||
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
||||
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||
|
||||
/* Dereference the object */
|
||||
ObDereferenceObject(KeyObject);
|
||||
if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
|
||||
ObDereferenceObject(KeyObject);
|
||||
/* Close the handle */
|
||||
ObDeleteHandle(PsGetCurrentProcess(), KeyHandle);
|
||||
/* FIXME: I think that ObDeleteHandle should dereference the object */
|
||||
ObDereferenceObject(KeyObject);
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||
|
||||
CmiSyncHives();
|
||||
/*
|
||||
* Note:
|
||||
* Hive-Synchronization will not be triggered here. This is done in
|
||||
* CmiObjectDelete() (in regobj.c) after all key-related structures
|
||||
* have been released.
|
||||
*/
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -678,6 +680,7 @@ NtFlushKey(IN HANDLE KeyHandle)
|
|||
NTSTATUS Status;
|
||||
PKEY_OBJECT KeyObject;
|
||||
PREGISTRY_HIVE RegistryHive;
|
||||
#if 0
|
||||
WCHAR LogName[MAX_PATH];
|
||||
UNICODE_STRING TmpFileName;
|
||||
HANDLE FileHandle;
|
||||
|
@ -686,29 +689,42 @@ NtFlushKey(IN HANDLE KeyHandle)
|
|||
LARGE_INTEGER fileOffset;
|
||||
DWORD * pEntDword;
|
||||
ULONG i;
|
||||
#endif
|
||||
|
||||
DPRINT("KeyHandle %x\n", KeyHandle);
|
||||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
KEY_QUERY_VALUE,
|
||||
CmiKeyType,
|
||||
UserMode,
|
||||
(PVOID *) &KeyObject,
|
||||
NULL);
|
||||
|
||||
KEY_QUERY_VALUE,
|
||||
CmiKeyType,
|
||||
UserMode,
|
||||
(PVOID *)&KeyObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Acquire hive lock */
|
||||
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||
|
||||
VERIFY_KEY_OBJECT(KeyObject);
|
||||
|
||||
RegistryHive = KeyObject->RegistryHive;
|
||||
|
||||
/* Acquire hive lock */
|
||||
ExAcquireResourceExclusiveLite(&RegistryHive->HiveResource,
|
||||
TRUE);
|
||||
|
||||
if (IsPermanentHive(RegistryHive))
|
||||
{
|
||||
/* Flush non-volatile hive */
|
||||
Status = CmiFlushRegistryHive(RegistryHive);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* Then write changed blocks in .log */
|
||||
wcscpy(LogName,RegistryHive->Filename.Buffer);
|
||||
wcscat(LogName,L".log");
|
||||
|
@ -891,8 +907,12 @@ END FIXME*/
|
|||
}
|
||||
|
||||
ZwClose(FileHandle);
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
#endif
|
||||
|
||||
ExReleaseResourceLite(&RegistryHive->HiveResource);
|
||||
|
||||
ObDereferenceObject(KeyObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1424,6 +1444,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
|||
{
|
||||
/* If new data size is <= current then overwrite current data */
|
||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
|
||||
RtlZeroMemory(DataCell->Data, ValueCell->DataSize);
|
||||
RtlCopyMemory(DataCell->Data, Data, DataSize);
|
||||
ValueCell->DataSize = DataSize;
|
||||
ValueCell->DataType = Type;
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
#include "cm.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||
|
||||
BOOLEAN CmiDoVerify = FALSE;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
VOID
|
||||
CmiCreateDefaultHiveHeader(PHIVE_HEADER Header)
|
||||
{
|
||||
|
@ -366,7 +368,7 @@ CmiPopulateHive(HANDLE FileHandle)
|
|||
PHBIN BinCell;
|
||||
PCHAR tBuf;
|
||||
ULONG i;
|
||||
|
||||
|
||||
tBuf = (PCHAR) ExAllocatePool(NonPagedPool, REG_BLOCK_SIZE);
|
||||
if (tBuf == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
@ -390,14 +392,14 @@ CmiPopulateHive(HANDLE FileHandle)
|
|||
FileOffset.u.LowPart = (2 + i) * REG_BLOCK_SIZE;
|
||||
|
||||
Status = ZwWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
tBuf,
|
||||
REG_BLOCK_SIZE,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
tBuf,
|
||||
REG_BLOCK_SIZE,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -421,48 +423,48 @@ CmiCreateNewRegFile(HANDLE FileHandle)
|
|||
PKEY_CELL RootKeyCell;
|
||||
NTSTATUS Status;
|
||||
PHBIN BinCell;
|
||||
PCHAR tBuf;
|
||||
|
||||
tBuf = (PCHAR) ExAllocatePool(NonPagedPool, 2 * REG_BLOCK_SIZE);
|
||||
if (tBuf == NULL)
|
||||
PCHAR Buffer;
|
||||
|
||||
Buffer = (PCHAR) ExAllocatePool(NonPagedPool, 2 * REG_BLOCK_SIZE);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
HiveHeader = (PHIVE_HEADER) tBuf;
|
||||
BinCell = (PHBIN) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE);
|
||||
RootKeyCell = (PKEY_CELL) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET);
|
||||
FreeCell = (PCELL_HEADER) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL));
|
||||
|
||||
HiveHeader = (PHIVE_HEADER)Buffer;
|
||||
BinCell = (PHBIN)((ULONG_PTR)Buffer + REG_BLOCK_SIZE);
|
||||
RootKeyCell = (PKEY_CELL)((ULONG_PTR)Buffer + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET);
|
||||
FreeCell = (PCELL_HEADER)((ULONG_PTR)Buffer + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL));
|
||||
|
||||
CmiCreateDefaultHiveHeader(HiveHeader);
|
||||
CmiCreateDefaultBinCell(BinCell);
|
||||
CmiCreateDefaultRootKeyCell(RootKeyCell);
|
||||
|
||||
// First block
|
||||
/* First block */
|
||||
BinCell->BlockOffset = 0;
|
||||
|
||||
// Offset to root key block
|
||||
/* Offset to root key block */
|
||||
HiveHeader->RootKeyCell = REG_HBIN_DATA_OFFSET;
|
||||
|
||||
// The rest of the block is free
|
||||
/* The rest of the block is free */
|
||||
FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL));
|
||||
|
||||
Status = ZwWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
tBuf,
|
||||
2 * REG_BLOCK_SIZE,
|
||||
0,
|
||||
NULL);
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
2 * REG_BLOCK_SIZE,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
ExFreePool(tBuf);
|
||||
ExFreePool(Buffer);
|
||||
|
||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||
|
||||
#if 1
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
CmiPopulateHive(FileHandle);
|
||||
CmiPopulateHive(FileHandle);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -472,8 +474,8 @@ CmiCreateNewRegFile(HANDLE FileHandle)
|
|||
|
||||
NTSTATUS
|
||||
CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||
PWSTR Filename,
|
||||
BOOLEAN CreateNew)
|
||||
PWSTR Filename,
|
||||
BOOLEAN CreateNew)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
FILE_STANDARD_INFORMATION fsi;
|
||||
|
@ -487,16 +489,18 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
|||
NTSTATUS Status;
|
||||
PHBIN tmpBin;
|
||||
ULONG i, j;
|
||||
ULONG BitmapSize;
|
||||
PULONG BitmapBuffer;
|
||||
|
||||
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew);
|
||||
DPRINT1("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew);
|
||||
|
||||
/* Duplicate Filename */
|
||||
Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("CmiInitPermanentRegistryHive() - Failed 1.\n");
|
||||
return Status;
|
||||
}
|
||||
{
|
||||
DPRINT1("CmiInitPermanentRegistryHive() - Failed 1.\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&RegistryHive->Filename,
|
||||
|
@ -504,7 +508,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
|||
NULL,
|
||||
NULL);
|
||||
|
||||
if (CreateNew)
|
||||
if (CreateNew == TRUE)
|
||||
CreateDisposition = FILE_OPEN_IF;
|
||||
else
|
||||
CreateDisposition = FILE_OPEN;
|
||||
|
@ -532,18 +536,18 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
|||
Status = CmiCreateNewRegFile(FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CmiCreateNewRegFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||
DPRINT1("CmiCreateNewRegFile() - Failed with status %x.\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
IoFileObjectType,
|
||||
UserMode,
|
||||
(PVOID*) &RegistryHive->FileObject,
|
||||
NULL);
|
||||
FILE_ALL_ACCESS,
|
||||
IoFileObjectType,
|
||||
UserMode,
|
||||
(PVOID*)&RegistryHive->FileObject,
|
||||
NULL);
|
||||
|
||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||
|
||||
|
@ -551,10 +555,11 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
|||
{
|
||||
NtClose(FileHandle);
|
||||
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||
DPRINT("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status);
|
||||
DPRINT1("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Read hive header */
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.LowPart = 0;
|
||||
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, sizeof(HIVE_HEADER), RegistryHive->HiveHeader);
|
||||
|
@ -567,9 +572,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
|||
sizeof(HIVE_HEADER),
|
||||
&FileOffset,
|
||||
0);
|
||||
|
||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(RegistryHive->FileObject);
|
||||
|
@ -744,7 +747,21 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
|||
BlockOffset += tmpBin->BlockSize;
|
||||
}
|
||||
|
||||
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Finished.\n", RegistryHive, Filename, CreateNew);
|
||||
/* Create block bitmap and clear all bits */
|
||||
|
||||
/* Calculate bitmap size in bytes (always a multiple of 32 bits) */
|
||||
BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8;
|
||||
DPRINT1("RegistryHive->BlockListSize: %lu\n", RegistryHive->BlockListSize);
|
||||
DPRINT1("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8);
|
||||
BitmapBuffer = (PULONG)ExAllocatePool(PagedPool,
|
||||
BitmapSize);
|
||||
RtlInitializeBitMap(&RegistryHive->DirtyBitMap,
|
||||
BitmapBuffer,
|
||||
BitmapSize * 8);
|
||||
RtlClearAllBits(&RegistryHive->DirtyBitMap);
|
||||
RegistryHive->HiveDirty = FALSE;
|
||||
|
||||
DPRINT1("CmiInitPermanentRegistryHive(%p, %S, %d) - Finished.\n", RegistryHive, Filename, CreateNew);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
@ -859,6 +876,113 @@ CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive)
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive)
|
||||
{
|
||||
ULONG BlockIndex;
|
||||
ULONG BlockOffset;
|
||||
PVOID BlockPtr;
|
||||
LARGE_INTEGER FileOffset;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE FileHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
|
||||
|
||||
|
||||
DPRINT("CmiFlushRegistryHive() called\n");
|
||||
|
||||
if (RegistryHive->HiveDirty == FALSE)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
DPRINT1("Hive '%wZ' is dirty\n", &RegistryHive->Filename);
|
||||
|
||||
|
||||
/* Open hive for writing */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&RegistryHive->Filename,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtCreateFile(&FileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
FILE_OPEN,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BlockIndex = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
BlockIndex = RtlFindSetBitsAndClear(&RegistryHive->DirtyBitMap,
|
||||
1,
|
||||
BlockIndex);
|
||||
if (BlockIndex == (ULONG)-1)
|
||||
{
|
||||
DPRINT("No more set bits\n");
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT1("Block %lu is dirty\n", BlockIndex);
|
||||
|
||||
BlockOffset = RegistryHive->BlockList[BlockIndex]->BlockOffset;
|
||||
DPRINT1("Block offset %lx\n", BlockOffset);
|
||||
|
||||
BlockPtr = RegistryHive->BlockList[BlockIndex] + ((BlockIndex * 4096) - BlockOffset);
|
||||
DPRINT1("BlockPtr %p\n", BlockPtr);
|
||||
|
||||
FileOffset.QuadPart = (ULONGLONG)(BlockIndex + 1) * 4096ULL;
|
||||
DPRINT1("File offset %I64x\n", FileOffset.QuadPart);
|
||||
|
||||
|
||||
/* Write hive block */
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
BlockPtr,
|
||||
REG_BLOCK_SIZE,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
NtClose(FileHandle);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
NtClose(FileHandle);
|
||||
|
||||
|
||||
/* Clear dirty flag */
|
||||
RegistryHive->HiveDirty = FALSE;
|
||||
|
||||
DPRINT("CmiFlushRegistryHive() done\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive,
|
||||
PKEY_CELL KeyCell)
|
||||
|
@ -1139,33 +1263,33 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
}
|
||||
else
|
||||
{
|
||||
NewKeyCell->Id = REG_KEY_CELL_ID;
|
||||
NewKeyCell->Type = REG_KEY_CELL_TYPE;
|
||||
ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime);
|
||||
NewKeyCell->ParentKeyOffset = -1;
|
||||
NewKeyCell->NumberOfSubKeys = 0;
|
||||
NewKeyCell->HashTableOffset = -1;
|
||||
NewKeyCell->NumberOfValues = 0;
|
||||
NewKeyCell->ValuesOffset = -1;
|
||||
NewKeyCell->SecurityKeyOffset = -1;
|
||||
NewKeyCell->NameSize = NameSize;
|
||||
wcstombs(NewKeyCell->Name, NewSubKeyName, NameSize);
|
||||
NewKeyCell->ClassNameOffset = -1;
|
||||
NewKeyCell->Id = REG_KEY_CELL_ID;
|
||||
NewKeyCell->Type = REG_KEY_CELL_TYPE;
|
||||
ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime);
|
||||
NewKeyCell->ParentKeyOffset = -1;
|
||||
NewKeyCell->NumberOfSubKeys = 0;
|
||||
NewKeyCell->HashTableOffset = -1;
|
||||
NewKeyCell->NumberOfValues = 0;
|
||||
NewKeyCell->ValuesOffset = -1;
|
||||
NewKeyCell->SecurityKeyOffset = -1;
|
||||
NewKeyCell->NameSize = NameSize;
|
||||
wcstombs(NewKeyCell->Name, NewSubKeyName, NameSize);
|
||||
NewKeyCell->ClassNameOffset = -1;
|
||||
|
||||
VERIFY_KEY_CELL(NewKeyCell);
|
||||
|
||||
if (Class)
|
||||
{
|
||||
PDATA_CELL pClass;
|
||||
if (Class)
|
||||
{
|
||||
PDATA_CELL pClass;
|
||||
|
||||
NewKeyCell->ClassSize = Class->Length + sizeof(WCHAR);
|
||||
Status = CmiAllocateBlock(RegistryHive,
|
||||
(PVOID) &pClass,
|
||||
NewKeyCell->ClassSize,
|
||||
&NewKeyCell->ClassNameOffset);
|
||||
wcsncpy((PWSTR) pClass->Data, Class->Buffer, Class->Length);
|
||||
((PWSTR) (pClass->Data))[Class->Length] = 0;
|
||||
}
|
||||
NewKeyCell->ClassSize = Class->Length + sizeof(WCHAR);
|
||||
Status = CmiAllocateBlock(RegistryHive,
|
||||
(PVOID) &pClass,
|
||||
NewKeyCell->ClassSize,
|
||||
&NewKeyCell->ClassNameOffset);
|
||||
wcsncpy((PWSTR) pClass->Data, Class->Buffer, Class->Length);
|
||||
((PWSTR) (pClass->Data))[Class->Length] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1178,17 +1302,16 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
/* Don't modify hash table if key is volatile and parent is not */
|
||||
if (IsVolatileHive(RegistryHive) && (!IsVolatileHive(Parent->RegistryHive)))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (KeyCell->HashTableOffset == (ULONG_PTR) -1)
|
||||
{
|
||||
Status = CmiAllocateHashTableBlock(RegistryHive,
|
||||
&HashBlock,
|
||||
&KeyCell->HashTableOffset,
|
||||
REG_INIT_HASH_TABLE_SIZE);
|
||||
|
||||
&HashBlock,
|
||||
&KeyCell->HashTableOffset,
|
||||
REG_INIT_HASH_TABLE_SIZE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
|
@ -1199,19 +1322,18 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
|
||||
if (((KeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize))
|
||||
{
|
||||
BLOCK_OFFSET HTOffset;
|
||||
BLOCK_OFFSET HTOffset;
|
||||
|
||||
/* Reallocate the hash table block */
|
||||
Status = CmiAllocateHashTableBlock(RegistryHive,
|
||||
&NewHashBlock,
|
||||
&HTOffset,
|
||||
HashBlock->HashTableSize +
|
||||
REG_EXTEND_HASH_TABLE_SIZE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
/* Reallocate the hash table block */
|
||||
Status = CmiAllocateHashTableBlock(RegistryHive,
|
||||
&NewHashBlock,
|
||||
&HTOffset,
|
||||
HashBlock->HashTableSize +
|
||||
REG_EXTEND_HASH_TABLE_SIZE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlZeroMemory(&NewHashBlock->Table[0],
|
||||
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
|
||||
|
@ -1470,9 +1592,9 @@ CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive,
|
|||
NewHashSize = sizeof(HASH_TABLE_CELL) +
|
||||
(HashTableSize - 1) * sizeof(HASH_RECORD);
|
||||
Status = CmiAllocateBlock(RegistryHive,
|
||||
(PVOID*) &NewHashBlock,
|
||||
NewHashSize,
|
||||
HBOffset);
|
||||
(PVOID*) &NewHashBlock,
|
||||
NewHashSize,
|
||||
HBOffset);
|
||||
|
||||
if ((NewHashBlock == NULL) || (!NT_SUCCESS(Status)))
|
||||
{
|
||||
|
@ -1537,6 +1659,27 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
|
||||
PHASH_TABLE_CELL HashBlock,
|
||||
BLOCK_OFFSET NKBOffset)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < HashBlock->HashTableSize; i++)
|
||||
{
|
||||
if (HashBlock->Table[i].KeyOffset == NKBOffset)
|
||||
{
|
||||
HashBlock->Table[i].KeyOffset = 0;
|
||||
RtlZeroMemory(&HashBlock->Table[i].HashValue, 4);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
|
||||
PVALUE_CELL *ValueCell,
|
||||
|
@ -1677,6 +1820,17 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
|
|||
/* Initialize a free block in this heap : */
|
||||
tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET);
|
||||
tmpBlock->CellSize = (REG_BLOCK_SIZE - REG_HBIN_DATA_OFFSET);
|
||||
|
||||
/* Grow bitmap if necessary */
|
||||
if (IsVolatileHive(RegistryHive) &&
|
||||
(RegistryHive->BlockListSize % (sizeof(ULONG) * 8) == 0))
|
||||
{
|
||||
DPRINT1("Grow hive bitmap - BlockListSize %lu\n", RegistryHive->BlockListSize);
|
||||
|
||||
/* FIXME */
|
||||
|
||||
}
|
||||
|
||||
*NewBlock = (PVOID) tmpBlock;
|
||||
|
||||
if (NewBlockOffset)
|
||||
|
@ -1742,7 +1896,10 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
|
|||
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
|
||||
|
||||
if (Temp)
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
{
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
CmiMarkBlockDirty(RegistryHive, RegistryHive->FreeListOffset[i]);
|
||||
}
|
||||
|
||||
if ((i + 1) < RegistryHive->FreeListSize)
|
||||
{
|
||||
|
@ -1777,6 +1934,7 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
|
|||
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
|
||||
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
|
||||
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
|
||||
CmiMarkBlockDirty(RegistryHive, *pBlockOffset + BlockSize);
|
||||
}
|
||||
else if (NewBlock->CellSize < BlockSize)
|
||||
{
|
||||
|
@ -1815,6 +1973,10 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
|
|||
if (pFree->CellSize < 0)
|
||||
pFree->CellSize = -pFree->CellSize;
|
||||
|
||||
/* Clear block (except the block size) */
|
||||
RtlZeroMemory(((PVOID)pFree) + sizeof(ULONG),
|
||||
pFree->CellSize - sizeof(ULONG));
|
||||
|
||||
CmiAddFree(RegistryHive, Block, Offset);
|
||||
CmiReleaseBlock(RegistryHive, Block);
|
||||
|
||||
|
@ -1822,6 +1984,8 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
|
|||
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
|
||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||
|
||||
CmiMarkBlockDirty(RegistryHive, Offset);
|
||||
|
||||
/* FIXME: Set first dword to block_offset of another free block ? */
|
||||
/* FIXME: Concatenate with previous and next block if free */
|
||||
}
|
||||
|
@ -1872,74 +2036,76 @@ DPRINT("\n");
|
|||
if (RegistryHive->FreeListMax)
|
||||
{
|
||||
DPRINT("\n");
|
||||
RtlMoveMemory(tmpList, RegistryHive->FreeList,
|
||||
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
|
||||
RtlMoveMemory(tmpList,
|
||||
RegistryHive->FreeList,
|
||||
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
|
||||
DPRINT("\n");
|
||||
RtlMoveMemory(tmpListOffset, RegistryHive->FreeListOffset,
|
||||
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax));
|
||||
RtlMoveMemory(tmpListOffset,
|
||||
RegistryHive->FreeListOffset,
|
||||
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax));
|
||||
DPRINT("\n");
|
||||
ExFreePool(RegistryHive->FreeList);
|
||||
ExFreePool(RegistryHive->FreeList);
|
||||
DPRINT("\n");
|
||||
ExFreePool(RegistryHive->FreeListOffset);
|
||||
ExFreePool(RegistryHive->FreeListOffset);
|
||||
DPRINT("\n");
|
||||
}
|
||||
}
|
||||
DPRINT("\n");
|
||||
RegistryHive->FreeList = tmpList;
|
||||
RegistryHive->FreeListOffset = tmpListOffset;
|
||||
RegistryHive->FreeListMax += 32;
|
||||
RegistryHive->FreeList = tmpList;
|
||||
RegistryHive->FreeListOffset = tmpListOffset;
|
||||
RegistryHive->FreeListMax += 32;
|
||||
DPRINT("\n");
|
||||
}
|
||||
}
|
||||
DPRINT("\n");
|
||||
|
||||
/* Add new offset to free list, maintaining list in ascending order */
|
||||
if ((RegistryHive->FreeListSize == 0)
|
||||
|| (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset))
|
||||
{
|
||||
/* Add new offset to free list, maintaining list in ascending order */
|
||||
if ((RegistryHive->FreeListSize == 0)
|
||||
|| (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset))
|
||||
{
|
||||
DPRINT("\n");
|
||||
/* Add to end of list */
|
||||
RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock;
|
||||
RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset;
|
||||
}
|
||||
else if (RegistryHive->FreeListOffset[0] > FreeOffset)
|
||||
{
|
||||
/* Add to end of list */
|
||||
RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock;
|
||||
RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset;
|
||||
}
|
||||
else if (RegistryHive->FreeListOffset[0] > FreeOffset)
|
||||
{
|
||||
DPRINT("\n");
|
||||
/* Add to begin of list */
|
||||
RtlMoveMemory(&RegistryHive->FreeList[1],
|
||||
&RegistryHive->FreeList[0],
|
||||
sizeof(RegistryHive->FreeList[0]) * RegistryHive->FreeListSize);
|
||||
RtlMoveMemory(&RegistryHive->FreeListOffset[1],
|
||||
&RegistryHive->FreeListOffset[0],
|
||||
sizeof(RegistryHive->FreeListOffset[0]) * RegistryHive->FreeListSize);
|
||||
RegistryHive->FreeList[0] = FreeBlock;
|
||||
RegistryHive->FreeListOffset[0] = FreeOffset;
|
||||
RegistryHive->FreeListSize++;
|
||||
}
|
||||
/* Add to begin of list */
|
||||
RtlMoveMemory(&RegistryHive->FreeList[1],
|
||||
&RegistryHive->FreeList[0],
|
||||
sizeof(RegistryHive->FreeList[0]) * RegistryHive->FreeListSize);
|
||||
RtlMoveMemory(&RegistryHive->FreeListOffset[1],
|
||||
&RegistryHive->FreeListOffset[0],
|
||||
sizeof(RegistryHive->FreeListOffset[0]) * RegistryHive->FreeListSize);
|
||||
RegistryHive->FreeList[0] = FreeBlock;
|
||||
RegistryHive->FreeListOffset[0] = FreeOffset;
|
||||
RegistryHive->FreeListSize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("\n");
|
||||
/* Search where to insert */
|
||||
minInd = 0;
|
||||
maxInd = RegistryHive->FreeListSize - 1;
|
||||
while ((maxInd - minInd) > 1)
|
||||
{
|
||||
medInd = (minInd + maxInd) / 2;
|
||||
if (RegistryHive->FreeListOffset[medInd] > FreeOffset)
|
||||
maxInd = medInd;
|
||||
else
|
||||
{
|
||||
DPRINT("\n");
|
||||
/* Search where to insert */
|
||||
minInd = 0;
|
||||
maxInd = RegistryHive->FreeListSize - 1;
|
||||
while ((maxInd - minInd) > 1)
|
||||
{
|
||||
medInd = (minInd + maxInd) / 2;
|
||||
if (RegistryHive->FreeListOffset[medInd] > FreeOffset)
|
||||
maxInd = medInd;
|
||||
else
|
||||
minInd = medInd;
|
||||
}
|
||||
minInd = medInd;
|
||||
}
|
||||
|
||||
/* Insert before maxInd */
|
||||
RtlMoveMemory(&RegistryHive->FreeList[maxInd+1],
|
||||
&RegistryHive->FreeList[maxInd],
|
||||
/* Insert before maxInd */
|
||||
RtlMoveMemory(&RegistryHive->FreeList[maxInd+1],
|
||||
&RegistryHive->FreeList[maxInd],
|
||||
sizeof(RegistryHive->FreeList[0]) * (RegistryHive->FreeListSize - minInd));
|
||||
RtlMoveMemory(&RegistryHive->FreeListOffset[maxInd + 1],
|
||||
RtlMoveMemory(&RegistryHive->FreeListOffset[maxInd + 1],
|
||||
&RegistryHive->FreeListOffset[maxInd],
|
||||
sizeof(RegistryHive->FreeListOffset[0]) * (RegistryHive->FreeListSize-minInd));
|
||||
RegistryHive->FreeList[maxInd] = FreeBlock;
|
||||
RegistryHive->FreeListOffset[maxInd] = FreeOffset;
|
||||
RegistryHive->FreeListSize++;
|
||||
}
|
||||
RegistryHive->FreeList[maxInd] = FreeBlock;
|
||||
RegistryHive->FreeListOffset[maxInd] = FreeOffset;
|
||||
RegistryHive->FreeListSize++;
|
||||
}
|
||||
DPRINT("\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -1948,8 +2114,8 @@ DPRINT("\n");
|
|||
|
||||
PVOID
|
||||
CmiGetBlock(PREGISTRY_HIVE RegistryHive,
|
||||
BLOCK_OFFSET BlockOffset,
|
||||
PHBIN * ppBin)
|
||||
BLOCK_OFFSET BlockOffset,
|
||||
PHBIN * ppBin)
|
||||
{
|
||||
if (ppBin)
|
||||
*ppBin = NULL;
|
||||
|
@ -1973,25 +2139,9 @@ CmiGetBlock(PREGISTRY_HIVE RegistryHive,
|
|||
}
|
||||
|
||||
|
||||
VOID
|
||||
CmiPrepareForWrite(PREGISTRY_HIVE RegistryHive,
|
||||
PHBIN pBin)
|
||||
{
|
||||
if (IsVolatileHive(RegistryHive))
|
||||
{
|
||||
/* No need to do anything special for volatile hives */
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CmiLockBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID Block)
|
||||
PVOID Block)
|
||||
{
|
||||
if (IsPermanentHive(RegistryHive))
|
||||
{
|
||||
|
@ -2002,7 +2152,7 @@ CmiLockBlock(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
VOID
|
||||
CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID Block)
|
||||
PVOID Block)
|
||||
{
|
||||
if (IsPermanentHive(RegistryHive))
|
||||
{
|
||||
|
@ -2011,6 +2161,26 @@ CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
|
|||
}
|
||||
|
||||
|
||||
VOID
|
||||
CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
|
||||
BLOCK_OFFSET BlockOffset)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
if (IsVolatileHive(RegistryHive))
|
||||
return;
|
||||
|
||||
Index = (ULONG)BlockOffset / 4096;
|
||||
|
||||
DPRINT1("CmiMarkBlockDirty(Offset 0x%lx) Index %lu\n", (ULONG)BlockOffset, Index);
|
||||
|
||||
RegistryHive->HiveDirty = TRUE;
|
||||
RtlSetBits(&RegistryHive->DirtyBitMap,
|
||||
Index,
|
||||
1);
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
|
||||
OUT PBOOLEAN Packable)
|
||||
|
@ -2043,12 +2213,10 @@ CmiComparePackedNames(IN PUNICODE_STRING Name,
|
|||
PWCHAR UNameBuffer;
|
||||
ULONG i;
|
||||
|
||||
if (NamePacked)
|
||||
if (NamePacked == TRUE)
|
||||
{
|
||||
if (Name->Length != NameBufferSize * sizeof(WCHAR))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: registry.c,v 1.81 2002/12/08 18:54:45 ekohl Exp $
|
||||
/* $Id: registry.c,v 1.82 2003/02/09 11:57:14 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -659,7 +659,11 @@ CmiConnectHive(PWSTR FileName,
|
|||
|
||||
Status = CmiCreateRegistryHive(FileName, &RegistryHive, CreateNew);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return(Status);
|
||||
{
|
||||
DPRINT1("CmiCreateRegistryHive() failed (Status %lx)\n", Status);
|
||||
KeBugCheck(0);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&uKeyName, FullName);
|
||||
|
||||
|
@ -675,7 +679,12 @@ CmiConnectHive(PWSTR FileName,
|
|||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return(Status);
|
||||
{
|
||||
DPRINT1("ObCreateObject() failed (Status %lx)\n", Status);
|
||||
KeBugCheck(0);
|
||||
CmiRemoveRegistryHive(RegistryHive);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NewKey->RegistryHive = RegistryHive;
|
||||
NewKey->BlockOffset = RegistryHive->HiveHeader->RootKeyCell;
|
||||
|
@ -731,7 +740,9 @@ CmiInitializeHive(PWSTR FileName,
|
|||
//Status = CmiConnectHive(FileName, FullName, KeyName, Parent, FALSE);
|
||||
Status = CmiConnectHive(FileName, FullName, KeyName, Parent, CreateNew);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
#if 0
|
||||
#ifdef WIN32_REGDBG
|
||||
WCHAR AltFileName[MAX_PATH];
|
||||
|
||||
|
@ -749,6 +760,7 @@ CmiInitializeHive(PWSTR FileName,
|
|||
CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName);
|
||||
//DPRINT("Status %.08x\n", Status);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -865,7 +877,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
|||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
//assert(NT_SUCCESS(Status));
|
||||
|
||||
/* Connect the SAM hive */
|
||||
wcscpy(EndPtr, REG_SAM_FILE_NAME);
|
||||
|
@ -881,7 +892,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
|||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
//assert(NT_SUCCESS(Status));
|
||||
|
||||
/* Connect the SECURITY hive */
|
||||
wcscpy(EndPtr, REG_SEC_FILE_NAME);
|
||||
|
@ -896,7 +906,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
|||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
//assert(NT_SUCCESS(Status));
|
||||
|
||||
/* Connect the DEFAULT hive */
|
||||
wcscpy(EndPtr, REG_USER_FILE_NAME);
|
||||
|
@ -912,7 +921,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
|||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
//assert(NT_SUCCESS(Status));
|
||||
|
||||
/* FIXME : initialize standards symbolic links */
|
||||
|
||||
|
@ -936,42 +944,41 @@ CmShutdownRegistry(VOID)
|
|||
{
|
||||
PREGISTRY_HIVE Hive;
|
||||
PLIST_ENTRY Entry;
|
||||
KIRQL oldlvl;
|
||||
// KIRQL oldlvl;
|
||||
|
||||
DPRINT1("CmShutdownRegistry() called\n");
|
||||
|
||||
/* Stop automatic hive synchronization */
|
||||
CmiHiveSyncEnabled = FALSE;
|
||||
|
||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||
// KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||
Entry = CmiHiveListHead.Flink;
|
||||
while (Entry != &CmiHiveListHead)
|
||||
{
|
||||
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
|
||||
|
||||
if (Hive->Flags & HIVE_VOLATILE)
|
||||
{
|
||||
DPRINT("Volatile hive\n");
|
||||
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
|
||||
|
||||
if (IsPermanentHive(Hive))
|
||||
{
|
||||
/* Acquire hive resource exclusively */
|
||||
ExAcquireResourceExclusiveLite(&Hive->HiveResource,
|
||||
TRUE);
|
||||
|
||||
/* Flush non-volatile hive */
|
||||
CmiFlushRegistryHive(Hive);
|
||||
|
||||
/* Dereference file */
|
||||
ObDereferenceObject(Hive->FileObject);
|
||||
Hive->FileObject = NULL;
|
||||
|
||||
/* Release hive resource */
|
||||
ExReleaseResourceLite(&Hive->HiveResource);
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Flush non-volatile hive '%wZ'\n", &Hive->Filename);
|
||||
// KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||
|
||||
/* Flush non-volatile hive */
|
||||
|
||||
/* Dereference file */
|
||||
ObDereferenceObject(Hive->FileObject);
|
||||
Hive->FileObject = NULL;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||
|
||||
/* Note:
|
||||
* Don't call UNIMPLEMENTED() here since this function is
|
||||
* called by NtShutdownSystem().
|
||||
*/
|
||||
DPRINT1("CmShutdownRegistry() called\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -981,9 +988,36 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
|||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
DPRINT("CmiHiveSyncDpcRoutine() called\n");
|
||||
PREGISTRY_HIVE Hive;
|
||||
PLIST_ENTRY Entry;
|
||||
KIRQL oldlvl;
|
||||
|
||||
DPRINT1("CmiHiveSyncDpcRoutine() called\n");
|
||||
|
||||
CmiHiveSyncPending = FALSE;
|
||||
|
||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||
Entry = CmiHiveListHead.Flink;
|
||||
while (Entry != &CmiHiveListHead)
|
||||
{
|
||||
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
|
||||
|
||||
if (IsPermanentHive(Hive))
|
||||
{
|
||||
/* Acquire hive resource exclusively */
|
||||
ExAcquireResourceExclusiveLite(&Hive->HiveResource,
|
||||
TRUE);
|
||||
|
||||
/* Flush non-volatile hive */
|
||||
CmiFlushRegistryHive(Hive);
|
||||
|
||||
/* Release hive resource */
|
||||
ExReleaseResourceLite(&Hive->HiveResource);
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||
}
|
||||
|
||||
|
||||
|
@ -992,6 +1026,8 @@ CmiSyncHives(VOID)
|
|||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
|
||||
DPRINT("CmiSyncHives() called\n");
|
||||
|
||||
if (CmiHiveSyncEnabled == FALSE ||
|
||||
CmiHiveSyncPending == TRUE)
|
||||
return;
|
||||
|
|
|
@ -277,10 +277,36 @@ CmiObjectDelete(PVOID DeletedObject)
|
|||
|
||||
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
|
||||
DPRINT("delete really key\n");
|
||||
|
||||
/* FIXME: Destroy the key's hash block */
|
||||
|
||||
/* Remove the key from the parent key's hash block */
|
||||
HashBlock = CmiGetBlock(KeyObject->RegistryHive,
|
||||
KeyObject->ParentKey->KeyCell->HashTableOffset, NULL);
|
||||
DPRINT1("HashBlock %p\n", HashBlock);
|
||||
if (HashBlock != NULL)
|
||||
{
|
||||
CmiRemoveKeyFromHashTable(KeyObject->RegistryHive,
|
||||
HashBlock,
|
||||
KeyObject->BlockOffset);
|
||||
CmiMarkBlockDirty(KeyObject->RegistryHive,
|
||||
KeyObject->ParentKey->KeyCell->HashTableOffset);
|
||||
}
|
||||
|
||||
/* Remove the key from the parent key's hash block */
|
||||
KeyObject->ParentKey->KeyCell->NumberOfSubKeys--;
|
||||
CmiMarkBlockDirty(KeyObject->RegistryHive,
|
||||
KeyObject->ParentKey->BlockOffset);
|
||||
|
||||
/* Destroy key cell */
|
||||
CmiDestroyBlock(KeyObject->RegistryHive,
|
||||
KeyObject->KeyCell,
|
||||
KeyObject->BlockOffset);
|
||||
if (IsPermanentHive(KeyObject->RegistryHive))
|
||||
CmiSyncHives();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue