From: Ziqing Hui zhui@codeweavers.com
Also correctly check wildcard in target file names. --- dlls/shell32/shlfileop.c | 41 ++++++++++++++++++++++++---------- dlls/shell32/tests/shlfileop.c | 7 ++---- 2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c index c330a94b3b1..1bb5b84ea3b 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -1097,6 +1097,32 @@ static void parse_file_list(FILE_LIST *flList, LPCWSTR szFiles, BOOL parse_wildc } }
+static DWORD parse_target_file_list(const SHFILEOPSTRUCTW *op, DWORD source_file_count, FILE_LIST *out) +{ + DWORD i, check_count = 1; + + if (op->wFunc == FO_DELETE) + return ERROR_SUCCESS; + if (!op->pTo) + return ERROR_ACCESS_DENIED; + + parse_file_list(out, op->pTo, FALSE); + + if (op->fFlags & FOF_MULTIDESTFILES) + check_count = min(source_file_count, out->dwNumFiles); + + for (i = 0; i < check_count; ++i) + { + if (out->feFiles[i].bFromWildcard) + { + file_list_destroy(out); + return ERROR_INVALID_NAME; + } + } + + return ERROR_SUCCESS; +} + static void create_dest_dirs(LPCWSTR szDestDir) { WCHAR dir[MAX_PATH]; @@ -1533,15 +1559,8 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) parse_file_list(&flFrom, lpFileOp->pFrom, parse_wildcard); op.bManyItems = (flFrom.dwNumFiles > 1);
- if (lpFileOp->wFunc != FO_DELETE) - { - if (!lpFileOp->pTo) - return ERROR_ACCESS_DENIED; - parse_file_list(&flTo, lpFileOp->pTo, FALSE); - } - - if (flTo.bAnyFromWildcard) - return ERROR_INVALID_NAME; + if ((ret = parse_target_file_list(lpFileOp, flFrom.dwNumFiles, &flTo)) != ERROR_SUCCESS) + return ret;
switch (lpFileOp->wFunc) { @@ -1562,9 +1581,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) }
file_list_destroy(&flFrom); - - if (lpFileOp->wFunc != FO_DELETE) - file_list_destroy(&flTo); + file_list_destroy(&flTo);
if (ret == ERROR_CANCELLED) lpFileOp->fAnyOperationsAborted = TRUE; diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c index 712b002f9fd..8e81483fc1c 100644 --- a/dlls/shell32/tests/shlfileop.c +++ b/dlls/shell32/tests/shlfileop.c @@ -1459,17 +1459,14 @@ static void test_copy(void)
check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "aa.txt\0", "one\0tw?\0", - ERROR_SUCCESS, FALSE, TRUE, FALSE); - todo_wine + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("one\aa.txt"), "Expected file to exist\n"); ok(!DeleteFileA("two\aa.txt"), "Expected file to not exist\n");
check_file_operation(FO_COPY, FOF_NO_UI, "aa.txt\0bb.txt\0", "one\0tw?\0", - ERROR_SUCCESS, FALSE, TRUE, FALSE); - todo_wine + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("one\aa.txt"), "Expected file to exist\n"); - todo_wine ok(DeleteFileA("one\bb.txt"), "Expected file to exist\n"); ok(!DeleteFileA("two\bb.txt"), "Expected file to not exist\n");