]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix incompatbilities with MS-Windows 2000 and older
authorJussi Lahdenniemi <jussi@aprikoodi.fi>
Sat, 16 Jan 2016 09:46:14 +0000 (11:46 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 16 Jan 2016 09:46:14 +0000 (11:46 +0200)
* 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

src/w32.c
src/w32.h
src/w32fns.c

index 7884bad619c4d463deb68f0cd150aafb0d3ff8f1..6f1d5fd169862088290d24153f760210568f32ae 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -486,6 +486,7 @@ typedef DWORD (WINAPI *GetAdaptersInfo_Proc) (
 
 int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int);
 int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
+DWORD multiByteToWideCharFlags;
 
   /* ** A utility function ** */
 static BOOL
@@ -1552,8 +1553,8 @@ codepage_for_filenames (CPINFO *cp_info)
 int
 filename_to_utf16 (const char *fn_in, wchar_t *fn_out)
 {
-  int result = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1,
-                                    fn_out, MAX_PATH);
+  int result = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, fn_in,
+                                    -1, fn_out, MAX_PATH);
 
   if (!result)
     {
@@ -1643,8 +1644,8 @@ filename_from_ansi (const char *fn_in, char *fn_out)
 {
   wchar_t fn_utf16[MAX_PATH];
   int codepage = codepage_for_filenames (NULL);
-  int result = pMultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1,
-                                    fn_utf16, MAX_PATH);
+  int result = pMultiByteToWideChar (codepage, multiByteToWideCharFlags, fn_in,
+                                    -1, fn_utf16, MAX_PATH);
 
   if (!result)
     {
@@ -9134,14 +9135,14 @@ check_windows_init_file (void)
                   "not unpacked properly.\nSee the README.W32 file in the "
                   "top-level Emacs directory for more information.",
                   init_file_name, load_path);
-         needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer,
-                                        -1, NULL, 0);
+         needed = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
+                                        buffer, -1, NULL, 0);
          if (needed > 0)
            {
              wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t));
 
-             pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, -1,
-                                   msg_w, needed);
+             pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, buffer,
+                                   -1, msg_w, needed);
              needed = pWideCharToMultiByte (CP_ACP, 0, msg_w, -1,
                                             NULL, 0, NULL, NULL);
              if (needed > 0)
@@ -9328,6 +9329,7 @@ maybe_load_unicows_dll (void)
            (MultiByteToWideChar_Proc)GetProcAddress (ret, "MultiByteToWideChar");
          pWideCharToMultiByte =
            (WideCharToMultiByte_Proc)GetProcAddress (ret, "WideCharToMultiByte");
+          multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
          return ret;
        }
       else
@@ -9357,6 +9359,11 @@ maybe_load_unicows_dll (void)
         pointers; no need for the LoadLibrary dance.  */
       pMultiByteToWideChar = MultiByteToWideChar;
       pWideCharToMultiByte = WideCharToMultiByte;
+      /* On NT 4.0, though, MB_ERR_INVALID_CHARS is not supported.  */
+      if (w32_major_version < 5)
+        multiByteToWideCharFlags = 0;
+      else
+        multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
       return LoadLibrary ("Gdi32.dll");
     }
 }
index ba3fec8b7e6a33c6e32d56262431d176e7f159a6..fde3803c739fd7b01726dbec32fff8345180b91b 100644 (file)
--- a/src/w32.h
+++ b/src/w32.h
@@ -183,6 +183,7 @@ typedef int (WINAPI *MultiByteToWideChar_Proc)(UINT,DWORD,LPCSTR,int,LPWSTR,int)
 typedef int (WINAPI *WideCharToMultiByte_Proc)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
 extern MultiByteToWideChar_Proc pMultiByteToWideChar;
 extern WideCharToMultiByte_Proc pWideCharToMultiByte;
+extern DWORD multiByteToWideCharFlags;
 
 extern void init_environment (char **);
 extern void check_windows_init_file (void);
index f3806a992a007418b3a6c1bedcfd704474a2f137..01f5d6f3ae0f3c2cd5d246f5b91d5a60a04e0843 100644 (file)
@@ -6984,12 +6984,12 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
            if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0)
              report_file_error ("filename too long", default_filename);
          }
-       len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                    SSDATA (prompt), -1, NULL, 0);
        if (len > 32768)
          len = 32768;
        prompt_w = alloca (len * sizeof (wchar_t));
-       pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                              SSDATA (prompt), -1, prompt_w, len);
       }
     else
@@ -7002,12 +7002,12 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
            if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0)
              report_file_error ("filename too long", default_filename);
          }
-       len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                    SSDATA (prompt), -1, NULL, 0);
        if (len > 32768)
          len = 32768;
        prompt_w = alloca (len * sizeof (wchar_t));
-       pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                              SSDATA (prompt), -1, prompt_w, len);
        len = pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL);
        if (len > 32768)
@@ -7489,10 +7489,10 @@ a ShowWindow flag:
   current_dir = ENCODE_FILE (current_dir);
   /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could
      be a URL that is not limited to MAX_PATH chararcters.  */
-  doclen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+  doclen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                 SSDATA (document), -1, NULL, 0);
   doc_w = xmalloc (doclen * sizeof (wchar_t));
-  pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+  pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                        SSDATA (document), -1, doc_w, doclen);
   if (use_unicode)
     {
@@ -7507,12 +7507,12 @@ a ShowWindow flag:
          int len;
 
          parameters = ENCODE_SYSTEM (parameters);
-         len = pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+         len = pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags,
                                      SSDATA (parameters), -1, NULL, 0);
          if (len > 32768)
            len = 32768;
          params_w = alloca (len * sizeof (wchar_t));
-         pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+         pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags,
                                SSDATA (parameters), -1, params_w, len);
          params_w[len - 1] = 0;
        }
@@ -8959,7 +8959,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
         later versions support up to 128.  */
       if (nidw.cbSize == MYNOTIFYICONDATAW_V1_SIZE)
        {
-         tiplen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                         tip, utf8_mbslen_lim (tip, 63),
                                         tipw, 64);
          if (tiplen >= 63)
@@ -8967,7 +8967,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
        }
       else
        {
-         tiplen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                         tip, utf8_mbslen_lim (tip, 127),
                                         tipw, 128);
          if (tiplen >= 127)
@@ -8986,7 +8986,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
        {
          int slen;
 
-         slen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                             msg, utf8_mbslen_lim (msg, 255),
                                             msgw, 256);
          if (slen >= 255)
@@ -8999,7 +8999,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
            }
          wcscpy (nidw.szInfo, msgw);
          nidw.uTimeout = timeout;
-         slen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                       title, utf8_mbslen_lim (title, 63),
                                       titlew, 64);
          if (slen >= 63)
@@ -9670,6 +9670,12 @@ static PVOID except_addr;
 
 /* Stack overflow recovery.  */
 
+/* MinGW headers don't declare this (should be in malloc.h).  Also,
+   the function is not present pre-W2K, so make the call through
+   a function pointer.  */
+typedef int (__cdecl *_resetstkoflw_proc) (void);
+static _resetstkoflw_proc resetstkoflw;
+
 /* Re-establish the guard page at stack limit.  This is needed because
    when a stack overflow is detected, Windows removes the guard bit
    from the guard page, so if we don't re-establish that protection,
@@ -9677,12 +9683,14 @@ static PVOID except_addr;
 void
 w32_reset_stack_overflow_guard (void)
 {
-  /* MinGW headers don't declare this (should be in malloc.h).  */
-  _CRTIMP int __cdecl _resetstkoflw (void);
-
+  if (resetstkoflw == NULL)
+    resetstkoflw =
+      (_resetstkoflw_proc)GetProcAddress (GetModuleHandle ("msvcrt.dll"),
+                                         "_resetstkoflw");
   /* We ignore the return value.  If _resetstkoflw fails, the next
      stack overflow will crash the program.  */
-  (void)_resetstkoflw ();
+  if (resetstkoflw != NULL)
+    (void)resetstkoflw ();
 }
 
 static void
@@ -9927,6 +9935,8 @@ globals_of_w32fns (void)
 
   after_deadkey = -1;
 
+  resetstkoflw = NULL;
+
   /* MessageBox does not work without this when linked to comctl32.dll 6.0.  */
   InitCommonControls ();