Added support for larger files.
This commit is contained in:
parent
3da9ff32ff
commit
6d2e1735f9
376
ole/storage32.c
376
ole/storage32.c
|
@ -1916,12 +1916,17 @@ HRESULT Storage32Impl_Construct(
|
||||||
Storage32Impl_ReleaseBigBlock(This, bigBlockBuffer);
|
Storage32Impl_ReleaseBigBlock(This, bigBlockBuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Load the header for the file.
|
* Load the header for the file.
|
||||||
*/
|
*/
|
||||||
Storage32Impl_LoadFileHeader(This);
|
Storage32Impl_LoadFileHeader(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is no block depot cached yet.
|
||||||
|
*/
|
||||||
|
This->indexBlockDepotCached = 0xFFFFFFFF;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the block chain abstractions.
|
* Create the block chain abstractions.
|
||||||
|
@ -2017,8 +2022,6 @@ void Storage32Impl_Destroy(
|
||||||
* Returns the index of the next free big block.
|
* Returns the index of the next free big block.
|
||||||
* If the big block depot is filled, this method will enlarge it.
|
* If the big block depot is filled, this method will enlarge it.
|
||||||
*
|
*
|
||||||
* TODO: Handle the case when the big block depot becomes bigger
|
|
||||||
* than COUNT_BBDEPOTINHEADER.
|
|
||||||
*/
|
*/
|
||||||
ULONG Storage32Impl_GetNextFreeBigBlock(
|
ULONG Storage32Impl_GetNextFreeBigBlock(
|
||||||
Storage32Impl* This)
|
Storage32Impl* This)
|
||||||
|
@ -2034,41 +2037,84 @@ ULONG Storage32Impl_GetNextFreeBigBlock(
|
||||||
/*
|
/*
|
||||||
* Scan the entire big block depot until we find a block marked free
|
* Scan the entire big block depot until we find a block marked free
|
||||||
*/
|
*/
|
||||||
while ( (depotIndex < COUNT_BBDEPOTINHEADER) &&
|
while (nextBlockIndex != BLOCK_UNUSED)
|
||||||
(nextBlockIndex != BLOCK_UNUSED))
|
|
||||||
{
|
{
|
||||||
depotBlockIndexPos = This->bigBlockDepotStart[depotIndex];
|
if (depotIndex < COUNT_BBDEPOTINHEADER)
|
||||||
|
|
||||||
if (depotBlockIndexPos == BLOCK_UNUSED)
|
|
||||||
{
|
{
|
||||||
|
depotBlockIndexPos = This->bigBlockDepotStart[depotIndex];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No more space in the big block depot, we have to enlarge it
|
* Grow the primary depot.
|
||||||
*/
|
*/
|
||||||
depotBlockIndexPos = depotIndex*blocksPerDepot;
|
if (depotBlockIndexPos == BLOCK_UNUSED)
|
||||||
depotBuffer = Storage32Impl_GetBigBlock(This, depotBlockIndexPos);
|
|
||||||
|
|
||||||
depotBlockOffset = 0;
|
|
||||||
|
|
||||||
/* mark this block as being part of the big block depot
|
|
||||||
*/
|
|
||||||
StorageUtl_WriteDWord(depotBuffer, depotBlockOffset, BLOCK_SPECIAL);
|
|
||||||
depotBlockOffset += sizeof(ULONG);
|
|
||||||
|
|
||||||
/* initialize blocks as free
|
|
||||||
*/
|
|
||||||
while ((depotBlockOffset < blocksPerDepot))
|
|
||||||
{
|
{
|
||||||
StorageUtl_WriteDWord(depotBuffer, depotBlockOffset, BLOCK_UNUSED);
|
depotBlockIndexPos = depotIndex*blocksPerDepot;
|
||||||
depotBlockOffset += sizeof(ULONG);
|
|
||||||
|
/*
|
||||||
|
* Add a block depot.
|
||||||
|
*/
|
||||||
|
Storage32Impl_AddBlockDepot(This, depotBlockIndexPos);
|
||||||
|
This->bigBlockDepotCount++;
|
||||||
|
This->bigBlockDepotStart[depotIndex] = depotBlockIndexPos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag it as a block depot.
|
||||||
|
*/
|
||||||
|
Storage32Impl_SetNextBlockInChain(This,
|
||||||
|
depotBlockIndexPos,
|
||||||
|
BLOCK_SPECIAL);
|
||||||
|
|
||||||
|
/* Save new header information.
|
||||||
|
*/
|
||||||
|
Storage32Impl_SaveFileHeader(This);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
depotBlockIndexPos = Storage32Impl_GetExtDepotBlock(This, depotIndex);
|
||||||
|
|
||||||
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
if (depotBlockIndexPos == BLOCK_UNUSED)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Grow the extended depot.
|
||||||
|
*/
|
||||||
|
ULONG extIndex = BLOCK_UNUSED;
|
||||||
|
ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER;
|
||||||
|
ULONG extBlockOffset = numExtBlocks % (blocksPerDepot - 1);
|
||||||
|
|
||||||
/* Save the information to the file header
|
if (extBlockOffset == 0)
|
||||||
*/
|
{
|
||||||
This->bigBlockDepotStart[depotIndex] = depotBlockIndexPos;
|
/* We need an extended block.
|
||||||
This->bigBlockDepotCount++;
|
*/
|
||||||
Storage32Impl_SaveFileHeader(This);
|
extIndex = Storage32Impl_AddExtBlockDepot(This);
|
||||||
|
This->extBigBlockDepotCount++;
|
||||||
|
depotBlockIndexPos = extIndex + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
depotBlockIndexPos = depotIndex * blocksPerDepot;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a block depot and mark it in the extended block.
|
||||||
|
*/
|
||||||
|
Storage32Impl_AddBlockDepot(This, depotBlockIndexPos);
|
||||||
|
This->bigBlockDepotCount++;
|
||||||
|
Storage32Impl_SetExtDepotBlock(This, depotIndex, depotBlockIndexPos);
|
||||||
|
|
||||||
|
/* Flag the block depot.
|
||||||
|
*/
|
||||||
|
Storage32Impl_SetNextBlockInChain(This,
|
||||||
|
depotBlockIndexPos,
|
||||||
|
BLOCK_SPECIAL);
|
||||||
|
|
||||||
|
/* If necessary, flag the extended depot block.
|
||||||
|
*/
|
||||||
|
if (extIndex != BLOCK_UNUSED)
|
||||||
|
Storage32Impl_SetNextBlockInChain(This, extIndex, BLOCK_EXTBBDEPOT);
|
||||||
|
|
||||||
|
/* Save header information.
|
||||||
|
*/
|
||||||
|
Storage32Impl_SaveFileHeader(This);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
depotBuffer = Storage32Impl_GetROBigBlock(This, depotBlockIndexPos);
|
depotBuffer = Storage32Impl_GetROBigBlock(This, depotBlockIndexPos);
|
||||||
|
@ -2097,6 +2143,168 @@ ULONG Storage32Impl_GetNextFreeBigBlock(
|
||||||
return blockNoInSequence;
|
return blockNoInSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Storage32Impl_AddBlockDepot
|
||||||
|
*
|
||||||
|
* This will create a depot block, essentially it is a block initialized
|
||||||
|
* to BLOCK_UNUSEDs.
|
||||||
|
*/
|
||||||
|
void Storage32Impl_AddBlockDepot(Storage32Impl* This, ULONG blockIndex)
|
||||||
|
{
|
||||||
|
BYTE* blockBuffer;
|
||||||
|
|
||||||
|
blockBuffer = Storage32Impl_GetBigBlock(This, blockIndex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize blocks as free
|
||||||
|
*/
|
||||||
|
memset(blockBuffer, BLOCK_UNUSED, This->bigBlockSize);
|
||||||
|
|
||||||
|
Storage32Impl_ReleaseBigBlock(This, blockBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Storage32Impl_GetExtDepotBlock
|
||||||
|
*
|
||||||
|
* Returns the index of the block that corresponds to the specified depot
|
||||||
|
* index. This method is only for depot indexes equal or greater than
|
||||||
|
* COUNT_BBDEPOTINHEADER.
|
||||||
|
*/
|
||||||
|
ULONG Storage32Impl_GetExtDepotBlock(Storage32Impl* This, ULONG depotIndex)
|
||||||
|
{
|
||||||
|
ULONG depotBlocksPerExtBlock = (This->bigBlockSize / sizeof(ULONG)) - 1;
|
||||||
|
ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER;
|
||||||
|
ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock;
|
||||||
|
ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock;
|
||||||
|
ULONG blockIndex = BLOCK_UNUSED;
|
||||||
|
ULONG extBlockIndex = This->extBigBlockDepotStart;
|
||||||
|
|
||||||
|
assert(depotIndex >= COUNT_BBDEPOTINHEADER);
|
||||||
|
|
||||||
|
if (This->extBigBlockDepotStart == BLOCK_END_OF_CHAIN)
|
||||||
|
return BLOCK_UNUSED;
|
||||||
|
|
||||||
|
while (extBlockCount > 0)
|
||||||
|
{
|
||||||
|
extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex);
|
||||||
|
extBlockCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extBlockIndex != BLOCK_UNUSED)
|
||||||
|
{
|
||||||
|
BYTE* depotBuffer;
|
||||||
|
|
||||||
|
depotBuffer = Storage32Impl_GetROBigBlock(This, extBlockIndex);
|
||||||
|
|
||||||
|
if (depotBuffer != 0)
|
||||||
|
{
|
||||||
|
StorageUtl_ReadDWord(depotBuffer,
|
||||||
|
extBlockOffset * sizeof(ULONG),
|
||||||
|
&blockIndex);
|
||||||
|
|
||||||
|
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Storage32Impl_SetExtDepotBlock
|
||||||
|
*
|
||||||
|
* Associates the specified block index to the specified depot index.
|
||||||
|
* This method is only for depot indexes equal or greater than
|
||||||
|
* COUNT_BBDEPOTINHEADER.
|
||||||
|
*/
|
||||||
|
void Storage32Impl_SetExtDepotBlock(Storage32Impl* This,
|
||||||
|
ULONG depotIndex,
|
||||||
|
ULONG blockIndex)
|
||||||
|
{
|
||||||
|
ULONG depotBlocksPerExtBlock = (This->bigBlockSize / sizeof(ULONG)) - 1;
|
||||||
|
ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER;
|
||||||
|
ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock;
|
||||||
|
ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock;
|
||||||
|
ULONG extBlockIndex = This->extBigBlockDepotStart;
|
||||||
|
|
||||||
|
assert(depotIndex >= COUNT_BBDEPOTINHEADER);
|
||||||
|
|
||||||
|
while (extBlockCount > 0)
|
||||||
|
{
|
||||||
|
extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex);
|
||||||
|
extBlockCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extBlockIndex != BLOCK_UNUSED)
|
||||||
|
{
|
||||||
|
BYTE* depotBuffer;
|
||||||
|
|
||||||
|
depotBuffer = Storage32Impl_GetBigBlock(This, extBlockIndex);
|
||||||
|
|
||||||
|
if (depotBuffer != 0)
|
||||||
|
{
|
||||||
|
StorageUtl_WriteDWord(depotBuffer,
|
||||||
|
extBlockOffset * sizeof(ULONG),
|
||||||
|
blockIndex);
|
||||||
|
|
||||||
|
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Storage32Impl_AddExtBlockDepot
|
||||||
|
*
|
||||||
|
* Creates an extended depot block.
|
||||||
|
*/
|
||||||
|
ULONG Storage32Impl_AddExtBlockDepot(Storage32Impl* This)
|
||||||
|
{
|
||||||
|
ULONG numExtBlocks = This->extBigBlockDepotCount;
|
||||||
|
ULONG nextExtBlock = This->extBigBlockDepotStart;
|
||||||
|
BYTE* depotBuffer = NULL;
|
||||||
|
ULONG index = BLOCK_UNUSED;
|
||||||
|
ULONG nextBlockOffset = This->bigBlockSize - sizeof(ULONG);
|
||||||
|
ULONG blocksPerDepotBlock = This->bigBlockSize / sizeof(ULONG);
|
||||||
|
ULONG depotBlocksPerExtBlock = blocksPerDepotBlock - 1;
|
||||||
|
|
||||||
|
index = (COUNT_BBDEPOTINHEADER + (numExtBlocks * depotBlocksPerExtBlock)) *
|
||||||
|
blocksPerDepotBlock;
|
||||||
|
|
||||||
|
if ((numExtBlocks == 0) && (nextExtBlock == BLOCK_END_OF_CHAIN))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The first extended block.
|
||||||
|
*/
|
||||||
|
This->extBigBlockDepotStart = index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
/*
|
||||||
|
* Follow the chain to the last one.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < (numExtBlocks - 1); i++)
|
||||||
|
{
|
||||||
|
nextExtBlock = Storage32Impl_GetNextExtendedBlock(This, nextExtBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the new extended block to the chain.
|
||||||
|
*/
|
||||||
|
depotBuffer = Storage32Impl_GetBigBlock(This, nextExtBlock);
|
||||||
|
StorageUtl_WriteDWord(depotBuffer, nextBlockOffset, index);
|
||||||
|
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize this block.
|
||||||
|
*/
|
||||||
|
depotBuffer = Storage32Impl_GetBigBlock(This, index);
|
||||||
|
memset(depotBuffer, BLOCK_UNUSED, This->bigBlockSize);
|
||||||
|
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Storage32Impl_FreeBigBlock
|
* Storage32Impl_FreeBigBlock
|
||||||
*
|
*
|
||||||
|
@ -2127,6 +2335,8 @@ void Storage32Impl_FreeBigBlock(
|
||||||
* a chain.
|
* a chain.
|
||||||
* BLOCK_UNUSED - If the block given was not past of a chain
|
* BLOCK_UNUSED - If the block given was not past of a chain
|
||||||
* and is available.
|
* and is available.
|
||||||
|
* BLOCK_EXTBBDEPOT - This block is part of the extended
|
||||||
|
* big block depot.
|
||||||
*
|
*
|
||||||
* See Windows documentation for more details on IStorage methods.
|
* See Windows documentation for more details on IStorage methods.
|
||||||
*/
|
*/
|
||||||
|
@ -2142,11 +2352,69 @@ ULONG Storage32Impl_GetNextBlockInChain(
|
||||||
ULONG depotBlockIndexPos;
|
ULONG depotBlockIndexPos;
|
||||||
|
|
||||||
assert(depotBlockCount < This->bigBlockDepotCount);
|
assert(depotBlockCount < This->bigBlockDepotCount);
|
||||||
assert(depotBlockCount < COUNT_BBDEPOTINHEADER);
|
|
||||||
|
|
||||||
depotBlockIndexPos = This->bigBlockDepotStart[depotBlockCount];
|
/*
|
||||||
|
* Cache the currently accessed depot block.
|
||||||
|
*/
|
||||||
|
if (depotBlockCount != This->indexBlockDepotCached)
|
||||||
|
{
|
||||||
|
This->indexBlockDepotCached = depotBlockCount;
|
||||||
|
|
||||||
depotBuffer = Storage32Impl_GetROBigBlock(This, depotBlockIndexPos);
|
if (depotBlockCount < COUNT_BBDEPOTINHEADER)
|
||||||
|
{
|
||||||
|
depotBlockIndexPos = This->bigBlockDepotStart[depotBlockCount];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We have to look in the extended depot.
|
||||||
|
*/
|
||||||
|
depotBlockIndexPos = Storage32Impl_GetExtDepotBlock(This, depotBlockCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
depotBuffer = Storage32Impl_GetROBigBlock(This, depotBlockIndexPos);
|
||||||
|
|
||||||
|
if (depotBuffer!=0)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++)
|
||||||
|
{
|
||||||
|
StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex);
|
||||||
|
This->blockDepotCached[index] = nextBlockIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)];
|
||||||
|
|
||||||
|
return nextBlockIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Storage32Impl_GetNextExtendedBlock
|
||||||
|
*
|
||||||
|
* Given an extended block this method will return the next extended block.
|
||||||
|
*
|
||||||
|
* NOTES:
|
||||||
|
* The last ULONG of an extended block is the block index of the next
|
||||||
|
* extended block. Extended blocks are marked as BLOCK_EXTBBDEPOT in the
|
||||||
|
* depot.
|
||||||
|
*
|
||||||
|
* Return values:
|
||||||
|
* - The index of the next extended block
|
||||||
|
* - BLOCK_UNUSED: there is no next extended block.
|
||||||
|
* - Any other return values denotes failure.
|
||||||
|
*/
|
||||||
|
ULONG Storage32Impl_GetNextExtendedBlock(Storage32Impl* This, ULONG blockIndex)
|
||||||
|
{
|
||||||
|
ULONG nextBlockIndex = BLOCK_SPECIAL;
|
||||||
|
ULONG depotBlockOffset = This->bigBlockSize - sizeof(ULONG);
|
||||||
|
void* depotBuffer;
|
||||||
|
|
||||||
|
depotBuffer = Storage32Impl_GetROBigBlock(This, blockIndex);
|
||||||
|
|
||||||
if (depotBuffer!=0)
|
if (depotBuffer!=0)
|
||||||
{
|
{
|
||||||
|
@ -2184,9 +2452,18 @@ void Storage32Impl_SetNextBlockInChain(
|
||||||
void* depotBuffer;
|
void* depotBuffer;
|
||||||
|
|
||||||
assert(depotBlockCount < This->bigBlockDepotCount);
|
assert(depotBlockCount < This->bigBlockDepotCount);
|
||||||
assert(depotBlockCount < COUNT_BBDEPOTINHEADER);
|
|
||||||
|
|
||||||
depotBlockIndexPos = This->bigBlockDepotStart[depotBlockCount];
|
if (depotBlockCount < COUNT_BBDEPOTINHEADER)
|
||||||
|
{
|
||||||
|
depotBlockIndexPos = This->bigBlockDepotStart[depotBlockCount];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We have to look in the extended depot.
|
||||||
|
*/
|
||||||
|
depotBlockIndexPos = Storage32Impl_GetExtDepotBlock(This, depotBlockCount);
|
||||||
|
}
|
||||||
|
|
||||||
depotBuffer = Storage32Impl_GetBigBlock(This, depotBlockIndexPos);
|
depotBuffer = Storage32Impl_GetBigBlock(This, depotBlockIndexPos);
|
||||||
|
|
||||||
|
@ -2196,7 +2473,13 @@ void Storage32Impl_SetNextBlockInChain(
|
||||||
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
Storage32Impl_ReleaseBigBlock(This, depotBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
/*
|
||||||
|
* Update the cached block depot, if necessary.
|
||||||
|
*/
|
||||||
|
if (depotBlockCount == This->indexBlockDepotCached)
|
||||||
|
{
|
||||||
|
This->blockDepotCached[depotBlockOffset/sizeof(ULONG)] = nextBlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -2671,7 +2954,7 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
||||||
{
|
{
|
||||||
ULONG bbHeadOfChain = BLOCK_END_OF_CHAIN;
|
ULONG bbHeadOfChain = BLOCK_END_OF_CHAIN;
|
||||||
ULARGE_INTEGER size, offset;
|
ULARGE_INTEGER size, offset;
|
||||||
ULONG cbRead, cbWritten;
|
ULONG cbRead, cbWritten, cbTotalRead, cbTotalWritten;
|
||||||
ULONG propertyIndex;
|
ULONG propertyIndex;
|
||||||
BOOL32 successRead, successWrite;
|
BOOL32 successRead, successWrite;
|
||||||
StgProperty chainProperty;
|
StgProperty chainProperty;
|
||||||
|
@ -2700,6 +2983,8 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
||||||
*/
|
*/
|
||||||
offset.LowPart = 0;
|
offset.LowPart = 0;
|
||||||
offset.HighPart = 0;
|
offset.HighPart = 0;
|
||||||
|
cbTotalRead = 0;
|
||||||
|
cbTotalWritten = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -2708,17 +2993,20 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
||||||
sizeof(buffer),
|
sizeof(buffer),
|
||||||
buffer,
|
buffer,
|
||||||
&cbRead);
|
&cbRead);
|
||||||
|
cbTotalRead += cbRead;
|
||||||
|
|
||||||
successWrite = BlockChainStream_WriteAt(bbTempChain,
|
successWrite = BlockChainStream_WriteAt(bbTempChain,
|
||||||
offset,
|
offset,
|
||||||
sizeof(buffer),
|
cbRead,
|
||||||
buffer,
|
buffer,
|
||||||
&cbWritten);
|
&cbWritten);
|
||||||
|
cbTotalWritten += cbWritten;
|
||||||
|
|
||||||
offset.LowPart += This->smallBlockSize;
|
offset.LowPart += This->smallBlockSize;
|
||||||
|
|
||||||
} while (successRead && successWrite);
|
} while (successRead && successWrite);
|
||||||
|
|
||||||
assert(cbRead == cbWritten);
|
assert(cbTotalRead == cbTotalWritten);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destroy the small block chain.
|
* Destroy the small block chain.
|
||||||
|
|
|
@ -29,7 +29,6 @@ static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C;
|
||||||
static const ULONG OFFSET_PS_NAME = 0x00000000;
|
static const ULONG OFFSET_PS_NAME = 0x00000000;
|
||||||
static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040;
|
static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040;
|
||||||
static const ULONG OFFSET_PS_PROPERTYTYPE = 0x00000042;
|
static const ULONG OFFSET_PS_PROPERTYTYPE = 0x00000042;
|
||||||
static const ULONG OFFSET_PS_BLOCKTYPE = 0x00000043;
|
|
||||||
static const ULONG OFFSET_PS_PREVIOUSPROP = 0x00000044;
|
static const ULONG OFFSET_PS_PREVIOUSPROP = 0x00000044;
|
||||||
static const ULONG OFFSET_PS_NEXTPROP = 0x00000048;
|
static const ULONG OFFSET_PS_NEXTPROP = 0x00000048;
|
||||||
static const ULONG OFFSET_PS_DIRPROP = 0x0000004C;
|
static const ULONG OFFSET_PS_DIRPROP = 0x0000004C;
|
||||||
|
@ -44,9 +43,10 @@ static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009;
|
||||||
static const WORD DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
|
static const WORD DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
|
||||||
static const WORD DEF_BIG_BLOCK_SIZE = 0x0200;
|
static const WORD DEF_BIG_BLOCK_SIZE = 0x0200;
|
||||||
static const WORD DEF_SMALL_BLOCK_SIZE = 0x0040;
|
static const WORD DEF_SMALL_BLOCK_SIZE = 0x0040;
|
||||||
static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD;
|
static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC;
|
||||||
static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
|
static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD;
|
||||||
static const ULONG BLOCK_UNUSED = 0xFFFFFFFF;
|
static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
|
||||||
|
static const ULONG BLOCK_UNUSED = 0xFFFFFFFF;
|
||||||
static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
|
static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
|
||||||
|
|
||||||
#define PROPERTY_NAME_MAX_LEN 0x20
|
#define PROPERTY_NAME_MAX_LEN 0x20
|
||||||
|
@ -76,6 +76,7 @@ static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
|
||||||
#define BIG_BLOCK_SIZE 0x200
|
#define BIG_BLOCK_SIZE 0x200
|
||||||
#define COUNT_BBDEPOTINHEADER 109
|
#define COUNT_BBDEPOTINHEADER 109
|
||||||
#define LIMIT_TO_USE_SMALL_BLOCK 0x1000
|
#define LIMIT_TO_USE_SMALL_BLOCK 0x1000
|
||||||
|
#define NUM_BLOCKS_PER_DEPOT_BLOCK 128
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are signatures to detect the type of Document file.
|
* These are signatures to detect the type of Document file.
|
||||||
|
@ -295,6 +296,9 @@ struct Storage32Impl
|
||||||
ULONG extBigBlockDepotCount;
|
ULONG extBigBlockDepotCount;
|
||||||
ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
|
ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
|
||||||
|
|
||||||
|
ULONG blockDepotCached[NUM_BLOCKS_PER_DEPOT_BLOCK];
|
||||||
|
ULONG indexBlockDepotCached;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Abstraction of the big block chains for the chains of the header.
|
* Abstraction of the big block chains for the chains of the header.
|
||||||
*/
|
*/
|
||||||
|
@ -423,6 +427,20 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
||||||
Storage32Impl* This,
|
Storage32Impl* This,
|
||||||
SmallBlockChainStream** ppsbChain);
|
SmallBlockChainStream** ppsbChain);
|
||||||
|
|
||||||
|
ULONG Storage32Impl_GetNextExtendedBlock(Storage32Impl* This,
|
||||||
|
ULONG blockIndex);
|
||||||
|
|
||||||
|
void Storage32Impl_AddBlockDepot(Storage32Impl* This,
|
||||||
|
ULONG blockIndex);
|
||||||
|
|
||||||
|
ULONG Storage32Impl_AddExtBlockDepot(Storage32Impl* This);
|
||||||
|
|
||||||
|
ULONG Storage32Impl_GetExtDepotBlock(Storage32Impl* This,
|
||||||
|
ULONG depotIndex);
|
||||||
|
|
||||||
|
void Storage32Impl_SetExtDepotBlock(Storage32Impl* This,
|
||||||
|
ULONG depotIndex,
|
||||||
|
ULONG blockIndex);
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Storage32InternalImpl definitions.
|
* Storage32InternalImpl definitions.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue