Zhenbo Li : shell32: Fix SHFileOperation when deleting a nonexistent directory.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Jun 25 13:42:03 CDT 2014
Module: wine
Branch: master
Commit: 2ba9ee018bce4953feb728595f4a4a6e47b186a1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2ba9ee018bce4953feb728595f4a4a6e47b186a1
Author: Zhenbo Li <litimetal at gmail.com>
Date: Sat Jun 21 22:34:58 2014 +0800
shell32: Fix SHFileOperation when deleting a nonexistent directory.
---
dlls/shell32/shlfileop.c | 68 +++++++++++++++++++++---------------------
dlls/shell32/tests/shlfileop.c | 4 ---
2 files changed, 34 insertions(+), 38 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c
index e6d44b0..62d7880 100644
--- a/dlls/shell32/shlfileop.c
+++ b/dlls/shell32/shlfileop.c
@@ -347,36 +347,36 @@ HRESULT WINAPI SHIsFileAvailableOffline(LPCWSTR path, LPDWORD status)
* Asks for confirmation when bShowUI is true and deletes the directory and
* all its subdirectories and files if necessary.
*/
-static BOOL SHELL_DeleteDirectoryW(HWND hwnd, LPCWSTR pszDir, BOOL bShowUI)
+static DWORD SHELL_DeleteDirectoryW(HWND hwnd, LPCWSTR pszDir, BOOL bShowUI)
{
- BOOL ret = TRUE;
- HANDLE hFind;
- WIN32_FIND_DATAW wfd;
- WCHAR szTemp[MAX_PATH];
-
- /* Make sure the directory exists before eventually prompting the user */
- PathCombineW(szTemp, pszDir, wWildcardFile);
- hFind = FindFirstFileW(szTemp, &wfd);
- if (hFind == INVALID_HANDLE_VALUE)
- return FALSE;
+ DWORD ret = 0;
+ HANDLE hFind;
+ WIN32_FIND_DATAW wfd;
+ WCHAR szTemp[MAX_PATH];
+
+ PathCombineW(szTemp, pszDir, wWildcardFile);
+ hFind = FindFirstFileW(szTemp, &wfd);
+
+ if (hFind != INVALID_HANDLE_VALUE) {
+ if (!bShowUI || SHELL_ConfirmDialogW(hwnd, ASK_DELETE_FOLDER, pszDir, NULL)) {
+ do {
+ if (IsDotDir(wfd.cFileName))
+ continue;
+ PathCombineW(szTemp, pszDir, wfd.cFileName);
+ if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
+ ret = SHELL_DeleteDirectoryW(hwnd, szTemp, FALSE);
+ else
+ ret = SHNotifyDeleteFileW(szTemp);
+ } while (!ret && FindNextFileW(hFind, &wfd));
+ }
+ FindClose(hFind);
+ }
+ if (ret == ERROR_SUCCESS)
+ ret = SHNotifyRemoveDirectoryW(pszDir);
- if (!bShowUI || (ret = SHELL_ConfirmDialogW(hwnd, ASK_DELETE_FOLDER, pszDir, NULL)))
- {
- do
- {
- if (IsDotDir(wfd.cFileName))
- continue;
- PathCombineW(szTemp, pszDir, wfd.cFileName);
- if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
- ret = SHELL_DeleteDirectoryW(hwnd, szTemp, FALSE);
- else
- ret = (SHNotifyDeleteFileW(szTemp) == ERROR_SUCCESS);
- } while (ret && FindNextFileW(hFind, &wfd));
- }
- FindClose(hFind);
- if (ret)
- ret = (SHNotifyRemoveDirectoryW(pszDir) == ERROR_SUCCESS);
- return ret;
+ return ret == ERROR_PATH_NOT_FOUND ?
+ 0x7C: /* DE_INVALIDFILES (legacy Windows error) */
+ ret;
}
/**************************************************************************
@@ -1331,8 +1331,7 @@ static BOOL confirm_delete_list(HWND hWnd, DWORD fFlags, BOOL fTrash, const FILE
static DWORD delete_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom)
{
const FILE_ENTRY *fileEntry;
- DWORD i;
- BOOL bPathExists;
+ DWORD i, ret;
BOOL bTrash;
if (!flFrom->dwNumFiles)
@@ -1378,12 +1377,13 @@ static DWORD delete_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom)
/* delete the file or directory */
if (IsAttribFile(fileEntry->attributes))
- bPathExists = DeleteFileW(fileEntry->szFullPath);
+ ret = DeleteFileW(fileEntry->szFullPath) ?
+ ERROR_SUCCESS : GetLastError();
else
- bPathExists = SHELL_DeleteDirectoryW(lpFileOp->hwnd, fileEntry->szFullPath, FALSE);
+ ret = SHELL_DeleteDirectoryW(lpFileOp->hwnd, fileEntry->szFullPath, FALSE);
- if (!bPathExists)
- return ERROR_PATH_NOT_FOUND;
+ if (ret)
+ return ret;
}
return ERROR_SUCCESS;
diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c
index eba5450..3468fcc 100644
--- a/dlls/shell32/tests/shlfileop.c
+++ b/dlls/shell32/tests/shlfileop.c
@@ -622,7 +622,6 @@ static void test_delete(void)
shfo.pFrom = "nonexistent.txt\0";
shfo.wFunc = FO_DELETE;
ret = SHFileOperationA(&shfo);
- todo_wine
ok(ret == 1026 ||
ret == ERROR_FILE_NOT_FOUND || /* Vista */
broken(ret == ERROR_SUCCESS), /* NT4 */
@@ -651,7 +650,6 @@ static void test_delete(void)
shfo.pFrom = "test1.txt\0nonexistent.txt\0test2.txt\0";
shfo.wFunc = FO_DELETE;
ret = SHFileOperationA(&shfo);
- todo_wine
ok(ret == 1026 ||
ret == ERROR_FILE_NOT_FOUND || /* Vista */
broken(ret == ERROR_SUCCESS), /* NT4 */
@@ -664,14 +662,12 @@ static void test_delete(void)
init_shfo_tests();
shfo.pFrom = "testdir2\\nonexistent.txt\0";
ret = SHFileOperationA(&shfo);
- todo_wine
ok(ret == ERROR_FILE_NOT_FOUND || /* Vista */
broken(ret == 0x402) || /* XP */
broken(ret == ERROR_SUCCESS), /* NT4 */
"Expected 0x402 or ERROR_FILE_NOT_FOUND, got %x\n", ret);
shfo.pFrom = "nonexistent\\one.txt\0";
ret = SHFileOperationA(&shfo);
- todo_wine
ok(ret == DE_INVALIDFILES || /* Vista or later */
broken(ret == 0x402), /* XP */
"Expected 0x402 or DE_INVALIDFILES, got %x\n", ret);
More information about the wine-cvs
mailing list