comparison src/os_win32.c @ 10571:b726d3ea70bc v8.0.0175

patch 8.0.0175: setting language on MS-Windows does not always work commit https://github.com/vim/vim/commit/972c3b8f1b50e2f887a397c324af99eb354aad0b Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jan 12 21:44:49 2017 +0100 patch 8.0.0175: setting language on MS-Windows does not always work Problem: Setting language in gvim on MS-Windows does not work when libintl.dll is dynamically linked with msvcrt.dll. Solution: Use putenv() from libintl as well. (Ken Takata, closes #1082)
author Christian Brabandt <cb@256bit.org>
date Thu, 12 Jan 2017 21:45:04 +0100
parents 56cb9538386c
children c96534dd2b2f
comparison
equal deleted inserted replaced
10570:33f9dbbfb7e5 10571:b726d3ea70bc
423 } 423 }
424 } 424 }
425 return dll; 425 return dll;
426 } 426 }
427 427
428 #if defined(DYNAMIC_ICONV) || defined(DYNAMIC_GETTEXT) || defined(PROTO)
429 /*
430 * Get related information about 'funcname' which is imported by 'hInst'.
431 * If 'info' is 0, return the function address.
432 * If 'info' is 1, return the module name which the function is imported from.
433 */
434 static void *
435 get_imported_func_info(HINSTANCE hInst, const char *funcname, int info)
436 {
437 PBYTE pImage = (PBYTE)hInst;
438 PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)hInst;
439 PIMAGE_NT_HEADERS pPE;
440 PIMAGE_IMPORT_DESCRIPTOR pImpDesc;
441 PIMAGE_THUNK_DATA pIAT; /* Import Address Table */
442 PIMAGE_THUNK_DATA pINT; /* Import Name Table */
443 PIMAGE_IMPORT_BY_NAME pImpName;
444
445 if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
446 return NULL;
447 pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
448 if (pPE->Signature != IMAGE_NT_SIGNATURE)
449 return NULL;
450 pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
451 + pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
452 .VirtualAddress);
453 for (; pImpDesc->FirstThunk; ++pImpDesc)
454 {
455 if (!pImpDesc->OriginalFirstThunk)
456 continue;
457 pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk);
458 pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk);
459 for (; pIAT->u1.Function; ++pIAT, ++pINT)
460 {
461 if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
462 continue;
463 pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
464 + (UINT_PTR)(pINT->u1.AddressOfData));
465 if (strcmp((char *)pImpName->Name, funcname) == 0)
466 {
467 switch (info)
468 {
469 case 0:
470 return (void *)pIAT->u1.Function;
471 case 1:
472 return (void *)(pImage + pImpDesc->Name);
473 default:
474 return NULL;
475 }
476 }
477 }
478 }
479 return NULL;
480 }
481
482 /*
483 * Get the module handle which 'funcname' in 'hInst' is imported from.
484 */
485 HINSTANCE
486 find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname)
487 {
488 char *modulename;
489
490 modulename = (char *)get_imported_func_info(hInst, funcname, 1);
491 if (modulename != NULL)
492 return GetModuleHandleA(modulename);
493 return NULL;
494 }
495
496 /*
497 * Get the address of 'funcname' which is imported by 'hInst' DLL.
498 */
499 void *
500 get_dll_import_func(HINSTANCE hInst, const char *funcname)
501 {
502 return get_imported_func_info(hInst, funcname, 0);
503 }
504 #endif
505
428 #if defined(DYNAMIC_GETTEXT) || defined(PROTO) 506 #if defined(DYNAMIC_GETTEXT) || defined(PROTO)
429 # ifndef GETTEXT_DLL 507 # ifndef GETTEXT_DLL
430 # define GETTEXT_DLL "libintl.dll" 508 # define GETTEXT_DLL "libintl.dll"
431 # define GETTEXT_DLL_ALT "libintl-8.dll" 509 # define GETTEXT_DLL_ALT "libintl-8.dll"
432 # endif 510 # endif
434 static char *null_libintl_gettext(const char *); 512 static char *null_libintl_gettext(const char *);
435 static char *null_libintl_ngettext(const char *, const char *, unsigned long n); 513 static char *null_libintl_ngettext(const char *, const char *, unsigned long n);
436 static char *null_libintl_textdomain(const char *); 514 static char *null_libintl_textdomain(const char *);
437 static char *null_libintl_bindtextdomain(const char *, const char *); 515 static char *null_libintl_bindtextdomain(const char *, const char *);
438 static char *null_libintl_bind_textdomain_codeset(const char *, const char *); 516 static char *null_libintl_bind_textdomain_codeset(const char *, const char *);
517 static int null_libintl_putenv(const char *);
439 518
440 static HINSTANCE hLibintlDLL = NULL; 519 static HINSTANCE hLibintlDLL = NULL;
441 char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext; 520 char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
442 char *(*dyn_libintl_ngettext)(const char *, const char *, unsigned long n) 521 char *(*dyn_libintl_ngettext)(const char *, const char *, unsigned long n)
443 = null_libintl_ngettext; 522 = null_libintl_ngettext;
444 char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain; 523 char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain;
445 char *(*dyn_libintl_bindtextdomain)(const char *, const char *) 524 char *(*dyn_libintl_bindtextdomain)(const char *, const char *)
446 = null_libintl_bindtextdomain; 525 = null_libintl_bindtextdomain;
447 char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *) 526 char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
448 = null_libintl_bind_textdomain_codeset; 527 = null_libintl_bind_textdomain_codeset;
528 int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv;
449 529
450 int 530 int
451 dyn_libintl_init(void) 531 dyn_libintl_init(void)
452 { 532 {
453 int i; 533 int i;
461 {"ngettext", (FARPROC*)&dyn_libintl_ngettext}, 541 {"ngettext", (FARPROC*)&dyn_libintl_ngettext},
462 {"textdomain", (FARPROC*)&dyn_libintl_textdomain}, 542 {"textdomain", (FARPROC*)&dyn_libintl_textdomain},
463 {"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain}, 543 {"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain},
464 {NULL, NULL} 544 {NULL, NULL}
465 }; 545 };
546 HINSTANCE hmsvcrt;
466 547
467 /* No need to initialize twice. */ 548 /* No need to initialize twice. */
468 if (hLibintlDLL) 549 if (hLibintlDLL)
469 return 1; 550 return 1;
470 /* Load gettext library (libintl.dll) */ 551 /* Load gettext library (libintl.dll) */
505 "bind_textdomain_codeset"); 586 "bind_textdomain_codeset");
506 if (dyn_libintl_bind_textdomain_codeset == NULL) 587 if (dyn_libintl_bind_textdomain_codeset == NULL)
507 dyn_libintl_bind_textdomain_codeset = 588 dyn_libintl_bind_textdomain_codeset =
508 null_libintl_bind_textdomain_codeset; 589 null_libintl_bind_textdomain_codeset;
509 590
591 /* _putenv() function for the libintl.dll is optional. */
592 hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv");
593 if (hmsvcrt != NULL)
594 dyn_libintl_putenv = (void *)GetProcAddress(hmsvcrt, "_putenv");
595 if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == putenv)
596 dyn_libintl_putenv = null_libintl_putenv;
597
510 return 1; 598 return 1;
511 } 599 }
512 600
513 void 601 void
514 dyn_libintl_end(void) 602 dyn_libintl_end(void)
519 dyn_libintl_gettext = null_libintl_gettext; 607 dyn_libintl_gettext = null_libintl_gettext;
520 dyn_libintl_ngettext = null_libintl_ngettext; 608 dyn_libintl_ngettext = null_libintl_ngettext;
521 dyn_libintl_textdomain = null_libintl_textdomain; 609 dyn_libintl_textdomain = null_libintl_textdomain;
522 dyn_libintl_bindtextdomain = null_libintl_bindtextdomain; 610 dyn_libintl_bindtextdomain = null_libintl_bindtextdomain;
523 dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset; 611 dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset;
612 dyn_libintl_putenv = null_libintl_putenv;
524 } 613 }
525 614
526 /*ARGSUSED*/ 615 /*ARGSUSED*/
527 static char * 616 static char *
528 null_libintl_gettext(const char *msgid) 617 null_libintl_gettext(const char *msgid)
558 /*ARGSUSED*/ 647 /*ARGSUSED*/
559 static char * 648 static char *
560 null_libintl_textdomain(const char *domainname) 649 null_libintl_textdomain(const char *domainname)
561 { 650 {
562 return NULL; 651 return NULL;
652 }
653
654 /*ARGSUSED*/
655 int
656 null_libintl_putenv(const char *envstring)
657 {
658 return 0;
563 } 659 }
564 660
565 #endif /* DYNAMIC_GETTEXT */ 661 #endif /* DYNAMIC_GETTEXT */
566 662
567 /* This symbol is not defined in older versions of the SDK or Visual C++ */ 663 /* This symbol is not defined in older versions of the SDK or Visual C++ */
4779 } 4875 }
4780 4876
4781 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) 4877 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
4782 static HANDLE 4878 static HANDLE
4783 job_io_file_open( 4879 job_io_file_open(
4784 char_u *fname, 4880 char_u *fname,
4785 DWORD dwDesiredAccess, 4881 DWORD dwDesiredAccess,
4786 DWORD dwShareMode, 4882 DWORD dwShareMode,
4787 LPSECURITY_ATTRIBUTES lpSecurityAttributes, 4883 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
4788 DWORD dwCreationDisposition, 4884 DWORD dwCreationDisposition,
4789 DWORD dwFlagsAndAttributes) 4885 DWORD dwFlagsAndAttributes)
4790 { 4886 {
4791 HANDLE h; 4887 HANDLE h;
4792 # ifdef FEAT_MBYTE 4888 # ifdef FEAT_MBYTE
4793 WCHAR *wn = NULL; 4889 WCHAR *wn = NULL;
4794 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) 4890 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
4795 { 4891 {
4796 wn = enc_to_utf16(fname, NULL); 4892 wn = enc_to_utf16(fname, NULL);
4797 if (wn != NULL) 4893 if (wn != NULL)
4798 { 4894 {
4799 h = CreateFileW(wn, dwDesiredAccess, dwShareMode, 4895 h = CreateFileW(wn, dwDesiredAccess, dwShareMode,
4800 lpSecurityAttributes, dwCreationDisposition, 4896 lpSecurityAttributes, dwCreationDisposition,
4801 dwFlagsAndAttributes, NULL); 4897 dwFlagsAndAttributes, NULL);
4802 vim_free(wn); 4898 vim_free(wn);
4803 } 4899 }
4804 } 4900 }
4805 if (wn == NULL) 4901 if (wn == NULL)
4806 # endif 4902 # endif
4807 h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode, 4903 h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode,
4808 lpSecurityAttributes, dwCreationDisposition, 4904 lpSecurityAttributes, dwCreationDisposition,
4809 dwFlagsAndAttributes, NULL); 4905 dwFlagsAndAttributes, NULL);
4810 return h; 4906 return h;
4811 } 4907 }
4812 4908
4813 void 4909 void
4814 mch_start_job(char *cmd, job_T *job, jobopt_T *options) 4910 mch_start_job(char *cmd, job_T *job, jobopt_T *options)