From 972e4a22f83f0799890c5a4ab0356513078fc8e0 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Wed, 19 Aug 2009 15:19:07 -0500 Subject: [PATCH] ole32: Allow small block chains with no property. --- dlls/ole32/stg_stream.c | 2 + dlls/ole32/storage32.c | 85 +++++++++++++++++++++++++++++++---------- dlls/ole32/storage32.h | 6 ++- 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c index 9acd4145191..f9a959d7392 100644 --- a/dlls/ole32/stg_stream.c +++ b/dlls/ole32/stg_stream.c @@ -232,6 +232,7 @@ static void StgStreamImpl_OpenBlockChain( { This->smallBlockChain = SmallBlockChainStream_Construct( This->parentStorage->ancestorStorage, + NULL, This->ownerProperty); } else @@ -591,6 +592,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize( { This->smallBlockChain = SmallBlockChainStream_Construct( This->parentStorage->ancestorStorage, + NULL, This->ownerProperty); } else diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 90eafb79c6a..d8c1d0b978a 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -4579,7 +4579,6 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This, * BlockChainStream_WriteAt * * Writes the specified number of bytes to this chain at the specified offset. - * bytesWritten may be NULL. * Will fail if not all specified number of bytes have been written. */ HRESULT BlockChainStream_WriteAt(BlockChainStream* This, @@ -4931,6 +4930,7 @@ static ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This) SmallBlockChainStream* SmallBlockChainStream_Construct( StorageImpl* parentStorage, + ULONG* headOfStreamPlaceHolder, ULONG propertyIndex) { SmallBlockChainStream* newStream; @@ -4938,6 +4938,7 @@ SmallBlockChainStream* SmallBlockChainStream_Construct( newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(SmallBlockChainStream)); newStream->parentStorage = parentStorage; + newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder; newStream->ownerPropertyIndex = propertyIndex; return newStream; @@ -4960,6 +4961,9 @@ static ULONG SmallBlockChainStream_GetHeadOfChain( StgProperty chainProperty; BOOL readSuccessful; + if (This->headOfStreamPlaceHolder != NULL) + return *(This->headOfStreamPlaceHolder); + if (This->ownerPropertyIndex) { readSuccessful = StorageImpl_ReadProperty( @@ -5322,7 +5326,6 @@ HRESULT SmallBlockChainStream_ReadAt( * SmallBlockChainStream_WriteAt * * Writes the specified number of bytes to this chain at the specified offset. - * bytesWritten may be NULL. * Will fail if not all specified number of bytes have been written. */ HRESULT SmallBlockChainStream_WriteAt( @@ -5362,9 +5365,6 @@ HRESULT SmallBlockChainStream_WriteAt( /* * Start writing the buffer. - * - * Here, I'm casting away the constness on the buffer variable - * This is OK since we don't intend to modify that buffer. */ *bytesWritten = 0; bufferWalker = buffer; @@ -5511,26 +5511,32 @@ static BOOL SmallBlockChainStream_Enlarge( blockIndex = SmallBlockChainStream_GetHeadOfChain(This); /* - * Empty chain + * Empty chain. Create the head. */ if (blockIndex == BLOCK_END_OF_CHAIN) { - - StgProperty chainProp; - - StorageImpl_ReadProperty(This->parentStorage, This->ownerPropertyIndex, - &chainProp); - - chainProp.startingBlock = SmallBlockChainStream_GetNextFreeBlock(This); - - StorageImpl_WriteProperty(This->parentStorage, This->ownerPropertyIndex, - &chainProp); - - blockIndex = chainProp.startingBlock; + blockIndex = SmallBlockChainStream_GetNextFreeBlock(This); SmallBlockChainStream_SetNextBlockInChain( - This, - blockIndex, - BLOCK_END_OF_CHAIN); + This, + blockIndex, + BLOCK_END_OF_CHAIN); + + if (This->headOfStreamPlaceHolder != NULL) + { + *(This->headOfStreamPlaceHolder) = blockIndex; + } + else + { + StgProperty chainProp; + + StorageImpl_ReadProperty(This->parentStorage, This->ownerPropertyIndex, + &chainProp); + + chainProp.startingBlock = blockIndex; + + StorageImpl_WriteProperty(This->parentStorage, This->ownerPropertyIndex, + &chainProp); + } } currentBlock = blockIndex; @@ -5605,6 +5611,32 @@ BOOL SmallBlockChainStream_SetSize( return TRUE; } +/****************************************************************************** + * SmallBlockChainStream_GetCount + * + * Returns the number of small blocks that comprises this chain. + * This is not the size of the stream as the last block may not be full! + * + */ +static ULONG SmallBlockChainStream_GetCount(SmallBlockChainStream* This) +{ + ULONG blockIndex; + ULONG count = 0; + + blockIndex = SmallBlockChainStream_GetHeadOfChain(This); + + while(blockIndex != BLOCK_END_OF_CHAIN) + { + count++; + + if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, + blockIndex, &blockIndex))) + return 0; + } + + return count; +} + /****************************************************************************** * SmallBlockChainStream_GetSize * @@ -5614,6 +5646,17 @@ static ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This) { StgProperty chainProperty; + if(This->headOfStreamPlaceHolder != NULL) + { + ULARGE_INTEGER result; + result.u.HighPart = 0; + + result.u.LowPart = SmallBlockChainStream_GetCount(This) * + This->parentStorage->smallBlockSize; + + return result; + } + StorageImpl_ReadProperty( This->parentStorage, This->ownerPropertyIndex, diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 4be0631eb7a..68a82bbdf78 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -464,14 +464,16 @@ struct SmallBlockChainStream { StorageImpl* parentStorage; ULONG ownerPropertyIndex; + ULONG* headOfStreamPlaceHolder; }; /* * Methods of the SmallBlockChainStream class. */ SmallBlockChainStream* SmallBlockChainStream_Construct( - StorageImpl* parentStorage, - ULONG propertyIndex); + StorageImpl* parentStorage, + ULONG* headOfStreamPlaceHolder, + ULONG propertyIndex); void SmallBlockChainStream_Destroy( SmallBlockChainStream* This);