Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52128
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net
-- v7: 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().
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 | 6 ++++++ dlls/scrrun/tests/filesystem.c | 7 +++++++ 2 files changed, 13 insertions(+)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 52e10239e05..4ab93a275a2 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3766,11 +3766,17 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de
static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { + DWORD attrs; + TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
if(!source || !source[0] || !destination || !destination[0]) return E_INVALIDARG;
+ attrs = GetFileAttributesW(source); + if(attrs == INVALID_FILE_ATTRIBUTES) + return CTL_E_PATHNOTFOUND; + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
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 | 2 +- dlls/scrrun/tests/filesystem.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 4ab93a275a2..1fb6a253c0b 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3774,7 +3774,7 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR return E_INVALIDARG;
attrs = GetFileAttributesW(source); - if(attrs == INVALID_FILE_ATTRIBUTES) + if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) return CTL_E_PATHNOTFOUND;
return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 8b84e743809..0cd8cf2c85d 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 | 13 ++++++++++++ dlls/scrrun/tests/filesystem.c | 38 +++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 1fb6a253c0b..5e9088e20d5 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3767,6 +3767,9 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { DWORD attrs; + int 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));
@@ -3777,6 +3780,16 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) return CTL_E_PATHNOTFOUND;
+ if (!GetFullPathNameW(source, MAX_PATH, src_path, &filename)) + return E_FAIL; + + 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(source), debugstr_w(dst_path)); + return MoveFileW(source, dst_path) ? S_OK : create_error(GetLastError()); + } return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 0cd8cf2c85d..6d1e69ce09e 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 | 55 +++++++++++++++++++++++++++------- dlls/scrrun/tests/filesystem.c | 27 ++++++++++++++++- 2 files changed, 70 insertions(+), 12 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 5e9088e20d5..a71a28f697d 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3767,30 +3767,63 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { DWORD attrs; - int dst_len; + + int 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));
if(!source || !source[0] || !destination || !destination[0]) return E_INVALIDARG;
- attrs = GetFileAttributesW(source); - if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) - return CTL_E_PATHNOTFOUND; - if (!GetFullPathNameW(source, MAX_PATH, src_path, &filename)) return E_FAIL; + src_len = (filename - src_path) / sizeof(WCHAR); + + if (wcspbrk(filename,L"*?")) + wildcard = TRUE; + + if (!wildcard) { + attrs = GetFileAttributesW(source); + if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) + return CTL_E_PATHNOTFOUND; + }
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(source), debugstr_w(dst_path)); - return MoveFileW(source, dst_path) ? S_OK : create_error(GetLastError()); + if (destination[dst_len-1] == '\' || destination[dst_len-1] == '/') + separator = TRUE; + + if (!wildcard && !separator) { + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); } - return MoveFileW(source, destination) ? S_OK : create_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 6d1e69ce09e..31bd5e96e59 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 | 5 +++++ dlls/scrrun/tests/filesystem.c | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index a71a28f697d..3d7d83557d1 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3810,6 +3810,11 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR return create_error(GetLastError());
do { + if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; + if(ffd.cFileName[0]=='.' && (ffd.cFileName[1]==0 || + (ffd.cFileName[1]=='.' && ffd.cFileName[2]==0))) + continue; name_len = lstrlenW(ffd.cFileName); if(src_len+name_len+1>=MAX_PATH || dst_len+name_len+1>=MAX_PATH) { FindClose(f); diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 31bd5e96e59..87347627884 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)
On Sun Jul 17 20:35:29 2022 +0000, Robert Wilhelm wrote:
Thanks for spotting this. I will add a test and a check. Looking at the code in copy_folder() in same file, I will also have to avoid special folders like "." and "..".
I have added check for non-directories and corresponding test in a new commit https://gitlab.winehq.org/wine/wine/-/merge_requests/391/diffs?commit_id=507...
I had an important realization about the directory check. If the source filename ends with a backslash, the MoveFileW call will only succeed if the source file is a directory. That should remove the need to check beforehand and eliminate the time-of-check to time-of-use problem.
It does still require remapping some error codes. I get `ERROR_FILE_NOT_FOUND` if it doesn't exist and `ERROR_INVALID_NAME` if it's a regular file. But I think it'd be an improvement overall.
Hi Esme, this is a clever idea. I will try this.