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,
-					     &currentEntry);
-
-  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, &currentEntry);
+      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