From 98133dfd6d7e0a04463aea0a184565490a035504 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 30 Nov 2009 15:05:41 -0600 Subject: [PATCH 2/5] ole32: Use the storage vtable to resize streams. --- dlls/ole32/stg_stream.c | 89 +---------------------------------------- dlls/ole32/storage32.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++- dlls/ole32/storage32.h | 7 +++ 3 files changed, 108 insertions(+), 88 deletions(-) diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c index e02a3f5..00a61a2 100644 --- a/dlls/ole32/stg_stream.c +++ b/dlls/ole32/stg_stream.c @@ -483,7 +483,6 @@ static HRESULT WINAPI StgStreamImpl_SetSize( { StgStreamImpl* const This=(StgStreamImpl*)iface; - DirEntry currentEntry; HRESULT hr; TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart); @@ -512,99 +511,17 @@ static HRESULT WINAPI StgStreamImpl_SetSize( return STG_E_ACCESSDENIED; } - /* In simple mode keep the stream size above the small block limit */ - if (This->parentStorage->openFlags & STGM_SIMPLE) - libNewSize.u.LowPart = max(libNewSize.u.LowPart, LIMIT_TO_USE_SMALL_BLOCK); - if (This->streamSize.u.LowPart == libNewSize.u.LowPart) return S_OK; - /* - * This will happen if we're creating a stream - */ - if ((This->smallBlockChain == 0) && (This->bigBlockChain == 0)) - { - if (libNewSize.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); - } - } - - /* - * Read this stream's size to see if it's small blocks or big blocks - */ - StorageBaseImpl_ReadDirEntry(This->parentStorage, - This->dirEntry, - ¤tEntry); - /* - * Determine if we have to switch from small to big blocks or vice versa - */ - if ( (This->smallBlockChain!=0) && - (currentEntry.size.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) - { - if (libNewSize.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) - { - /* - * Transform the small block chain into a big block chain - */ - This->bigBlockChain = Storage32Impl_SmallBlocksToBigBlocks( - This->parentStorage->ancestorStorage, - &This->smallBlockChain); - } - } - else if ( (This->bigBlockChain!=0) && - (currentEntry.size.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) ) - { - if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) - { - /* - * Transform the big block chain into a small block chain - */ - This->smallBlockChain = Storage32Impl_BigBlocksToSmallBlocks( - This->parentStorage->ancestorStorage, - &This->bigBlockChain); - } - } - - if (This->smallBlockChain!=0) - { - SmallBlockChainStream_SetSize(This->smallBlockChain, libNewSize); - } - else - { - BlockChainStream_SetSize(This->bigBlockChain, libNewSize); - } - - /* - * Write the new information about this stream to the directory entry - */ - hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, - This->dirEntry, - ¤tEntry); - - currentEntry.size.u.HighPart = libNewSize.u.HighPart; - currentEntry.size.u.LowPart = libNewSize.u.LowPart; + hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize); if (SUCCEEDED(hr)) { - StorageBaseImpl_WriteDirEntry(This->parentStorage, - This->dirEntry, - ¤tEntry); + This->streamSize = libNewSize; } - This->streamSize = libNewSize; - - return S_OK; + return hr; } /*** diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index f34dadd..ec38adb 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2246,6 +2246,93 @@ static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index, } } +static HRESULT StorageImpl_StreamSetSize(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER newsize) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + SmallBlockChainStream *smallblock=NULL; + BlockChainStream *bigblock=NULL; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + /* In simple mode keep the stream size above the small block limit */ + if (This->base.openFlags & STGM_SIMPLE) + newsize.QuadPart = max(newsize.QuadPart, LIMIT_TO_USE_SMALL_BLOCK); + + if (data.size.QuadPart == newsize.QuadPart) + return S_OK; + + /* Create a block chain object of the appropriate type */ + if (data.size.QuadPart == 0) + { + if (newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = SmallBlockChainStream_Construct(This, NULL, index); + if (!smallblock) return E_OUTOFMEMORY; + } + else + { + bigblock = BlockChainStream_Construct(This, NULL, index); + if (!bigblock) return E_OUTOFMEMORY; + } + } + else if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = SmallBlockChainStream_Construct(This, NULL, index); + if (!smallblock) return E_OUTOFMEMORY; + } + else + { + bigblock = BlockChainStream_Construct(This, NULL, index); + if (!bigblock) return E_OUTOFMEMORY; + } + + /* Change the block chain type if necessary. */ + if (smallblock && newsize.QuadPart >= LIMIT_TO_USE_SMALL_BLOCK) + { + bigblock = Storage32Impl_SmallBlocksToBigBlocks(This, &smallblock); + if (!bigblock) + { + SmallBlockChainStream_Destroy(smallblock); + return E_FAIL; + } + } + else if (bigblock && newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = Storage32Impl_BigBlocksToSmallBlocks(This, &bigblock); + if (!smallblock) + { + BlockChainStream_Destroy(bigblock); + return E_FAIL; + } + } + + /* Set the size of the block chain. */ + if (smallblock) + { + SmallBlockChainStream_SetSize(smallblock, newsize); + SmallBlockChainStream_Destroy(smallblock); + } + else + { + BlockChainStream_SetSize(bigblock, newsize); + BlockChainStream_Destroy(bigblock); + } + + /* Set the size in the directory entry. */ + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (SUCCEEDED(hr)) + { + data.size = newsize; + + hr = StorageImpl_WriteDirEntry(This, index, &data); + } + return hr; +} + static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) { @@ -2325,7 +2412,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl = StorageImpl_BaseReadDirEntry, StorageImpl_DestroyDirEntry, StorageImpl_StreamReadAt, - StorageImpl_StreamWriteAt + StorageImpl_StreamWriteAt, + StorageImpl_StreamSetSize }; static HRESULT StorageImpl_Construct( @@ -3787,6 +3875,13 @@ static HRESULT StorageInternalImpl_StreamWriteAt(StorageBaseImpl *base, index, offset, size, buffer, bytesWritten); } +static HRESULT StorageInternalImpl_StreamSetSize(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER newsize) +{ + return StorageBaseImpl_StreamSetSize(&base->ancestorStorage->base, + index, newsize); +} + /****************************************************************************** ** ** Storage32InternalImpl_Commit @@ -4235,7 +4330,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl = StorageInternalImpl_ReadDirEntry, StorageInternalImpl_DestroyDirEntry, StorageInternalImpl_StreamReadAt, - StorageInternalImpl_StreamWriteAt + StorageInternalImpl_StreamWriteAt, + StorageInternalImpl_StreamSetSize }; /****************************************************************************** diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index ef8c894..53cb76a 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -254,6 +254,7 @@ struct StorageBaseImplVtbl { HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef); HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*); + HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER); }; static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) @@ -299,6 +300,12 @@ static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This, return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten); } +static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER newsize) +{ + return This->baseVtbl->StreamSetSize(This, index, newsize); +} + /**************************************************************************** * StorageBaseImpl stream list handlers */ -- 1.6.3.3