Vincent Povirk : ole32: Use the storage vtable to write to streams.

Alexandre Julliard julliard at winehq.org
Wed Dec 9 10:46:25 CST 2009


Module: wine
Branch: master
Commit: 1d4c698ef38ed35297968cafd5573a4f137335ab
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1d4c698ef38ed35297968cafd5573a4f137335ab

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Mon Nov 30 11:38:45 2009 -0600

ole32: Use the storage vtable to write to streams.

---

 dlls/ole32/stg_stream.c |   34 ++++----------------------
 dlls/ole32/storage32.c  |   59 +++++++++++++++++++++++++++++++++++++++++++++-
 dlls/ole32/storage32.h  |    8 ++++++
 3 files changed, 71 insertions(+), 30 deletions(-)

diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c
index 0888180..e02a3f5 100644
--- a/dlls/ole32/stg_stream.c
+++ b/dlls/ole32/stg_stream.c
@@ -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.
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index 0e5861d..f34dadd 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -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
 };
 
 /******************************************************************************
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index 24070d1..ef8c894 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -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
  */




More information about the wine-cvs mailing list