aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJussi Lahdenniemi2016-01-16 11:46:14 +0200
committerEli Zaretskii2016-01-16 11:46:14 +0200
commit86e45139698fe773ffb4efbe59387f90201b80c8 (patch)
tree591778934aa994ac1b839a9fe2fb3dc40e8ecfcc /src
parent4e96521948b74b8e91eb5a6bca18427f8243bc98 (diff)
downloademacs-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')
-rw-r--r--src/w32.c23
-rw-r--r--src/w32.h1
-rw-r--r--src/w32fns.c42
3 files changed, 42 insertions, 24 deletions
diff --git a/src/w32.c b/src/w32.c
index 7884bad619c..6f1d5fd1698 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -486,6 +486,7 @@ typedef DWORD (WINAPI *GetAdaptersInfo_Proc) (
486 486
487int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int); 487int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int);
488int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL); 488int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
489DWORD multiByteToWideCharFlags;
489 490
490 /* ** A utility function ** */ 491 /* ** A utility function ** */
491static BOOL 492static BOOL
@@ -1552,8 +1553,8 @@ codepage_for_filenames (CPINFO *cp_info)
1552int 1553int
1553filename_to_utf16 (const char *fn_in, wchar_t *fn_out) 1554filename_to_utf16 (const char *fn_in, wchar_t *fn_out)
1554{ 1555{
1555 int result = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1, 1556 int result = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, fn_in,
1556 fn_out, MAX_PATH); 1557 -1, fn_out, MAX_PATH);
1557 1558
1558 if (!result) 1559 if (!result)
1559 { 1560 {
@@ -1643,8 +1644,8 @@ filename_from_ansi (const char *fn_in, char *fn_out)
1643{ 1644{
1644 wchar_t fn_utf16[MAX_PATH]; 1645 wchar_t fn_utf16[MAX_PATH];
1645 int codepage = codepage_for_filenames (NULL); 1646 int codepage = codepage_for_filenames (NULL);
1646 int result = pMultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1, 1647 int result = pMultiByteToWideChar (codepage, multiByteToWideCharFlags, fn_in,
1647 fn_utf16, MAX_PATH); 1648 -1, fn_utf16, MAX_PATH);
1648 1649
1649 if (!result) 1650 if (!result)
1650 { 1651 {
@@ -9134,14 +9135,14 @@ check_windows_init_file (void)
9134 "not unpacked properly.\nSee the README.W32 file in the " 9135 "not unpacked properly.\nSee the README.W32 file in the "
9135 "top-level Emacs directory for more information.", 9136 "top-level Emacs directory for more information.",
9136 init_file_name, load_path); 9137 init_file_name, load_path);
9137 needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, 9138 needed = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
9138 -1, NULL, 0); 9139 buffer, -1, NULL, 0);
9139 if (needed > 0) 9140 if (needed > 0)
9140 { 9141 {
9141 wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t)); 9142 wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t));
9142 9143
9143 pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, -1, 9144 pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, buffer,
9144 msg_w, needed); 9145 -1, msg_w, needed);
9145 needed = pWideCharToMultiByte (CP_ACP, 0, msg_w, -1, 9146 needed = pWideCharToMultiByte (CP_ACP, 0, msg_w, -1,
9146 NULL, 0, NULL, NULL); 9147 NULL, 0, NULL, NULL);
9147 if (needed > 0) 9148 if (needed > 0)
@@ -9328,6 +9329,7 @@ maybe_load_unicows_dll (void)
9328 (MultiByteToWideChar_Proc)GetProcAddress (ret, "MultiByteToWideChar"); 9329 (MultiByteToWideChar_Proc)GetProcAddress (ret, "MultiByteToWideChar");
9329 pWideCharToMultiByte = 9330 pWideCharToMultiByte =
9330 (WideCharToMultiByte_Proc)GetProcAddress (ret, "WideCharToMultiByte"); 9331 (WideCharToMultiByte_Proc)GetProcAddress (ret, "WideCharToMultiByte");
9332 multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
9331 return ret; 9333 return ret;
9332 } 9334 }
9333 else 9335 else
@@ -9357,6 +9359,11 @@ maybe_load_unicows_dll (void)
9357 pointers; no need for the LoadLibrary dance. */ 9359 pointers; no need for the LoadLibrary dance. */
9358 pMultiByteToWideChar = MultiByteToWideChar; 9360 pMultiByteToWideChar = MultiByteToWideChar;
9359 pWideCharToMultiByte = WideCharToMultiByte; 9361 pWideCharToMultiByte = WideCharToMultiByte;
9362 /* On NT 4.0, though, MB_ERR_INVALID_CHARS is not supported. */
9363 if (w32_major_version < 5)
9364 multiByteToWideCharFlags = 0;
9365 else
9366 multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
9360 return LoadLibrary ("Gdi32.dll"); 9367 return LoadLibrary ("Gdi32.dll");
9361 } 9368 }
9362} 9369}
diff --git a/src/w32.h b/src/w32.h
index ba3fec8b7e6..fde3803c739 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -183,6 +183,7 @@ typedef int (WINAPI *MultiByteToWideChar_Proc)(UINT,DWORD,LPCSTR,int,LPWSTR,int)
183typedef int (WINAPI *WideCharToMultiByte_Proc)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL); 183typedef int (WINAPI *WideCharToMultiByte_Proc)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
184extern MultiByteToWideChar_Proc pMultiByteToWideChar; 184extern MultiByteToWideChar_Proc pMultiByteToWideChar;
185extern WideCharToMultiByte_Proc pWideCharToMultiByte; 185extern WideCharToMultiByte_Proc pWideCharToMultiByte;
186extern DWORD multiByteToWideCharFlags;
186 187
187extern void init_environment (char **); 188extern void init_environment (char **);
188extern void check_windows_init_file (void); 189extern void check_windows_init_file (void);
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. */
9676typedef int (__cdecl *_resetstkoflw_proc) (void);
9677static _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;
9677void 9683void
9678w32_reset_stack_overflow_guard (void) 9684w32_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
9688static void 9696static 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