From 4b8f27979521239c23e85f9836e7e51f8fb7471a Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 30 Nov 2009 10:35:55 -0600 Subject: [PATCH 5/5] ole32: Use the storage vtable to read streams. --- dlls/ole32/stg_stream.c | 58 ++++++---------------------------------- dlls/ole32/storage32.c | 67 +++++++++++++++++++++++++++++++++++++++++++++- dlls/ole32/storage32.h | 8 +++++ 3 files changed, 82 insertions(+), 51 deletions(-) diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c index 6200126..0888180 100644 --- a/dlls/ole32/stg_stream.c +++ b/dlls/ole32/stg_stream.c @@ -264,7 +264,6 @@ static HRESULT WINAPI StgStreamImpl_Read( StgStreamImpl* const This=(StgStreamImpl*)iface; ULONG bytesReadBuffer; - ULONG bytesToReadFromBuffer; HRESULT res; TRACE("(%p, %p, %d, %p)\n", @@ -283,60 +282,21 @@ static HRESULT WINAPI StgStreamImpl_Read( if (pcbRead==0) pcbRead = &bytesReadBuffer; - /* - * Using the known size of the stream, calculate the number of bytes - * to read from the block chain - */ - bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); - - /* - * Depending on the type of chain that was opened when the stream was constructed, - * we delegate the work to the method that reads the block chains. - */ - if (This->smallBlockChain!=0) - { - res = SmallBlockChainStream_ReadAt(This->smallBlockChain, - This->currentPosition, - bytesToReadFromBuffer, - pv, - pcbRead); + res = StorageBaseImpl_StreamReadAt(This->parentStorage, + This->dirEntry, + This->currentPosition, + cb, + pv, + pcbRead); - } - else if (This->bigBlockChain!=0) - { - res = BlockChainStream_ReadAt(This->bigBlockChain, - This->currentPosition, - bytesToReadFromBuffer, - pv, - pcbRead); - } - else + if (SUCCEEDED(res)) { /* - * Small and big block chains are both NULL. This case will happen - * when a stream starts with BLOCK_END_OF_CHAIN and has size zero. + * Advance the pointer for the number of positions read. */ - - *pcbRead = 0; - res = S_OK; - goto end; - } - - if (SUCCEEDED(res)) - { - /* - * We should always be able to read the proper amount of data from the - * chain. - */ - assert(bytesToReadFromBuffer == *pcbRead); - - /* - * Advance the pointer for the number of positions read. - */ - This->currentPosition.u.LowPart += *pcbRead; + This->currentPosition.u.LowPart += *pcbRead; } -end: TRACE("<-- %08x\n", res); return res; } diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 53c2c87..0e5861d 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2192,6 +2192,60 @@ static HRESULT StorageImpl_BaseReadDirEntry(StorageBaseImpl *base, return StorageImpl_ReadDirEntry(This, index, data); } +static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + ULONG bytesToRead; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + if (data.size.QuadPart == 0) + { + *bytesRead = 0; + return S_OK; + } + + if (offset.QuadPart + size > data.size.QuadPart) + { + bytesToRead = data.size.QuadPart - offset.QuadPart; + } + else + { + bytesToRead = size; + } + + if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + SmallBlockChainStream *stream; + + stream = SmallBlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = SmallBlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead); + + SmallBlockChainStream_Destroy(stream); + + return hr; + } + else + { + BlockChainStream *stream; + + stream = BlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = BlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead); + + BlockChainStream_Destroy(stream); + + return hr; + } +} + /* * Virtual function table for the IStorage32Impl class. */ @@ -2223,7 +2277,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl = StorageImpl_CreateDirEntry, StorageImpl_BaseWriteDirEntry, StorageImpl_BaseReadDirEntry, - StorageImpl_DestroyDirEntry + StorageImpl_DestroyDirEntry, + StorageImpl_StreamReadAt }; static HRESULT StorageImpl_Construct( @@ -3671,6 +3726,13 @@ static HRESULT StorageInternalImpl_DestroyDirEntry(StorageBaseImpl *base, index); } +static HRESULT StorageInternalImpl_StreamReadAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + return StorageBaseImpl_StreamReadAt(&base->ancestorStorage->base, + index, offset, size, buffer, bytesRead); +} + /****************************************************************************** ** ** Storage32InternalImpl_Commit @@ -4117,7 +4179,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl = StorageInternalImpl_CreateDirEntry, StorageInternalImpl_WriteDirEntry, StorageInternalImpl_ReadDirEntry, - StorageInternalImpl_DestroyDirEntry + StorageInternalImpl_DestroyDirEntry, + StorageInternalImpl_StreamReadAt }; /****************************************************************************** diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 12cff71..24070d1 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -252,6 +252,7 @@ struct StorageBaseImplVtbl { HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*); HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*); HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef); + HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); }; static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) @@ -283,6 +284,13 @@ static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This, return This->baseVtbl->DestroyDirEntry(This, index); } +/* Read up to size bytes from this directory entry's stream at the given offset. */ +static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead); +} + /**************************************************************************** * StorageBaseImpl stream list handlers */ -- 1.6.3.3