mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +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
|
#define MAX_REG_STD_HANDLE_NAME 19
|
||||||
|
|
||||||
// BLOCK_OFFSET = offset in file after header block
|
// BLOCK_OFFSET = offset in file after header block
|
||||||
typedef DWORD BLOCK_OFFSET;
|
typedef ULONG BLOCK_OFFSET;
|
||||||
|
|
||||||
/* header for registry hive file : */
|
/* header for registry hive file : */
|
||||||
typedef struct _HIVE_HEADER
|
typedef struct _HIVE_HEADER
|
||||||
|
@ -256,6 +256,9 @@ typedef struct _REGISTRY_HIVE
|
||||||
BLOCK_OFFSET *FreeListOffset;
|
BLOCK_OFFSET *FreeListOffset;
|
||||||
ERESOURCE HiveResource;
|
ERESOURCE HiveResource;
|
||||||
|
|
||||||
|
RTL_BITMAP DirtyBitMap;
|
||||||
|
BOOLEAN HiveDirty;
|
||||||
|
|
||||||
// NTSTATUS (*Extend)(ULONG NewSize);
|
// NTSTATUS (*Extend)(ULONG NewSize);
|
||||||
// PVOID (*Flush)(VOID);
|
// PVOID (*Flush)(VOID);
|
||||||
} REGISTRY_HIVE, *PREGISTRY_HIVE;
|
} REGISTRY_HIVE, *PREGISTRY_HIVE;
|
||||||
|
@ -396,6 +399,9 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
|
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
|
CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
|
||||||
IN PKEY_CELL KeyCell);
|
IN PKEY_CELL KeyCell);
|
||||||
|
@ -473,6 +479,11 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
||||||
PKEY_CELL NewKeyCell,
|
PKEY_CELL NewKeyCell,
|
||||||
BLOCK_OFFSET NKBOffset);
|
BLOCK_OFFSET NKBOffset);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
|
||||||
|
PHASH_TABLE_CELL HashBlock,
|
||||||
|
BLOCK_OFFSET NKBOffset);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
|
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
|
||||||
OUT PVALUE_CELL *ValueCell,
|
OUT PVALUE_CELL *ValueCell,
|
||||||
|
@ -508,6 +519,10 @@ VOID
|
||||||
CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
|
CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
|
||||||
PVOID Block);
|
PVOID Block);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
|
||||||
|
BLOCK_OFFSET BlockOffset);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiAddFree(PREGISTRY_HIVE RegistryHive,
|
CmiAddFree(PREGISTRY_HIVE RegistryHive,
|
||||||
PCELL_HEADER FreeBlock,
|
PCELL_HEADER FreeBlock,
|
||||||
|
|
|
@ -112,7 +112,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
NULL,
|
NULL,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
(PVOID*)&KeyObject);
|
(PVOID*)&KeyObject);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -142,7 +141,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
TitleIndex,
|
TitleIndex,
|
||||||
Class,
|
Class,
|
||||||
CreateOptions);
|
CreateOptions);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
@ -203,12 +201,11 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
||||||
KEY_WRITE,
|
KEY_WRITE,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
UserMode,
|
UserMode,
|
||||||
(PVOID *) &KeyObject,
|
(PVOID *)&KeyObject,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Acquire hive lock */
|
/* Acquire hive lock */
|
||||||
|
@ -219,21 +216,26 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
||||||
/* Set the marked for delete bit in the key object */
|
/* Set the marked for delete bit in the key object */
|
||||||
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
|
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
|
||||||
|
|
||||||
|
/* Release hive lock */
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
|
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||||
|
|
||||||
/* Dereference the object */
|
/* Dereference the object */
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
|
if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
/* Close the handle */
|
|
||||||
ObDeleteHandle(PsGetCurrentProcess(), KeyHandle);
|
|
||||||
/* FIXME: I think that ObDeleteHandle should dereference the object */
|
|
||||||
ObDereferenceObject(KeyObject);
|
|
||||||
|
|
||||||
/* Release hive lock */
|
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
|
||||||
|
|
||||||
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;
|
NTSTATUS Status;
|
||||||
PKEY_OBJECT KeyObject;
|
PKEY_OBJECT KeyObject;
|
||||||
PREGISTRY_HIVE RegistryHive;
|
PREGISTRY_HIVE RegistryHive;
|
||||||
|
#if 0
|
||||||
WCHAR LogName[MAX_PATH];
|
WCHAR LogName[MAX_PATH];
|
||||||
UNICODE_STRING TmpFileName;
|
UNICODE_STRING TmpFileName;
|
||||||
HANDLE FileHandle;
|
HANDLE FileHandle;
|
||||||
|
@ -686,6 +689,7 @@ NtFlushKey(IN HANDLE KeyHandle)
|
||||||
LARGE_INTEGER fileOffset;
|
LARGE_INTEGER fileOffset;
|
||||||
DWORD * pEntDword;
|
DWORD * pEntDword;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
#endif
|
||||||
|
|
||||||
DPRINT("KeyHandle %x\n", KeyHandle);
|
DPRINT("KeyHandle %x\n", KeyHandle);
|
||||||
|
|
||||||
|
@ -694,21 +698,33 @@ NtFlushKey(IN HANDLE KeyHandle)
|
||||||
KEY_QUERY_VALUE,
|
KEY_QUERY_VALUE,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
UserMode,
|
UserMode,
|
||||||
(PVOID *) &KeyObject,
|
(PVOID *)&KeyObject,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Acquire hive lock */
|
|
||||||
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
RegistryHive = KeyObject->RegistryHive;
|
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 */
|
/* Then write changed blocks in .log */
|
||||||
wcscpy(LogName,RegistryHive->Filename.Buffer);
|
wcscpy(LogName,RegistryHive->Filename.Buffer);
|
||||||
wcscat(LogName,L".log");
|
wcscat(LogName,L".log");
|
||||||
|
@ -891,8 +907,12 @@ END FIXME*/
|
||||||
}
|
}
|
||||||
|
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
#endif
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&RegistryHive->HiveResource);
|
||||||
|
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1424,6 +1444,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
||||||
{
|
{
|
||||||
/* If new data size is <= current then overwrite current data */
|
/* If new data size is <= current then overwrite current data */
|
||||||
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
|
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
|
||||||
|
RtlZeroMemory(DataCell->Data, ValueCell->DataSize);
|
||||||
RtlCopyMemory(DataCell->Data, Data, DataSize);
|
RtlCopyMemory(DataCell->Data, Data, DataSize);
|
||||||
ValueCell->DataSize = DataSize;
|
ValueCell->DataSize = DataSize;
|
||||||
ValueCell->DataType = Type;
|
ValueCell->DataType = Type;
|
||||||
|
|
|
@ -24,10 +24,12 @@
|
||||||
#include "cm.h"
|
#include "cm.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||||
|
|
||||||
BOOLEAN CmiDoVerify = FALSE;
|
BOOLEAN CmiDoVerify = FALSE;
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
CmiCreateDefaultHiveHeader(PHIVE_HEADER Header)
|
CmiCreateDefaultHiveHeader(PHIVE_HEADER Header)
|
||||||
{
|
{
|
||||||
|
@ -421,28 +423,28 @@ CmiCreateNewRegFile(HANDLE FileHandle)
|
||||||
PKEY_CELL RootKeyCell;
|
PKEY_CELL RootKeyCell;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PHBIN BinCell;
|
PHBIN BinCell;
|
||||||
PCHAR tBuf;
|
PCHAR Buffer;
|
||||||
|
|
||||||
tBuf = (PCHAR) ExAllocatePool(NonPagedPool, 2 * REG_BLOCK_SIZE);
|
Buffer = (PCHAR) ExAllocatePool(NonPagedPool, 2 * REG_BLOCK_SIZE);
|
||||||
if (tBuf == NULL)
|
if (Buffer == NULL)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
HiveHeader = (PHIVE_HEADER) tBuf;
|
HiveHeader = (PHIVE_HEADER)Buffer;
|
||||||
BinCell = (PHBIN) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE);
|
BinCell = (PHBIN)((ULONG_PTR)Buffer + REG_BLOCK_SIZE);
|
||||||
RootKeyCell = (PKEY_CELL) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET);
|
RootKeyCell = (PKEY_CELL)((ULONG_PTR)Buffer + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET);
|
||||||
FreeCell = (PCELL_HEADER) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL));
|
FreeCell = (PCELL_HEADER)((ULONG_PTR)Buffer + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL));
|
||||||
|
|
||||||
CmiCreateDefaultHiveHeader(HiveHeader);
|
CmiCreateDefaultHiveHeader(HiveHeader);
|
||||||
CmiCreateDefaultBinCell(BinCell);
|
CmiCreateDefaultBinCell(BinCell);
|
||||||
CmiCreateDefaultRootKeyCell(RootKeyCell);
|
CmiCreateDefaultRootKeyCell(RootKeyCell);
|
||||||
|
|
||||||
// First block
|
/* First block */
|
||||||
BinCell->BlockOffset = 0;
|
BinCell->BlockOffset = 0;
|
||||||
|
|
||||||
// Offset to root key block
|
/* Offset to root key block */
|
||||||
HiveHeader->RootKeyCell = REG_HBIN_DATA_OFFSET;
|
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));
|
FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL));
|
||||||
|
|
||||||
Status = ZwWriteFile(FileHandle,
|
Status = ZwWriteFile(FileHandle,
|
||||||
|
@ -450,12 +452,12 @@ CmiCreateNewRegFile(HANDLE FileHandle)
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
tBuf,
|
Buffer,
|
||||||
2 * REG_BLOCK_SIZE,
|
2 * REG_BLOCK_SIZE,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
ExFreePool(tBuf);
|
ExFreePool(Buffer);
|
||||||
|
|
||||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||||
|
|
||||||
|
@ -487,14 +489,16 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PHBIN tmpBin;
|
PHBIN tmpBin;
|
||||||
ULONG i, j;
|
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 */
|
/* Duplicate Filename */
|
||||||
Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename);
|
Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("CmiInitPermanentRegistryHive() - Failed 1.\n");
|
DPRINT1("CmiInitPermanentRegistryHive() - Failed 1.\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,7 +508,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (CreateNew)
|
if (CreateNew == TRUE)
|
||||||
CreateDisposition = FILE_OPEN_IF;
|
CreateDisposition = FILE_OPEN_IF;
|
||||||
else
|
else
|
||||||
CreateDisposition = FILE_OPEN;
|
CreateDisposition = FILE_OPEN;
|
||||||
|
@ -532,8 +536,8 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
Status = CmiCreateNewRegFile(FileHandle);
|
Status = CmiCreateNewRegFile(FileHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("CmiCreateNewRegFile() failed (Status %lx)\n", Status);
|
||||||
RtlFreeUnicodeString(&RegistryHive->Filename);
|
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||||
DPRINT1("CmiCreateNewRegFile() - Failed with status %x.\n", Status);
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,7 +546,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
FILE_ALL_ACCESS,
|
FILE_ALL_ACCESS,
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
UserMode,
|
UserMode,
|
||||||
(PVOID*) &RegistryHive->FileObject,
|
(PVOID*)&RegistryHive->FileObject,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||||
|
@ -551,10 +555,11 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
{
|
{
|
||||||
NtClose(FileHandle);
|
NtClose(FileHandle);
|
||||||
RtlFreeUnicodeString(&RegistryHive->Filename);
|
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||||
DPRINT("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status);
|
DPRINT1("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read hive header */
|
||||||
FileOffset.u.HighPart = 0;
|
FileOffset.u.HighPart = 0;
|
||||||
FileOffset.u.LowPart = 0;
|
FileOffset.u.LowPart = 0;
|
||||||
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, sizeof(HIVE_HEADER), RegistryHive->HiveHeader);
|
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),
|
sizeof(HIVE_HEADER),
|
||||||
&FileOffset,
|
&FileOffset,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(RegistryHive->FileObject);
|
ObDereferenceObject(RegistryHive->FileObject);
|
||||||
|
@ -744,7 +747,21 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
BlockOffset += tmpBin->BlockSize;
|
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);
|
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
|
ULONG
|
||||||
CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive,
|
CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive,
|
||||||
PKEY_CELL KeyCell)
|
PKEY_CELL KeyCell)
|
||||||
|
@ -1188,7 +1312,6 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
&HashBlock,
|
&HashBlock,
|
||||||
&KeyCell->HashTableOffset,
|
&KeyCell->HashTableOffset,
|
||||||
REG_INIT_HASH_TABLE_SIZE);
|
REG_INIT_HASH_TABLE_SIZE);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1207,7 +1330,6 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
&HTOffset,
|
&HTOffset,
|
||||||
HashBlock->HashTableSize +
|
HashBlock->HashTableSize +
|
||||||
REG_EXTEND_HASH_TABLE_SIZE);
|
REG_EXTEND_HASH_TABLE_SIZE);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return 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
|
NTSTATUS
|
||||||
CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
|
CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
|
||||||
PVALUE_CELL *ValueCell,
|
PVALUE_CELL *ValueCell,
|
||||||
|
@ -1677,6 +1820,17 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
|
||||||
/* Initialize a free block in this heap : */
|
/* Initialize a free block in this heap : */
|
||||||
tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET);
|
tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET);
|
||||||
tmpBlock->CellSize = (REG_BLOCK_SIZE - 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;
|
*NewBlock = (PVOID) tmpBlock;
|
||||||
|
|
||||||
if (NewBlockOffset)
|
if (NewBlockOffset)
|
||||||
|
@ -1742,7 +1896,10 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
|
||||||
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
|
Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
|
||||||
|
|
||||||
if (Temp)
|
if (Temp)
|
||||||
|
{
|
||||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||||
|
CmiMarkBlockDirty(RegistryHive, RegistryHive->FreeListOffset[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if ((i + 1) < RegistryHive->FreeListSize)
|
if ((i + 1) < RegistryHive->FreeListSize)
|
||||||
{
|
{
|
||||||
|
@ -1777,6 +1934,7 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
|
||||||
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
|
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
|
||||||
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
|
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
|
||||||
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
|
CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
|
||||||
|
CmiMarkBlockDirty(RegistryHive, *pBlockOffset + BlockSize);
|
||||||
}
|
}
|
||||||
else if (NewBlock->CellSize < BlockSize)
|
else if (NewBlock->CellSize < BlockSize)
|
||||||
{
|
{
|
||||||
|
@ -1815,6 +1973,10 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
|
||||||
if (pFree->CellSize < 0)
|
if (pFree->CellSize < 0)
|
||||||
pFree->CellSize = -pFree->CellSize;
|
pFree->CellSize = -pFree->CellSize;
|
||||||
|
|
||||||
|
/* Clear block (except the block size) */
|
||||||
|
RtlZeroMemory(((PVOID)pFree) + sizeof(ULONG),
|
||||||
|
pFree->CellSize - sizeof(ULONG));
|
||||||
|
|
||||||
CmiAddFree(RegistryHive, Block, Offset);
|
CmiAddFree(RegistryHive, Block, Offset);
|
||||||
CmiReleaseBlock(RegistryHive, Block);
|
CmiReleaseBlock(RegistryHive, Block);
|
||||||
|
|
||||||
|
@ -1822,6 +1984,8 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
|
||||||
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
|
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
|
||||||
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
ZwQuerySystemTime((PTIME) &pBin->DateModified);
|
||||||
|
|
||||||
|
CmiMarkBlockDirty(RegistryHive, Offset);
|
||||||
|
|
||||||
/* FIXME: Set first dword to block_offset of another free block ? */
|
/* FIXME: Set first dword to block_offset of another free block ? */
|
||||||
/* FIXME: Concatenate with previous and next block if free */
|
/* FIXME: Concatenate with previous and next block if free */
|
||||||
}
|
}
|
||||||
|
@ -1872,10 +2036,12 @@ DPRINT("\n");
|
||||||
if (RegistryHive->FreeListMax)
|
if (RegistryHive->FreeListMax)
|
||||||
{
|
{
|
||||||
DPRINT("\n");
|
DPRINT("\n");
|
||||||
RtlMoveMemory(tmpList, RegistryHive->FreeList,
|
RtlMoveMemory(tmpList,
|
||||||
|
RegistryHive->FreeList,
|
||||||
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
|
sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
|
||||||
DPRINT("\n");
|
DPRINT("\n");
|
||||||
RtlMoveMemory(tmpListOffset, RegistryHive->FreeListOffset,
|
RtlMoveMemory(tmpListOffset,
|
||||||
|
RegistryHive->FreeListOffset,
|
||||||
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax));
|
sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax));
|
||||||
DPRINT("\n");
|
DPRINT("\n");
|
||||||
ExFreePool(RegistryHive->FreeList);
|
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
|
VOID
|
||||||
CmiLockBlock(PREGISTRY_HIVE RegistryHive,
|
CmiLockBlock(PREGISTRY_HIVE RegistryHive,
|
||||||
PVOID Block)
|
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
|
ULONG
|
||||||
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
|
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
|
||||||
OUT PBOOLEAN Packable)
|
OUT PBOOLEAN Packable)
|
||||||
|
@ -2043,12 +2213,10 @@ CmiComparePackedNames(IN PUNICODE_STRING Name,
|
||||||
PWCHAR UNameBuffer;
|
PWCHAR UNameBuffer;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
if (NamePacked)
|
if (NamePacked == TRUE)
|
||||||
{
|
{
|
||||||
if (Name->Length != NameBufferSize * sizeof(WCHAR))
|
if (Name->Length != NameBufferSize * sizeof(WCHAR))
|
||||||
{
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -659,7 +659,11 @@ CmiConnectHive(PWSTR FileName,
|
||||||
|
|
||||||
Status = CmiCreateRegistryHive(FileName, &RegistryHive, CreateNew);
|
Status = CmiCreateRegistryHive(FileName, &RegistryHive, CreateNew);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CmiCreateRegistryHive() failed (Status %lx)\n", Status);
|
||||||
|
KeBugCheck(0);
|
||||||
return(Status);
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
RtlInitUnicodeString(&uKeyName, FullName);
|
RtlInitUnicodeString(&uKeyName, FullName);
|
||||||
|
|
||||||
|
@ -675,7 +679,12 @@ CmiConnectHive(PWSTR FileName,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
(PVOID*)&NewKey);
|
(PVOID*)&NewKey);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ObCreateObject() failed (Status %lx)\n", Status);
|
||||||
|
KeBugCheck(0);
|
||||||
|
CmiRemoveRegistryHive(RegistryHive);
|
||||||
return(Status);
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
NewKey->RegistryHive = RegistryHive;
|
NewKey->RegistryHive = RegistryHive;
|
||||||
NewKey->BlockOffset = RegistryHive->HiveHeader->RootKeyCell;
|
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, FALSE);
|
||||||
Status = CmiConnectHive(FileName, FullName, KeyName, Parent, CreateNew);
|
Status = CmiConnectHive(FileName, FullName, KeyName, Parent, CreateNew);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
#ifdef WIN32_REGDBG
|
#ifdef WIN32_REGDBG
|
||||||
WCHAR AltFileName[MAX_PATH];
|
WCHAR AltFileName[MAX_PATH];
|
||||||
|
|
||||||
|
@ -749,6 +760,7 @@ CmiInitializeHive(PWSTR FileName,
|
||||||
CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName);
|
CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName);
|
||||||
//DPRINT("Status %.08x\n", Status);
|
//DPRINT("Status %.08x\n", Status);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +877,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
||||||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
|
||||||
|
|
||||||
/* Connect the SAM hive */
|
/* Connect the SAM hive */
|
||||||
wcscpy(EndPtr, REG_SAM_FILE_NAME);
|
wcscpy(EndPtr, REG_SAM_FILE_NAME);
|
||||||
|
@ -881,7 +892,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
||||||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
|
||||||
|
|
||||||
/* Connect the SECURITY hive */
|
/* Connect the SECURITY hive */
|
||||||
wcscpy(EndPtr, REG_SEC_FILE_NAME);
|
wcscpy(EndPtr, REG_SEC_FILE_NAME);
|
||||||
|
@ -896,7 +906,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
||||||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
|
||||||
|
|
||||||
/* Connect the DEFAULT hive */
|
/* Connect the DEFAULT hive */
|
||||||
wcscpy(EndPtr, REG_USER_FILE_NAME);
|
wcscpy(EndPtr, REG_USER_FILE_NAME);
|
||||||
|
@ -912,7 +921,6 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
||||||
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
|
||||||
|
|
||||||
/* FIXME : initialize standards symbolic links */
|
/* FIXME : initialize standards symbolic links */
|
||||||
|
|
||||||
|
@ -936,42 +944,41 @@ CmShutdownRegistry(VOID)
|
||||||
{
|
{
|
||||||
PREGISTRY_HIVE Hive;
|
PREGISTRY_HIVE Hive;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
KIRQL oldlvl;
|
// KIRQL oldlvl;
|
||||||
|
|
||||||
DPRINT1("CmShutdownRegistry() called\n");
|
DPRINT1("CmShutdownRegistry() called\n");
|
||||||
|
|
||||||
/* Stop automatic hive synchronization */
|
/* Stop automatic hive synchronization */
|
||||||
CmiHiveSyncEnabled = FALSE;
|
CmiHiveSyncEnabled = FALSE;
|
||||||
|
|
||||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
// KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||||
Entry = CmiHiveListHead.Flink;
|
Entry = CmiHiveListHead.Flink;
|
||||||
while (Entry != &CmiHiveListHead)
|
while (Entry != &CmiHiveListHead)
|
||||||
{
|
{
|
||||||
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
|
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
|
||||||
|
|
||||||
if (Hive->Flags & HIVE_VOLATILE)
|
if (IsPermanentHive(Hive))
|
||||||
{
|
{
|
||||||
DPRINT("Volatile hive\n");
|
/* Acquire hive resource exclusively */
|
||||||
}
|
ExAcquireResourceExclusiveLite(&Hive->HiveResource,
|
||||||
else
|
TRUE);
|
||||||
{
|
|
||||||
DPRINT("Flush non-volatile hive '%wZ'\n", &Hive->Filename);
|
|
||||||
|
|
||||||
/* Flush non-volatile hive */
|
/* Flush non-volatile hive */
|
||||||
|
CmiFlushRegistryHive(Hive);
|
||||||
|
|
||||||
/* Dereference file */
|
/* Dereference file */
|
||||||
ObDereferenceObject(Hive->FileObject);
|
ObDereferenceObject(Hive->FileObject);
|
||||||
Hive->FileObject = NULL;
|
Hive->FileObject = NULL;
|
||||||
|
|
||||||
|
/* Release hive resource */
|
||||||
|
ExReleaseResourceLite(&Hive->HiveResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
// KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||||
|
|
||||||
/* Note:
|
DPRINT1("CmShutdownRegistry() called\n");
|
||||||
* Don't call UNIMPLEMENTED() here since this function is
|
|
||||||
* called by NtShutdownSystem().
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -981,9 +988,36 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||||
PVOID SystemArgument1,
|
PVOID SystemArgument1,
|
||||||
PVOID SystemArgument2)
|
PVOID SystemArgument2)
|
||||||
{
|
{
|
||||||
DPRINT("CmiHiveSyncDpcRoutine() called\n");
|
PREGISTRY_HIVE Hive;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
KIRQL oldlvl;
|
||||||
|
|
||||||
|
DPRINT1("CmiHiveSyncDpcRoutine() called\n");
|
||||||
|
|
||||||
CmiHiveSyncPending = FALSE;
|
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;
|
LARGE_INTEGER Timeout;
|
||||||
|
|
||||||
|
DPRINT("CmiSyncHives() called\n");
|
||||||
|
|
||||||
if (CmiHiveSyncEnabled == FALSE ||
|
if (CmiHiveSyncEnabled == FALSE ||
|
||||||
CmiHiveSyncPending == TRUE)
|
CmiHiveSyncPending == TRUE)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -277,10 +277,36 @@ CmiObjectDelete(PVOID DeletedObject)
|
||||||
|
|
||||||
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
|
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
|
||||||
{
|
{
|
||||||
|
PHASH_TABLE_CELL HashBlock;
|
||||||
|
|
||||||
DPRINT("delete really key\n");
|
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,
|
CmiDestroyBlock(KeyObject->RegistryHive,
|
||||||
KeyObject->KeyCell,
|
KeyObject->KeyCell,
|
||||||
KeyObject->BlockOffset);
|
KeyObject->BlockOffset);
|
||||||
|
if (IsPermanentHive(KeyObject->RegistryHive))
|
||||||
|
CmiSyncHives();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue