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; U32 Checksum;
} __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER; } __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
typedef struct _HBIN
typedef struct _BIN_HEADER
{ {
/* Bin identifier "hbin" (0x6E696268) */ /* Bin identifier "hbin" (0x6E696268) */
U32 BlockId; U32 HeaderId;
/* Block offset of this bin */ /* Bin offset */
BLOCK_OFFSET BlockOffset; BLOCK_OFFSET BinOffset;
/* Size in bytes, multiple of the block size (4KB) */ /* Size in bytes, multiple of the block size (4KB) */
U32 BlockSize; U32 BinSize;
/* ? */ /* ? */
U32 Unused1; U32 Unused1;
@ -318,9 +319,9 @@ CmiCreateDefaultBinCell (PHBIN BinCell)
{ {
assert(BinCell); assert(BinCell);
memset (BinCell, 0, REG_BLOCK_SIZE); memset (BinCell, 0, REG_BLOCK_SIZE);
BinCell->BlockId = REG_BIN_ID; BinCell->HeaderId = REG_BIN_ID;
BinCell->DateModified = 0ULL; BinCell->DateModified = 0ULL;
BinCell->BlockSize = REG_BLOCK_SIZE; BinCell->BinSize = REG_BLOCK_SIZE;
} }
@ -424,7 +425,7 @@ CmiCreateHive (PCHAR KeyName)
/* Init first bin */ /* Init first bin */
BinCell = (PHBIN)Hive->BlockList[0]; BinCell = (PHBIN)Hive->BlockList[0];
CmiCreateDefaultBinCell(BinCell); CmiCreateDefaultBinCell(BinCell);
BinCell->BlockOffset = 0; BinCell->BinOffset = 0;
/* Init root key cell */ /* Init root key cell */
RootKeyCell = (PKEY_CELL)((U32)BinCell + REG_HBIN_DATA_OFFSET); RootKeyCell = (PKEY_CELL)((U32)BinCell + REG_HBIN_DATA_OFFSET);
@ -496,8 +497,8 @@ CmiMergeFree(PREGISTRY_HIVE RegistryHive,
DbgPrint((DPRINT_REGISTRY, "Bin %p\n", Bin)); DbgPrint((DPRINT_REGISTRY, "Bin %p\n", Bin));
BinOffset = Bin->BlockOffset; BinOffset = Bin->BinOffset;
BinSize = Bin->BlockSize; BinSize = Bin->BinSize;
DbgPrint((DPRINT_REGISTRY, "Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize)); DbgPrint((DPRINT_REGISTRY, "Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize));
for (i = 0; i < RegistryHive->FreeListSize; i++) for (i = 0; i < RegistryHive->FreeListSize; i++)
@ -674,45 +675,51 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
static BOOL static BOOL
CmiAddBin(PREGISTRY_HIVE RegistryHive, CmiAddBin(PREGISTRY_HIVE RegistryHive,
U32 BlockCount,
PVOID *NewBlock, PVOID *NewBlock,
PBLOCK_OFFSET NewBlockOffset) PBLOCK_OFFSET NewBlockOffset)
{ {
PCELL_HEADER tmpBlock; PCELL_HEADER tmpBlock;
PHBIN * tmpBlockList; PHBIN *BlockList;
PHBIN tmpBin; PHBIN tmpBin;
U32 BinSize;
U32 i;
tmpBin = AllocateMbMemory (REG_BLOCK_SIZE); BinSize = BlockCount * REG_BLOCK_SIZE;
tmpBin = AllocateMbMemory (BinSize);
if (tmpBin == NULL) if (tmpBin == NULL)
{ {
return FALSE; return FALSE;
} }
memset (tmpBin, 0, REG_BLOCK_SIZE); memset (tmpBin, 0, BinSize);
tmpBin->BlockId = REG_BIN_ID; tmpBin->HeaderId = REG_BIN_ID;
tmpBin->BlockOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
RegistryHive->FileSize += REG_BLOCK_SIZE; RegistryHive->FileSize += BinSize;
tmpBin->BlockSize = REG_BLOCK_SIZE; tmpBin->BinSize = BinSize;
tmpBin->Unused1 = 0; tmpBin->Unused1 = 0;
tmpBin->DateModified = 0ULL; tmpBin->DateModified = 0ULL;
tmpBin->Unused2 = 0; tmpBin->Unused2 = 0;
/* Increase size of list of blocks */ /* Increase size of list of blocks */
tmpBlockList = MmAllocateMemory (sizeof(PHBIN) * (RegistryHive->BlockListSize + 1)); BlockList = MmAllocateMemory (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount));
if (tmpBlockList == NULL) if (BlockList == NULL)
{ {
return FALSE; return FALSE;
} }
if (RegistryHive->BlockListSize > 0) if (RegistryHive->BlockListSize > 0)
{ {
memcpy (tmpBlockList, memcpy (BlockList,
RegistryHive->BlockList, RegistryHive->BlockList,
sizeof(PHBIN) * RegistryHive->BlockListSize); sizeof(PHBIN) * RegistryHive->BlockListSize);
MmFreeMemory (RegistryHive->BlockList); MmFreeMemory (RegistryHive->BlockList);
} }
RegistryHive->BlockList = tmpBlockList; RegistryHive->BlockList = BlockList;
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 : */ /* Initialize a free block in this heap : */
tmpBlock = (PCELL_HEADER)((U32) tmpBin + REG_HBIN_DATA_OFFSET); tmpBlock = (PCELL_HEADER)((U32) tmpBin + REG_HBIN_DATA_OFFSET);
@ -721,7 +728,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
*NewBlock = (PVOID) tmpBlock; *NewBlock = (PVOID) tmpBlock;
if (NewBlockOffset) if (NewBlockOffset)
*NewBlockOffset = tmpBin->BlockOffset + REG_HBIN_DATA_OFFSET; *NewBlockOffset = tmpBin->BinOffset + REG_HBIN_DATA_OFFSET;
return TRUE; return TRUE;
} }
@ -729,7 +736,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
static BOOL static BOOL
CmiAllocateCell (PREGISTRY_HIVE RegistryHive, CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
S32 BlockSize, S32 CellSize,
PVOID *Block, PVOID *Block,
PBLOCK_OFFSET pBlockOffset) PBLOCK_OFFSET pBlockOffset)
{ {
@ -739,13 +746,13 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
*Block = NULL; *Block = NULL;
/* Round to 16 bytes multiple */ /* Round to 16 bytes multiple */
BlockSize = ROUND_UP(BlockSize, 16); CellSize = ROUND_UP(CellSize, 16);
/* first search in free blocks */ /* first search in free blocks */
NewBlock = NULL; NewBlock = NULL;
for (i = 0; i < RegistryHive->FreeListSize; i++) for (i = 0; i < RegistryHive->FreeListSize; i++)
{ {
if (RegistryHive->FreeList[i]->CellSize >= BlockSize) if (RegistryHive->FreeList[i]->CellSize >= CellSize)
{ {
NewBlock = RegistryHive->FreeList[i]; NewBlock = RegistryHive->FreeList[i];
if (pBlockOffset) if (pBlockOffset)
@ -767,33 +774,36 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
} }
} }
/* Need to extend hive file : */ /* Need to extend hive file */
if (NewBlock == NULL) if (NewBlock == NULL)
{ {
/* Add a new block */ /* 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; return FALSE;
} }
*Block = NewBlock; *Block = NewBlock;
/* Split the block in two parts */ /* Split the block in two parts */
if (NewBlock->CellSize > BlockSize) if (NewBlock->CellSize > CellSize)
{ {
NewBlock = (PCELL_HEADER) ((U32) NewBlock+BlockSize); NewBlock = (PCELL_HEADER) ((U32)NewBlock + CellSize);
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize;
CmiAddFree (RegistryHive, CmiAddFree (RegistryHive,
NewBlock, NewBlock,
*pBlockOffset + BlockSize, *pBlockOffset + CellSize,
TRUE); TRUE);
} }
else if (NewBlock->CellSize < BlockSize) else if (NewBlock->CellSize < CellSize)
{ {
return FALSE; return FALSE;
} }
memset(*Block, 0, BlockSize); memset(*Block, 0, CellSize);
((PCELL_HEADER)(*Block))->CellSize = -BlockSize; ((PCELL_HEADER)(*Block))->CellSize = -CellSize;
return TRUE; return TRUE;
} }
@ -817,7 +827,7 @@ CmiGetCell (PREGISTRY_HIVE Hive,
if (Bin == NULL) if (Bin == NULL)
return 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); RootBin = (PHBIN)((U32)HiveHeader + REG_BLOCK_SIZE);
DbgPrint((DPRINT_REGISTRY, "RootBin: %x\n", RootBin)); 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")); DbgPrint((DPRINT_REGISTRY, "Invalid bin id!\n"));
return FALSE; return FALSE;

View file

@ -1,6 +1,6 @@
/* /*
* ReactOS kernel * 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 * 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 * 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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS hive maker * PROJECT: ReactOS hive maker
* FILE: tools/mkhive/binhive.c * FILE: tools/mkhive/binhive.c
@ -110,13 +110,13 @@ typedef struct _HIVE_HEADER
typedef struct _HBIN typedef struct _HBIN
{ {
/* Bin identifier "hbin" (0x6E696268) */ /* Bin identifier "hbin" (0x6E696268) */
ULONG BlockId; ULONG HeaderId;
/* Block offset of this bin */ /* Block offset of this bin */
BLOCK_OFFSET BlockOffset; BLOCK_OFFSET BinOffset;
/* Size in bytes, multiple of the block size (4KB) */ /* Size in bytes, multiple of the block size (4KB) */
ULONG BlockSize; ULONG BinSize;
/* ? */ /* ? */
ULONG Unused1; ULONG Unused1;
@ -297,9 +297,9 @@ CmiCreateDefaultBinCell(PHBIN BinCell)
{ {
assert (BinCell); assert (BinCell);
memset (BinCell, 0, REG_BLOCK_SIZE); memset (BinCell, 0, REG_BLOCK_SIZE);
BinCell->BlockId = REG_BIN_ID; BinCell->HeaderId = REG_BIN_ID;
BinCell->DateModified = 0ULL; BinCell->DateModified = 0ULL;
BinCell->BlockSize = REG_BLOCK_SIZE; BinCell->BinSize = REG_BLOCK_SIZE;
} }
@ -409,7 +409,7 @@ CmiCreateRegistryHive (PCHAR KeyName)
/* Init first bin */ /* Init first bin */
BinCell = (PHBIN)Hive->BlockList[0]; BinCell = (PHBIN)Hive->BlockList[0];
CmiCreateDefaultBinCell (BinCell); CmiCreateDefaultBinCell (BinCell);
BinCell->BlockOffset = 0; BinCell->BinOffset = 0;
/* Init root key cell */ /* Init root key cell */
RootKeyCell = (PKEY_CELL)((ULONG_PTR)BinCell + REG_HBIN_DATA_OFFSET); RootKeyCell = (PKEY_CELL)((ULONG_PTR)BinCell + REG_HBIN_DATA_OFFSET);
@ -498,7 +498,7 @@ CmiGetCell (PREGISTRY_HIVE Hive,
if (ppBin) if (ppBin)
*ppBin = pBin; *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) if (Bin == NULL)
return FALSE; return FALSE;
BinOffset = Bin->BlockOffset; BinOffset = Bin->BinOffset;
BinSize = Bin->BlockSize; BinSize = Bin->BinSize;
DPRINT("Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize); DPRINT("Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize);
for (i = 0; i < RegistryHive->FreeListSize; i++) for (i = 0; i < RegistryHive->FreeListSize; i++)
@ -702,30 +702,34 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
static BOOL static BOOL
CmiAddBin(PREGISTRY_HIVE RegistryHive, CmiAddBin(PREGISTRY_HIVE RegistryHive,
ULONG BlockCount,
PVOID *NewBlock, PVOID *NewBlock,
PBLOCK_OFFSET NewBlockOffset) PBLOCK_OFFSET NewBlockOffset)
{ {
PCELL_HEADER tmpBlock; PCELL_HEADER tmpBlock;
PHBIN * tmpBlockList; PHBIN * tmpBlockList;
PHBIN tmpBin; PHBIN tmpBin;
ULONG BinSize;
ULONG i;
tmpBin = malloc (REG_BLOCK_SIZE); BinSize = BlockCount *REG_BLOCK_SIZE;
tmpBin = malloc (BinSize);
if (tmpBin == NULL) if (tmpBin == NULL)
{ {
return FALSE; return FALSE;
} }
memset (tmpBin, 0, REG_BLOCK_SIZE); memset (tmpBin, 0, BinSize);
tmpBin->BlockId = REG_BIN_ID; tmpBin->HeaderId = REG_BIN_ID;
tmpBin->BlockOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
RegistryHive->FileSize += REG_BLOCK_SIZE; RegistryHive->FileSize += BinSize;
tmpBin->BlockSize = REG_BLOCK_SIZE; tmpBin->BinSize = BinSize;
tmpBin->Unused1 = 0; tmpBin->Unused1 = 0;
tmpBin->DateModified = 0ULL; tmpBin->DateModified = 0ULL;
tmpBin->Unused2 = 0; tmpBin->Unused2 = 0;
/* Increase size of list of blocks */ /* Increase size of list of blocks */
tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + 1)); tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount));
if (tmpBlockList == NULL) if (tmpBlockList == NULL)
{ {
free (tmpBin); free (tmpBin);
@ -741,7 +745,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
} }
RegistryHive->BlockList = tmpBlockList; 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 : */ /* 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);
@ -750,7 +756,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
*NewBlock = (PVOID) tmpBlock; *NewBlock = (PVOID) tmpBlock;
if (NewBlockOffset) if (NewBlockOffset)
*NewBlockOffset = tmpBin->BlockOffset + REG_HBIN_DATA_OFFSET; *NewBlockOffset = tmpBin->BinOffset + REG_HBIN_DATA_OFFSET;
return TRUE; return TRUE;
} }
@ -758,7 +764,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
static BOOL static BOOL
CmiAllocateCell (PREGISTRY_HIVE RegistryHive, CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
LONG BlockSize, LONG CellSize,
PVOID *Block, PVOID *Block,
PBLOCK_OFFSET pBlockOffset) PBLOCK_OFFSET pBlockOffset)
{ {
@ -768,13 +774,13 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
*Block = NULL; *Block = NULL;
/* Round to 16 bytes multiple */ /* Round to 16 bytes multiple */
BlockSize = ROUND_UP(BlockSize, 16); CellSize = ROUND_UP(CellSize, 16);
/* first search in free blocks */ /* first search in free blocks */
NewBlock = NULL; NewBlock = NULL;
for (i = 0; i < RegistryHive->FreeListSize; i++) for (i = 0; i < RegistryHive->FreeListSize; i++)
{ {
if (RegistryHive->FreeList[i]->CellSize >= BlockSize) if (RegistryHive->FreeList[i]->CellSize >= CellSize)
{ {
NewBlock = RegistryHive->FreeList[i]; NewBlock = RegistryHive->FreeList[i];
if (pBlockOffset) if (pBlockOffset)
@ -800,29 +806,32 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
if (NewBlock == NULL) if (NewBlock == NULL)
{ {
/* Add a new block */ /* 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; return FALSE;
} }
*Block = NewBlock; *Block = NewBlock;
/* Split the block in two parts */ /* Split the block in two parts */
if (NewBlock->CellSize > BlockSize) if (NewBlock->CellSize > CellSize)
{ {
NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize); NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock + CellSize);
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize;
CmiAddFree (RegistryHive, CmiAddFree (RegistryHive,
NewBlock, NewBlock,
*pBlockOffset + BlockSize, *pBlockOffset + CellSize,
TRUE); TRUE);
} }
else if (NewBlock->CellSize < BlockSize) else if (NewBlock->CellSize < CellSize)
{ {
return FALSE; return FALSE;
} }
memset(*Block, 0, BlockSize); memset(*Block, 0, CellSize);
((PCELL_HEADER)(*Block))->CellSize = -BlockSize; ((PCELL_HEADER)(*Block))->CellSize = -CellSize;
return TRUE; return TRUE;
} }
@ -1369,7 +1378,7 @@ CmiWriteHive(PREGISTRY_HIVE Hive,
DPRINT ("Bin[%lu]: Offset 0x%lx Size 0x%lx\n", DPRINT ("Bin[%lu]: Offset 0x%lx Size 0x%lx\n",
i, Bin->BlockOffset, Bin->BlockSize); i, Bin->BlockOffset, Bin->BlockSize);
fwrite (Bin, Bin->BlockSize, 1, File); fwrite (Bin, Bin->BinSize, 1, File);
} }
} }