Support multi-block bins.

svn path=/trunk/; revision=9337
This commit is contained in:
Eric Kohl 2004-05-09 14:50:09 +00:00
parent f760135f5d
commit c2f0a2f385
2 changed files with 88 additions and 69 deletions

View file

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

View file

@ -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);
}
}