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,
|
||||
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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