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:
Eric Kohl 2003-02-09 11:57:14 +00:00
parent 652669005d
commit 8a23cc7a5b
5 changed files with 504 additions and 238 deletions

View file

@ -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,
@ -508,6 +519,10 @@ VOID
CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
PVOID Block);
VOID
CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
BLOCK_OFFSET BlockOffset);
NTSTATUS
CmiAddFree(PREGISTRY_HIVE RegistryHive,
PCELL_HEADER FreeBlock,

View file

@ -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);
@ -203,12 +201,11 @@ NtDeleteKey(IN HANDLE KeyHandle)
KEY_WRITE,
CmiKeyType,
UserMode,
(PVOID *) &KeyObject,
(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,6 +689,7 @@ NtFlushKey(IN HANDLE KeyHandle)
LARGE_INTEGER fileOffset;
DWORD * pEntDword;
ULONG i;
#endif
DPRINT("KeyHandle %x\n", KeyHandle);
@ -694,21 +698,33 @@ NtFlushKey(IN HANDLE KeyHandle)
KEY_QUERY_VALUE,
CmiKeyType,
UserMode,
(PVOID *) &KeyObject,
(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;

View file

@ -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)
{
@ -421,28 +423,28 @@ CmiCreateNewRegFile(HANDLE FileHandle)
PKEY_CELL RootKeyCell;
NTSTATUS Status;
PHBIN BinCell;
PCHAR tBuf;
PCHAR Buffer;
tBuf = (PCHAR) ExAllocatePool(NonPagedPool, 2 * REG_BLOCK_SIZE);
if (tBuf == NULL)
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,
@ -450,12 +452,12 @@ CmiCreateNewRegFile(HANDLE FileHandle)
NULL,
NULL,
&IoStatusBlock,
tBuf,
Buffer,
2 * REG_BLOCK_SIZE,
0,
NULL);
ExFreePool(tBuf);
ExFreePool(Buffer);
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
@ -487,14 +489,16 @@ 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");
DPRINT1("CmiInitPermanentRegistryHive() - Failed 1.\n");
return Status;
}
@ -504,7 +508,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
NULL,
NULL);
if (CreateNew)
if (CreateNew == TRUE)
CreateDisposition = FILE_OPEN_IF;
else
CreateDisposition = FILE_OPEN;
@ -532,8 +536,8 @@ 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);
}
}
@ -542,7 +546,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
FILE_ALL_ACCESS,
IoFileObjectType,
UserMode,
(PVOID*) &RegistryHive->FileObject,
(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)
@ -1188,7 +1312,6 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
&HashBlock,
&KeyCell->HashTableOffset,
REG_INIT_HASH_TABLE_SIZE);
if (!NT_SUCCESS(Status))
{
return Status;
@ -1207,7 +1330,6 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
&HTOffset,
HashBlock->HashTableSize +
REG_EXTEND_HASH_TABLE_SIZE);
if (!NT_SUCCESS(Status))
{
return 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);
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,10 +2036,12 @@ DPRINT("\n");
if (RegistryHive->FreeListMax)
{
DPRINT("\n");
RtlMoveMemory(tmpList, RegistryHive->FreeList,
RtlMoveMemory(tmpList,
RegistryHive->FreeList,
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
DPRINT("\n");
RtlMoveMemory(tmpListOffset, RegistryHive->FreeListOffset,
RtlMoveMemory(tmpListOffset,
RegistryHive->FreeListOffset,
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax));
DPRINT("\n");
ExFreePool(RegistryHive->FreeList);
@ -1973,22 +2139,6 @@ 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)
@ -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++)
{

View file

@ -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))
{
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))
{
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)
if (IsPermanentHive(Hive))
{
DPRINT("Volatile hive\n");
}
else
{
DPRINT("Flush non-volatile hive '%wZ'\n", &Hive->Filename);
/* 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;
}
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
// 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;

View file

@ -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
{