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
This commit is contained in:
parent
4e96521948
commit
86e4513969
3 changed files with 42 additions and 24 deletions
23
src/w32.c
23
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
42
src/w32fns.c
42
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,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 ();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue