shell32: for FO_COPY, if the destination is an empty string, SHFileOperation should use the current directory. Additionally, in parse_file_list, check result of HeapAlloc against NULL.
Lionel Debroux
lionel_debroux at yahoo.fr
Thu May 21 07:05:40 CDT 2009
Based on a patch by Nikolay Sivov <bunglehead at gmail.com>.
---
dlls/shell32/shlfileop.c | 21 ++++++++++++++++++---
dlls/shell32/tests/shlfileop.c | 13 +++++++++++++
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c
index b48e46d..b86b86a 100644
--- a/dlls/shell32/shlfileop.c
+++ b/dlls/shell32/shlfileop.c
@@ -1013,13 +1013,16 @@ static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles)
flList->num_alloc = 32;
flList->dwNumFiles = 0;
- /* empty list */
+ /* Empty list: return without having allocated flList->feFiles. */
if (!szFiles[0])
return ERROR_ACCESS_DENIED;
flList->feFiles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
flList->num_alloc * sizeof(FILE_ENTRY));
+ if (!flList->feFiles)
+ return E_OUTOFMEMORY;
+
while (*ptr)
{
if (i >= flList->num_alloc) grow_list( flList );
@@ -1177,8 +1180,20 @@ static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, FILE_LIST
{
DWORD i;
const FILE_ENTRY *entryToCopy;
- const FILE_ENTRY *fileDest = &flTo->feFiles[0];
+ const FILE_ENTRY *fileDest;
+ /* if the destination is empty, SHFileOperation should use the current directory */
+ if (op->req->pTo[0] == '\0') {
+ WCHAR currd[MAX_PATH];
+ GetCurrentDirectoryW(MAX_PATH, currd);
+ /* Due to the empty destination, a previous call to parse_file_list(), triggered
+ by SHFileOperationW, returned before allocating and filling flTo->feFiles.
+ => destroy_file_list() needn't be called. */
+ parse_file_list(flTo, currd);
+ }
+
+ fileDest = &flTo->feFiles[0];
+
if (flFrom->bAnyDontExist)
return ERROR_SHELL_INTERNAL_FILE_NOT_FOUND;
diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c
index 540fd0d..0495b01 100644
--- a/dlls/shell32/tests/shlfileop.c
+++ b/dlls/shell32/tests/shlfileop.c
@@ -1673,6 +1673,19 @@ static void test_copy(void)
ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
+
+ /* pTo is an empty string */
+ CreateDirectoryA("one", NULL);
+ createTestFile("one\\abcdefghi.abc");
+ shfo.pFrom = "one\\abcdefghi.abc\0";
+ shfo.pTo = "\0";
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_FILESONLY |
+ FOF_NOCONFIRMMKDIR;
+ retval = SHFileOperation(&shfo);
+ ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
+ ok(DeleteFileA("abcdefghi.abc"), "Expected file to exist\n");
+ ok(DeleteFileA("one\\abcdefghi.abc"), "Expected file to exist\n");
+ ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
}
/* tests the FO_MOVE action */
--
1.6.3.1.61.g065b0
--------------030308050403090406010208--
More information about the wine-patches
mailing list