diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c69b81340..49e344333 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +2006-12-07 Corinna Vinschen + + * autoload.cc (SHFileOperationA): Define. + * syscalls.cc (try_to_bin): New function trying to move a file to + the recycle bin. + (unlink): Fix arguments used in CreateFile for delete on close. + Before closing the handle, try to move the file to the recycle bin. + 2006-12-07 Corinna Vinschen * cygheap.h (struct cwdstuff): Add "sync" member and accompanying diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 1e7fb783a..2a0653174 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -527,6 +527,7 @@ LoadDLLfuncEx (Wow64DisableWow64FsRedirection, 4, kernel32, 1) LoadDLLfuncEx (Wow64RevertWow64FsRedirection, 4, kernel32, 1) LoadDLLfunc (SHGetDesktopFolder, 4, shell32) +LoadDLLfunc (SHFileOperationA, 4, shell32) LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1) LoadDLLfuncEx (waveOutOpen, 24, winmm, 1) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 3ca624e9a..3113ac6b3 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -45,6 +45,7 @@ details. */ #include #include /* for UNLEN */ #include +#include #undef fstat #undef lstat @@ -136,6 +137,42 @@ dup2 (int oldfd, int newfd) return cygheap->fdtab.dup2 (oldfd, newfd); } +#ifndef FOF_NORECURSION +#define FOF_NORECURSION 0x1000 +#endif +#ifndef FOF_NORECURSEREPARSE +#define FOF_NORECURSEREPARSE 0x8000 +#endif + +static void +try_to_bin (const char *win32_path) +{ + /* The op.pFrom parameter must be double \0 terminated since it's not + just a filename, but a list of filenames. If the double \0 is + missing, SHFileOperationA returns with error number 1026 (which is + not a valid system error number). */ + char file[CYG_MAX_PATH + 1] = { 0 }; + SHFILEOPSTRUCT op; + int ret; + + op.hwnd = NULL; + op.wFunc = FO_DELETE; + op.pFrom = strcpy (file, win32_path); + op.pTo = NULL; + op.fFlags = FOF_ALLOWUNDO + | FOF_NOCONFIRMATION + | FOF_NOCONFIRMMKDIR + | FOF_NOERRORUI + | FOF_NORECURSION + | FOF_NORECURSEREPARSE + | FOF_SILENT; + op.fAnyOperationsAborted = FALSE; + op.hNameMappings = NULL; + op.lpszProgressTitle = NULL; + ret = SHFileOperationA (&op); + debug_printf ("SHFileOperation (%s) = %d\n", win32_path, ret); +} + extern "C" int unlink (const char *ourname) { @@ -208,12 +245,13 @@ unlink (const char *ourname) DWORD flags = FILE_FLAG_DELETE_ON_CLOSE; if (win32_name.is_rep_symlink ()) flags |= FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS; - h = CreateFile (win32_name, 0, FILE_SHARE_READ, &sec_none_nih, + h = CreateFile (win32_name, DELETE, wincap.shared (), &sec_none_nih, OPEN_EXISTING, flags, 0); if (h != INVALID_HANDLE_VALUE) { if (wincap.has_hard_links () && setattrs) SetFileAttributes (win32_name, (DWORD) win32_name); + try_to_bin (win32_name.get_win32 ()); BOOL res = CloseHandle (h); syscall_printf ("%d = CloseHandle (%p)", res, h); if (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES