diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32fns.c | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/src/w32fns.c b/src/w32fns.c index 4664ea79a12..9b630679c39 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -51,6 +51,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 51 | 51 | ||
| 52 | #ifdef WINDOWSNT | 52 | #ifdef WINDOWSNT |
| 53 | #include "w32heap.h" | 53 | #include "w32heap.h" |
| 54 | #include <mbstring.h> | ||
| 54 | #endif /* WINDOWSNT */ | 55 | #endif /* WINDOWSNT */ |
| 55 | 56 | ||
| 56 | #if CYGWIN | 57 | #if CYGWIN |
| @@ -6655,38 +6656,80 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash, | |||
| 6655 | operation = intern ("delete-directory"); | 6656 | operation = intern ("delete-directory"); |
| 6656 | filename = Fdirectory_file_name (filename); | 6657 | filename = Fdirectory_file_name (filename); |
| 6657 | } | 6658 | } |
| 6659 | |||
| 6660 | /* Must have fully qualified file names for moving files to Recycle | ||
| 6661 | Bin. */ | ||
| 6658 | filename = Fexpand_file_name (filename, Qnil); | 6662 | filename = Fexpand_file_name (filename, Qnil); |
| 6659 | 6663 | ||
| 6660 | handler = Ffind_file_name_handler (filename, operation); | 6664 | handler = Ffind_file_name_handler (filename, operation); |
| 6661 | if (!NILP (handler)) | 6665 | if (!NILP (handler)) |
| 6662 | return call2 (handler, operation, filename); | 6666 | return call2 (handler, operation, filename); |
| 6667 | else | ||
| 6668 | { | ||
| 6669 | const char * path; | ||
| 6670 | int result; | ||
| 6663 | 6671 | ||
| 6664 | encoded_file = ENCODE_FILE (filename); | 6672 | encoded_file = ENCODE_FILE (filename); |
| 6665 | 6673 | ||
| 6666 | { | 6674 | path = map_w32_filename (SDATA (encoded_file), NULL); |
| 6667 | const char * path; | ||
| 6668 | SHFILEOPSTRUCT file_op; | ||
| 6669 | char tmp_path[MAX_PATH + 1]; | ||
| 6670 | 6675 | ||
| 6671 | path = map_w32_filename (SDATA (encoded_file), NULL); | 6676 | /* The Unicode version of SHFileOperation is not supported on |
| 6677 | Windows 9X. */ | ||
| 6678 | if (w32_unicode_filenames && os_subtype != OS_9X) | ||
| 6679 | { | ||
| 6680 | SHFILEOPSTRUCTW file_op_w; | ||
| 6681 | /* We need one more element beyond MAX_PATH because this is | ||
| 6682 | a list of file names, with the last element double-null | ||
| 6683 | terminated. */ | ||
| 6684 | wchar_t tmp_path_w[MAX_PATH + 1]; | ||
| 6685 | |||
| 6686 | memset (tmp_path_w, 0, sizeof (tmp_path_w)); | ||
| 6687 | filename_to_utf16 (path, tmp_path_w); | ||
| 6688 | |||
| 6689 | /* On Windows, write permission is required to delete/move files. */ | ||
| 6690 | _wchmod (tmp_path_w, 0666); | ||
| 6691 | |||
| 6692 | memset (&file_op_w, 0, sizeof (file_op_w)); | ||
| 6693 | file_op_w.hwnd = HWND_DESKTOP; | ||
| 6694 | file_op_w.wFunc = FO_DELETE; | ||
| 6695 | file_op_w.pFrom = tmp_path_w; | ||
| 6696 | file_op_w.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO | ||
| 6697 | | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS; | ||
| 6698 | file_op_w.fAnyOperationsAborted = FALSE; | ||
| 6699 | |||
| 6700 | result = SHFileOperationW (&file_op_w); | ||
| 6701 | } | ||
| 6702 | else | ||
| 6703 | { | ||
| 6704 | SHFILEOPSTRUCTA file_op_a; | ||
| 6705 | char tmp_path_a[MAX_PATH + 1]; | ||
| 6672 | 6706 | ||
| 6673 | /* On Windows, write permission is required to delete/move files. */ | 6707 | memset (tmp_path_a, 0, sizeof (tmp_path_a)); |
| 6674 | _chmod (path, 0666); | 6708 | filename_to_ansi (path, tmp_path_a); |
| 6675 | 6709 | ||
| 6676 | memset (tmp_path, 0, sizeof (tmp_path)); | 6710 | /* If a file cannot be represented in ANSI codepage, don't |
| 6677 | strcpy (tmp_path, path); | 6711 | let them inadvertently delete other files because some |
| 6712 | characters are interpreted as a wildcards. */ | ||
| 6713 | if (_mbspbrk (tmp_path_a, "?*")) | ||
| 6714 | result = ERROR_FILE_NOT_FOUND; | ||
| 6715 | else | ||
| 6716 | { | ||
| 6717 | _chmod (tmp_path_a, 0666); | ||
| 6678 | 6718 | ||
| 6679 | memset (&file_op, 0, sizeof (file_op)); | 6719 | memset (&file_op_a, 0, sizeof (file_op_a)); |
| 6680 | file_op.hwnd = HWND_DESKTOP; | 6720 | file_op_a.hwnd = HWND_DESKTOP; |
| 6681 | file_op.wFunc = FO_DELETE; | 6721 | file_op_a.wFunc = FO_DELETE; |
| 6682 | file_op.pFrom = tmp_path; | 6722 | file_op_a.pFrom = tmp_path_a; |
| 6683 | file_op.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO | 6723 | file_op_a.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO |
| 6684 | | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS; | 6724 | | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS; |
| 6685 | file_op.fAnyOperationsAborted = FALSE; | 6725 | file_op_a.fAnyOperationsAborted = FALSE; |
| 6686 | 6726 | ||
| 6687 | if (SHFileOperation (&file_op) != 0) | 6727 | result = SHFileOperationA (&file_op_a); |
| 6688 | report_file_error ("Removing old name", list1 (filename)); | 6728 | } |
| 6689 | } | 6729 | } |
| 6730 | if (result != 0) | ||
| 6731 | report_file_error ("Removing old name", list1 (filename)); | ||
| 6732 | } | ||
| 6690 | return Qnil; | 6733 | return Qnil; |
| 6691 | } | 6734 | } |
| 6692 | 6735 | ||