Module: wine Branch: master Commit: 2ba9ee018bce4953feb728595f4a4a6e47b186a1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2ba9ee018bce4953feb728595f...
Author: Zhenbo Li litimetal@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);