This patch adds correct calls to SHChangeNotify on every operation in SHFileOperation. It also treats FOF_NOCONFIRMATION flag properly. Actually absence of this flag. Vitaliy Margolen changelog: dlls/shell32/shlfileop.c * add calls to SHChangeNotify for all operations * show confirmation dialogs if FOF_NOCONFIRMATION is not set Index: dlls/shell32/shlfileop.c =================================================================== RCS file: /home/wine/wine/dlls/shell32/shlfileop.c,v retrieving revision 1.24 diff -u -r1.24 shlfileop.c --- dlls/shell32/shlfileop.c 1 Feb 2003 00:41:30 -0000 1.24 +++ dlls/shell32/shlfileop.c 9 Mar 2003 01:03:08 -0000 @@ -72,6 +72,49 @@ return (IDOK == MessageBoxA(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION)); } +/************************************************************************ + * Win32DeleteFile [SHELL32.164] + * + * Deletes a file. Also triggers a change notify if one exists. + * + * NOTES: + * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI. + * This is Unicode on NT/2000 + */ +static BOOL Win32DeleteFileA(LPCSTR fName) +{ + LPITEMIDLIST Pidls[1]; + DWORD dummy; + + TRACE("%p(%s)\n", fName, fName); + + SHILCreateFromPathA(fName, &Pidls[0], &dummy); + DeleteFileA(fName); + SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, Pidls[0], NULL); + SHFree(Pidls[0]); + return TRUE; +} + +static BOOL Win32DeleteFileW(LPCWSTR fName) +{ + LPITEMIDLIST Pidls[1]; + DWORD dummy; + + TRACE("%p(%s)\n", fName, debugstr_w(fName)); + + SHILCreateFromPathW(fName, &Pidls[0], &dummy); + DeleteFileW(fName); + SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, Pidls[0], NULL); + return TRUE; +} + +DWORD WINAPI Win32DeleteFileAW(LPCVOID fName) +{ + if (SHELL_OsIsUnicode()) + return Win32DeleteFileW(fName); + return Win32DeleteFileA(fName); +} + /************************************************************************** * SHELL_DeleteDirectoryA() * @@ -84,6 +127,8 @@ HANDLE hFind; WIN32_FIND_DATAA wfd; char szTemp[MAX_PATH]; + LPITEMIDLIST Pidls[1]; + DWORD dummy; strcpy(szTemp, pszDir); PathAddBackslashA(szTemp); @@ -103,14 +148,18 @@ strcat(szTemp, wfd.cFileName); if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) - SHELL_DeleteDirectoryA(szTemp, FALSE); + SHELL_DeleteDirectoryA(szTemp, bShowUI); else - DeleteFileA(szTemp); + Win32DeleteFileA((LPCSTR)szTemp); } } while(FindNextFileA(hFind, &wfd)); FindClose(hFind); + SHILCreateFromPathA(pszDir, &Pidls[0], &dummy); ret = RemoveDirectoryA(pszDir); + if (ret) + SHChangeNotify(SHCNE_RMDIR, SHCNF_IDLIST, Pidls[0], NULL); + SHFree(Pidls[0]); } return ret; @@ -122,10 +171,19 @@ BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI) { + BOOL ret; + LPITEMIDLIST Pidls[1]; + DWORD dummy; + if (bShowUI && !SHELL_ConfirmDialog(ASK_DELETE_FILE, pszFile)) return FALSE; - return DeleteFileA(pszFile); + SHILCreateFromPathA(pszFile, &Pidls[0], &dummy); + ret = DeleteFileA(pszFile); + if (ret) + SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, Pidls[0], NULL); + SHFree(Pidls[0]); + return ret; } /************************************************************************* @@ -174,40 +232,6 @@ return ret; } -/************************************************************************ - * Win32DeleteFile [SHELL32.164] - * - * Deletes a file. Also triggers a change notify if one exists. - * - * NOTES: - * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI. - * This is Unicode on NT/2000 - */ -static BOOL Win32DeleteFileA(LPCSTR fName) -{ - TRACE("%p(%s)\n", fName, fName); - - DeleteFileA(fName); - SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, fName, NULL); - return TRUE; -} - -static BOOL Win32DeleteFileW(LPCWSTR fName) -{ - TRACE("%p(%s)\n", fName, debugstr_w(fName)); - - DeleteFileW(fName); - SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fName, NULL); - return TRUE; -} - -DWORD WINAPI Win32DeleteFileAW(LPCVOID fName) -{ - if (SHELL_OsIsUnicode()) - return Win32DeleteFileW(fName); - return Win32DeleteFileA(fName); -} - /************************************************************************** * SHELL_FileNamesMatch() * @@ -241,6 +265,7 @@ LPSTR pFrom = (LPSTR)lpFileOp->pFrom; LPSTR pTo = (LPSTR)lpFileOp->pTo; LPSTR pTempTo; + TRACE("flags (0x%04x) : %s%s%s%s%s%s%s%s%s%s%s%s \n", lpFileOp->fFlags, lpFileOp->fFlags & FOF_MULTIDESTFILES ? "FOF_MULTIDESTFILES " : "", lpFileOp->fFlags & FOF_CONFIRMMOUSE ? "FOF_CONFIRMMOUSE " : "", @@ -277,6 +302,8 @@ int multifrom = pFrom[strlen(pFrom) + 1] != '\0'; int destisdir = PathIsDirectoryA( pTo ); int todir = 0; + LPITEMIDLIST Pidls[1]; + DWORD dummy; if (lpFileOp->wFunc == FO_COPY) TRACE("File Copy:\n"); @@ -366,12 +393,18 @@ } } else - CopyFileA(szTempFrom, pTempTo, FALSE); + if (CopyFileA(szTempFrom, pTempTo, FALSE)) + SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTempTo, NULL); } else { + SHILCreateFromPathA(szTempFrom, &Pidls[0], &dummy); /* move file/directory */ - MoveFileA(szTempFrom, pTempTo); + if (MoveFileA(szTempFrom, pTempTo)){ + SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTempTo, NULL); + SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, szTempFrom, NULL); + } + SHFree(Pidls[0]); } HeapFree(GetProcessHeap(), 0, pTempTo); } @@ -402,9 +435,20 @@ HeapFree(GetProcessHeap(), 0, pTempTo); } if (lpFileOp->wFunc == FO_COPY) - CopyFileA(pFrom, pTo, FALSE); + { + if (CopyFileA(pFrom, pTo, FALSE)) + SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTo, NULL); + } else - MoveFileA(pFrom, pTo); + { + SHILCreateFromPathA(pFrom, &Pidls[0], &dummy); + if (MoveFileA(pFrom, pTo)) + { + SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, &Pidls[0], NULL); + SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTo, NULL); + } + SHFree(Pidls[0]); + } pFrom += strlen(pFrom) + 1; pTo += strlen(pTo) + 1; @@ -442,10 +486,10 @@ if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) { if(!(lpFileOp->fFlags & FOF_FILESONLY)) - SHELL_DeleteDirectoryA(szTemp, FALSE); + SHELL_DeleteDirectoryA(szTemp, !(lpFileOp->fFlags & FOF_NOCONFIRMATION)); } else - DeleteFileA(szTemp); + SHELL_DeleteFileA(szTemp, !(lpFileOp->fFlags & FOF_NOCONFIRMATION)); } } while(FindNextFileA(hFind, &wfd)); @@ -459,6 +503,11 @@ } case FO_RENAME: + { + LPITEMIDLIST Pidls[2]; + DWORD dummy; + DWORD ret; + TRACE("File Rename:\n"); if (pFrom[strlen(pFrom) + 1] != '\0') { @@ -467,7 +516,18 @@ } lpFileOp->fAnyOperationsAborted = FALSE; TRACE("From %s, To %s\n", pFrom, pTo); - return !MoveFileA(pFrom, pTo); + + SHILCreateFromPathA(pFrom, &Pidls[0], &dummy); + ret = MoveFileA(pFrom, pTo); + if (ret) + { + SHILCreateFromPathA(pTo, &Pidls[1], &dummy); + SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_IDLIST, &Pidls[0], &Pidls[1]); + SHFree(Pidls[1]); + } + SHFree(Pidls[0]); + return !ret; + } default: FIXME("Unhandled shell file operation %d\n", lpFileOp->wFunc);