From 0ef7696d619cc31b1f075d2cb6999dc4a0652b6f Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Fri, 5 Mar 2010 11:03:18 -0600 Subject: [PATCH] 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); -- 1.7.0