From 9a8fc06357f7a761375bfe51b65ad6e87cebfe51 Mon Sep 17 00:00:00 2001 From: Huw D M Davies Date: Fri, 16 Aug 2002 19:55:14 +0000 Subject: [PATCH] DWORD at offset 0x40 in the header is the number of big blocks in the small block depot chain. Better failure handling. --- dlls/ole32/storage32.c | 260 +++++++++++++++++++++++------------------ dlls/ole32/storage32.h | 16 +-- 2 files changed, 153 insertions(+), 123 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 2e35ed25f32..abf8c32adec 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2316,13 +2316,14 @@ HRESULT StorageImpl_Construct( /* * Create the block chain abstractions. */ - This->rootBlockChain = - BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL); + if(!(This->rootBlockChain = + BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL))) + return STG_E_READFAULT; - This->smallBlockDepotChain = BlockChainStream_Construct( - This, - &This->smallBlockDepotStart, - PROPERTY_NULL); + if(!(This->smallBlockDepotChain = + BlockChainStream_Construct(This, &This->smallBlockDepotStart, + PROPERTY_NULL))) + return STG_E_READFAULT; /* * Write the root property @@ -2376,16 +2377,15 @@ HRESULT StorageImpl_Construct( if (!readSuccessful) { /* TODO CLEANUP */ - return E_FAIL; + return STG_E_READFAULT; } /* * Create the block chain abstraction for the small block root chain. */ - This->smallBlockRootChain = BlockChainStream_Construct( - This, - NULL, - This->rootPropertySetIndex); + if(!(This->smallBlockRootChain = + BlockChainStream_Construct(This, NULL, This->rootPropertySetIndex))) + return STG_E_READFAULT; return hr; } @@ -2726,6 +2726,7 @@ void StorageImpl_FreeBigBlock( * Params: This - Pointer to the Storage object. * blockIndex - Index of the block to retrieve the chain * for. + * nextBlockIndex - receives the return value. * * Returns: This method returns the index of the next block in the chain. * It will return the constants: @@ -2740,18 +2741,26 @@ void StorageImpl_FreeBigBlock( * * See Windows documentation for more details on IStorage methods. */ -ULONG StorageImpl_GetNextBlockInChain( +HRESULT StorageImpl_GetNextBlockInChain( StorageImpl* This, - ULONG blockIndex) + ULONG blockIndex, + ULONG* nextBlockIndex) { ULONG offsetInDepot = blockIndex * sizeof (ULONG); ULONG depotBlockCount = offsetInDepot / This->bigBlockSize; ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize; - ULONG nextBlockIndex = BLOCK_SPECIAL; void* depotBuffer; 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. @@ -2774,23 +2783,20 @@ ULONG StorageImpl_GetNextBlockInChain( depotBuffer = StorageImpl_GetROBigBlock(This, depotBlockIndexPos); - if (depotBuffer!=0) + if (!depotBuffer) + return STG_E_READFAULT; + + for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++) { - int index; - - for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++) - { - StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex); - This->blockDepotCached[index] = nextBlockIndex; - } - - StorageImpl_ReleaseBigBlock(This, depotBuffer); + StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), nextBlockIndex); + This->blockDepotCached[index] = *nextBlockIndex; } + StorageImpl_ReleaseBigBlock(This, depotBuffer); } - nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)]; + *nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)]; - return nextBlockIndex; + return S_OK; } /****************************************************************************** @@ -3039,56 +3045,58 @@ void StorageImpl_SaveFileHeader( StorageUtl_WriteWord(headerBigBlock, 0x1a, 0x3); StorageUtl_WriteWord(headerBigBlock, 0x1c, (WORD)-2); StorageUtl_WriteDWord(headerBigBlock, 0x38, (DWORD)0x1000); - StorageUtl_WriteDWord(headerBigBlock, 0x40, (DWORD)0x0001); } /* * Write the information to the header. */ - if (headerBigBlock!=0) + StorageUtl_WriteWord( + headerBigBlock, + OFFSET_BIGBLOCKSIZEBITS, + This->bigBlockSizeBits); + + StorageUtl_WriteWord( + headerBigBlock, + OFFSET_SMALLBLOCKSIZEBITS, + This->smallBlockSizeBits); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_BBDEPOTCOUNT, + This->bigBlockDepotCount); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_ROOTSTARTBLOCK, + This->rootStartBlock); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_SBDEPOTSTART, + This->smallBlockDepotStart); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_SBDEPOTCOUNT, + This->smallBlockDepotChain ? + BlockChainStream_GetCount(This->smallBlockDepotChain) : 0); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_EXTBBDEPOTSTART, + This->extBigBlockDepotStart); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_EXTBBDEPOTCOUNT, + This->extBigBlockDepotCount); + + for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++) { - StorageUtl_WriteWord( - headerBigBlock, - OFFSET_BIGBLOCKSIZEBITS, - This->bigBlockSizeBits); - - StorageUtl_WriteWord( - headerBigBlock, - OFFSET_SMALLBLOCKSIZEBITS, - This->smallBlockSizeBits); - StorageUtl_WriteDWord( headerBigBlock, - OFFSET_BBDEPOTCOUNT, - This->bigBlockDepotCount); - - StorageUtl_WriteDWord( - headerBigBlock, - OFFSET_ROOTSTARTBLOCK, - This->rootStartBlock); - - StorageUtl_WriteDWord( - headerBigBlock, - OFFSET_SBDEPOTSTART, - This->smallBlockDepotStart); - - StorageUtl_WriteDWord( - headerBigBlock, - OFFSET_EXTBBDEPOTSTART, - This->extBigBlockDepotStart); - - StorageUtl_WriteDWord( - headerBigBlock, - OFFSET_EXTBBDEPOTCOUNT, - This->extBigBlockDepotCount); - - for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++) - { - StorageUtl_WriteDWord( - headerBigBlock, - OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index), - (This->bigBlockDepotStart[index])); - } + OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index), + (This->bigBlockDepotStart[index])); } /* @@ -3377,7 +3385,7 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( bbTempChain = BlockChainStream_Construct(This, &bbHeadOfChain, PROPERTY_NULL); - + if(!bbTempChain) return NULL; /* * Grow the big block chain. */ @@ -4158,9 +4166,14 @@ BlockChainStream* BlockChainStream_Construct( newStream->numBlocks++; newStream->tailIndex = blockIndex; - blockIndex = StorageImpl_GetNextBlockInChain( - parentStorage, - blockIndex); + if(FAILED(StorageImpl_GetNextBlockInChain( + parentStorage, + blockIndex, + &blockIndex))) + { + HeapFree(GetProcessHeap(), 0, newStream); + return NULL; + } } return newStream; @@ -4221,9 +4234,11 @@ ULONG BlockChainStream_GetCount(BlockChainStream* This) { count++; - blockIndex = StorageImpl_GetNextBlockInChain( + if(FAILED(StorageImpl_GetNextBlockInChain( This->parentStorage, - blockIndex); + blockIndex, + &blockIndex))) + return 0; } return count; @@ -4270,9 +4285,8 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This, while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) { - blockIndex = - StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); - + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex))) + return FALSE; blockNoInSequence--; } @@ -4305,8 +4319,8 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This, /* * Step to the next big block. */ - blockIndex = - StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex))) + return FALSE; bufferWalker += bytesToReadInBuffer; size -= bytesToReadInBuffer; @@ -4359,9 +4373,9 @@ BOOL BlockChainStream_WriteAt(BlockChainStream* This, while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) { - blockIndex = - StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); - + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, + &blockIndex))) + return FALSE; blockNoInSequence--; } @@ -4394,9 +4408,9 @@ BOOL BlockChainStream_WriteAt(BlockChainStream* This, /* * Step to the next big block. */ - blockIndex = - StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); - + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, + &blockIndex))) + return FALSE; bufferWalker += bytesToWrite; size -= bytesToWrite; *bytesWritten += bytesToWrite; @@ -4439,15 +4453,16 @@ BOOL BlockChainStream_Shrink(BlockChainStream* This, */ while (count < numBlocks) { - blockIndex = - StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); - + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, + &blockIndex))) + return FALSE; count++; } /* Get the next block before marking the new end */ - extraBlock = - StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, + &extraBlock))) + return FALSE; /* Mark the new end of chain */ StorageImpl_SetNextBlockInChain( @@ -4463,9 +4478,9 @@ BOOL BlockChainStream_Shrink(BlockChainStream* This, */ while (extraBlock != BLOCK_END_OF_CHAIN) { - blockIndex = - StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock); - + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock, + &blockIndex))) + return FALSE; StorageImpl_FreeBigBlock(This->parentStorage, extraBlock); extraBlock = blockIndex; } @@ -4543,8 +4558,9 @@ BOOL BlockChainStream_Enlarge(BlockChainStream* This, This->numBlocks++; currentBlock = blockIndex; - blockIndex = - StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock); + if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock, + &blockIndex))) + return FALSE; } This->tailIndex = currentBlock; @@ -4731,16 +4747,18 @@ ULONG SmallBlockChainStream_GetHeadOfChain( * - BLOCK_END_OF_CHAIN: end of this chain * - BLOCK_UNUSED: small block 'blockIndex' is free */ -ULONG SmallBlockChainStream_GetNextBlockInChain( +HRESULT SmallBlockChainStream_GetNextBlockInChain( SmallBlockChainStream* This, - ULONG blockIndex) + ULONG blockIndex, + ULONG* nextBlockInChain) { ULARGE_INTEGER offsetOfBlockInDepot; DWORD buffer; - ULONG nextBlockInChain = BLOCK_END_OF_CHAIN; ULONG bytesRead; BOOL success; + *nextBlockInChain = BLOCK_END_OF_CHAIN; + offsetOfBlockInDepot.s.HighPart = 0; offsetOfBlockInDepot.s.LowPart = blockIndex * sizeof(ULONG); @@ -4756,10 +4774,11 @@ ULONG SmallBlockChainStream_GetNextBlockInChain( 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) { sbdIndex = nextBlock; - nextBlock = - StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex); + StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex, &nextBlock); } newsbdIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage); @@ -5002,8 +5020,9 @@ BOOL SmallBlockChainStream_ReadAt( while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) { - blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); - + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, + &blockIndex))) + return FALSE; blockNoInSequence--; } @@ -5044,7 +5063,8 @@ BOOL SmallBlockChainStream_ReadAt( /* * Step to the next big block. */ - blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex))) + return FALSE; bufferWalker += bytesToReadInBuffer; size -= bytesToReadInBuffer; *bytesRead += bytesToReadInBuffer; @@ -5090,8 +5110,8 @@ BOOL SmallBlockChainStream_WriteAt( while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) { - blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); - + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex))) + return FALSE; blockNoInSequence--; } @@ -5134,7 +5154,9 @@ BOOL SmallBlockChainStream_WriteAt( /* * Step to the next big block. */ - blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, + &blockIndex))) + return FALSE; bufferWalker += bytesToWriteInBuffer; size -= bytesToWriteInBuffer; *bytesWritten += bytesToWriteInBuffer; @@ -5169,7 +5191,9 @@ BOOL SmallBlockChainStream_Shrink( */ while (count < numBlocks) { - blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, + &blockIndex))) + return FALSE; count++; } @@ -5199,7 +5223,9 @@ BOOL SmallBlockChainStream_Shrink( else { /* 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 */ SmallBlockChainStream_SetNextBlockInChain( @@ -5213,7 +5239,9 @@ BOOL SmallBlockChainStream_Shrink( */ while (extraBlock != BLOCK_END_OF_CHAIN) { - blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, extraBlock); + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, extraBlock, + &blockIndex))) + return FALSE; SmallBlockChainStream_FreeBlock(This, extraBlock); extraBlock = blockIndex; } @@ -5276,7 +5304,8 @@ BOOL SmallBlockChainStream_Enlarge( { oldNumBlocks++; 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++; - blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex))) + return 0; } return count; @@ -5739,7 +5769,7 @@ HRESULT WINAPI StgOpenStorageOnILockBytes( hr = StorageImpl_Construct( newStorage, 0, - 0, + 0, plkbyt, grfMode, FALSE, diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 5e8316ce265..d5ed920d4e4 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -42,6 +42,7 @@ static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020; static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C; static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030; static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C; +static const ULONG OFFSET_SBDEPOTCOUNT = 0x00000040; static const ULONG OFFSET_EXTBBDEPOTSTART = 0x00000044; static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048; static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C; @@ -442,14 +443,15 @@ void StorageImpl_FreeBigBlock( StorageImpl* This, ULONG blockIndex); -ULONG StorageImpl_GetNextBlockInChain( +HRESULT StorageImpl_GetNextBlockInChain( StorageImpl* This, - ULONG blockIndex); + ULONG blockIndex, + ULONG* nextBlockIndex); void StorageImpl_SetNextBlockInChain( StorageImpl* This, ULONG blockIndex, - ULONG nextBlock); + ULONG nextBlock); HRESULT StorageImpl_LoadFileHeader( StorageImpl* This); @@ -843,9 +845,10 @@ void SmallBlockChainStream_Destroy( ULONG SmallBlockChainStream_GetHeadOfChain( SmallBlockChainStream* This); -ULONG SmallBlockChainStream_GetNextBlockInChain( +HRESULT SmallBlockChainStream_GetNextBlockInChain( SmallBlockChainStream* This, - ULONG blockIndex); + ULONG blockIndex, + ULONG* nextBlockIndex); void SmallBlockChainStream_SetNextBlockInChain( SmallBlockChainStream* This, @@ -885,6 +888,3 @@ ULONG SmallBlockChainStream_GetCount( #endif /* __STORAGE32_H__ */ - - -