From 4538a137e089240f1981f0d6f82fb8d63a65f4f6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 13 Nov 2019 20:55:03 +0100 Subject: [PATCH] ntdll: Move locale functions to a new locale.c file. Signed-off-by: Alexandre Julliard --- dlls/ntdll/Makefile.in | 1 + dlls/ntdll/directory.c | 134 ----------------------- dlls/ntdll/loader.c | 1 + dlls/ntdll/locale.c | 236 ++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll_misc.h | 4 +- dlls/ntdll/resource.c | 59 +--------- 6 files changed, 242 insertions(+), 193 deletions(-) create mode 100644 dlls/ntdll/locale.c diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index 9b4d70f6e8a..491cf5a707c 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -24,6 +24,7 @@ C_SRCS = \ large_int.c \ loader.c \ loadorder.c \ + locale.c \ misc.c \ nt.c \ om.c \ diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 75549347015..64b0afc4ca0 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -30,8 +30,6 @@ #endif #include #include -#include -#include #include #include #include @@ -169,8 +167,6 @@ struct file_identity static struct file_identity ignored_files[MAX_IGNORED_FILES]; static unsigned int ignored_files_count; -static const union cptable *unix_table; /* NULL if UTF8 */ - union file_directory_info { ULONG next; @@ -233,115 +229,6 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug = static RTL_CRITICAL_SECTION dir_section = { &critsect_debug, -1, 0, 0, 0, 0 }; -#if !defined(__APPLE__) && !defined(__ANDROID__) /* these platforms always use UTF-8 */ - -/* charset to codepage map, sorted by name */ -static const struct { const char *name; UINT cp; } charset_names[] = -{ - { "ANSIX341968", 20127 }, - { "BIG5", 950 }, - { "BIG5HKSCS", 950 }, - { "CP1250", 1250 }, - { "CP1251", 1251 }, - { "CP1252", 1252 }, - { "CP1253", 1253 }, - { "CP1254", 1254 }, - { "CP1255", 1255 }, - { "CP1256", 1256 }, - { "CP1257", 1257 }, - { "CP1258", 1258 }, - { "CP932", 932 }, - { "CP936", 936 }, - { "CP949", 949 }, - { "CP950", 950 }, - { "EUCJP", 20932 }, - { "EUCKR", 949 }, - { "GB18030", 936 /* 54936 */ }, - { "GB2312", 936 }, - { "GBK", 936 }, - { "IBM037", 37 }, - { "IBM1026", 1026 }, - { "IBM424", 424 }, - { "IBM437", 437 }, - { "IBM500", 500 }, - { "IBM850", 850 }, - { "IBM852", 852 }, - { "IBM855", 855 }, - { "IBM857", 857 }, - { "IBM860", 860 }, - { "IBM861", 861 }, - { "IBM862", 862 }, - { "IBM863", 863 }, - { "IBM864", 864 }, - { "IBM865", 865 }, - { "IBM866", 866 }, - { "IBM869", 869 }, - { "IBM874", 874 }, - { "IBM875", 875 }, - { "ISO88591", 28591 }, - { "ISO885910", 28600 }, - { "ISO885911", 28601 }, - { "ISO885913", 28603 }, - { "ISO885914", 28604 }, - { "ISO885915", 28605 }, - { "ISO885916", 28606 }, - { "ISO88592", 28592 }, - { "ISO88593", 28593 }, - { "ISO88594", 28594 }, - { "ISO88595", 28595 }, - { "ISO88596", 28596 }, - { "ISO88597", 28597 }, - { "ISO88598", 28598 }, - { "ISO88599", 28599 }, - { "KOI8R", 20866 }, - { "KOI8U", 21866 }, - { "TIS620", 28601 }, - { "UTF8", CP_UTF8 } -}; - -static void init_unix_codepage(void) -{ - char charset_name[16]; - const char *name; - size_t i, j; - int min = 0, max = ARRAY_SIZE(charset_names) - 1; - - setlocale( LC_CTYPE, "" ); - if (!(name = nl_langinfo( CODESET ))) return; - - /* remove punctuation characters from charset name */ - for (i = j = 0; name[i] && j < sizeof(charset_name)-1; i++) - if (isalnum((unsigned char)name[i])) charset_name[j++] = name[i]; - charset_name[j] = 0; - - while (min <= max) - { - int pos = (min + max) / 2; - int res = _strnicmp( charset_names[pos].name, charset_name, -1 ); - if (!res) - { - if (charset_names[pos].cp == CP_UTF8) return; - unix_table = wine_cp_get_table( charset_names[pos].cp ); - return; - } - if (res > 0) max = pos - 1; - else min = pos + 1; - } - ERR( "unrecognized charset '%s'\n", name ); -} - -#else /* __APPLE__ || __ANDROID__ */ - -static void init_unix_codepage(void) { } - -#endif /* __APPLE__ || __ANDROID__ */ - -UINT CDECL __wine_get_unix_codepage(void) -{ - if (!unix_table) return CP_UTF8; - return unix_table->info.codepage; -} - /* check if a given Unicode char is OK in a DOS short name */ static inline BOOL is_invalid_dos_char( WCHAR ch ) { @@ -508,26 +395,6 @@ static void free_dir_data( struct dir_data *data ) RtlFreeHeap( GetProcessHeap(), 0, data ); } -int ntdll_umbstowcs( DWORD flags, const char *src, int srclen, WCHAR *dst, int dstlen ) -{ -#ifdef __APPLE__ - /* work around broken Mac OS X filesystem that enforces decomposed Unicode */ - flags |= MB_COMPOSITE; -#endif - return unix_table ? - wine_cp_mbstowcs( unix_table, flags, src, srclen, dst, dstlen ) : - wine_utf8_mbstowcs( flags, src, srclen, dst, dstlen ); -} - -int ntdll_wcstoumbs( DWORD flags, const WCHAR *src, int srclen, char *dst, int dstlen, - const char *defchar, int *used ) -{ - if (unix_table) - return wine_cp_wcstombs( unix_table, flags, src, srclen, dst, dstlen, defchar, used ); - if (used) *used = 0; /* all chars are valid for UTF-8 */ - return wine_utf8_wcstombs( flags, src, srclen, dst, dstlen ); -} - /* support for a directory queue for filesystem searches */ @@ -2452,7 +2319,6 @@ static int get_redirect_path( char *unix_name, int pos, const WCHAR *name, int l */ void init_directories(void) { - init_unix_codepage(); #ifndef _WIN64 if (is_wow64) init_redirects(); #endif diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index d550b6ae123..f8e1d0f589b 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -4251,6 +4251,7 @@ void __wine_process_init(void) peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL ); peb->LoaderLock = &loader_section; + init_unix_codepage(); init_directories(); init_user_process_params( info_size ); diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c new file mode 100644 index 00000000000..71c4391ea72 --- /dev/null +++ b/dlls/ntdll/locale.c @@ -0,0 +1,236 @@ +/* + * Locale functions + * + * Copyright 2004, 2019 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "ntdll_misc.h" +#include "wine/unicode.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(nls); + +LCID user_lcid = 0, system_lcid = 0; + +static LANGID user_ui_language, system_ui_language; +static const union cptable *unix_table; /* NULL if UTF8 */ + +#if !defined(__APPLE__) && !defined(__ANDROID__) /* these platforms always use UTF-8 */ + +/* charset to codepage map, sorted by name */ +static const struct { const char *name; UINT cp; } charset_names[] = +{ + { "ANSIX341968", 20127 }, + { "BIG5", 950 }, + { "BIG5HKSCS", 950 }, + { "CP1250", 1250 }, + { "CP1251", 1251 }, + { "CP1252", 1252 }, + { "CP1253", 1253 }, + { "CP1254", 1254 }, + { "CP1255", 1255 }, + { "CP1256", 1256 }, + { "CP1257", 1257 }, + { "CP1258", 1258 }, + { "CP932", 932 }, + { "CP936", 936 }, + { "CP949", 949 }, + { "CP950", 950 }, + { "EUCJP", 20932 }, + { "EUCKR", 949 }, + { "GB18030", 936 /* 54936 */ }, + { "GB2312", 936 }, + { "GBK", 936 }, + { "IBM037", 37 }, + { "IBM1026", 1026 }, + { "IBM424", 424 }, + { "IBM437", 437 }, + { "IBM500", 500 }, + { "IBM850", 850 }, + { "IBM852", 852 }, + { "IBM855", 855 }, + { "IBM857", 857 }, + { "IBM860", 860 }, + { "IBM861", 861 }, + { "IBM862", 862 }, + { "IBM863", 863 }, + { "IBM864", 864 }, + { "IBM865", 865 }, + { "IBM866", 866 }, + { "IBM869", 869 }, + { "IBM874", 874 }, + { "IBM875", 875 }, + { "ISO88591", 28591 }, + { "ISO885910", 28600 }, + { "ISO885911", 28601 }, + { "ISO885913", 28603 }, + { "ISO885914", 28604 }, + { "ISO885915", 28605 }, + { "ISO885916", 28606 }, + { "ISO88592", 28592 }, + { "ISO88593", 28593 }, + { "ISO88594", 28594 }, + { "ISO88595", 28595 }, + { "ISO88596", 28596 }, + { "ISO88597", 28597 }, + { "ISO88598", 28598 }, + { "ISO88599", 28599 }, + { "KOI8R", 20866 }, + { "KOI8U", 21866 }, + { "TIS620", 28601 }, + { "UTF8", CP_UTF8 } +}; + +void init_unix_codepage(void) +{ + char charset_name[16]; + const char *name; + size_t i, j; + int min = 0, max = ARRAY_SIZE(charset_names) - 1; + + setlocale( LC_CTYPE, "" ); + if (!(name = nl_langinfo( CODESET ))) return; + + /* remove punctuation characters from charset name */ + for (i = j = 0; name[i] && j < sizeof(charset_name)-1; i++) + if (isalnum((unsigned char)name[i])) charset_name[j++] = name[i]; + charset_name[j] = 0; + + while (min <= max) + { + int pos = (min + max) / 2; + int res = _strnicmp( charset_names[pos].name, charset_name, -1 ); + if (!res) + { + if (charset_names[pos].cp == CP_UTF8) return; + unix_table = wine_cp_get_table( charset_names[pos].cp ); + return; + } + if (res > 0) max = pos - 1; + else min = pos + 1; + } + ERR( "unrecognized charset '%s'\n", name ); +} + +#else /* __APPLE__ || __ANDROID__ */ + +void init_unix_codepage(void) { } + +#endif /* __APPLE__ || __ANDROID__ */ + + +/****************************************************************** + * ntdll_umbstowcs + */ +int ntdll_umbstowcs( DWORD flags, const char *src, int srclen, WCHAR *dst, int dstlen ) +{ +#ifdef __APPLE__ + /* work around broken Mac OS X filesystem that enforces decomposed Unicode */ + flags |= MB_COMPOSITE; +#endif + return unix_table ? + wine_cp_mbstowcs( unix_table, flags, src, srclen, dst, dstlen ) : + wine_utf8_mbstowcs( flags, src, srclen, dst, dstlen ); +} + + +/****************************************************************** + * ntdll_wcstoumbs + */ +int ntdll_wcstoumbs( DWORD flags, const WCHAR *src, int srclen, char *dst, int dstlen, + const char *defchar, int *used ) +{ + if (unix_table) + return wine_cp_wcstombs( unix_table, flags, src, srclen, dst, dstlen, defchar, used ); + if (used) *used = 0; /* all chars are valid for UTF-8 */ + return wine_utf8_wcstombs( flags, src, srclen, dst, dstlen ); +} + + +/****************************************************************** + * __wine_get_unix_codepage (NTDLL.@) + */ +UINT CDECL __wine_get_unix_codepage(void) +{ + if (!unix_table) return CP_UTF8; + return unix_table->info.codepage; +} + + +/********************************************************************** + * NtQueryDefaultLocale (NTDLL.@) + */ +NTSTATUS WINAPI NtQueryDefaultLocale( BOOLEAN user, LCID *lcid ) +{ + *lcid = user ? user_lcid : system_lcid; + return STATUS_SUCCESS; +} + + +/********************************************************************** + * NtSetDefaultLocale (NTDLL.@) + */ +NTSTATUS WINAPI NtSetDefaultLocale( BOOLEAN user, LCID lcid ) +{ + if (user) user_lcid = lcid; + else + { + system_lcid = lcid; + system_ui_language = LANGIDFROMLCID(lcid); /* there is no separate call to set it */ + } + return STATUS_SUCCESS; +} + + +/********************************************************************** + * NtQueryDefaultUILanguage (NTDLL.@) + */ +NTSTATUS WINAPI NtQueryDefaultUILanguage( LANGID *lang ) +{ + *lang = user_ui_language; + return STATUS_SUCCESS; +} + + +/********************************************************************** + * NtSetDefaultUILanguage (NTDLL.@) + */ +NTSTATUS WINAPI NtSetDefaultUILanguage( LANGID lang ) +{ + user_ui_language = lang; + return STATUS_SUCCESS; +} + + +/********************************************************************** + * NtQueryInstallUILanguage (NTDLL.@) + */ +NTSTATUS WINAPI NtQueryInstallUILanguage( LANGID *lang ) +{ + *lang = system_ui_language; + return STATUS_SUCCESS; +} diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index ac146941236..758bd49ec6f 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -85,6 +85,7 @@ extern void virtual_init(void) DECLSPEC_HIDDEN; extern void virtual_init_threading(void) DECLSPEC_HIDDEN; extern void fill_cpu_info(void) DECLSPEC_HIDDEN; extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN; +extern void init_unix_codepage(void) DECLSPEC_HIDDEN; extern void init_user_process_params( SIZE_T data_size ) DECLSPEC_HIDDEN; extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN; extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN; @@ -200,7 +201,8 @@ extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN; extern NTSTATUS NTDLL_AddCompletion( HANDLE hFile, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, ULONG Information, BOOL async) DECLSPEC_HIDDEN; -/* code pages */ +/* locale */ +extern LCID user_lcid, system_lcid; extern int ntdll_umbstowcs(DWORD flags, const char* src, int srclen, WCHAR* dst, int dstlen) DECLSPEC_HIDDEN; extern int ntdll_wcstoumbs(DWORD flags, const WCHAR* src, int srclen, char* dst, int dstlen, const char* defchar, int *used ) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/resource.c b/dlls/ntdll/resource.c index f649e200cba..4a81ab84b59 100644 --- a/dlls/ntdll/resource.c +++ b/dlls/ntdll/resource.c @@ -40,6 +40,7 @@ #include "winbase.h" #include "winnt.h" #include "winternl.h" +#include "ntdll_misc.h" #include "wine/asm.h" #include "wine/exception.h" #include "wine/unicode.h" @@ -47,9 +48,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(resource); -static LCID user_lcid, system_lcid; -static LANGID user_ui_language, system_ui_language; - #define IS_INTRESOURCE(x) (((ULONG_PTR)(x) >> 16) == 0) /********************************************************************** @@ -450,58 +448,3 @@ NTSTATUS WINAPI RtlFormatMessage( LPWSTR Message, UCHAR MaxWidth, ArgumentIsArray ? "TRUE" : "FALSE", Arguments, Buffer, BufferSize); return STATUS_SUCCESS; } - - -/********************************************************************** - * NtQueryDefaultLocale (NTDLL.@) - */ -NTSTATUS WINAPI NtQueryDefaultLocale( BOOLEAN user, LCID *lcid ) -{ - *lcid = user ? user_lcid : system_lcid; - return STATUS_SUCCESS; -} - - -/********************************************************************** - * NtSetDefaultLocale (NTDLL.@) - */ -NTSTATUS WINAPI NtSetDefaultLocale( BOOLEAN user, LCID lcid ) -{ - if (user) user_lcid = lcid; - else - { - system_lcid = lcid; - system_ui_language = LANGIDFROMLCID(lcid); /* there is no separate call to set it */ - } - return STATUS_SUCCESS; -} - - -/********************************************************************** - * NtQueryDefaultUILanguage (NTDLL.@) - */ -NTSTATUS WINAPI NtQueryDefaultUILanguage( LANGID *lang ) -{ - *lang = user_ui_language; - return STATUS_SUCCESS; -} - - -/********************************************************************** - * NtSetDefaultUILanguage (NTDLL.@) - */ -NTSTATUS WINAPI NtSetDefaultUILanguage( LANGID lang ) -{ - user_ui_language = lang; - return STATUS_SUCCESS; -} - - -/********************************************************************** - * NtQueryInstallUILanguage (NTDLL.@) - */ -NTSTATUS WINAPI NtQueryInstallUILanguage( LANGID *lang ) -{ - *lang = system_ui_language; - return STATUS_SUCCESS; -}