Vincent Povirk : ole32: Use the storage vtable to resize streams.
Alexandre Julliard
julliard at winehq.org
Wed Dec 9 10:46:25 CST 2009
Module: wine
Branch: master
Commit: 6d06c43e53a1e0d266230f5ae92aad671ed63e2b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6d06c43e53a1e0d266230f5ae92aad671ed63e2b
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Nov 30 15:05:41 2009 -0600
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
*/
More information about the wine-cvs
mailing list