mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
ole32: Use the storage vtable to read streams.
This commit is contained in:
parent
ee39a21d2b
commit
62e54bacba
@ -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);
|
||||
|
||||
}
|
||||
else if (This->bigBlockChain!=0)
|
||||
{
|
||||
res = BlockChainStream_ReadAt(This->bigBlockChain,
|
||||
This->currentPosition,
|
||||
bytesToReadFromBuffer,
|
||||
pv,
|
||||
pcbRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
*pcbRead = 0;
|
||||
res = S_OK;
|
||||
goto end;
|
||||
}
|
||||
res = StorageBaseImpl_StreamReadAt(This->parentStorage,
|
||||
This->dirEntry,
|
||||
This->currentPosition,
|
||||
cb,
|
||||
pv,
|
||||
pcbRead);
|
||||
|
||||
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;
|
||||
/*
|
||||
* Advance the pointer for the number of positions read.
|
||||
*/
|
||||
This->currentPosition.u.LowPart += *pcbRead;
|
||||
}
|
||||
|
||||
end:
|
||||
TRACE("<-- %08x\n", res);
|
||||
return res;
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user