[PATCH v2 0/3] MR11054: ole32: Implement IStorage::MoveElementTo().
-- v2: ole32: Implement IStorage::MoveElementTo() for storage element. ole32: Implement IStorage::MoveElementTo() for stream element. ole32/tests: Add some tests for IStorage::MoveElementTo(). https://gitlab.winehq.org/wine/wine/-/merge_requests/11054
From: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> --- dlls/ole32/tests/storage32.c | 115 +++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index cb77b025293..5e8fc396718 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -3937,6 +3937,120 @@ static void test_custom_lockbytes(void) DeleteTestLockBytes(lockbytes); } +static void test_MoveElementTo(void) +{ + WCHAR temp[MAX_PATH], src_name[MAX_PATH], dst_name[MAX_PATH]; + IStorage *src, *dst, *stg; + IStream *stream; + HRESULT hr; + + GetTempPathW(MAX_PATH, temp); + GetTempFileNameW(temp, L"stg", 0, src_name); + GetTempFileNameW(temp, L"stg", 0, dst_name); + + hr = StgCreateDocfile(src_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &src); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = create_test_file(src); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = StgCreateDocfile(dst_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &dst); + ok(hr == S_OK, "got %#lx\n", hr); + + /* 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); + + hr = IStorage_MoveElementTo(src, strmA_name, dst, strmC_name, STGMOVE_COPY); + ok(hr == STG_E_FILENOTFOUND, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, strmC_name, dst, NULL, 0); + ok(hr == STG_E_INVALIDNAME, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, strmC_name, NULL, strmC_name, STGMOVE_COPY); + ok(hr == STG_E_INVALIDPOINTER, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, strmC_name, NULL, strmC_name, ~0); + ok(hr == STG_E_INVALIDFLAG, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, strmC_name, src, strmC_name, STGMOVE_COPY); + ok(hr == STG_E_ACCESSDENIED, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, strmC_name, dst, strmC_name, STGMOVE_COPY); + ok(hr == S_OK, "got %#lx\n", hr); + + /* STGMOVE_COPY doesn't fail if the target already exsists */ + hr = IStorage_MoveElementTo(src, strmC_name, dst, strmC_name, STGMOVE_COPY); + ok(hr == S_OK, "got %#lx\n", hr); + + /* STGMOVE_MOVE fails if the target already exsists */ + hr = IStorage_MoveElementTo(src, strmC_name, dst, strmC_name, STGMOVE_MOVE); + ok(hr == STG_E_FILEALREADYEXISTS, "got %#lx\n", hr); + + hr = IStorage_DestroyElement(dst, strmC_name); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, strmC_name, dst, strmC_name, STGMOVE_MOVE); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = IStorage_OpenStream(src, strmC_name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); + ok(hr == STG_E_FILENOTFOUND, "got %#lx\n", hr); + + hr = IStorage_OpenStream(dst, strmC_name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); + ok(hr == S_OK, "got %#lx\n", hr); + IStream_Release(stream); + + hr = IStorage_MoveElementTo(src, strmC_name, dst, strmC_name, STGMOVE_COPY); + ok(hr == STG_E_FILENOTFOUND, "got %#lx\n", hr); + + /* STGTY_STORAGE */ + +next: + hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_COPY); + todo_wine + ok(hr == S_OK, "got %#lx\n", hr); + if (hr != S_OK) goto done; + + /* STGMOVE_COPY doesn't fail if the target already exsists */ + hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_COPY); + ok(hr == S_OK, "got %#lx\n", hr); + + /* STGMOVE_MOVE fails if the target already exsists */ + hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_MOVE); + ok(hr == STG_E_FILEALREADYEXISTS, "got %#lx\n", hr); + + hr = IStorage_DestroyElement(dst, stgB_name); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_MOVE); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_COPY); + ok(hr == STG_E_FILENOTFOUND, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, stgB_name, dst, stgA_name, STGMOVE_MOVE); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = IStorage_MoveElementTo(src, stgB_name, dst, stgA_name, STGMOVE_COPY); + ok(hr == STG_E_FILENOTFOUND, "got %#lx\n", hr); + + hr = IStorage_OpenStorage(dst, stgB_name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg); + ok(hr == S_OK, "got %#lx\n", hr); + IStorage_Release(stg); + +done: + IStorage_Release(src); + IStorage_Release(dst); + DeleteFileW(src_name); + DeleteFileW(dst_name); +} + START_TEST(storage32) { CHAR temp[MAX_PATH]; @@ -3986,4 +4100,5 @@ START_TEST(storage32) test_transacted_shared(); test_overwrite(); test_custom_lockbytes(); + test_MoveElementTo(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11054
From: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> --- dlls/ole32/storage32.c | 59 ++++++++++++++++++++++++++++++------ dlls/ole32/tests/storage32.c | 3 -- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index d3f4760cfe1..fed7eb760f0 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2363,16 +2363,57 @@ 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; + DWORD create_mode; + + 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; + + create_mode = STGM_WRITE | STGM_SHARE_EXCLUSIVE; + create_mode |= (mode == STGMOVE_MOVE) ? STGM_FAILIFTHERE : STGM_CREATE; + + /* 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, create_mode, 0, 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
From: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> --- dlls/ole32/storage32.c | 18 +++++++++++++++++- dlls/ole32/tests/storage32.c | 3 --- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index fed7eb760f0..39700ca785f 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2387,7 +2387,6 @@ static HRESULT WINAPI StorageBaseImpl_MoveElementTo(IStorage *iface, create_mode = STGM_WRITE | STGM_SHARE_EXCLUSIVE; create_mode |= (mode == STGMOVE_MOVE) ? STGM_FAILIFTHERE : STGM_CREATE; - /* FIXME: Handle STGTY_STORAGE */ hr = IStorage_OpenStream(iface, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &src); if (hr == S_OK) { @@ -2409,6 +2408,23 @@ static HRESULT WINAPI StorageBaseImpl_MoveElementTo(IStorage *iface, IStream_Release(src); } + else if (hr == STG_E_FILENOTFOUND) + { + IStorage *src_stg, *dst_stg; + + hr = IStorage_OpenStorage(iface, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &src_stg); + if (hr == S_OK) + { + hr = IStorage_CreateStorage(dest, new_name, create_mode, 0, 0, &dst_stg); + if (hr == S_OK) + { + hr = IStorage_CopyTo(src_stg, 0, NULL, NULL, dst_stg); + IStorage_Release(dst_stg); + } + + IStorage_Release(src_stg); + } + } if (hr == S_OK && mode == STGMOVE_MOVE) hr = IStorage_DestroyElement(iface, name); diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index 66382548f60..7bca822aa96 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -4010,9 +4010,7 @@ static void test_MoveElementTo(void) /* STGTY_STORAGE */ hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_COPY); - todo_wine ok(hr == S_OK, "got %#lx\n", hr); - if (hr != S_OK) goto done; /* STGMOVE_COPY doesn't fail if the target already exsists */ hr = IStorage_MoveElementTo(src, stgA_name, dst, stgB_name, STGMOVE_COPY); @@ -4041,7 +4039,6 @@ static void test_MoveElementTo(void) ok(hr == S_OK, "got %#lx\n", hr); IStorage_Release(stg); -done: IStorage_Release(src); IStorage_Release(dst); DeleteFileW(src_name); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11054
This merge request was approved by Esme Povirk. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11054
participants (3)
-
Dmitry Timoshkov -
Dmitry Timoshkov (@dmitry) -
Esme Povirk (@madewokherd)