>From adaf947b7d045bbbc6b3fb7febd5e482abf0d28a Mon Sep 17 00:00:00 2001 From: Jussi Lahdenniemi Date: Thu, 14 Jan 2016 14:28:52 +0200 Subject: [PATCH] Windows 98 and NT4 compatibility fixes * w32.h: Add the variable multiByteToWideCharFlags * w32.c: MultiByteToWideChar flags conditional on OS * w32fns.c: Ditto, plus call _resetstkovflw through a function pointer --- src/w32.c | 15 +++++++++++---- src/w32.h | 1 + src/w32fns.c | 39 +++++++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/w32.c b/src/w32.c index 4770718..27a9fea 100644 --- a/src/w32.c +++ b/src/w32.c @@ -484,6 +484,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 @@ -1550,7 +1551,7 @@ 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, + int result = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, fn_in, -1, fn_out, MAX_PATH); if (!result) @@ -1641,7 +1642,7 @@ 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, + int result = pMultiByteToWideChar (codepage, multiByteToWideCharFlags, fn_in, -1, fn_utf16, MAX_PATH); if (!result) @@ -9081,13 +9082,13 @@ 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, + 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, + pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, buffer, -1, msg_w, needed); needed = pWideCharToMultiByte (CP_ACP, 0, msg_w, -1, NULL, 0, NULL, NULL); @@ -9275,6 +9276,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 @@ -9304,6 +9306,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"); } } diff --git a/src/w32.h b/src/w32.h index 501056d..097241b 100644 --- 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); diff --git a/src/w32fns.c b/src/w32fns.c index f3806a9..3778557 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. */) 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,11 @@ 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-Win2000, so make the call through + a function pointer. */ +typedef int (__cdecl *_resetstkoflw_proc) (void); + /* 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 +9682,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); - + static _resetstkoflw_proc resetstkoflw; + 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 -- 2.6.2