Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52128
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net
-- v9: scrrun: Return path not found error if no folders were moved in MoveFolder(). scrrun: return path not found error if source ends with path separator in MoveFolder(). scrrun: Move directories only in MoveFolder(). scrrun: Support wildcards in MoveFolder(). scrrun: Move source dir into destination dir if destination ends with separator in MoveFolder(). scrrun: Check that source is directory in MoveFolder().
From: Robert Wilhelm robert.wilhelm@gmx.net
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52128
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 7 +++---- dlls/scrrun/tests/filesystem.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 35b43e2f124..dac3b9fdcf7 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3764,12 +3764,11 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
-static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface,BSTR Source, - BSTR Destination) +static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { - FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination)); + TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
- return E_NOTIMPL; + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 1ba0e81a2d1..7654b07b003 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2600,6 +2600,25 @@ static void test_MoveFile(void) SysFreeString(str); }
+static void test_MoveFolder(void) +{ + BSTR src, dst; + WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; + HRESULT hr; + + get_temp_path(L"foo", buffW1); + get_temp_path(L"bar", buffW2); + + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); +} + static void test_DoOpenPipeStream(void) { static const char testdata[] = "test"; @@ -2733,6 +2752,7 @@ START_TEST(filesystem) test_GetExtensionName(); test_GetSpecialFolder(); test_MoveFile(); + test_MoveFolder(); test_DoOpenPipeStream();
IFileSystem3_Release(fs3);
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 3 +++ dlls/scrrun/tests/filesystem.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index dac3b9fdcf7..52e10239e05 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3768,6 +3768,9 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR { TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
+ if(!source || !source[0] || !destination || !destination[0]) + return E_INVALIDARG; + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 7654b07b003..48560a90a63 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2602,7 +2602,7 @@ static void test_MoveFile(void)
static void test_MoveFolder(void) { - BSTR src, dst; + BSTR src, dst, str, empty; WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; HRESULT hr;
@@ -2617,6 +2617,19 @@ static void test_MoveFolder(void) SysFreeString(src); SysFreeString(dst); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + + str = SysAllocString(L"null.dir"); + empty = SysAllocString(L""); + hr = IFileSystem3_MoveFolder(fs3, str, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = IFileSystem3_MoveFolder(fs3, NULL, str); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = IFileSystem3_MoveFolder(fs3, str, empty); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = IFileSystem3_MoveFolder(fs3, empty, str); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + SysFreeString(str); + SysFreeString(empty); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/tests/filesystem.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 48560a90a63..5b183b9436e 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2630,6 +2630,17 @@ static void test_MoveFolder(void) ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); SysFreeString(str); SysFreeString(empty); + + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); /* dst already exists */ + ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 16 +++++++++++++++- dlls/scrrun/tests/filesystem.c | 7 +++++++ 2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 52e10239e05..08db360bbe6 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3764,6 +3764,20 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
+static inline HRESULT create_movefolder_error(DWORD err) +{ + switch(err) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: return CTL_E_PATHNOTFOUND; + case ERROR_ACCESS_DENIED: return CTL_E_PERMISSIONDENIED; + case ERROR_FILE_EXISTS: return CTL_E_FILEALREADYEXISTS; + case ERROR_ALREADY_EXISTS: return CTL_E_FILEALREADYEXISTS; + default: + FIXME("Unsupported error code: %ld\n", err); + return E_FAIL; + } +} + static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination)); @@ -3771,7 +3785,7 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR if(!source || !source[0] || !destination || !destination[0]) return E_INVALIDARG;
- return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); + return MoveFileW(source, destination) ? S_OK : create_movefolder_error(GetLastError()); }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 5b183b9436e..8b84e743809 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2641,6 +2641,13 @@ static void test_MoveFolder(void) SysFreeString(dst); ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); /* src nonexistant */ + ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 10 +++++++++- dlls/scrrun/tests/filesystem.c | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 08db360bbe6..a7488454e95 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3767,6 +3767,7 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de static inline HRESULT create_movefolder_error(DWORD err) { switch(err) { + case ERROR_INVALID_NAME: case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: return CTL_E_PATHNOTFOUND; case ERROR_ACCESS_DENIED: return CTL_E_PERMISSIONDENIED; @@ -3780,12 +3781,19 @@ static inline HRESULT create_movefolder_error(DWORD err)
static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { + int len; + WCHAR src_path[MAX_PATH]; + TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
if(!source || !source[0] || !destination || !destination[0]) return E_INVALIDARG;
- return MoveFileW(source, destination) ? S_OK : create_movefolder_error(GetLastError()); + len = SysStringLen(source); + lstrcpyW(src_path, source); + if (source[len-1] != '\' && source[len-1] != '/') wcscat(src_path, L"\"); + + return MoveFileW(src_path, destination) ? S_OK : create_movefolder_error(GetLastError()); }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 8b84e743809..91c265b2ace 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2605,6 +2605,7 @@ static void test_MoveFolder(void) BSTR src, dst, str, empty; WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; HRESULT hr; + HANDLE file;
get_temp_path(L"foo", buffW1); get_temp_path(L"bar", buffW2); @@ -2648,6 +2649,19 @@ static void test_MoveFolder(void) ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); SysFreeString(src); SysFreeString(dst); + + file = CreateFileW(buffW1, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + CloseHandle(file); + + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); /* src is regular file */ + ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + DeleteFileW(buffW1); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 16 ++++++++++++-- dlls/scrrun/tests/filesystem.c | 38 +++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index a7488454e95..feaf7968a60 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3781,18 +3781,30 @@ static inline HRESULT create_movefolder_error(DWORD err)
static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { - int len; - WCHAR src_path[MAX_PATH]; + int len, dst_len; + WCHAR src_path[MAX_PATH], dst_path[MAX_PATH]; + WCHAR *filename;
TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
if(!source || !source[0] || !destination || !destination[0]) return E_INVALIDARG;
+ if (!GetFullPathNameW(source, MAX_PATH, src_path, &filename)) + return E_FAIL; + len = SysStringLen(source); lstrcpyW(src_path, source); if (source[len-1] != '\' && source[len-1] != '/') wcscat(src_path, L"\");
+ dst_len = lstrlenW(destination); + if (destination[dst_len-1] == '\' || destination[dst_len-1] == '/') { + lstrcpyW(dst_path, destination); + lstrcatW(dst_path, filename); + TRACE("move %s to %s\n", debugstr_w(src_path), debugstr_w(dst_path)); + return MoveFileW(src_path, dst_path) ? S_OK : create_movefolder_error(GetLastError()); + } + TRACE("move %s to %s\n", debugstr_w(src_path), debugstr_w(destination)); return MoveFileW(src_path, destination) ? S_OK : create_movefolder_error(GetLastError()); }
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 91c265b2ace..96d1bdfffcb 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2603,7 +2603,7 @@ static void test_MoveFile(void) static void test_MoveFolder(void) { BSTR src, dst, str, empty; - WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; + WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH]; HRESULT hr; HANDLE file;
@@ -2662,6 +2662,42 @@ static void test_MoveFolder(void) SysFreeString(src); SysFreeString(dst); DeleteFileW(buffW1); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"bar"); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + lstrcpyW(pathW,buffW2); + lstrcatW(pathW,L"\"); + src = SysAllocString(buffW1); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + lstrcatW(pathW,L"foo"); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"bar"); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + lstrcpyW(pathW,buffW2); + lstrcatW(pathW,L"/"); + src = SysAllocString(buffW1); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + lstrcatW(pathW,L"foo"); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 46 ++++++++++++++++++++++++++++------ dlls/scrrun/tests/filesystem.c | 27 +++++++++++++++++++- 2 files changed, 64 insertions(+), 9 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index feaf7968a60..4ec2511a811 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3781,9 +3781,12 @@ static inline HRESULT create_movefolder_error(DWORD err)
static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { - int len, dst_len; + int len, src_len, dst_len, name_len; WCHAR src_path[MAX_PATH], dst_path[MAX_PATH]; WCHAR *filename; + WIN32_FIND_DATAW ffd; + HANDLE f; + BOOL wildcard = FALSE, separator = FALSE;
TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
@@ -3792,20 +3795,47 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR
if (!GetFullPathNameW(source, MAX_PATH, src_path, &filename)) return E_FAIL; + src_len = (filename - src_path) / sizeof(WCHAR); + + if (wcspbrk(filename,L"*?")) + wildcard = TRUE;
len = SysStringLen(source); lstrcpyW(src_path, source); if (source[len-1] != '\' && source[len-1] != '/') wcscat(src_path, L"\");
dst_len = lstrlenW(destination); - if (destination[dst_len-1] == '\' || destination[dst_len-1] == '/') { - lstrcpyW(dst_path, destination); - lstrcatW(dst_path, filename); - TRACE("move %s to %s\n", debugstr_w(src_path), debugstr_w(dst_path)); - return MoveFileW(src_path, dst_path) ? S_OK : create_movefolder_error(GetLastError()); + + if (destination[dst_len-1] == '\' || destination[dst_len-1] == '/') + separator = TRUE; + + if (!wildcard && !separator) { + TRACE("move %s to %s\n", debugstr_w(src_path), debugstr_w(destination)); + return MoveFileW(src_path, destination) ? S_OK : create_movefolder_error(GetLastError()); } - TRACE("move %s to %s\n", debugstr_w(src_path), debugstr_w(destination)); - return MoveFileW(src_path, destination) ? S_OK : create_movefolder_error(GetLastError()); + + memcpy(dst_path, destination, dst_len*sizeof(WCHAR)); + if (!separator) + dst_path[dst_len++] = '\'; + + f = FindFirstFileW(source, &ffd); + if(f == INVALID_HANDLE_VALUE) + return create_error(GetLastError()); + + do { + name_len = lstrlenW(ffd.cFileName); + if(src_len+name_len+1>=MAX_PATH || dst_len+name_len+1>=MAX_PATH) { + FindClose(f); + return E_FAIL; + } + memcpy(filename, ffd.cFileName, (name_len+1)*sizeof(WCHAR)); + memcpy(dst_path + dst_len, ffd.cFileName, (name_len+1)*sizeof(WCHAR)); + TRACE("move %s to %s\n", debugstr_w(src_path), debugstr_w(dst_path)); + if (!MoveFileW(src_path, dst_path)) return create_error(GetLastError()); + } while(FindNextFileW(f, &ffd)); + FindClose(f); + + return S_OK; }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 96d1bdfffcb..5e6dfc1752e 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2603,7 +2603,7 @@ static void test_MoveFile(void) static void test_MoveFolder(void) { BSTR src, dst, str, empty; - WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH]; + WCHAR buffW1[MAX_PATH], buffW2[MAX_PATH], pathW[MAX_PATH], srcW[MAX_PATH]; HRESULT hr; HANDLE file;
@@ -2698,6 +2698,31 @@ static void test_MoveFolder(void) lstrcatW(pathW,L"foo"); ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo1"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"foo2"); + GetTempPathW(MAX_PATH, srcW); + lstrcatW(srcW,L"foo?"); + GetTempPathW(MAX_PATH, pathW); + lstrcatW(pathW,L"bar"); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + ok(CreateDirectoryW(pathW, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(pathW)); + src = SysAllocString(srcW); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + lstrcpyW(buffW1,pathW); + lstrcatW(buffW1,L"\foo1"); + lstrcpyW(buffW2,pathW); + lstrcatW(buffW2,L"\foo2"); + ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 8 ++++++-- dlls/scrrun/tests/filesystem.c | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 4ec2511a811..236f304c854 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3824,14 +3824,18 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR
do { name_len = lstrlenW(ffd.cFileName); - if(src_len+name_len+1>=MAX_PATH || dst_len+name_len+1>=MAX_PATH) { + if(src_len+name_len+2>=MAX_PATH || dst_len+name_len+1>=MAX_PATH) { FindClose(f); return E_FAIL; } memcpy(filename, ffd.cFileName, (name_len+1)*sizeof(WCHAR)); + wcscat(filename, L"\"); memcpy(dst_path + dst_len, ffd.cFileName, (name_len+1)*sizeof(WCHAR)); TRACE("move %s to %s\n", debugstr_w(src_path), debugstr_w(dst_path)); - if (!MoveFileW(src_path, dst_path)) return create_error(GetLastError()); + if (!MoveFileW(src_path, dst_path)) { + if (GetLastError() == ERROR_INVALID_NAME) continue; + return create_movefolder_error(GetLastError()); + } } while(FindNextFileW(f, &ffd)); FindClose(f);
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 5e6dfc1752e..34869ee531f 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2603,7 +2603,7 @@ static void test_MoveFile(void) static void test_MoveFolder(void) { BSTR src, dst, str, empty; - WCHAR buffW1[MAX_PATH], buffW2[MAX_PATH], pathW[MAX_PATH], srcW[MAX_PATH]; + WCHAR buffW1[MAX_PATH], buffW2[MAX_PATH], buffW3[MAX_PATH], pathW[MAX_PATH], srcW[MAX_PATH]; HRESULT hr; HANDLE file;
@@ -2703,6 +2703,8 @@ static void test_MoveFolder(void) lstrcatW(buffW1,L"foo1"); GetTempPathW(MAX_PATH, buffW2); lstrcatW(buffW2,L"foo2"); + GetTempPathW(MAX_PATH, buffW3); + lstrcatW(buffW3,L"foo3"); GetTempPathW(MAX_PATH, srcW); lstrcatW(srcW,L"foo?"); GetTempPathW(MAX_PATH, pathW); @@ -2710,6 +2712,11 @@ static void test_MoveFolder(void) ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); ok(CreateDirectoryW(pathW, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(pathW)); + /* create a file, should not be moved by MoveFolder() */ + file = CreateFileW(buffW3, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + CloseHandle(file); src = SysAllocString(srcW); dst = SysAllocString(pathW); hr = IFileSystem3_MoveFolder(fs3, src, dst); @@ -2723,6 +2730,7 @@ static void test_MoveFolder(void) ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); + ok(DeleteFileW(buffW3), "can't remove %s\n", wine_dbgstr_w(buffW3)); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
--- dlls/scrrun/filesystem.c | 7 +++++-- dlls/scrrun/tests/filesystem.c | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 236f304c854..eb982457f50 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3793,6 +3793,10 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR if(!source || !source[0] || !destination || !destination[0]) return E_INVALIDARG;
+ len = SysStringLen(source); + if (source[len-1] == '\' || source[len-1] == '/') + return CTL_E_PATHNOTFOUND; + if (!GetFullPathNameW(source, MAX_PATH, src_path, &filename)) return E_FAIL; src_len = (filename - src_path) / sizeof(WCHAR); @@ -3800,9 +3804,8 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR if (wcspbrk(filename,L"*?")) wildcard = TRUE;
- len = SysStringLen(source); lstrcpyW(src_path, source); - if (source[len-1] != '\' && source[len-1] != '/') wcscat(src_path, L"\"); + wcscat(src_path, L"\");
dst_len = lstrlenW(destination);
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 34869ee531f..5217be00007 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2681,6 +2681,23 @@ static void test_MoveFolder(void) ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2));
+ GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"bar"); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + lstrcpyW(pathW,buffW1); + lstrcatW(pathW,L"\"); + src = SysAllocString(pathW); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + GetTempPathW(MAX_PATH, buffW1); lstrcatW(buffW1,L"foo"); GetTempPathW(MAX_PATH, buffW2);
From: Robert Wilhelm robert.wilhelm@gmx.net
--- dlls/scrrun/filesystem.c | 5 +++-- dlls/scrrun/tests/filesystem.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index eb982457f50..3f0a76b5993 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3786,7 +3786,7 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR WCHAR *filename; WIN32_FIND_DATAW ffd; HANDLE f; - BOOL wildcard = FALSE, separator = FALSE; + BOOL wildcard = FALSE, separator = FALSE, success = FALSE;
TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
@@ -3839,10 +3839,11 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR if (GetLastError() == ERROR_INVALID_NAME) continue; return create_movefolder_error(GetLastError()); } + success = TRUE; } while(FindNextFileW(f, &ffd)); FindClose(f);
- return S_OK; + return success ? S_OK : CTL_E_PATHNOTFOUND; }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 5217be00007..16353dde355 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2748,6 +2748,34 @@ static void test_MoveFolder(void) ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); ok(DeleteFileW(buffW3), "can't remove %s\n", wine_dbgstr_w(buffW3)); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo1"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"foo2"); + GetTempPathW(MAX_PATH, srcW); + lstrcatW(srcW,L"foo*"); + GetTempPathW(MAX_PATH, pathW); + lstrcatW(pathW,L"bar"); + ok(CreateDirectoryW(pathW, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(pathW)); + /* create two files, should not be moved by MoveFolder() */ + file = CreateFileW(buffW1, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + CloseHandle(file); + file = CreateFileW(buffW2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + CloseHandle(file); + src = SysAllocString(srcW); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); + ok(DeleteFileW(buffW1), "can't remove %s\n", wine_dbgstr_w(buffW1)); + ok(DeleteFileW(buffW2), "can't remove %s\n", wine_dbgstr_w(buffW2)); }
static void test_DoOpenPipeStream(void)
Esme Povirk (@madewokherd) commented about dlls/scrrun/filesystem.c:
if (!GetFullPathNameW(source, MAX_PATH, src_path, &filename)) return E_FAIL;
- src_len = (filename - src_path) / sizeof(WCHAR);
This looks wrong. Pointer subtraction already implicitly divides by item size.