From c2f0a2f385cd7a17545ce96030a98fc8e5837c5e Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 9 May 2004 14:50:09 +0000 Subject: [PATCH] Support multi-block bins. svn path=/trunk/; revision=9337 --- freeldr/freeldr/reactos/binhive.c | 84 +++++++++++++++++-------------- reactos/tools/mkhive/binhive.c | 73 +++++++++++++++------------ 2 files changed, 88 insertions(+), 69 deletions(-) diff --git a/freeldr/freeldr/reactos/binhive.c b/freeldr/freeldr/reactos/binhive.c index 23f8b43d836..20171d3d47b 100644 --- a/freeldr/freeldr/reactos/binhive.c +++ b/freeldr/freeldr/reactos/binhive.c @@ -94,16 +94,17 @@ typedef struct _HIVE_HEADER U32 Checksum; } __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER; -typedef struct _HBIN + +typedef struct _BIN_HEADER { /* Bin identifier "hbin" (0x6E696268) */ - U32 BlockId; + U32 HeaderId; - /* Block offset of this bin */ - BLOCK_OFFSET BlockOffset; + /* Bin offset */ + BLOCK_OFFSET BinOffset; /* Size in bytes, multiple of the block size (4KB) */ - U32 BlockSize; + U32 BinSize; /* ? */ U32 Unused1; @@ -318,9 +319,9 @@ CmiCreateDefaultBinCell (PHBIN BinCell) { assert(BinCell); memset (BinCell, 0, REG_BLOCK_SIZE); - BinCell->BlockId = REG_BIN_ID; + BinCell->HeaderId = REG_BIN_ID; BinCell->DateModified = 0ULL; - BinCell->BlockSize = REG_BLOCK_SIZE; + BinCell->BinSize = REG_BLOCK_SIZE; } @@ -424,7 +425,7 @@ CmiCreateHive (PCHAR KeyName) /* Init first bin */ BinCell = (PHBIN)Hive->BlockList[0]; CmiCreateDefaultBinCell(BinCell); - BinCell->BlockOffset = 0; + BinCell->BinOffset = 0; /* Init root key cell */ RootKeyCell = (PKEY_CELL)((U32)BinCell + REG_HBIN_DATA_OFFSET); @@ -496,8 +497,8 @@ CmiMergeFree(PREGISTRY_HIVE RegistryHive, DbgPrint((DPRINT_REGISTRY, "Bin %p\n", Bin)); - BinOffset = Bin->BlockOffset; - BinSize = Bin->BlockSize; + BinOffset = Bin->BinOffset; + BinSize = Bin->BinSize; DbgPrint((DPRINT_REGISTRY, "Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize)); for (i = 0; i < RegistryHive->FreeListSize; i++) @@ -674,45 +675,51 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive, static BOOL CmiAddBin(PREGISTRY_HIVE RegistryHive, + U32 BlockCount, PVOID *NewBlock, PBLOCK_OFFSET NewBlockOffset) { PCELL_HEADER tmpBlock; - PHBIN * tmpBlockList; + PHBIN *BlockList; PHBIN tmpBin; + U32 BinSize; + U32 i; - tmpBin = AllocateMbMemory (REG_BLOCK_SIZE); + BinSize = BlockCount * REG_BLOCK_SIZE; + tmpBin = AllocateMbMemory (BinSize); if (tmpBin == NULL) { return FALSE; } - memset (tmpBin, 0, REG_BLOCK_SIZE); + memset (tmpBin, 0, BinSize); - tmpBin->BlockId = REG_BIN_ID; - tmpBin->BlockOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; - RegistryHive->FileSize += REG_BLOCK_SIZE; - tmpBin->BlockSize = REG_BLOCK_SIZE; + tmpBin->HeaderId = REG_BIN_ID; + tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; + RegistryHive->FileSize += BinSize; + tmpBin->BinSize = BinSize; tmpBin->Unused1 = 0; tmpBin->DateModified = 0ULL; tmpBin->Unused2 = 0; /* Increase size of list of blocks */ - tmpBlockList = MmAllocateMemory (sizeof(PHBIN) * (RegistryHive->BlockListSize + 1)); - if (tmpBlockList == NULL) + BlockList = MmAllocateMemory (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount)); + if (BlockList == NULL) { return FALSE; } if (RegistryHive->BlockListSize > 0) { - memcpy (tmpBlockList, + memcpy (BlockList, RegistryHive->BlockList, sizeof(PHBIN) * RegistryHive->BlockListSize); MmFreeMemory (RegistryHive->BlockList); } - RegistryHive->BlockList = tmpBlockList; - RegistryHive->BlockList[RegistryHive->BlockListSize++] = tmpBin; + RegistryHive->BlockList = BlockList; + for (i = 0; i < BlockCount; i++) + RegistryHive->BlockList[RegistryHive->BlockListSize + i] = tmpBin; + RegistryHive->BlockListSize += BlockCount; /* Initialize a free block in this heap : */ tmpBlock = (PCELL_HEADER)((U32) tmpBin + REG_HBIN_DATA_OFFSET); @@ -721,7 +728,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, *NewBlock = (PVOID) tmpBlock; if (NewBlockOffset) - *NewBlockOffset = tmpBin->BlockOffset + REG_HBIN_DATA_OFFSET; + *NewBlockOffset = tmpBin->BinOffset + REG_HBIN_DATA_OFFSET; return TRUE; } @@ -729,7 +736,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, static BOOL CmiAllocateCell (PREGISTRY_HIVE RegistryHive, - S32 BlockSize, + S32 CellSize, PVOID *Block, PBLOCK_OFFSET pBlockOffset) { @@ -739,13 +746,13 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive, *Block = NULL; /* Round to 16 bytes multiple */ - BlockSize = ROUND_UP(BlockSize, 16); + CellSize = ROUND_UP(CellSize, 16); /* first search in free blocks */ NewBlock = NULL; for (i = 0; i < RegistryHive->FreeListSize; i++) { - if (RegistryHive->FreeList[i]->CellSize >= BlockSize) + if (RegistryHive->FreeList[i]->CellSize >= CellSize) { NewBlock = RegistryHive->FreeList[i]; if (pBlockOffset) @@ -767,33 +774,36 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive, } } - /* Need to extend hive file : */ + /* Need to extend hive file */ if (NewBlock == NULL) { /* Add a new block */ - if (!CmiAddBin(RegistryHive, (PVOID *)&NewBlock , pBlockOffset)) + if (!CmiAddBin(RegistryHive, + ((sizeof(HBIN) + CellSize - 1) / REG_BLOCK_SIZE) + 1, + (PVOID *)&NewBlock, + pBlockOffset)) return FALSE; } *Block = NewBlock; /* Split the block in two parts */ - if (NewBlock->CellSize > BlockSize) + if (NewBlock->CellSize > CellSize) { - NewBlock = (PCELL_HEADER) ((U32) NewBlock+BlockSize); - NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; + NewBlock = (PCELL_HEADER) ((U32)NewBlock + CellSize); + NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize; CmiAddFree (RegistryHive, NewBlock, - *pBlockOffset + BlockSize, + *pBlockOffset + CellSize, TRUE); } - else if (NewBlock->CellSize < BlockSize) + else if (NewBlock->CellSize < CellSize) { return FALSE; } - memset(*Block, 0, BlockSize); - ((PCELL_HEADER)(*Block))->CellSize = -BlockSize; + memset(*Block, 0, CellSize); + ((PCELL_HEADER)(*Block))->CellSize = -CellSize; return TRUE; } @@ -817,7 +827,7 @@ CmiGetCell (PREGISTRY_HIVE Hive, if (Bin == NULL) return NULL; - return (PVOID)((U32)Bin + (BlockOffset - Bin->BlockOffset)); + return (PVOID)((U32)Bin + (BlockOffset - Bin->BinOffset)); } @@ -1561,7 +1571,7 @@ RegImportBinaryHive(PCHAR ChunkBase, RootBin = (PHBIN)((U32)HiveHeader + REG_BLOCK_SIZE); DbgPrint((DPRINT_REGISTRY, "RootBin: %x\n", RootBin)); - if (RootBin->BlockId != REG_BIN_ID || RootBin->BlockSize == 0) + if (RootBin->HeaderId != REG_BIN_ID || RootBin->BinSize == 0) { DbgPrint((DPRINT_REGISTRY, "Invalid bin id!\n")); return FALSE; diff --git a/reactos/tools/mkhive/binhive.c b/reactos/tools/mkhive/binhive.c index bf0413361d2..fd6fd63c232 100644 --- a/reactos/tools/mkhive/binhive.c +++ b/reactos/tools/mkhive/binhive.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003 ReactOS Team + * Copyright (C) 2003, 2004 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: binhive.c,v 1.9 2004/01/08 14:57:17 ekohl Exp $ +/* $Id: binhive.c,v 1.10 2004/05/09 14:50:09 ekohl Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/binhive.c @@ -110,13 +110,13 @@ typedef struct _HIVE_HEADER typedef struct _HBIN { /* Bin identifier "hbin" (0x6E696268) */ - ULONG BlockId; + ULONG HeaderId; /* Block offset of this bin */ - BLOCK_OFFSET BlockOffset; + BLOCK_OFFSET BinOffset; /* Size in bytes, multiple of the block size (4KB) */ - ULONG BlockSize; + ULONG BinSize; /* ? */ ULONG Unused1; @@ -297,9 +297,9 @@ CmiCreateDefaultBinCell(PHBIN BinCell) { assert (BinCell); memset (BinCell, 0, REG_BLOCK_SIZE); - BinCell->BlockId = REG_BIN_ID; + BinCell->HeaderId = REG_BIN_ID; BinCell->DateModified = 0ULL; - BinCell->BlockSize = REG_BLOCK_SIZE; + BinCell->BinSize = REG_BLOCK_SIZE; } @@ -409,7 +409,7 @@ CmiCreateRegistryHive (PCHAR KeyName) /* Init first bin */ BinCell = (PHBIN)Hive->BlockList[0]; CmiCreateDefaultBinCell (BinCell); - BinCell->BlockOffset = 0; + BinCell->BinOffset = 0; /* Init root key cell */ RootKeyCell = (PKEY_CELL)((ULONG_PTR)BinCell + REG_HBIN_DATA_OFFSET); @@ -498,7 +498,7 @@ CmiGetCell (PREGISTRY_HIVE Hive, if (ppBin) *ppBin = pBin; - return (PVOID)((ULONG_PTR)pBin + (BlockOffset - pBin->BlockOffset)); + return (PVOID)((ULONG_PTR)pBin + (BlockOffset - pBin->BinOffset)); } @@ -524,8 +524,8 @@ CmiMergeFree(PREGISTRY_HIVE RegistryHive, if (Bin == NULL) return FALSE; - BinOffset = Bin->BlockOffset; - BinSize = Bin->BlockSize; + BinOffset = Bin->BinOffset; + BinSize = Bin->BinSize; DPRINT("Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize); for (i = 0; i < RegistryHive->FreeListSize; i++) @@ -702,30 +702,34 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive, static BOOL CmiAddBin(PREGISTRY_HIVE RegistryHive, + ULONG BlockCount, PVOID *NewBlock, PBLOCK_OFFSET NewBlockOffset) { PCELL_HEADER tmpBlock; PHBIN * tmpBlockList; PHBIN tmpBin; + ULONG BinSize; + ULONG i; - tmpBin = malloc (REG_BLOCK_SIZE); + BinSize = BlockCount *REG_BLOCK_SIZE; + tmpBin = malloc (BinSize); if (tmpBin == NULL) { return FALSE; } - memset (tmpBin, 0, REG_BLOCK_SIZE); + memset (tmpBin, 0, BinSize); - tmpBin->BlockId = REG_BIN_ID; - tmpBin->BlockOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; - RegistryHive->FileSize += REG_BLOCK_SIZE; - tmpBin->BlockSize = REG_BLOCK_SIZE; + tmpBin->HeaderId = REG_BIN_ID; + tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; + RegistryHive->FileSize += BinSize; + tmpBin->BinSize = BinSize; tmpBin->Unused1 = 0; tmpBin->DateModified = 0ULL; tmpBin->Unused2 = 0; /* Increase size of list of blocks */ - tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + 1)); + tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount)); if (tmpBlockList == NULL) { free (tmpBin); @@ -741,7 +745,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, } RegistryHive->BlockList = tmpBlockList; - RegistryHive->BlockList[RegistryHive->BlockListSize++] = tmpBin; + for (i = 0; i < BlockCount; i++) + RegistryHive->BlockList[RegistryHive->BlockListSize + i] = tmpBin; + RegistryHive->BlockListSize += BlockCount; /* Initialize a free block in this heap : */ tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET); @@ -750,7 +756,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, *NewBlock = (PVOID) tmpBlock; if (NewBlockOffset) - *NewBlockOffset = tmpBin->BlockOffset + REG_HBIN_DATA_OFFSET; + *NewBlockOffset = tmpBin->BinOffset + REG_HBIN_DATA_OFFSET; return TRUE; } @@ -758,7 +764,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, static BOOL CmiAllocateCell (PREGISTRY_HIVE RegistryHive, - LONG BlockSize, + LONG CellSize, PVOID *Block, PBLOCK_OFFSET pBlockOffset) { @@ -768,13 +774,13 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive, *Block = NULL; /* Round to 16 bytes multiple */ - BlockSize = ROUND_UP(BlockSize, 16); + CellSize = ROUND_UP(CellSize, 16); /* first search in free blocks */ NewBlock = NULL; for (i = 0; i < RegistryHive->FreeListSize; i++) { - if (RegistryHive->FreeList[i]->CellSize >= BlockSize) + if (RegistryHive->FreeList[i]->CellSize >= CellSize) { NewBlock = RegistryHive->FreeList[i]; if (pBlockOffset) @@ -800,29 +806,32 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive, if (NewBlock == NULL) { /* Add a new block */ - if (!CmiAddBin(RegistryHive, (PVOID *)&NewBlock , pBlockOffset)) + if (!CmiAddBin(RegistryHive, + ((sizeof(HBIN) + CellSize - 1) / REG_BLOCK_SIZE) + 1, + (PVOID *)&NewBlock, + pBlockOffset)) return FALSE; } *Block = NewBlock; /* Split the block in two parts */ - if (NewBlock->CellSize > BlockSize) + if (NewBlock->CellSize > CellSize) { - NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize); - NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; + NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock + CellSize); + NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize; CmiAddFree (RegistryHive, NewBlock, - *pBlockOffset + BlockSize, + *pBlockOffset + CellSize, TRUE); } - else if (NewBlock->CellSize < BlockSize) + else if (NewBlock->CellSize < CellSize) { return FALSE; } - memset(*Block, 0, BlockSize); - ((PCELL_HEADER)(*Block))->CellSize = -BlockSize; + memset(*Block, 0, CellSize); + ((PCELL_HEADER)(*Block))->CellSize = -CellSize; return TRUE; } @@ -1369,7 +1378,7 @@ CmiWriteHive(PREGISTRY_HIVE Hive, DPRINT ("Bin[%lu]: Offset 0x%lx Size 0x%lx\n", i, Bin->BlockOffset, Bin->BlockSize); - fwrite (Bin, Bin->BlockSize, 1, File); + fwrite (Bin, Bin->BinSize, 1, File); } }