diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 397ac71a5f6..d9cb286a028 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -256,6 +256,7 @@ typedef struct _REGISTRY_HIVE BLOCK_OFFSET *FreeListOffset; ERESOURCE HiveResource; + PULONG BitmapBuffer; RTL_BITMAP DirtyBitMap; BOOLEAN HiveDirty; } REGISTRY_HIVE, *PREGISTRY_HIVE; diff --git a/reactos/ntoskrnl/cm/import.c b/reactos/ntoskrnl/cm/import.c index e1bd153fd95..0776f53afe6 100644 --- a/reactos/ntoskrnl/cm/import.c +++ b/reactos/ntoskrnl/cm/import.c @@ -1,4 +1,4 @@ -/* $Id: import.c,v 1.11 2003/03/22 18:26:53 ekohl Exp $ +/* $Id: import.c,v 1.12 2003/03/24 19:09:04 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -613,29 +613,202 @@ CmImportTextHive(PCHAR ChunkBase, } -VOID +BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize) { + PREGISTRY_HIVE Hive; + PCELL_HEADER FreeBlock; + BLOCK_OFFSET BlockOffset; + PHBIN Bin; + ULONG i, j; + ULONG FreeOffset; + NTSTATUS Status; + ULONG BitmapSize; + + +// CmImportTextHive (ChunkBase, ChunkSize); + if (strncmp (ChunkBase, "REGEDIT4", 8) == 0) { - DPRINT("Found 'REGEDIT4' magic\n"); + DPRINT1("Found 'REGEDIT4' magic\n"); CmImportTextHive (ChunkBase, ChunkSize); + return TRUE; } - else + else if (strncpy (ChunkBase, "regf", 4) != 0) { - DPRINT1("Found '%*s' magic\n", 4, ChunkBase); - KeBugCheck(0); + DPRINT1("Found invalid '%*s' magic\n", 4, ChunkBase); + return FALSE; } + + /* Create a new hive */ + Hive = ExAllocatePool (NonPagedPool, + sizeof(REGISTRY_HIVE)); + if (Hive == NULL) + { + return FALSE; + } + RtlZeroMemory (Hive, + sizeof(REGISTRY_HIVE)); + + Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool, + sizeof(HIVE_HEADER)); + if (Hive->HiveHeader == NULL) + { + DPRINT1 ("Allocating hive header failed\n"); + ExFreePool (Hive); + return FALSE; + } + + /* Import the hive header */ + RtlCopyMemory (Hive->HiveHeader, + ChunkBase, + sizeof(HIVE_HEADER)); + + /* Read update counter */ + Hive->UpdateCounter = Hive->HiveHeader->UpdateCounter1; + + /* Set the hive's size */ + Hive->FileSize = ChunkSize; + + /* Set the size of the block list */ + Hive->BlockListSize = (Hive->FileSize / 4096) - 1; + + /* Allocate block list */ + DPRINT1("Space needed for block list describing hive: 0x%x\n", + sizeof(PHBIN *) * Hive->BlockListSize); + Hive->BlockList = ExAllocatePool(NonPagedPool, + sizeof(PHBIN *) * Hive->BlockListSize); + if (Hive->BlockList == NULL) + { + DPRINT1 ("Allocating block list failed\n"); + ExFreePool (Hive->HiveHeader); + ExFreePool (Hive); + return FALSE; + } + + /* Allocate the first hive block */ + Hive->BlockList[0] = ExAllocatePool(PagedPool, + Hive->FileSize - 4096); + if (Hive->BlockList[0] == NULL) + { + DPRINT1 ("Allocating the first hive block failed\n"); + ExFreePool (Hive->BlockList); + ExFreePool (Hive->HiveHeader); + ExFreePool (Hive); + return FALSE; + } + + /* Import the hive block */ + RtlCopyMemory (Hive->BlockList[0], + ChunkBase + 4096, + Hive->FileSize - 4096); + + /* Initialize the free block list */ + Hive->FreeListSize = 0; + Hive->FreeListMax = 0; + Hive->FreeList = NULL; + + BlockOffset = 0; + for (i = 0; i < Hive->BlockListSize; i++) + { + Hive->BlockList[i] = (PHBIN) (((ULONG_PTR)Hive->BlockList[0]) + BlockOffset); + Bin = (PHBIN) (((ULONG_PTR)Hive->BlockList[i])); + if (Bin->BlockId != REG_BIN_ID) + { + DPRINT1("Bad BlockId %x, offset %x\n", Bin->BlockId, BlockOffset); + /* FIXME: */ + assert(FALSE); +// return STATUS_INSUFFICIENT_RESOURCES; + } + + assertmsg((Bin->BlockSize % 4096) == 0, ("BlockSize (0x%.08x) must be multiplum of 4K\n", Bin->BlockSize)); + + if (Bin->BlockSize > 4096) + { + for (j = 1; j < Bin->BlockSize / 4096; j++) + { + Hive->BlockList[i + j] = Hive->BlockList[i]; + } + i = i + j - 1; + } + + /* Search free blocks and add to list */ + FreeOffset = REG_HBIN_DATA_OFFSET; + while (FreeOffset < Bin->BlockSize) + { + FreeBlock = (PCELL_HEADER) ((ULONG_PTR)Hive->BlockList[i] + FreeOffset); + if (FreeBlock->CellSize > 0) + { + Status = CmiAddFree(Hive, + FreeBlock, + Hive->BlockList[i]->BlockOffset + FreeOffset, + FALSE); + if (!NT_SUCCESS(Status)) + { + /* FIXME: */ + assert(FALSE); + } + + FreeOffset += FreeBlock->CellSize; + } + else + { + FreeOffset -= FreeBlock->CellSize; + } + } + BlockOffset += Bin->BlockSize; + } + + /* Calculate bitmap size in bytes (always a multiple of 32 bits) */ + BitmapSize = ROUND_UP(Hive->BlockListSize, sizeof(ULONG) * 8) / 8; + DPRINT("Hive->BlockListSize: %lu\n", Hive->BlockListSize); + DPRINT("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8); + + /* Allocate bitmap */ + Hive->BitmapBuffer = (PULONG)ExAllocatePool(PagedPool, + BitmapSize); + if (Hive->BitmapBuffer == NULL) + { + DPRINT1 ("Allocating the hive bitmap failed\n"); + ExFreePool (Hive->BlockList[0]); + ExFreePool (Hive->BlockList); + ExFreePool (Hive->HiveHeader); + ExFreePool (Hive); + return FALSE; + } + + /* Initialize bitmap */ + RtlInitializeBitMap(&Hive->DirtyBitMap, + Hive->BitmapBuffer, + BitmapSize * 8); + RtlClearAllBits(&Hive->DirtyBitMap); + Hive->HiveDirty = FALSE; + + + /* Initialize the hive's executive resource */ + ExInitializeResourceLite(&Hive->HiveResource); + + /* Acquire hive list lock exclusively */ + ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); + + /* Add the new hive to the hive list */ + InsertTailList(&CmiHiveListHead, &Hive->HiveList); + + /* Release hive list lock */ + ExReleaseResourceLite(&CmiHiveListLock); + + return TRUE; } -VOID +BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize) { DPRINT1("CmImportHardwareHive() called\n"); + return TRUE; } /* EOF */ diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index 6e751e5daf7..9a6f20a220d 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -6,9 +6,6 @@ * UPDATE HISTORY: */ -#ifdef WIN32_REGDBG -#include "cm_win32.h" -#else #include #include #include @@ -23,7 +20,7 @@ #include #include "cm.h" -#endif + /* uncomment to enable hive checks (incomplete and probably buggy) */ // #define HIVE_CHECK @@ -81,11 +78,7 @@ CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell) { assert(RootKeyCell); RtlZeroMemory(RootKeyCell, sizeof(KEY_CELL)); -#ifdef WIN32_REGDBG - RootKeyCell->CellSize = -(LONG)sizeof(KEY_CELL); -#else RootKeyCell->CellSize = -sizeof(KEY_CELL); -#endif RootKeyCell->Id = REG_KEY_CELL_ID; RootKeyCell->Type = REG_ROOT_KEY_CELL_TYPE; NtQuerySystemTime((PTIME) &RootKeyCell->LastWriteTime); @@ -766,9 +759,9 @@ CmiInitNonVolatileRegistryHive(PREGISTRY_HIVE RegistryHive, PHBIN tmpBin; ULONG i, j; ULONG BitmapSize; - PULONG BitmapBuffer; - DPRINT1("CmiInitNonVolatileRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew); + DPRINT("CmiInitNonVolatileRegistryHive(%p, %S, %d) called\n", + RegistryHive, Filename, CreateNew); /* Duplicate Filename */ Status = RtlCreateUnicodeString(&RegistryHive->HiveFileName, @@ -896,7 +889,7 @@ CmiInitNonVolatileRegistryHive(PREGISTRY_HIVE RegistryHive, sizeof(fsi), FileStandardInformation); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status) || fsi.EndOfFile.u.LowPart == 0) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); @@ -906,17 +899,6 @@ CmiInitNonVolatileRegistryHive(PREGISTRY_HIVE RegistryHive, } RegistryHive->FileSize = fsi.EndOfFile.u.LowPart; -#ifdef WIN32_REGDBG -// assert(RegistryHive->FileSize); - if (RegistryHive->FileSize == 0) - { - DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n"); - NtClose(FileHandle); - RtlFreeUnicodeString(&RegistryHive->HiveFileName); - RtlFreeUnicodeString(&RegistryHive->LogFileName); - return STATUS_INSUFFICIENT_RESOURCES; - } -#endif RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; DPRINT("Space needed for block list describing hive: 0x%x\n", @@ -937,10 +919,6 @@ CmiInitNonVolatileRegistryHive(PREGISTRY_HIVE RegistryHive, RegistryHive->BlockList[0] = ExAllocatePool(PagedPool, RegistryHive->FileSize - 4096); -#ifdef WIN32_REGDBG - RtlZeroMemory(RegistryHive->BlockList[0], RegistryHive->FileSize - 4096); -#endif - if (RegistryHive->BlockList[0] == NULL) { ExFreePool(RegistryHive->BlockList); @@ -1034,10 +1012,10 @@ CmiInitNonVolatileRegistryHive(PREGISTRY_HIVE RegistryHive, DPRINT("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8); /* Allocate bitmap */ - BitmapBuffer = (PULONG)ExAllocatePool(PagedPool, - BitmapSize); + RegistryHive->BitmapBuffer = (PULONG)ExAllocatePool(PagedPool, + BitmapSize); RtlInitializeBitMap(&RegistryHive->DirtyBitMap, - BitmapBuffer, + RegistryHive->BitmapBuffer, BitmapSize * 8); /* Initialize bitmap */ @@ -1822,7 +1800,7 @@ CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive) ULONG CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive, - PKEY_CELL KeyCell) + PKEY_CELL KeyCell) { PHASH_TABLE_CELL HashBlock; PKEY_CELL CurSubKeyCell; @@ -1841,27 +1819,27 @@ CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive, for (i = 0; i < HashBlock->HashTableSize; i++) { if (HashBlock->Table[i].KeyOffset != 0) - { - CurSubKeyCell = CmiGetBlock(RegistryHive, - HashBlock->Table[i].KeyOffset, - NULL); - if (MaxName < CurSubKeyCell->NameSize) - { - MaxName = CurSubKeyCell->NameSize; - } - CmiReleaseBlock(RegistryHive, CurSubKeyCell); - } + { + CurSubKeyCell = CmiGetBlock(RegistryHive, + HashBlock->Table[i].KeyOffset, + NULL); + if (MaxName < CurSubKeyCell->NameSize) + { + MaxName = CurSubKeyCell->NameSize; + } + CmiReleaseBlock(RegistryHive, CurSubKeyCell); + } } CmiReleaseBlock(RegistryHive, HashBlock); - + return MaxName; } ULONG CmiGetMaxClassLength(PREGISTRY_HIVE RegistryHive, - PKEY_CELL KeyCell) + PKEY_CELL KeyCell) { PHASH_TABLE_CELL HashBlock; PKEY_CELL CurSubKeyCell; @@ -1880,16 +1858,16 @@ CmiGetMaxClassLength(PREGISTRY_HIVE RegistryHive, for (i = 0; i < HashBlock->HashTableSize; i++) { if (HashBlock->Table[i].KeyOffset != 0) - { - CurSubKeyCell = CmiGetBlock(RegistryHive, - HashBlock->Table[i].KeyOffset, - NULL); - if (MaxClass < CurSubKeyCell->ClassSize) - { - MaxClass = CurSubKeyCell->ClassSize; - } - CmiReleaseBlock(RegistryHive, CurSubKeyCell); - } + { + CurSubKeyCell = CmiGetBlock(RegistryHive, + HashBlock->Table[i].KeyOffset, + NULL); + if (MaxClass < CurSubKeyCell->ClassSize) + { + MaxClass = CurSubKeyCell->ClassSize; + } + CmiReleaseBlock(RegistryHive, CurSubKeyCell); + } } CmiReleaseBlock(RegistryHive, HashBlock); @@ -1898,9 +1876,9 @@ CmiGetMaxClassLength(PREGISTRY_HIVE RegistryHive, } -ULONG +ULONG CmiGetMaxValueNameLength(PREGISTRY_HIVE RegistryHive, - PKEY_CELL KeyCell) + PKEY_CELL KeyCell) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; @@ -1909,7 +1887,9 @@ CmiGetMaxValueNameLength(PREGISTRY_HIVE RegistryHive, VERIFY_KEY_CELL(KeyCell); - ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); + ValueListCell = CmiGetBlock(RegistryHive, + KeyCell->ValuesOffset, + NULL); MaxValueName = 0; if (ValueListCell == NULL) { @@ -1930,7 +1910,7 @@ CmiGetMaxValueNameLength(PREGISTRY_HIVE RegistryHive, } CmiReleaseBlock(RegistryHive, ValueListCell); - + return MaxValueName; } @@ -1973,12 +1953,12 @@ CmiGetMaxValueDataLength(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - OUT PKEY_CELL *SubKeyCell, - OUT BLOCK_OFFSET *BlockOffset, - IN PCHAR KeyName, - IN ACCESS_MASK DesiredAccess, - IN ULONG Attributes) + IN PKEY_CELL KeyCell, + OUT PKEY_CELL *SubKeyCell, + OUT BLOCK_OFFSET *BlockOffset, + IN PCHAR KeyName, + IN ACCESS_MASK DesiredAccess, + IN ULONG Attributes) { PHASH_TABLE_CELL HashBlock; PKEY_CELL CurSubKeyCell; @@ -2336,10 +2316,10 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - IN PUNICODE_STRING ValueName, - OUT PVALUE_CELL *ValueCell, - OUT BLOCK_OFFSET *VBOffset) + IN PKEY_CELL KeyCell, + IN PUNICODE_STRING ValueName, + OUT PVALUE_CELL *ValueCell, + OUT BLOCK_OFFSET *VBOffset) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; @@ -2386,9 +2366,9 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - IN ULONG Index, - OUT PVALUE_CELL *ValueCell) + IN PKEY_CELL KeyCell, + IN ULONG Index, + OUT PVALUE_CELL *ValueCell) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; @@ -2775,8 +2755,8 @@ CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddBin(PREGISTRY_HIVE RegistryHive, - PVOID *NewBlock, - BLOCK_OFFSET *NewBlockOffset) + PVOID *NewBlock, + BLOCK_OFFSET *NewBlockOffset) { PCELL_HEADER tmpBlock; PHBIN * tmpBlockList; @@ -2839,9 +2819,10 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, RtlCopyMemory(BitmapBuffer, RegistryHive->DirtyBitMap.Buffer, RegistryHive->DirtyBitMap.SizeOfBitMap); - ExFreePool(RegistryHive->DirtyBitMap.Buffer); + ExFreePool(RegistryHive->BitmapBuffer); + RegistryHive->BitmapBuffer = BitmapBuffer; RtlInitializeBitMap(&RegistryHive->DirtyBitMap, - BitmapBuffer, + RegistryHive->BitmapBuffer, BitmapSize * 8); } diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 439b674b8cd..0264bcb41a7 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -45,8 +45,8 @@ VOID PsInit(VOID); VOID CmInitializeRegistry(VOID); VOID CmInit2(PCHAR CommandLine); VOID CmShutdownRegistry(VOID); -VOID CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize); -VOID CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize); +BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize); +BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize); VOID KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock); VOID RtlpInitNlsTables(VOID);