From: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> --- dlls/ole32/storage32.c | 58 ++++++++++++++++++++++++++++++------ dlls/ole32/tests/storage32.c | 3 -- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index d3f4760cfe1..6b90e7cc237 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2363,16 +2363,56 @@ static HRESULT WINAPI StorageBaseImpl_CopyTo( /************************************************************************* * MoveElementTo (IStorage) */ -static HRESULT WINAPI StorageBaseImpl_MoveElementTo( - IStorage* iface, - const OLECHAR *pwcsName, /* [string][in] */ - IStorage *pstgDest, /* [unique][in] */ - const OLECHAR *pwcsNewName,/* [string][in] */ - DWORD grfFlags) /* [in] */ +static HRESULT WINAPI StorageBaseImpl_MoveElementTo(IStorage *iface, + const OLECHAR *name, IStorage *dest, const OLECHAR *new_name, DWORD mode) { - FIXME("%p, %s, %p, %s, %#lx: stub\n", iface, debugstr_w(pwcsName), pstgDest, - debugstr_w(pwcsNewName), grfFlags); - return E_NOTIMPL; + IStream *src, *dst; + HRESULT hr; + + TRACE("%p, %s, %p, %s, %#lx\n", iface, debugstr_w(name), dest, debugstr_w(new_name), mode); + + if (mode != STGMOVE_COPY && mode != STGMOVE_MOVE) + return STG_E_INVALIDFLAG; + + if (!name || !new_name) + return STG_E_INVALIDNAME; + + if (!dest) + return STG_E_INVALIDPOINTER; + + if (iface == dest) /* FIXME */ + return STG_E_ACCESSDENIED; + + /* FIXME: Handle STGTY_STORAGE */ + hr = IStorage_OpenStream(iface, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &src); + if (hr == S_OK) + { + STATSTG stat; + + hr = IStream_Stat(src, &stat, STATFLAG_NONAME); + if (hr != S_OK) + { + IStream_Release(src); + return hr; + } + + hr = IStorage_CreateStream(dest, new_name, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_FAILIFTHERE, 0, 0, &dst); + /* STGMOVE_MOVE fails if the target already exsists */ + if (hr == STG_E_FILEALREADYEXISTS && mode != STGMOVE_MOVE) + hr = IStorage_OpenStream(dest, new_name, NULL, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &dst); + if (hr == S_OK) + { + hr = IStream_CopyTo(src, dst, stat.cbSize, NULL, NULL); + IStream_Release(dst); + } + + IStream_Release(src); + } + + if (hr == S_OK && mode == STGMOVE_MOVE) + hr = IStorage_DestroyElement(iface, name); + + return hr; } /************************************************************************* diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index 5e8fc396718..66382548f60 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -3960,9 +3960,7 @@ static void test_MoveElementTo(void) /* STGTY_STREAM */ hr = IStorage_MoveElementTo(src, NULL, NULL, NULL, 0); - todo_wine ok(hr == STG_E_INVALIDNAME, "got %#lx\n", hr); - if (hr != STG_E_INVALIDNAME) goto next; hr = IStorage_MoveElementTo(src, strmA_name, dst, strmC_name, ~0); ok(hr == STG_E_INVALIDFLAG, "got %#lx\n", hr); @@ -4011,7 +4009,6 @@ static void test_MoveElementTo(void) /* STGTY_STORAGE */ -next: hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_COPY); todo_wine ok(hr == S_OK, "got %#lx\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11054