diff options
| author | Jussi Lahdenniemi | 2016-01-16 11:46:14 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2016-01-16 11:46:14 +0200 |
| commit | 86e45139698fe773ffb4efbe59387f90201b80c8 (patch) | |
| tree | 591778934aa994ac1b839a9fe2fb3dc40e8ecfcc /src/w32fns.c | |
| parent | 4e96521948b74b8e91eb5a6bca18427f8243bc98 (diff) | |
| download | emacs-86e45139698fe773ffb4efbe59387f90201b80c8.tar.gz emacs-86e45139698fe773ffb4efbe59387f90201b80c8.zip | |
Fix incompatbilities with MS-Windows 2000 and older
* src/w32.c <multiByteToWideCharFlags>: New global variable.
(filename_to_utf16, filename_from_ansi, check_windows_init_file):
Use it instead of the literal MB_ERR_INVALID_CHARS.
(maybe_load_unicows_dll): Initialize multiByteToWideCharFlags as
appropriate for the underlying OS version. For details, see
http://lists.gnu.org/archive/html/emacs-devel/2016-01/msg00835.html.
* src/w32.h: Declare multiByteToWideCharFlags.
* src/w32fns.c (Fx_file_dialog, Fw32_shell_execute)
(add_tray_notification): Use multiByteToWideCharFlags instead of
the literal MB_ERR_INVALID_CHARS.
(_resetstkoflw_proc): New typedef.
(w32_reset_stack_overflow_guard): Call _resetstkoflw via a
pointer, as this function is absent in msvcrt.dll shipped with W2K
and older systems.
Copyright-paperwork-exempt: yes
Diffstat (limited to 'src/w32fns.c')
| -rw-r--r-- | src/w32fns.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/src/w32fns.c b/src/w32fns.c index f3806a992a0..01f5d6f3ae0 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -6984,12 +6984,12 @@ value of DIR as in previous invocations; this is standard Windows behavior. */) | |||
| 6984 | if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0) | 6984 | if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0) |
| 6985 | report_file_error ("filename too long", default_filename); | 6985 | report_file_error ("filename too long", default_filename); |
| 6986 | } | 6986 | } |
| 6987 | len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 6987 | len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 6988 | SSDATA (prompt), -1, NULL, 0); | 6988 | SSDATA (prompt), -1, NULL, 0); |
| 6989 | if (len > 32768) | 6989 | if (len > 32768) |
| 6990 | len = 32768; | 6990 | len = 32768; |
| 6991 | prompt_w = alloca (len * sizeof (wchar_t)); | 6991 | prompt_w = alloca (len * sizeof (wchar_t)); |
| 6992 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 6992 | pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 6993 | SSDATA (prompt), -1, prompt_w, len); | 6993 | SSDATA (prompt), -1, prompt_w, len); |
| 6994 | } | 6994 | } |
| 6995 | else | 6995 | else |
| @@ -7002,12 +7002,12 @@ value of DIR as in previous invocations; this is standard Windows behavior. */) | |||
| 7002 | if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0) | 7002 | if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0) |
| 7003 | report_file_error ("filename too long", default_filename); | 7003 | report_file_error ("filename too long", default_filename); |
| 7004 | } | 7004 | } |
| 7005 | len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 7005 | len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 7006 | SSDATA (prompt), -1, NULL, 0); | 7006 | SSDATA (prompt), -1, NULL, 0); |
| 7007 | if (len > 32768) | 7007 | if (len > 32768) |
| 7008 | len = 32768; | 7008 | len = 32768; |
| 7009 | prompt_w = alloca (len * sizeof (wchar_t)); | 7009 | prompt_w = alloca (len * sizeof (wchar_t)); |
| 7010 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 7010 | pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 7011 | SSDATA (prompt), -1, prompt_w, len); | 7011 | SSDATA (prompt), -1, prompt_w, len); |
| 7012 | len = pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL); | 7012 | len = pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL); |
| 7013 | if (len > 32768) | 7013 | if (len > 32768) |
| @@ -7489,10 +7489,10 @@ a ShowWindow flag: | |||
| 7489 | current_dir = ENCODE_FILE (current_dir); | 7489 | current_dir = ENCODE_FILE (current_dir); |
| 7490 | /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could | 7490 | /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could |
| 7491 | be a URL that is not limited to MAX_PATH chararcters. */ | 7491 | be a URL that is not limited to MAX_PATH chararcters. */ |
| 7492 | doclen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 7492 | doclen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 7493 | SSDATA (document), -1, NULL, 0); | 7493 | SSDATA (document), -1, NULL, 0); |
| 7494 | doc_w = xmalloc (doclen * sizeof (wchar_t)); | 7494 | doc_w = xmalloc (doclen * sizeof (wchar_t)); |
| 7495 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 7495 | pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 7496 | SSDATA (document), -1, doc_w, doclen); | 7496 | SSDATA (document), -1, doc_w, doclen); |
| 7497 | if (use_unicode) | 7497 | if (use_unicode) |
| 7498 | { | 7498 | { |
| @@ -7507,12 +7507,12 @@ a ShowWindow flag: | |||
| 7507 | int len; | 7507 | int len; |
| 7508 | 7508 | ||
| 7509 | parameters = ENCODE_SYSTEM (parameters); | 7509 | parameters = ENCODE_SYSTEM (parameters); |
| 7510 | len = pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, | 7510 | len = pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags, |
| 7511 | SSDATA (parameters), -1, NULL, 0); | 7511 | SSDATA (parameters), -1, NULL, 0); |
| 7512 | if (len > 32768) | 7512 | if (len > 32768) |
| 7513 | len = 32768; | 7513 | len = 32768; |
| 7514 | params_w = alloca (len * sizeof (wchar_t)); | 7514 | params_w = alloca (len * sizeof (wchar_t)); |
| 7515 | pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, | 7515 | pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags, |
| 7516 | SSDATA (parameters), -1, params_w, len); | 7516 | SSDATA (parameters), -1, params_w, len); |
| 7517 | params_w[len - 1] = 0; | 7517 | params_w[len - 1] = 0; |
| 7518 | } | 7518 | } |
| @@ -8959,7 +8959,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip, | |||
| 8959 | later versions support up to 128. */ | 8959 | later versions support up to 128. */ |
| 8960 | if (nidw.cbSize == MYNOTIFYICONDATAW_V1_SIZE) | 8960 | if (nidw.cbSize == MYNOTIFYICONDATAW_V1_SIZE) |
| 8961 | { | 8961 | { |
| 8962 | tiplen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 8962 | tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 8963 | tip, utf8_mbslen_lim (tip, 63), | 8963 | tip, utf8_mbslen_lim (tip, 63), |
| 8964 | tipw, 64); | 8964 | tipw, 64); |
| 8965 | if (tiplen >= 63) | 8965 | if (tiplen >= 63) |
| @@ -8967,7 +8967,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip, | |||
| 8967 | } | 8967 | } |
| 8968 | else | 8968 | else |
| 8969 | { | 8969 | { |
| 8970 | tiplen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 8970 | tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 8971 | tip, utf8_mbslen_lim (tip, 127), | 8971 | tip, utf8_mbslen_lim (tip, 127), |
| 8972 | tipw, 128); | 8972 | tipw, 128); |
| 8973 | if (tiplen >= 127) | 8973 | if (tiplen >= 127) |
| @@ -8986,7 +8986,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip, | |||
| 8986 | { | 8986 | { |
| 8987 | int slen; | 8987 | int slen; |
| 8988 | 8988 | ||
| 8989 | slen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 8989 | slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 8990 | msg, utf8_mbslen_lim (msg, 255), | 8990 | msg, utf8_mbslen_lim (msg, 255), |
| 8991 | msgw, 256); | 8991 | msgw, 256); |
| 8992 | if (slen >= 255) | 8992 | if (slen >= 255) |
| @@ -8999,7 +8999,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip, | |||
| 8999 | } | 8999 | } |
| 9000 | wcscpy (nidw.szInfo, msgw); | 9000 | wcscpy (nidw.szInfo, msgw); |
| 9001 | nidw.uTimeout = timeout; | 9001 | nidw.uTimeout = timeout; |
| 9002 | slen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 9002 | slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 9003 | title, utf8_mbslen_lim (title, 63), | 9003 | title, utf8_mbslen_lim (title, 63), |
| 9004 | titlew, 64); | 9004 | titlew, 64); |
| 9005 | if (slen >= 63) | 9005 | if (slen >= 63) |
| @@ -9670,6 +9670,12 @@ static PVOID except_addr; | |||
| 9670 | 9670 | ||
| 9671 | /* Stack overflow recovery. */ | 9671 | /* Stack overflow recovery. */ |
| 9672 | 9672 | ||
| 9673 | /* MinGW headers don't declare this (should be in malloc.h). Also, | ||
| 9674 | the function is not present pre-W2K, so make the call through | ||
| 9675 | a function pointer. */ | ||
| 9676 | typedef int (__cdecl *_resetstkoflw_proc) (void); | ||
| 9677 | static _resetstkoflw_proc resetstkoflw; | ||
| 9678 | |||
| 9673 | /* Re-establish the guard page at stack limit. This is needed because | 9679 | /* Re-establish the guard page at stack limit. This is needed because |
| 9674 | when a stack overflow is detected, Windows removes the guard bit | 9680 | when a stack overflow is detected, Windows removes the guard bit |
| 9675 | from the guard page, so if we don't re-establish that protection, | 9681 | from the guard page, so if we don't re-establish that protection, |
| @@ -9677,12 +9683,14 @@ static PVOID except_addr; | |||
| 9677 | void | 9683 | void |
| 9678 | w32_reset_stack_overflow_guard (void) | 9684 | w32_reset_stack_overflow_guard (void) |
| 9679 | { | 9685 | { |
| 9680 | /* MinGW headers don't declare this (should be in malloc.h). */ | 9686 | if (resetstkoflw == NULL) |
| 9681 | _CRTIMP int __cdecl _resetstkoflw (void); | 9687 | resetstkoflw = |
| 9682 | 9688 | (_resetstkoflw_proc)GetProcAddress (GetModuleHandle ("msvcrt.dll"), | |
| 9689 | "_resetstkoflw"); | ||
| 9683 | /* We ignore the return value. If _resetstkoflw fails, the next | 9690 | /* We ignore the return value. If _resetstkoflw fails, the next |
| 9684 | stack overflow will crash the program. */ | 9691 | stack overflow will crash the program. */ |
| 9685 | (void)_resetstkoflw (); | 9692 | if (resetstkoflw != NULL) |
| 9693 | (void)resetstkoflw (); | ||
| 9686 | } | 9694 | } |
| 9687 | 9695 | ||
| 9688 | static void | 9696 | static void |
| @@ -9927,6 +9935,8 @@ globals_of_w32fns (void) | |||
| 9927 | 9935 | ||
| 9928 | after_deadkey = -1; | 9936 | after_deadkey = -1; |
| 9929 | 9937 | ||
| 9938 | resetstkoflw = NULL; | ||
| 9939 | |||
| 9930 | /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ | 9940 | /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ |
| 9931 | InitCommonControls (); | 9941 | InitCommonControls (); |
| 9932 | 9942 | ||