Vincent Povirk : ole32: Allow CopyTo to succeed in spite of already open source streams.

Alexandre Julliard julliard at winehq.org
Mon Mar 15 12:19:29 CDT 2010


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

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Fri Mar  5 11:03:18 2010 -0600

ole32: Allow CopyTo to succeed in spite of already open source streams.

---

 dlls/ole32/storage32.c       |   26 ++++++++++++++++++++++----
 dlls/ole32/tests/storage32.c |    2 +-
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index 837365b..f1a98e1 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -1599,11 +1599,15 @@ static HRESULT WINAPI StorageBaseImpl_CopyTo(
   SNB         snbExclude,   /* [unique][in] */
   IStorage*   pstgDest)     /* [unique][in] */
 {
+  StorageBaseImpl* const This=(StorageBaseImpl*)iface;
+
   IEnumSTATSTG *elements     = 0;
   STATSTG      curElement, strStat;
   HRESULT      hr;
   IStorage     *pstgTmp, *pstgChild;
   IStream      *pstrTmp, *pstrChild;
+  DirRef       srcEntryRef;
+  DirEntry     srcEntry;
   BOOL         skip = FALSE, skip_storage = FALSE, skip_stream = FALSE;
   int          i;
 
@@ -1728,11 +1732,25 @@ static HRESULT WINAPI StorageBaseImpl_CopyTo(
         goto cleanup;
 
       /*
-       * open child stream storage
+       * open child stream storage. This operation must succeed even if the
+       * stream is already open, so we use internal functions to do it.
        */
-      hr = IStorage_OpenStream( iface, curElement.pwcsName, NULL,
-				STGM_READ|STGM_SHARE_EXCLUSIVE,
-				0, &pstrChild );
+      srcEntryRef = findElement( This, This->storageDirEntry, curElement.pwcsName,
+        &srcEntry);
+      if (!srcEntryRef)
+      {
+        ERR("source stream not found\n");
+        hr = STG_E_DOCFILECORRUPT;
+      }
+
+      if (hr == S_OK)
+      {
+        pstrChild = (IStream*)StgStreamImpl_Construct(This, STGM_READ|STGM_SHARE_EXCLUSIVE, srcEntryRef);
+        if (pstrChild)
+          IStream_AddRef(pstrChild);
+        else
+          hr = E_OUTOFMEMORY;
+      }
 
       if (hr == S_OK)
       {
diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c
index 7568a0c..8fa1afd 100644
--- a/dlls/ole32/tests/storage32.c
+++ b/dlls/ole32/tests/storage32.c
@@ -2750,7 +2750,7 @@ static void test_copyto_locking(void)
 
     /* Try to copy the storage while the stream is open */
     r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
-    todo_wine ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
+    ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
 
     IStream_Release(stm);
 




More information about the wine-cvs mailing list