From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Toru TSUNEYOSHI" Newsgroups: gmane.emacs.devel Subject: Re: patch about moving file (or directory) to the Recycle Bin on Windows NT series Date: Thu, 24 Apr 2008 01:45:00 +0900 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0011_01C8A5AC.CF21DCC0" X-Trace: ger.gmane.org 1208971209 23607 80.91.229.12 (23 Apr 2008 17:20:09 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 23 Apr 2008 17:20:09 +0000 (UTC) Cc: Eli Zaretskii To: Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Apr 23 19:20:44 2008 connect(): Connection refused Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1Joidr-0004AK-1e for ged-emacs-devel@m.gmane.org; Wed, 23 Apr 2008 19:20:23 +0200 Original-Received: from localhost ([127.0.0.1]:51992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JoidB-0002Iz-6o for ged-emacs-devel@m.gmane.org; Wed, 23 Apr 2008 13:19:41 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Joi5r-00015f-5s for emacs-devel@gnu.org; Wed, 23 Apr 2008 12:45:15 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Joi5p-00015T-Mq for emacs-devel@gnu.org; Wed, 23 Apr 2008 12:45:13 -0400 Original-Received: from [199.232.76.173] (port=36212 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Joi5p-00015Q-G6 for emacs-devel@gnu.org; Wed, 23 Apr 2008 12:45:13 -0400 Original-Received: from bay0-omc3-s33.bay0.hotmail.com ([65.54.246.233]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Joi5k-0004KU-Cw; Wed, 23 Apr 2008 12:45:08 -0400 Original-Received: from hotmail.com ([207.46.10.12]) by bay0-omc3-s33.bay0.hotmail.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 23 Apr 2008 09:45:07 -0700 Original-Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC; Wed, 23 Apr 2008 09:45:06 -0700 Original-Received: from 124.155.30.210 by BAY121-DAV2.phx.gbl with DAV; Wed, 23 Apr 2008 16:45:03 +0000 X-Originating-IP: [124.155.30.210] X-Originating-Email: [t_tuneyosi@hotmail.com] X-Sender: t_tuneyosi@hotmail.com X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1914 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1914 X-OriginalArrivalTime: 23 Apr 2008 16:45:06.0919 (UTC) FILETIME=[62DE0F70:01C8A561] X-detected-kernel: by monty-python.gnu.org: Windows 2000 SP4, XP SP1+ X-Mailman-Approved-At: Wed, 23 Apr 2008 13:18:49 -0400 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:95849 Archived-At: This is a multi-part message in MIME format. ------=_NextPart_000_0011_01C8A5AC.CF21DCC0 Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit Thanks, everyone, especially Eli Zaretskii. Just Now I checked new suggestion from Stefan Monnier. But I have already fixed as follows, I will send it. ----- Original Message ----- From: "Eli Zaretskii" To: "Toru TSUNEYOSHI" Cc: Sent: Wednesday, April 23, 2008 3:19 AM Subject: Re: patch about moving file (or directory) to the Recycle Bin on Windows NT series > > From: "Toru TSUNEYOSHI" > > Date: Tue, 22 Apr 2008 06:32:12 +0900 > > > > I made a revised edition (including w32.h). > > Thank you. > > I think this contribution is large enough to require legal papers, but > I'll let Stefan and Yidong decide that. > You are welcome. > > +#ifdef W32_SYS_UNLINK_USE_SHELLAPI > > +extern void syms_of_w32 (void); > > +#endif /* W32_SYS_UNLINK_USE_SHELLAPI */ > > If we are going to support this feature, we don't need this > conditional compilation, so please remove the #ifdef's (here and > everywhere else). > I removed all of them. > > + if (w32_sys_unlink_use_shellapi) > > + { > > + /* Each file name must be terminated by a single NULL > > + character. An additional NULL character must be appended to the > > + end of the final name to indicate the end of pFrom. */ > > + TCHAR tmp_path[MAX_PATH + 1 + 1]; > > AFAIU from the Microsoft documentation, there's no need for the second > "+1", as MAX_PATH already accounts for one terminating null character. > Oops. You are right. I fixed it. > > + SHFILEOPSTRUCT stFileOp; > > + > > + path = map_w32_filename (path, NULL); > > MSDN advises to use only absolute file names with SHFileOperation, > otherwise they say that recycling will not work (see > http://msdn2.microsoft.com/en-us/library/bb759795(VS.85).aspx for the > details). So I think we need to make the file name absolute here. > Yes, I added statements for it. > > + /* On Unix, unlink works without write permission. */ > > + _chmod (path, 0666); > > Can this somehow leave the file writable without deleting it, if the > code is interrupted before it gets to undo this _chmod call? If so, > we need to guard against that somehow. > I don't know what to do about it. So, I do nothing. > > + ZeroMemory(&stFileOp, sizeof(SHFILEOPSTRUCT)); > > + stFileOp.hwnd = HWND_DESKTOP; > > + stFileOp.wFunc = FO_DELETE; > > + stFileOp.pFrom = tmp_path; > > + stFileOp.pTo = NULL; > > + stFileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT; > > Do we want to use the FOF_NO_CONNECTED_ELEMENTS flag here? Deleting > connected files, which is the default with shell API, is not what > happens with the normal unlink, is it? So it might surprise the user > if we do that when using the shell API. > OK, I added it. And, I build Emacs by MS VC++ 6.0. SHELLAPI.H in MS VC++ 6.0 don't include `FOF_NO_CONNECTED_ELEMENTS', so I added it to w32.c. > How about FOF_NOERRORUI? do we want it? I understand that without it, > a dialog will be presented to the user in case of any errors during > the deletion. > Yes, I added it. > > + /* value returned by SHFileOperation() must match value returned by _unlink() */ > > + return (SHFileOperation(&stFileOp) == 0 ? 0 : -1); > > Do we want to set errno here, at least for some popular reasons that > fail the deletion, using the DE_* error codes documented on the MSDN? > The caller of this function may wish to look at errno and provide > diagnostics. > I don't know what to do about it, because the caller of this function may assume that _unlink() or _rmdir() returns 0 or -1 in the existing code. > > +void > > +syms_of_w32 () > > +{ > > + DEFVAR_BOOL ("w32-sys-unlink-use-shellapi", &w32_sys_unlink_use_shellapi, > > + "Non-nil means using shellapi for sys_unlink(), sys_rmdir()."); > > + w32_sys_unlink_use_shellapi = 1; > > +} > > Please use a more descriptive name, such as w32-delete-to-recycle-bin > or something similar. The point is that the name should tell a user > what this option will do, not which API it will use. (I imagine that > many Emacs users don't even know what is the shell API.) > > Also, please make this option off by default. > I fixed it as you wrote. > In addition, we need an entry for NEWS about this new feature. Could > you please write it? > Yes, I wrote it. But I don't know document format for NEWS, so I followed examples in etc/NEWS. > Finally, using this feature requires to add -lshellapi to the linker > switches in nt/?make.defs, right? Or is that linked in by default? > It already existed. There is variable SHELL32 in nt/nmake.defs. SHELL32 = shell32.lib There is variable SHELL32 in nt/gmake.defs SHELL32 = -lshell32 And, varialbe LIBS in src/makefile.w32-in includes variable SHELL32. > Thanks again for working on this. > Thanks a lot for your helping. ------=_NextPart_000_0011_01C8A5AC.CF21DCC0 Content-Type: application/octet-stream; name="w32.h_w32.c_emacs.c.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="w32.h_w32.c_emacs.c.diff" --- src/w32.h.original 2008-01-10 21:16:16.000000000 +0900=0A= +++ src/w32.h 2008-04-24 00:44:33.769063800 +0900=0A= @@ -129,6 +129,7 @@=0A= =0A= extern void init_ntproc (void);=0A= extern void term_ntproc (void);=0A= +extern void syms_of_w32 (void);=0A= extern void globals_of_w32 (void);=0A= extern void syms_of_w32term (void);=0A= extern void syms_of_w32fns (void);=0A= --- src/w32.c.original 2008-02-23 22:49:09.000000000 +0900=0A= +++ src/w32.c 2008-04-24 00:42:22.761991200 +0900=0A= @@ -75,6 +75,11 @@=0A= #include =0A= #include =0A= =0A= +#include =0A= +#ifndef FOF_NO_CONNECTED_ELEMENTS=0A= +#define FOF_NO_CONNECTED_ELEMENTS 0x2000 /* don't operate on connected = elements. */=0A= +#endif /* FOF_NO_CONNECTED_ELEMENTS */=0A= +=0A= #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */=0A= #include =0A= #undef socket=0A= @@ -104,6 +109,7 @@=0A= typedef HRESULT (WINAPI * ShGetFolderPath_fn)=0A= (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);=0A= =0A= +void syms_of_w32 ();=0A= void globals_of_w32 ();=0A= =0A= extern Lisp_Object Vw32_downcase_file_names;=0A= @@ -111,6 +117,8 @@=0A= extern Lisp_Object Vw32_get_true_file_attributes;=0A= extern int w32_num_mouse_buttons;=0A= =0A= +int w32_delete_to_recycle_bin;=0A= +=0A= =0C=0A= /*=0A= Initialization states=0A= @@ -2243,17 +2251,58 @@=0A= int=0A= sys_rmdir (const char * path)=0A= {=0A= - return _rmdir (map_w32_filename (path, NULL));=0A= + if (w32_delete_to_recycle_bin)=0A= + return (sys_unlink (path));=0A= + else=0A= + return _rmdir (map_w32_filename (path, NULL));=0A= }=0A= =0A= int=0A= sys_unlink (const char * path)=0A= {=0A= - path =3D map_w32_filename (path, NULL);=0A= + if (w32_delete_to_recycle_bin)=0A= + {=0A= + SHFILEOPSTRUCT file_op;=0A= + /* `pFrom' member of struct SHFILEOPSTRUCT:=0A= + Each file name must be terminated by a single NULL=0A= + character. An additional NULL character must be appended to the=0A= + end of the final name to indicate the end of pFrom. */=0A= + char tmp_path[MAX_PATH + 1];=0A= + Lisp_Object tmp;=0A= +=0A= + /* Must use only absolute file names with SHFileOperation(). */=0A= + tmp =3D Fexpand_file_name (build_string (path), Qnil);=0A= +=0A= + path =3D map_w32_filename (SDATA (tmp), NULL);=0A= +=0A= + /* On Unix, unlink works without write permission. */=0A= + _chmod (path, 0666);=0A= +=0A= + memset (tmp_path, 0, sizeof (tmp_path));=0A= + strcpy(tmp_path, path);=0A= +=0A= + memset(&file_op, 0, sizeof (file_op));=0A= + file_op.hwnd =3D HWND_DESKTOP;=0A= + file_op.wFunc =3D FO_DELETE;=0A= + file_op.pFrom =3D tmp_path;=0A= + file_op.pTo =3D NULL;=0A= + file_op.fFlags =3D FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO=0A= + | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;=0A= + file_op.fAnyOperationsAborted =3D FALSE;=0A= + file_op.hNameMappings =3D NULL;=0A= + file_op.lpszProgressTitle =3D NULL;=0A= +=0A= + /* value returned by SHFileOperation() must match value returned = by _unlink() */=0A= + return (SHFileOperation(&file_op) =3D=3D 0 ? 0 : -1);=0A= + }=0A= + else=0A= + {=0A= + path =3D map_w32_filename (path, NULL);=0A= =0A= - /* On Unix, unlink works without write permission. */=0A= - _chmod (path, 0666);=0A= - return _unlink (path);=0A= + /* On Unix, unlink works without write permission. */=0A= + _chmod (path, 0666);=0A= + return _unlink (path);=0A= + }=0A= }=0A= =0A= static FILETIME utc_base_ft;=0A= @@ -4160,6 +4209,16 @@=0A= SetConsoleCtrlHandler(shutdown_handler, TRUE);=0A= }=0A= =0A= +void=0A= +syms_of_w32 ()=0A= +{=0A= + DEFVAR_BOOL ("w32-delete-to-recycle-bin",=0A= + &w32_delete_to_recycle_bin,=0A= + doc: /* Non-nil means delete file or directory to recycle bin.=0A= +Default is nil, which means just delete it. */);=0A= + w32_delete_to_recycle_bin =3D 0;=0A= +}=0A= +=0A= /* end of w32.c */=0A= =0A= /* arch-tag: 90442dd3-37be-482b-b272-ac752e3049f1=0A= --- src/emacs.c.original 2008-01-10 21:16:14.000000000 +0900=0A= +++ src/emacs.c 2008-04-24 00:43:32.060947200 +0900=0A= @@ -1588,6 +1588,7 @@=0A= syms_of_vmsproc ();=0A= #endif /* VMS */=0A= #ifdef WINDOWSNT=0A= + syms_of_w32 ();=0A= syms_of_ntproc ();=0A= #endif /* WINDOWSNT */=0A= syms_of_window ();=0A= ------=_NextPart_000_0011_01C8A5AC.CF21DCC0 Content-Type: application/octet-stream; name="NEWS" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="NEWS" ** Deleting files to the Recycle Bin is now supported on MS Windows. Now Emacs can delete files or directories to the Recycle Bin on MS Windows. This feature is disabled by default. To enable it, put (setq w32-delete-to-recycle-bin t) in your .emacs or some other startup file. ------=_NextPart_000_0011_01C8A5AC.CF21DCC0--