Vincent Povirk : ole32: Don' t track the stream size in storage stream objects.
Alexandre Julliard
julliard at winehq.org
Wed Dec 9 10:46:25 CST 2009
Module: wine
Branch: master
Commit: 8518323e070377c07a3d421573dc3348e28008a4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8518323e070377c07a3d421573dc3348e28008a4
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Nov 30 15:40:53 2009 -0600
ole32: Don't track the stream size in storage stream objects.
We can't do this safely when there are multiple objects for a single stream.
---
dlls/ole32/stg_stream.c | 128 ++---------------------------------------------
dlls/ole32/storage32.c | 14 ++++--
dlls/ole32/storage32.h | 16 +-----
3 files changed, 17 insertions(+), 141 deletions(-)
diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c
index 00a61a2..bfecbc7 100644
--- a/dlls/ole32/stg_stream.c
+++ b/dlls/ole32/stg_stream.c
@@ -75,21 +75,6 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This)
This->parentStorage = 0;
/*
- * Make sure we clean-up the block chain stream objects that we were using.
- */
- if (This->bigBlockChain != 0)
- {
- BlockChainStream_Destroy(This->bigBlockChain);
- This->bigBlockChain = 0;
- }
-
- if (This->smallBlockChain != 0)
- {
- SmallBlockChainStream_Destroy(This->smallBlockChain);
- This->smallBlockChain = 0;
- }
-
- /*
* Finally, free the memory used-up by the class.
*/
HeapFree(GetProcessHeap(), 0, This);
@@ -180,73 +165,6 @@ static ULONG WINAPI StgStreamImpl_Release(
}
/***
- * This method will open the block chain pointed by the directory entry
- * that describes the stream.
- * If the stream's size is null, no chain is opened.
- */
-static void StgStreamImpl_OpenBlockChain(
- StgStreamImpl* This)
-{
- DirEntry currentEntry;
- HRESULT hr;
-
- /*
- * Make sure no old object is left over.
- */
- if (This->smallBlockChain != 0)
- {
- SmallBlockChainStream_Destroy(This->smallBlockChain);
- This->smallBlockChain = 0;
- }
-
- if (This->bigBlockChain != 0)
- {
- BlockChainStream_Destroy(This->bigBlockChain);
- This->bigBlockChain = 0;
- }
-
- /*
- * Read the information from the directory entry.
- */
- hr = StorageBaseImpl_ReadDirEntry(This->parentStorage,
- This->dirEntry,
- ¤tEntry);
-
- if (SUCCEEDED(hr))
- {
- This->streamSize = currentEntry.size;
-
- /*
- * This code supports only streams that are <32 bits in size.
- */
- assert(This->streamSize.u.HighPart == 0);
-
- if(currentEntry.startingBlock == BLOCK_END_OF_CHAIN)
- {
- assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) );
- }
- else
- {
- if ( (This->streamSize.u.HighPart == 0) &&
- (This->streamSize.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);
- }
- }
- }
-}
-
-/***
* This method is part of the ISequentialStream interface.
*
* It reads a block of information from the stream at the current
@@ -319,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
- ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
HRESULT res;
@@ -365,22 +282,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
TRACE("<-- S_OK, written 0\n");
return S_OK;
}
- else
- {
- newSize.u.HighPart = 0;
- newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
- }
-
- /*
- * Verify if we need to grow the stream
- */
- if (newSize.u.LowPart > This->streamSize.u.LowPart)
- {
- /* grow stream */
- res = IStream_SetSize(iface, newSize);
- if (FAILED(res))
- return res;
- }
res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
This->dirEntry,
@@ -415,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek(
StgStreamImpl* const This=(StgStreamImpl*)iface;
ULARGE_INTEGER newPosition;
+ DirEntry currentEntry;
+ HRESULT hr;
TRACE("(%p, %d, %d, %p)\n",
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
@@ -453,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek(
*plibNewPosition = This->currentPosition;
break;
case STREAM_SEEK_END:
- *plibNewPosition = This->streamSize;
+ hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, ¤tEntry);
+ if (FAILED(hr)) return hr;
+ *plibNewPosition = currentEntry.size;
break;
default:
WARN("invalid dwOrigin %d\n", dwOrigin);
@@ -511,16 +416,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
return STG_E_ACCESSDENIED;
}
- if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
- return S_OK;
-
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
-
- if (SUCCEEDED(hr))
- {
- This->streamSize = libNewSize;
- }
-
return hr;
}
@@ -853,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct(
newStream->currentPosition.u.HighPart = 0;
newStream->currentPosition.u.LowPart = 0;
- /*
- * Initialize the rest of the data.
- */
- newStream->streamSize.u.HighPart = 0;
- newStream->streamSize.u.LowPart = 0;
- newStream->bigBlockChain = 0;
- newStream->smallBlockChain = 0;
-
- /*
- * Read the size from the directory entry and determine if the blocks forming
- * this stream are large or small.
- */
- StgStreamImpl_OpenBlockChain(newStream);
-
/* add us to the storage's list of active streams */
StorageBaseImpl_AddStream(parentStorage, newStream);
}
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index ec38adb..9652077 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -2339,16 +2339,22 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
StorageImpl *This = (StorageImpl*)base;
DirEntry data;
HRESULT hr;
+ ULARGE_INTEGER newSize;
hr = StorageImpl_ReadDirEntry(This, index, &data);
if (FAILED(hr)) return hr;
- /* FIXME: Enlarge the stream first if necessary. */
+ /* Grow the stream if necessary */
+ newSize.QuadPart = 0;
+ newSize.QuadPart = offset.QuadPart + size;
- if (data.size.QuadPart == 0)
+ if (newSize.QuadPart > data.size.QuadPart)
{
- /* This shouldn't happen for now, because the stream object will set the size. */
- assert(FALSE);
+ hr = StorageImpl_StreamSetSize(base, index, newSize);
+ if (FAILED(hr))
+ return hr;
+
+ data.size = newSize;
}
if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index 53cb76a..ba4288d 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -293,7 +293,8 @@ 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. */
+/* Write size bytes to this directory entry's stream at the given offset,
+ * growing the stream if necessary. */
static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
{
@@ -431,22 +432,9 @@ struct StgStreamImpl
DirRef dirEntry;
/*
- * Helper variable that contains the size of the stream
- */
- ULARGE_INTEGER streamSize;
-
- /*
* This is the current position of the cursor in the stream
*/
ULARGE_INTEGER currentPosition;
-
- /*
- * The information in the stream is represented by a chain of small blocks
- * or a chain of large blocks. Depending on the case, one of the two
- * following variables points to that information.
- */
- BlockChainStream* bigBlockChain;
- SmallBlockChainStream* smallBlockChain;
};
/*
More information about the wine-cvs
mailing list