From bc8c8c5955c908c0126457048972886bcf64a588 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 30 Nov 2009 15:40:53 -0600 Subject: [PATCH 3/5] ole32: Don't track the stream size in storage stream objects. We can't do this safely when there are multiple objects for a single stream. --- dlls/ole32/stg_stream.c | 128 ++--------------------------------------------- dlls/ole32/storage32.c | 14 ++++-- dlls/ole32/storage32.h | 16 +----- 3 files changed, 17 insertions(+), 141 deletions(-) diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c index 00a61a2..bfecbc7 100644 --- a/dlls/ole32/stg_stream.c +++ b/dlls/ole32/stg_stream.c @@ -75,21 +75,6 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This) This->parentStorage = 0; /* - * Make sure we clean-up the block chain stream objects that we were using. - */ - if (This->bigBlockChain != 0) - { - BlockChainStream_Destroy(This->bigBlockChain); - This->bigBlockChain = 0; - } - - if (This->smallBlockChain != 0) - { - SmallBlockChainStream_Destroy(This->smallBlockChain); - This->smallBlockChain = 0; - } - - /* * Finally, free the memory used-up by the class. */ HeapFree(GetProcessHeap(), 0, This); @@ -180,73 +165,6 @@ static ULONG WINAPI StgStreamImpl_Release( } /*** - * This method will open the block chain pointed by the directory entry - * that describes the stream. - * If the stream's size is null, no chain is opened. - */ -static void StgStreamImpl_OpenBlockChain( - StgStreamImpl* This) -{ - DirEntry currentEntry; - HRESULT hr; - - /* - * Make sure no old object is left over. - */ - if (This->smallBlockChain != 0) - { - SmallBlockChainStream_Destroy(This->smallBlockChain); - This->smallBlockChain = 0; - } - - if (This->bigBlockChain != 0) - { - BlockChainStream_Destroy(This->bigBlockChain); - This->bigBlockChain = 0; - } - - /* - * Read the information from the directory entry. - */ - hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, - This->dirEntry, - ¤tEntry); - - if (SUCCEEDED(hr)) - { - This->streamSize = currentEntry.size; - - /* - * This code supports only streams that are <32 bits in size. - */ - assert(This->streamSize.u.HighPart == 0); - - if(currentEntry.startingBlock == BLOCK_END_OF_CHAIN) - { - assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) ); - } - else - { - if ( (This->streamSize.u.HighPart == 0) && - (This->streamSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) - { - This->smallBlockChain = SmallBlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->dirEntry); - } - else - { - This->bigBlockChain = BlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->dirEntry); - } - } - } -} - -/*** * This method is part of the ISequentialStream interface. * * It reads a block of information from the stream at the current @@ -319,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write( { StgStreamImpl* const This=(StgStreamImpl*)iface; - ULARGE_INTEGER newSize; ULONG bytesWritten = 0; HRESULT res; @@ -365,22 +282,6 @@ static HRESULT WINAPI StgStreamImpl_Write( TRACE("<-- S_OK, written 0\n"); return S_OK; } - else - { - newSize.u.HighPart = 0; - newSize.u.LowPart = This->currentPosition.u.LowPart + cb; - } - - /* - * Verify if we need to grow the stream - */ - if (newSize.u.LowPart > This->streamSize.u.LowPart) - { - /* grow stream */ - res = IStream_SetSize(iface, newSize); - if (FAILED(res)) - return res; - } res = StorageBaseImpl_StreamWriteAt(This->parentStorage, This->dirEntry, @@ -415,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek( StgStreamImpl* const This=(StgStreamImpl*)iface; ULARGE_INTEGER newPosition; + DirEntry currentEntry; + HRESULT hr; TRACE("(%p, %d, %d, %p)\n", iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition); @@ -453,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek( *plibNewPosition = This->currentPosition; break; case STREAM_SEEK_END: - *plibNewPosition = This->streamSize; + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, ¤tEntry); + if (FAILED(hr)) return hr; + *plibNewPosition = currentEntry.size; break; default: WARN("invalid dwOrigin %d\n", dwOrigin); @@ -511,16 +416,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize( return STG_E_ACCESSDENIED; } - if (This->streamSize.u.LowPart == libNewSize.u.LowPart) - return S_OK; - hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize); - - if (SUCCEEDED(hr)) - { - This->streamSize = libNewSize; - } - return hr; } @@ -853,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct( newStream->currentPosition.u.HighPart = 0; newStream->currentPosition.u.LowPart = 0; - /* - * Initialize the rest of the data. - */ - newStream->streamSize.u.HighPart = 0; - newStream->streamSize.u.LowPart = 0; - newStream->bigBlockChain = 0; - newStream->smallBlockChain = 0; - - /* - * Read the size from the directory entry and determine if the blocks forming - * this stream are large or small. - */ - StgStreamImpl_OpenBlockChain(newStream); - /* add us to the storage's list of active streams */ StorageBaseImpl_AddStream(parentStorage, newStream); } diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index ec38adb..9652077 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2339,16 +2339,22 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, StorageImpl *This = (StorageImpl*)base; DirEntry data; HRESULT hr; + ULARGE_INTEGER newSize; hr = StorageImpl_ReadDirEntry(This, index, &data); if (FAILED(hr)) return hr; - /* FIXME: Enlarge the stream first if necessary. */ + /* Grow the stream if necessary */ + newSize.QuadPart = 0; + newSize.QuadPart = offset.QuadPart + size; - if (data.size.QuadPart == 0) + if (newSize.QuadPart > data.size.QuadPart) { - /* This shouldn't happen for now, because the stream object will set the size. */ - assert(FALSE); + hr = StorageImpl_StreamSetSize(base, index, newSize); + if (FAILED(hr)) + return hr; + + data.size = newSize; } if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 53cb76a..ba4288d 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -293,7 +293,8 @@ static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This, return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead); } -/* Write size bytes to this directory entry's stream at the given offset. */ +/* Write size bytes to this directory entry's stream at the given offset, + * growing the stream if necessary. */ static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This, DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) { @@ -431,22 +432,9 @@ struct StgStreamImpl DirRef dirEntry; /* - * Helper variable that contains the size of the stream - */ - ULARGE_INTEGER streamSize; - - /* * This is the current position of the cursor in the stream */ ULARGE_INTEGER currentPosition; - - /* - * The information in the stream is represented by a chain of small blocks - * or a chain of large blocks. Depending on the case, one of the two - * following variables points to that information. - */ - BlockChainStream* bigBlockChain; - SmallBlockChainStream* smallBlockChain; }; /* -- 1.6.3.3