ole32: Use the storage vtable to write to streams.
This commit is contained in:
parent
71b4ac9c71
commit
1d4c698ef3
|
@ -382,34 +382,12 @@ static HRESULT WINAPI StgStreamImpl_Write(
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Depending on the type of chain that was opened when the stream was constructed,
|
||||
* we delegate the work to the method that readwrites to the block chains.
|
||||
*/
|
||||
if (This->smallBlockChain!=0)
|
||||
{
|
||||
res = SmallBlockChainStream_WriteAt(This->smallBlockChain,
|
||||
This->currentPosition,
|
||||
cb,
|
||||
pv,
|
||||
pcbWritten);
|
||||
|
||||
}
|
||||
else if (This->bigBlockChain!=0)
|
||||
{
|
||||
res = BlockChainStream_WriteAt(This->bigBlockChain,
|
||||
This->currentPosition,
|
||||
cb,
|
||||
pv,
|
||||
pcbWritten);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this should never happen because the IStream_SetSize call above will
|
||||
* make sure a big or small block chain is created */
|
||||
assert(FALSE);
|
||||
res = 0;
|
||||
}
|
||||
res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
|
||||
This->dirEntry,
|
||||
This->currentPosition,
|
||||
cb,
|
||||
pv,
|
||||
pcbWritten);
|
||||
|
||||
/*
|
||||
* Advance the position pointer for the number of positions written.
|
||||
|
|
|
@ -2246,6 +2246,52 @@ static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index,
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
|
||||
ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
|
||||
{
|
||||
StorageImpl *This = (StorageImpl*)base;
|
||||
DirEntry data;
|
||||
HRESULT hr;
|
||||
|
||||
hr = StorageImpl_ReadDirEntry(This, index, &data);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
/* FIXME: Enlarge the stream first if necessary. */
|
||||
|
||||
if (data.size.QuadPart == 0)
|
||||
{
|
||||
/* This shouldn't happen for now, because the stream object will set the size. */
|
||||
assert(FALSE);
|
||||
}
|
||||
|
||||
if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)
|
||||
{
|
||||
SmallBlockChainStream *stream;
|
||||
|
||||
stream = SmallBlockChainStream_Construct(This, NULL, index);
|
||||
if (!stream) return E_OUTOFMEMORY;
|
||||
|
||||
hr = SmallBlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten);
|
||||
|
||||
SmallBlockChainStream_Destroy(stream);
|
||||
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockChainStream *stream;
|
||||
|
||||
stream = BlockChainStream_Construct(This, NULL, index);
|
||||
if (!stream) return E_OUTOFMEMORY;
|
||||
|
||||
hr = BlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten);
|
||||
|
||||
BlockChainStream_Destroy(stream);
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Virtual function table for the IStorage32Impl class.
|
||||
*/
|
||||
|
@ -2278,7 +2324,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl =
|
|||
StorageImpl_BaseWriteDirEntry,
|
||||
StorageImpl_BaseReadDirEntry,
|
||||
StorageImpl_DestroyDirEntry,
|
||||
StorageImpl_StreamReadAt
|
||||
StorageImpl_StreamReadAt,
|
||||
StorageImpl_StreamWriteAt
|
||||
};
|
||||
|
||||
static HRESULT StorageImpl_Construct(
|
||||
|
@ -3733,6 +3780,13 @@ static HRESULT StorageInternalImpl_StreamReadAt(StorageBaseImpl *base,
|
|||
index, offset, size, buffer, bytesRead);
|
||||
}
|
||||
|
||||
static HRESULT StorageInternalImpl_StreamWriteAt(StorageBaseImpl *base,
|
||||
DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
|
||||
{
|
||||
return StorageBaseImpl_StreamWriteAt(&base->ancestorStorage->base,
|
||||
index, offset, size, buffer, bytesWritten);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
** Storage32InternalImpl_Commit
|
||||
|
@ -4180,7 +4234,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl =
|
|||
StorageInternalImpl_WriteDirEntry,
|
||||
StorageInternalImpl_ReadDirEntry,
|
||||
StorageInternalImpl_DestroyDirEntry,
|
||||
StorageInternalImpl_StreamReadAt
|
||||
StorageInternalImpl_StreamReadAt,
|
||||
StorageInternalImpl_StreamWriteAt
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -253,6 +253,7 @@ struct StorageBaseImplVtbl {
|
|||
HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
|
||||
HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
|
||||
HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
|
||||
HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
|
||||
};
|
||||
|
||||
static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
|
||||
|
@ -291,6 +292,13 @@ 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. */
|
||||
static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
|
||||
DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
|
||||
{
|
||||
return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* StorageBaseImpl stream list handlers
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue