DWORD at offset 0x40 in the header is the number of big blocks in the

small block depot chain.
Better failure handling.
This commit is contained in:
Huw D M Davies 2002-08-16 19:55:14 +00:00 committed by Alexandre Julliard
parent 10cd651ef3
commit 9a8fc06357
2 changed files with 153 additions and 123 deletions

View File

@ -2316,13 +2316,14 @@ HRESULT StorageImpl_Construct(
/* /*
* Create the block chain abstractions. * Create the block chain abstractions.
*/ */
This->rootBlockChain = if(!(This->rootBlockChain =
BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL); BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL)))
return STG_E_READFAULT;
This->smallBlockDepotChain = BlockChainStream_Construct( if(!(This->smallBlockDepotChain =
This, BlockChainStream_Construct(This, &This->smallBlockDepotStart,
&This->smallBlockDepotStart, PROPERTY_NULL)))
PROPERTY_NULL); return STG_E_READFAULT;
/* /*
* Write the root property * Write the root property
@ -2376,16 +2377,15 @@ HRESULT StorageImpl_Construct(
if (!readSuccessful) if (!readSuccessful)
{ {
/* TODO CLEANUP */ /* TODO CLEANUP */
return E_FAIL; return STG_E_READFAULT;
} }
/* /*
* Create the block chain abstraction for the small block root chain. * Create the block chain abstraction for the small block root chain.
*/ */
This->smallBlockRootChain = BlockChainStream_Construct( if(!(This->smallBlockRootChain =
This, BlockChainStream_Construct(This, NULL, This->rootPropertySetIndex)))
NULL, return STG_E_READFAULT;
This->rootPropertySetIndex);
return hr; return hr;
} }
@ -2726,6 +2726,7 @@ void StorageImpl_FreeBigBlock(
* Params: This - Pointer to the Storage object. * Params: This - Pointer to the Storage object.
* blockIndex - Index of the block to retrieve the chain * blockIndex - Index of the block to retrieve the chain
* for. * for.
* nextBlockIndex - receives the return value.
* *
* Returns: This method returns the index of the next block in the chain. * Returns: This method returns the index of the next block in the chain.
* It will return the constants: * It will return the constants:
@ -2740,18 +2741,26 @@ void StorageImpl_FreeBigBlock(
* *
* See Windows documentation for more details on IStorage methods. * See Windows documentation for more details on IStorage methods.
*/ */
ULONG StorageImpl_GetNextBlockInChain( HRESULT StorageImpl_GetNextBlockInChain(
StorageImpl* This, StorageImpl* This,
ULONG blockIndex) ULONG blockIndex,
ULONG* nextBlockIndex)
{ {
ULONG offsetInDepot = blockIndex * sizeof (ULONG); ULONG offsetInDepot = blockIndex * sizeof (ULONG);
ULONG depotBlockCount = offsetInDepot / This->bigBlockSize; ULONG depotBlockCount = offsetInDepot / This->bigBlockSize;
ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize; ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize;
ULONG nextBlockIndex = BLOCK_SPECIAL;
void* depotBuffer; void* depotBuffer;
ULONG depotBlockIndexPos; ULONG depotBlockIndexPos;
int index;
assert(depotBlockCount < This->bigBlockDepotCount); *nextBlockIndex = BLOCK_SPECIAL;
if(depotBlockCount >= This->bigBlockDepotCount)
{
WARN("depotBlockCount %ld, bigBlockDepotCount %ld\n", depotBlockCount,
This->bigBlockDepotCount);
return STG_E_READFAULT;
}
/* /*
* Cache the currently accessed depot block. * Cache the currently accessed depot block.
@ -2774,23 +2783,20 @@ ULONG StorageImpl_GetNextBlockInChain(
depotBuffer = StorageImpl_GetROBigBlock(This, depotBlockIndexPos); depotBuffer = StorageImpl_GetROBigBlock(This, depotBlockIndexPos);
if (depotBuffer!=0) if (!depotBuffer)
{ return STG_E_READFAULT;
int index;
for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++) for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++)
{ {
StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex); StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), nextBlockIndex);
This->blockDepotCached[index] = nextBlockIndex; This->blockDepotCached[index] = *nextBlockIndex;
} }
StorageImpl_ReleaseBigBlock(This, depotBuffer); StorageImpl_ReleaseBigBlock(This, depotBuffer);
} }
}
nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)]; *nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)];
return nextBlockIndex; return S_OK;
} }
/****************************************************************************** /******************************************************************************
@ -3039,14 +3045,11 @@ void StorageImpl_SaveFileHeader(
StorageUtl_WriteWord(headerBigBlock, 0x1a, 0x3); StorageUtl_WriteWord(headerBigBlock, 0x1a, 0x3);
StorageUtl_WriteWord(headerBigBlock, 0x1c, (WORD)-2); StorageUtl_WriteWord(headerBigBlock, 0x1c, (WORD)-2);
StorageUtl_WriteDWord(headerBigBlock, 0x38, (DWORD)0x1000); StorageUtl_WriteDWord(headerBigBlock, 0x38, (DWORD)0x1000);
StorageUtl_WriteDWord(headerBigBlock, 0x40, (DWORD)0x0001);
} }
/* /*
* Write the information to the header. * Write the information to the header.
*/ */
if (headerBigBlock!=0)
{
StorageUtl_WriteWord( StorageUtl_WriteWord(
headerBigBlock, headerBigBlock,
OFFSET_BIGBLOCKSIZEBITS, OFFSET_BIGBLOCKSIZEBITS,
@ -3072,6 +3075,12 @@ void StorageImpl_SaveFileHeader(
OFFSET_SBDEPOTSTART, OFFSET_SBDEPOTSTART,
This->smallBlockDepotStart); This->smallBlockDepotStart);
StorageUtl_WriteDWord(
headerBigBlock,
OFFSET_SBDEPOTCOUNT,
This->smallBlockDepotChain ?
BlockChainStream_GetCount(This->smallBlockDepotChain) : 0);
StorageUtl_WriteDWord( StorageUtl_WriteDWord(
headerBigBlock, headerBigBlock,
OFFSET_EXTBBDEPOTSTART, OFFSET_EXTBBDEPOTSTART,
@ -3089,7 +3098,6 @@ void StorageImpl_SaveFileHeader(
OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index), OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index),
(This->bigBlockDepotStart[index])); (This->bigBlockDepotStart[index]));
} }
}
/* /*
* Write the big block back to the file. * Write the big block back to the file.
@ -3377,7 +3385,7 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
bbTempChain = BlockChainStream_Construct(This, bbTempChain = BlockChainStream_Construct(This,
&bbHeadOfChain, &bbHeadOfChain,
PROPERTY_NULL); PROPERTY_NULL);
if(!bbTempChain) return NULL;
/* /*
* Grow the big block chain. * Grow the big block chain.
*/ */
@ -4158,9 +4166,14 @@ BlockChainStream* BlockChainStream_Construct(
newStream->numBlocks++; newStream->numBlocks++;
newStream->tailIndex = blockIndex; newStream->tailIndex = blockIndex;
blockIndex = StorageImpl_GetNextBlockInChain( if(FAILED(StorageImpl_GetNextBlockInChain(
parentStorage, parentStorage,
blockIndex); blockIndex,
&blockIndex)))
{
HeapFree(GetProcessHeap(), 0, newStream);
return NULL;
}
} }
return newStream; return newStream;
@ -4221,9 +4234,11 @@ ULONG BlockChainStream_GetCount(BlockChainStream* This)
{ {
count++; count++;
blockIndex = StorageImpl_GetNextBlockInChain( if(FAILED(StorageImpl_GetNextBlockInChain(
This->parentStorage, This->parentStorage,
blockIndex); blockIndex,
&blockIndex)))
return 0;
} }
return count; return count;
@ -4270,9 +4285,8 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This,
while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN))
{ {
blockIndex = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex)))
StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); return FALSE;
blockNoInSequence--; blockNoInSequence--;
} }
@ -4305,8 +4319,8 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This,
/* /*
* Step to the next big block. * Step to the next big block.
*/ */
blockIndex = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex)))
StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); return FALSE;
bufferWalker += bytesToReadInBuffer; bufferWalker += bytesToReadInBuffer;
size -= bytesToReadInBuffer; size -= bytesToReadInBuffer;
@ -4359,9 +4373,9 @@ BOOL BlockChainStream_WriteAt(BlockChainStream* This,
while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN))
{ {
blockIndex = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); &blockIndex)))
return FALSE;
blockNoInSequence--; blockNoInSequence--;
} }
@ -4394,9 +4408,9 @@ BOOL BlockChainStream_WriteAt(BlockChainStream* This,
/* /*
* Step to the next big block. * Step to the next big block.
*/ */
blockIndex = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); &blockIndex)))
return FALSE;
bufferWalker += bytesToWrite; bufferWalker += bytesToWrite;
size -= bytesToWrite; size -= bytesToWrite;
*bytesWritten += bytesToWrite; *bytesWritten += bytesToWrite;
@ -4439,15 +4453,16 @@ BOOL BlockChainStream_Shrink(BlockChainStream* This,
*/ */
while (count < numBlocks) while (count < numBlocks)
{ {
blockIndex = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); &blockIndex)))
return FALSE;
count++; count++;
} }
/* Get the next block before marking the new end */ /* Get the next block before marking the new end */
extraBlock = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); &extraBlock)))
return FALSE;
/* Mark the new end of chain */ /* Mark the new end of chain */
StorageImpl_SetNextBlockInChain( StorageImpl_SetNextBlockInChain(
@ -4463,9 +4478,9 @@ BOOL BlockChainStream_Shrink(BlockChainStream* This,
*/ */
while (extraBlock != BLOCK_END_OF_CHAIN) while (extraBlock != BLOCK_END_OF_CHAIN)
{ {
blockIndex = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock,
StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock); &blockIndex)))
return FALSE;
StorageImpl_FreeBigBlock(This->parentStorage, extraBlock); StorageImpl_FreeBigBlock(This->parentStorage, extraBlock);
extraBlock = blockIndex; extraBlock = blockIndex;
} }
@ -4543,8 +4558,9 @@ BOOL BlockChainStream_Enlarge(BlockChainStream* This,
This->numBlocks++; This->numBlocks++;
currentBlock = blockIndex; currentBlock = blockIndex;
blockIndex = if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock,
StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock); &blockIndex)))
return FALSE;
} }
This->tailIndex = currentBlock; This->tailIndex = currentBlock;
@ -4731,16 +4747,18 @@ ULONG SmallBlockChainStream_GetHeadOfChain(
* - BLOCK_END_OF_CHAIN: end of this chain * - BLOCK_END_OF_CHAIN: end of this chain
* - BLOCK_UNUSED: small block 'blockIndex' is free * - BLOCK_UNUSED: small block 'blockIndex' is free
*/ */
ULONG SmallBlockChainStream_GetNextBlockInChain( HRESULT SmallBlockChainStream_GetNextBlockInChain(
SmallBlockChainStream* This, SmallBlockChainStream* This,
ULONG blockIndex) ULONG blockIndex,
ULONG* nextBlockInChain)
{ {
ULARGE_INTEGER offsetOfBlockInDepot; ULARGE_INTEGER offsetOfBlockInDepot;
DWORD buffer; DWORD buffer;
ULONG nextBlockInChain = BLOCK_END_OF_CHAIN;
ULONG bytesRead; ULONG bytesRead;
BOOL success; BOOL success;
*nextBlockInChain = BLOCK_END_OF_CHAIN;
offsetOfBlockInDepot.s.HighPart = 0; offsetOfBlockInDepot.s.HighPart = 0;
offsetOfBlockInDepot.s.LowPart = blockIndex * sizeof(ULONG); offsetOfBlockInDepot.s.LowPart = blockIndex * sizeof(ULONG);
@ -4756,10 +4774,11 @@ ULONG SmallBlockChainStream_GetNextBlockInChain(
if (success) if (success)
{ {
StorageUtl_ReadDWord(&buffer, 0, &nextBlockInChain); StorageUtl_ReadDWord(&buffer, 0, nextBlockInChain);
return S_OK;
} }
return nextBlockInChain; return STG_E_READFAULT;
} }
/****************************************************************************** /******************************************************************************
@ -4864,8 +4883,7 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
while (nextBlock != BLOCK_END_OF_CHAIN) while (nextBlock != BLOCK_END_OF_CHAIN)
{ {
sbdIndex = nextBlock; sbdIndex = nextBlock;
nextBlock = StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex, &nextBlock);
StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex);
} }
newsbdIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage); newsbdIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage);
@ -5002,8 +5020,9 @@ BOOL SmallBlockChainStream_ReadAt(
while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN))
{ {
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
&blockIndex)))
return FALSE;
blockNoInSequence--; blockNoInSequence--;
} }
@ -5044,7 +5063,8 @@ BOOL SmallBlockChainStream_ReadAt(
/* /*
* Step to the next big block. * Step to the next big block.
*/ */
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
return FALSE;
bufferWalker += bytesToReadInBuffer; bufferWalker += bytesToReadInBuffer;
size -= bytesToReadInBuffer; size -= bytesToReadInBuffer;
*bytesRead += bytesToReadInBuffer; *bytesRead += bytesToReadInBuffer;
@ -5090,8 +5110,8 @@ BOOL SmallBlockChainStream_WriteAt(
while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN))
{ {
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
return FALSE;
blockNoInSequence--; blockNoInSequence--;
} }
@ -5134,7 +5154,9 @@ BOOL SmallBlockChainStream_WriteAt(
/* /*
* Step to the next big block. * Step to the next big block.
*/ */
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
&blockIndex)))
return FALSE;
bufferWalker += bytesToWriteInBuffer; bufferWalker += bytesToWriteInBuffer;
size -= bytesToWriteInBuffer; size -= bytesToWriteInBuffer;
*bytesWritten += bytesToWriteInBuffer; *bytesWritten += bytesToWriteInBuffer;
@ -5169,7 +5191,9 @@ BOOL SmallBlockChainStream_Shrink(
*/ */
while (count < numBlocks) while (count < numBlocks)
{ {
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
&blockIndex)))
return FALSE;
count++; count++;
} }
@ -5199,7 +5223,9 @@ BOOL SmallBlockChainStream_Shrink(
else else
{ {
/* Get the next block before marking the new end */ /* Get the next block before marking the new end */
extraBlock = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
&extraBlock)))
return FALSE;
/* Mark the new end of chain */ /* Mark the new end of chain */
SmallBlockChainStream_SetNextBlockInChain( SmallBlockChainStream_SetNextBlockInChain(
@ -5213,7 +5239,9 @@ BOOL SmallBlockChainStream_Shrink(
*/ */
while (extraBlock != BLOCK_END_OF_CHAIN) while (extraBlock != BLOCK_END_OF_CHAIN)
{ {
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, extraBlock); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, extraBlock,
&blockIndex)))
return FALSE;
SmallBlockChainStream_FreeBlock(This, extraBlock); SmallBlockChainStream_FreeBlock(This, extraBlock);
extraBlock = blockIndex; extraBlock = blockIndex;
} }
@ -5276,7 +5304,8 @@ BOOL SmallBlockChainStream_Enlarge(
{ {
oldNumBlocks++; oldNumBlocks++;
currentBlock = blockIndex; currentBlock = blockIndex;
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, currentBlock); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, currentBlock, &blockIndex)))
return FALSE;
} }
/* /*
@ -5316,7 +5345,8 @@ ULONG SmallBlockChainStream_GetCount(SmallBlockChainStream* This)
{ {
count++; count++;
blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
return 0;
} }
return count; return count;

View File

@ -42,6 +42,7 @@ static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020;
static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C; static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C;
static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030; static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030;
static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C; static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C;
static const ULONG OFFSET_SBDEPOTCOUNT = 0x00000040;
static const ULONG OFFSET_EXTBBDEPOTSTART = 0x00000044; static const ULONG OFFSET_EXTBBDEPOTSTART = 0x00000044;
static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048; static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048;
static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C; static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C;
@ -442,9 +443,10 @@ void StorageImpl_FreeBigBlock(
StorageImpl* This, StorageImpl* This,
ULONG blockIndex); ULONG blockIndex);
ULONG StorageImpl_GetNextBlockInChain( HRESULT StorageImpl_GetNextBlockInChain(
StorageImpl* This, StorageImpl* This,
ULONG blockIndex); ULONG blockIndex,
ULONG* nextBlockIndex);
void StorageImpl_SetNextBlockInChain( void StorageImpl_SetNextBlockInChain(
StorageImpl* This, StorageImpl* This,
@ -843,9 +845,10 @@ void SmallBlockChainStream_Destroy(
ULONG SmallBlockChainStream_GetHeadOfChain( ULONG SmallBlockChainStream_GetHeadOfChain(
SmallBlockChainStream* This); SmallBlockChainStream* This);
ULONG SmallBlockChainStream_GetNextBlockInChain( HRESULT SmallBlockChainStream_GetNextBlockInChain(
SmallBlockChainStream* This, SmallBlockChainStream* This,
ULONG blockIndex); ULONG blockIndex,
ULONG* nextBlockIndex);
void SmallBlockChainStream_SetNextBlockInChain( void SmallBlockChainStream_SetNextBlockInChain(
SmallBlockChainStream* This, SmallBlockChainStream* This,
@ -885,6 +888,3 @@ ULONG SmallBlockChainStream_GetCount(
#endif /* __STORAGE32_H__ */ #endif /* __STORAGE32_H__ */