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