ntdll / kernel32: #40
Eric Pouech
pouech-eric at wanadoo.fr
Sat Jan 3 03:48:07 CST 2004
This patch allows to use the UNIX code page inside of ntdll.
The full change log:
- moved code page & NLS resources from kernel32 to ntdll
- moved locale initialisation from kernel32 to ntdll
- created unix code page handling in ntdll
- made use of this unix cp for the initial environment creation (in PEB)
in order to keep the size of the patch small, I didn't include in the
patch the bits for moving dlls/kernel32/locale.rc (resp.
dlls/kernel32/nls/*) to dlls/ntdll/locale.rc (resp dlls/ntdll/nls/*).
This should be done by hand.
A+
-------------- next part --------------
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel39/kernel.rc dlls/kernel/kernel.rc
--- dlls/kernel39/kernel.rc 2004-01-01 09:53:31.000000000 +0100
+++ dlls/kernel/kernel.rc 2004-01-01 09:53:34.000000000 +0100
@@ -16,8 +16,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "locale_rc.rc"
-
#include "messages/winerr_enu.mc.rc"
#include "version.rc"
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel39/locale.c dlls/kernel/locale.c
--- dlls/kernel39/locale.c 2004-01-01 09:53:31.000000000 +0100
+++ dlls/kernel/locale.c 2004-01-01 09:53:34.000000000 +0100
@@ -47,7 +47,7 @@
#define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|LOCALE_RETURN_NUMBER)
-static const WCHAR kernel32W[] = { 'K','E','R','N','E','L','3','2','\0' };
+static const WCHAR ntdllW[] = { 'N','T','D','L','L','\0' };
/* current code pages */
static const union cptable *ansi_cptable;
@@ -55,103 +55,6 @@
static const union cptable *mac_cptable;
static const union cptable *unix_cptable; /* NULL if UTF8 */
-/* Charset to codepage map, sorted by name. */
-static const struct charset_entry
-{
- const char *charset_name;
- UINT codepage;
-} charset_names[] =
-{
- { "CP1250", 1250 },
- { "CP1251", 1251 },
- { "CP1252", 1252 },
- { "CP1253", 1253 },
- { "CP1254", 1254 },
- { "CP1255", 1255 },
- { "CP1256", 1256 },
- { "CP1257", 1257 },
- { "CP1258", 1258 },
- { "EUCJP", 20932 },
- { "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 },
- { "ISO885913", 28603 },
- { "ISO885914", 28604 },
- { "ISO885915", 28605 },
- { "ISO88592", 28592 },
- { "ISO88593", 28593 },
- { "ISO88594", 28594 },
- { "ISO88595", 28595 },
- { "ISO88596", 28596 },
- { "ISO88597", 28597 },
- { "ISO88598", 28598 },
- { "ISO88599", 28599 },
- { "KOI8R", 20866 },
- { "KOI8U", 20866 },
- { "UTF8", CP_UTF8 }
-};
-
-#define NLS_MAX_LANGUAGES 20
-typedef struct {
- WCHAR lang[128];
- WCHAR country[4];
- LANGID found_lang_id[NLS_MAX_LANGUAGES];
- WCHAR found_language[NLS_MAX_LANGUAGES][3];
- WCHAR found_country[NLS_MAX_LANGUAGES][3];
- int n_found;
-} LANG_FIND_DATA;
-
-
-/* copy Unicode string to Ascii without using codepages */
-static inline void strcpyWtoA( char *dst, const WCHAR *src )
-{
- while ((*dst++ = *src++));
-}
-
-/* Copy Ascii string to Unicode without using codepages */
-static inline void strcpynAtoW( WCHAR *dst, const char *src, size_t n )
-{
- while (n > 1 && *src)
- {
- *dst++ = (unsigned char)*src++;
- n--;
- }
- if (n) *dst = 0;
-}
-
-/* return a printable string for a language id */
-static const char *debugstr_lang( LANGID lang )
-{
- WCHAR langW[4], countryW[4];
- char buffer[8];
- LCID lcid = MAKELCID( lang, SORT_DEFAULT );
-
- GetLocaleInfoW(lcid, LOCALE_SISO639LANGNAME|LOCALE_NOUSEROVERRIDE, langW, sizeof(langW));
- GetLocaleInfoW(lcid, LOCALE_SISO3166CTRYNAME|LOCALE_NOUSEROVERRIDE, countryW, sizeof(countryW));
- strcpyWtoA( buffer, langW );
- strcat( buffer, "_" );
- strcpyWtoA( buffer + strlen(buffer), countryW );
- return wine_dbg_sprintf( "%s", buffer );
-}
-
/***********************************************************************
* get_lcid_codepage
*
@@ -177,7 +80,7 @@
assert( ansi_cptable ); /* init must have been done already */
- switch(codepage)
+ switch (codepage)
{
case CP_ACP:
return ansi_cptable;
@@ -303,232 +206,6 @@
}
}
-
-/***********************************************************************
- * find_language_id_proc
- */
-static BOOL CALLBACK find_language_id_proc( HMODULE hModule, LPCWSTR type,
- LPCWSTR name, WORD LangID, LPARAM lParam )
-{
- LANG_FIND_DATA *l_data = (LANG_FIND_DATA *)lParam;
- LCID lcid = MAKELCID(LangID, SORT_DEFAULT);
- WCHAR buf_language[128];
- WCHAR buf_country[128];
- WCHAR buf_en_language[128];
-
- if(PRIMARYLANGID(LangID) == LANG_NEUTRAL)
- return TRUE; /* continue search */
-
- buf_language[0] = 0;
- buf_country[0] = 0;
-
- GetLocaleInfoW(lcid, LOCALE_SISO639LANGNAME|LOCALE_NOUSEROVERRIDE,
- buf_language, sizeof(buf_language));
- GetLocaleInfoW(lcid, LOCALE_SISO3166CTRYNAME|LOCALE_NOUSEROVERRIDE,
- buf_country, sizeof(buf_country));
-
- if(l_data->lang[0] && !strcmpiW(l_data->lang, buf_language))
- {
- if(l_data->country[0])
- {
- if(!strcmpiW(l_data->country, buf_country))
- {
- l_data->found_lang_id[0] = LangID;
- l_data->n_found = 1;
- TRACE("Found id %04X for lang %s country %s\n",
- LangID, debugstr_w(l_data->lang), debugstr_w(l_data->country));
- return FALSE; /* stop enumeration */
- }
- }
- else goto found; /* l_data->country not specified */
- }
-
- /* Just in case, check LOCALE_SENGLANGUAGE too,
- * in hope that possible alias name might have that value.
- */
- buf_en_language[0] = 0;
- GetLocaleInfoW(lcid, LOCALE_SENGLANGUAGE|LOCALE_NOUSEROVERRIDE,
- buf_en_language, sizeof(buf_en_language));
-
- if(l_data->lang[0] && !strcmpiW(l_data->lang, buf_en_language)) goto found;
- return TRUE; /* not found, continue search */
-
-found:
- l_data->found_lang_id[l_data->n_found] = LangID;
- strncpyW(l_data->found_country[l_data->n_found], buf_country, 3);
- strncpyW(l_data->found_language[l_data->n_found], buf_language, 3);
- l_data->n_found++;
- TRACE("Found id %04X for lang %s\n", LangID, debugstr_w(l_data->lang));
- return (l_data->n_found < NLS_MAX_LANGUAGES); /* continue search, unless we have enough */
-}
-
-
-/***********************************************************************
- * get_language_id
- *
- * INPUT:
- * Lang: a string whose two first chars are the iso name of a language.
- * Country: a string whose two first chars are the iso name of country
- * Charset: a string defining the chosen charset encoding
- * Dialect: a string defining a variation of the locale
- *
- * all those values are from the standardized format of locale
- * name in unix which is: Lang[_Country][.Charset][@Dialect]
- *
- * RETURNS:
- * the numeric code of the language used by Windows
- *
- * FIXME: Charset and Dialect are not handled
- */
-static LANGID get_language_id(LPCSTR Lang, LPCSTR Country, LPCSTR Charset, LPCSTR Dialect)
-{
- LANG_FIND_DATA l_data;
- HMODULE hKernel32;
-
- if(!Lang)
- {
- l_data.found_lang_id[0] = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
- goto END;
- }
-
- l_data.n_found = 0;
- strcpynAtoW(l_data.lang, Lang, sizeof(l_data.lang));
-
- if (Country) strcpynAtoW(l_data.country, Country, sizeof(l_data.country));
- else l_data.country[0] = 0;
-
- hKernel32 = GetModuleHandleW(kernel32W);
-
- EnumResourceLanguagesW(hKernel32, (LPCWSTR)RT_STRING, (LPCWSTR)LOCALE_ILANGUAGE,
- find_language_id_proc, (LPARAM)&l_data);
-
- if (l_data.n_found == 1) goto END;
-
- if(!l_data.n_found)
- {
- if(l_data.country[0])
- {
- /* retry without country name */
- l_data.country[0] = 0;
- EnumResourceLanguagesW(hKernel32, (LPCWSTR)RT_STRING, (LPCWSTR)LOCALE_ILANGUAGE,
- find_language_id_proc, (LONG)&l_data);
- if (!l_data.n_found)
- {
- MESSAGE("Warning: Language '%s_%s' was not recognized, defaulting to English.\n",
- Lang, Country);
- l_data.found_lang_id[0] = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
- }
- else MESSAGE("Warning: Language '%s_%s' was not recognized, defaulting to '%s'.\n",
- Lang, Country, debugstr_lang(l_data.found_lang_id[0]) );
- }
- else
- {
- MESSAGE("Warning: Language '%s' was not recognized, defaulting to English.\n", Lang);
- l_data.found_lang_id[0] = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
- }
- }
- else
- {
- int i;
-
- if (Country && Country[0])
- MESSAGE("For language '%s_%s' several language ids were found:\n", Lang, Country);
- else
- MESSAGE("For language '%s' several language ids were found:\n", Lang);
-
- /* print a list of languages with their description */
- for (i = 0; i < l_data.n_found; i++)
- {
- WCHAR buffW[128];
- char buffA[128];
- GetLocaleInfoW( MAKELCID( l_data.found_lang_id[i], SORT_DEFAULT ),
- LOCALE_SLANGUAGE|LOCALE_NOUSEROVERRIDE, buffW, sizeof(buffW));
- strcpyWtoA( buffA, buffW );
- MESSAGE( " %s (%04X) - %s\n", debugstr_lang(l_data.found_lang_id[i]),
- l_data.found_lang_id[i], buffA );
- }
- MESSAGE("Defaulting to '%s'. You should specify the exact language you want\n"
- "by defining your LANG environment variable like this: LANG=%s\n",
- debugstr_lang(l_data.found_lang_id[0]), debugstr_lang(l_data.found_lang_id[0]) );
- }
-END:
- TRACE("Returning %04X (%s)\n", l_data.found_lang_id[0], debugstr_lang(l_data.found_lang_id[0]));
- return l_data.found_lang_id[0];
-}
-
-
-/***********************************************************************
- * charset_cmp (internal)
- */
-static int charset_cmp( const void *name, const void *entry )
-{
- const struct charset_entry *charset = (struct charset_entry *)entry;
- return strcasecmp( (char *)name, charset->charset_name );
-}
-
-/***********************************************************************
- * init_default_lcid
- */
-static LCID init_default_lcid( UINT *unix_cp )
-{
- char *buf, *lang,*country,*charset,*dialect,*next;
- LCID ret = 0;
-
- if ((lang = getenv( "LC_ALL" )) ||
- (lang = getenv( "LC_CTYPE" )) ||
- (lang = getenv( "LANGUAGE" )) ||
- (lang = getenv( "LC_MESSAGES" )) ||
- (lang = getenv( "LANG" )))
- {
- if (!strcmp(lang,"POSIX") || !strcmp(lang,"C")) goto done;
-
- buf = RtlAllocateHeap( GetProcessHeap(), 0, strlen(lang) + 1 );
- strcpy( buf, lang );
- lang=buf;
-
- do {
- next=strchr(lang,':'); if (next) *next++='\0';
- dialect=strchr(lang,'@'); if (dialect) *dialect++='\0';
- charset=strchr(lang,'.'); if (charset) *charset++='\0';
- country=strchr(lang,'_'); if (country) *country++='\0';
-
- ret = get_language_id(lang, country, charset, dialect);
- if (ret && charset)
- {
- const struct charset_entry *entry;
- char charset_name[16];
- size_t i, j;
-
- /* remove punctuation characters from charset name */
- for (i = j = 0; charset[i] && j < sizeof(charset_name)-1; i++)
- if (isalnum(charset[i])) charset_name[j++] = charset[i];
- charset_name[j] = 0;
-
- entry = bsearch( charset_name, charset_names,
- sizeof(charset_names)/sizeof(charset_names[0]),
- sizeof(charset_names[0]), charset_cmp );
- if (entry)
- {
- *unix_cp = entry->codepage;
- TRACE("charset %s was mapped to cp %u\n", charset, *unix_cp);
- }
- else
- FIXME("charset %s was not recognized\n", charset);
- }
-
- lang=next;
- } while (lang && !ret);
-
- if (!ret) MESSAGE("Warning: language '%s' not recognized, defaulting to English\n", buf);
- RtlFreeHeap( GetProcessHeap(), 0, buf );
- }
-
- done:
- if (!ret) ret = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT) ;
- return ret;
-}
-
-
/***********************************************************************
* GetUserDefaultLangID (KERNEL32.@)
*
@@ -945,7 +622,7 @@
if (SUBLANGID(lang_id) == SUBLANG_NEUTRAL)
lang_id = MAKELANGID(PRIMARYLANGID(lang_id), SUBLANG_DEFAULT);
- hModule = GetModuleHandleW( kernel32W );
+ hModule = GetModuleHandleW( ntdllW );
if (!(hrsrc = FindResourceExW( hModule, (LPWSTR)RT_STRING, (LPCWSTR)((lctype >> 4) + 1), lang_id )))
{
SetLastError( ERROR_INVALID_FLAGS ); /* no such lctype */
@@ -1189,7 +866,7 @@
*/
BOOL WINAPI IsValidCodePage( UINT codepage )
{
- switch(codepage) {
+ switch (codepage) {
case CP_SYMBOL:
return FALSE;
case CP_UTF7:
@@ -1423,7 +1100,7 @@
if (flags & MB_USEGLYPHCHARS) FIXME("MB_USEGLYPHCHARS not supported\n");
- switch(page)
+ switch (page)
{
case CP_UTF7:
FIXME("UTF-7 not supported\n");
@@ -1451,7 +1128,7 @@
if (ret < 0)
{
- switch(ret)
+ switch (ret)
{
case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
@@ -1501,7 +1178,7 @@
if (srclen < 0) srclen = strlenW(src) + 1;
- switch(page)
+ switch (page)
{
case CP_UTF7:
FIXME("UTF-7 not supported\n");
@@ -1651,7 +1328,7 @@
BOOL WINAPI IsValidLocale( LCID lcid, DWORD flags )
{
/* check if language is registered in the kernel32 resources */
- return FindResourceExW( GetModuleHandleW(kernel32W), (LPWSTR)RT_STRING,
+ return FindResourceExW( GetModuleHandleW(ntdllW), (LPWSTR)RT_STRING,
(LPCWSTR)LOCALE_ILANGUAGE, LANGIDFROMLCID(lcid)) != 0;
}
@@ -1692,7 +1369,7 @@
BOOL WINAPI EnumSystemLocalesA( LOCALE_ENUMPROCA lpfnLocaleEnum, DWORD dwFlags )
{
TRACE("(%p,%08lx)\n", lpfnLocaleEnum, dwFlags);
- EnumResourceLanguagesA( GetModuleHandleW(kernel32W), (LPSTR)RT_STRING,
+ EnumResourceLanguagesA( GetModuleHandleW(ntdllW), (LPSTR)RT_STRING,
(LPCSTR)LOCALE_ILANGUAGE, enum_lang_proc_a,
(LONG)lpfnLocaleEnum);
return TRUE;
@@ -1707,7 +1384,7 @@
BOOL WINAPI EnumSystemLocalesW( LOCALE_ENUMPROCW lpfnLocaleEnum, DWORD dwFlags )
{
TRACE("(%p,%08lx)\n", lpfnLocaleEnum, dwFlags);
- EnumResourceLanguagesW( GetModuleHandleW(kernel32W), (LPWSTR)RT_STRING,
+ EnumResourceLanguagesW( GetModuleHandleW(ntdllW), (LPWSTR)RT_STRING,
(LPCWSTR)LOCALE_ILANGUAGE, enum_lang_proc_w,
(LONG)lpfnLocaleEnum);
return TRUE;
@@ -1754,7 +1431,7 @@
BOOL WINAPI GetStringTypeW( DWORD type, LPCWSTR src, INT count, LPWORD chartype )
{
if (count == -1) count = strlenW(src) + 1;
- switch(type)
+ switch (type)
{
case CT_CTYPE1:
while (count--) *chartype++ = get_char_typeW( *src++ ) & 0xfff;
@@ -2389,22 +2066,18 @@
*/
void LOCALE_Init(void)
{
- extern void __wine_init_codepages( const union cptable *ansi_cp, const union cptable *oem_cp );
-
- UINT ansi_cp = 1252, oem_cp = 437, mac_cp = 10000, unix_cp = ~0U;
- LCID lcid = init_default_lcid( &unix_cp );
+ LCID lcid;
+ UINT ansi_cp, oem_cp, mac_cp, unix_cp;
- NtSetDefaultLocale( FALSE, lcid );
- NtSetDefaultLocale( TRUE, lcid );
+ NtQueryDefaultLocale( TRUE, &lcid );
ansi_cp = get_lcid_codepage(lcid);
+
GetLocaleInfoW( lcid, LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
(LPWSTR)&mac_cp, sizeof(mac_cp)/sizeof(WCHAR) );
GetLocaleInfoW( lcid, LOCALE_IDEFAULTCODEPAGE | LOCALE_RETURN_NUMBER,
(LPWSTR)&oem_cp, sizeof(oem_cp)/sizeof(WCHAR) );
- if (unix_cp == ~0U)
- GetLocaleInfoW( lcid, LOCALE_IDEFAULTUNIXCODEPAGE | LOCALE_RETURN_NUMBER,
- (LPWSTR)&unix_cp, sizeof(unix_cp)/sizeof(WCHAR) );
+ unix_cp = NtCurrentTeb()->Peb->unix_code_page;
if (!(ansi_cptable = wine_cp_get_table( ansi_cp )))
ansi_cptable = wine_cp_get_table( 1252 );
@@ -2412,13 +2085,9 @@
oem_cptable = wine_cp_get_table( 437 );
if (!(mac_cptable = wine_cp_get_table( mac_cp )))
mac_cptable = wine_cp_get_table( 10000 );
- if (unix_cp != CP_UTF8)
- {
- if (!(unix_cptable = wine_cp_get_table( unix_cp )))
- unix_cptable = wine_cp_get_table( 28591 );
- }
- __wine_init_codepages( ansi_cptable, oem_cptable );
+ if (unix_cp != CP_UTF8 && !(unix_cptable = wine_cp_get_table( unix_cp )))
+ unix_cptable = wine_cp_get_table( 28591 );
TRACE( "ansi=%03d oem=%03d mac=%03d unix=%03d\n",
ansi_cptable->info.codepage, oem_cptable->info.codepage,
@@ -2523,7 +2192,7 @@
static BOOL NLS_GetLanguageGroupName(LGRPID lgrpid, LPWSTR szName, ULONG nameSize)
{
- HMODULE hModule = GetModuleHandleW(kernel32W);
+ HMODULE hModule = GetModuleHandleW(ntdllW);
LANGID langId;
LPCWSTR szResourceName = (LPCWSTR)(((lgrpid + 0x2000) >> 4) + 1);
HRSRC hResource;
@@ -3030,3 +2699,6 @@
FIXME("%ld\n",GeoID);
return FALSE;
}
+
+
+
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel39/process.c dlls/kernel/process.c
--- dlls/kernel39/process.c 2004-01-01 09:53:31.000000000 +0100
+++ dlls/kernel/process.c 2004-01-02 17:35:25.000000000 +0100
@@ -333,48 +333,6 @@
return module;
}
-/***********************************************************************
- * build_initial_environment
- *
- * Build the Win32 environment from the Unix environment
- */
-static BOOL build_initial_environment( char **environ )
-{
- ULONG size = 1;
- char **e;
- WCHAR *p, *endptr;
- void *ptr;
-
- /* Compute the total size of the Unix environment */
- for (e = environ; *e; e++)
- {
- if (!memcmp(*e, "PATH=", 5)) continue;
- size += MultiByteToWideChar( CP_UNIXCP, 0, *e, -1, NULL, 0 );
- }
- size *= sizeof(WCHAR);
-
- /* Now allocate the environment */
- if (NtAllocateVirtualMemory(NtCurrentProcess(), &ptr, 0, &size,
- MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) != STATUS_SUCCESS)
- return FALSE;
-
- NtCurrentTeb()->Peb->ProcessParameters->Environment = p = ptr;
- endptr = p + size / sizeof(WCHAR);
-
- /* And fill it with the Unix environment */
- for (e = environ; *e; e++)
- {
- char *str = *e;
- /* skip Unix PATH and store WINEPATH as PATH */
- if (!memcmp(str, "PATH=", 5)) continue;
- if (!memcmp(str, "WINEPATH=", 9 )) str += 4;
- MultiByteToWideChar( CP_UNIXCP, 0, str, -1, p, endptr - p );
- p += strlenW(p) + 1;
- }
- *p = 0;
- return TRUE;
-}
-
/***********************************************************************
* set_library_wargv
@@ -611,7 +569,7 @@
*
* Main process initialisation code
*/
-static BOOL process_init( char *argv[], char **environ )
+static BOOL process_init( char *argv[] )
{
BOOL ret;
size_t info_size = 0;
@@ -695,9 +653,6 @@
LOCALE_Init();
- /* Copy the parent environment */
- if (!build_initial_environment( environ )) return FALSE;
-
/* Parse command line arguments */
OPTIONS_ParseOptions( !info_size ? argv : NULL );
@@ -771,7 +726,7 @@
PEB *peb = NtCurrentTeb()->Peb;
/* Initialize everything */
- if (!process_init( __wine_main_argv, __wine_main_environ )) exit(1);
+ if (!process_init( __wine_main_argv )) exit(1);
/* update argc in case options have been removed */
for (__wine_main_argc = 0; __wine_main_argv[__wine_main_argc]; __wine_main_argc++) /*nothing*/;
@@ -1152,7 +1107,6 @@
return NULL;
}
- params->Environment = NULL; /* we pass it through the Unix environment */
params->hStdInput = startup->hStdInput;
params->hStdOutput = startup->hStdOutput;
params->hStdError = startup->hStdError;
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll39/env.c dlls/ntdll/env.c
--- dlls/ntdll39/env.c 2004-01-01 09:53:16.000000000 +0100
+++ dlls/ntdll/env.c 2004-01-02 20:29:36.000000000 +0100
@@ -29,10 +29,53 @@
#include "winternl.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/library.h"
#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL(environ);
+/***********************************************************************
+ * build_initial_environment
+ *
+ * Build the Win32 environment from the Unix environment
+ */
+BOOL build_initial_environment( void )
+{
+ ULONG size = 1;
+ char **e;
+ WCHAR *p, *endptr;
+ void* new_env;
+
+ /* Compute the total size of the Unix environment */
+ for (e = __wine_main_environ; *e; e++)
+ {
+ if (!memcmp(*e, "PATH=", 5)) continue;
+ size += ntdll_mbs2wcs( 0, *e, strlen(*e) + 1, NULL, 0 );
+ }
+ size *= sizeof(WCHAR);
+
+ /* Now allocate the environment */
+ if (NtAllocateVirtualMemory(NtCurrentProcess(), &new_env, 0, &size,
+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) != STATUS_SUCCESS)
+ return FALSE;
+ p = ntdll_get_process_pmts()->Environment = new_env;
+ endptr = p + size / sizeof(WCHAR);
+
+ /* And fill it with the Unix environment */
+ for (e = __wine_main_environ; *e; e++)
+ {
+ char *str = *e;
+ /* skip Unix PATH and store WINEPATH as PATH */
+ if (!memcmp(str, "PATH=", 5)) continue;
+ if (!memcmp(str, "WINEPATH=", 9 )) str += 4;
+ ntdll_mbs2wcs( 0, str, strlen(str) + 1, p, endptr - p );
+ p += strlenW(p) + 1;
+ }
+ *p = 0;
+ return TRUE;
+}
+
+
/******************************************************************************
* RtlCreateEnvironment [NTDLL.@]
*/
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll39/loader.c dlls/ntdll/loader.c
--- dlls/ntdll39/loader.c 2004-01-02 20:34:06.000000000 +0100
+++ dlls/ntdll/loader.c 2004-01-02 20:45:31.000000000 +0100
@@ -1962,6 +1962,9 @@
/* setup the load callback and create ntdll modref */
wine_dll_set_callback( load_builtin_callback );
+ LOCALE_Init();
+ build_initial_environment();
+
if ((status = load_builtin_dll( NULL, kernel32W, 0, &wm )) != STATUS_SUCCESS)
{
MESSAGE( "wine: could not load kernel32.dll, status %lx\n", status );
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll39/locale.c dlls/ntdll/locale.c
--- dlls/ntdll39/locale.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/ntdll/locale.c 2004-01-01 09:53:20.000000000 +0100
@@ -0,0 +1,517 @@
+/*
+ * Locale support
+ *
+ * Copyright 1995 Martin von Loewis
+ * Copyright 1998 David Lee Lambert
+ * Copyright 2000 Julio César Gázquez
+ * Copyright 2002 Alexandre Julliard for CodeWeavers
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "wine/port.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "ntstatus.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h" /* for RT_STRINGW */
+#include "winreg.h"
+#include "winternl.h"
+#include "wine/unicode.h"
+#include "winnls.h"
+#include "winerror.h"
+#include "thread.h"
+#include "ntdll_misc.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(nls);
+
+#define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|LOCALE_RETURN_NUMBER)
+
+UINT NlsAnsiCodePage = 0;
+BYTE NlsMbCodePageTag = 0;
+BYTE NlsMbOemCodePageTag = 0;
+
+/* current code page tables */
+const union cptable *ansi_cptable;
+const union cptable *oem_cptable;
+const union cptable *unix_cptable; /* NULL if UTF8 */
+
+/* Charset to codepage map, sorted by name. */
+static const struct charset_entry
+{
+ const char *charset_name;
+ UINT codepage;
+} charset_names[] =
+{
+ { "CP1250", 1250 },
+ { "CP1251", 1251 },
+ { "CP1252", 1252 },
+ { "CP1253", 1253 },
+ { "CP1254", 1254 },
+ { "CP1255", 1255 },
+ { "CP1256", 1256 },
+ { "CP1257", 1257 },
+ { "CP1258", 1258 },
+ { "EUCJP", 20932 },
+ { "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 },
+ { "ISO885913", 28603 },
+ { "ISO885914", 28604 },
+ { "ISO885915", 28605 },
+ { "ISO88592", 28592 },
+ { "ISO88593", 28593 },
+ { "ISO88594", 28594 },
+ { "ISO88595", 28595 },
+ { "ISO88596", 28596 },
+ { "ISO88597", 28597 },
+ { "ISO88598", 28598 },
+ { "ISO88599", 28599 },
+ { "KOI8R", 20866 },
+ { "KOI8U", 20866 },
+ { "UTF8", CP_UTF8 }
+};
+
+#define NLS_MAX_LANGUAGES 20
+typedef struct {
+ WCHAR lang[128];
+ WCHAR country[4];
+ LANGID found_lang_id[NLS_MAX_LANGUAGES];
+ WCHAR found_language[NLS_MAX_LANGUAGES][3];
+ WCHAR found_country[NLS_MAX_LANGUAGES][3];
+ int n_found;
+} LANG_FIND_DATA;
+
+
+/* copy Unicode string to Ascii without using codepages */
+static inline void strcpyWtoA( char *dst, const WCHAR *src )
+{
+ while ((*dst++ = *src++));
+}
+
+/* Copy Ascii string to Unicode without using codepages */
+static inline void strcpynAtoW( WCHAR *dst, const char *src, size_t n )
+{
+ while (n > 1 && *src)
+ {
+ *dst++ = (unsigned char)*src++;
+ n--;
+ }
+ if (n) *dst = 0;
+}
+
+static LPCWSTR get_locale_info_head( LCID lcid, LCTYPE lctype )
+{
+ LANGID lang_id;
+ LDR_RESOURCE_INFO info;
+ const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
+ UINT i, lcflags;
+ LPCWSTR p;
+ LDR_MODULE* mod;
+
+ lang_id = LANGIDFROMLCID(lcid);
+ if (SUBLANGID(lang_id) == SUBLANG_NEUTRAL)
+ {
+ lang_id = MAKELANGID(PRIMARYLANGID(lang_id), SUBLANG_DEFAULT);
+ lcid = MAKELCID(lang_id, SORTIDFROMLCID(lcid));
+ }
+
+ lcflags = lctype & LOCALE_LOCALEINFOFLAGSMASK;
+ lctype &= 0xffff;
+
+ /* now load it from kernel resources */
+ info.Type = (ULONG)RT_STRING;
+ info.Name = (lctype >> 4) + 1;
+ info.Language = lang_id;
+
+ mod = CONTAINING_RECORD(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList.Flink->Flink, LDR_MODULE, InLoadOrderModuleList);
+
+ if (LdrFindResource_U( mod->BaseAddress, &info, 3, &entry ) ||
+ LdrAccessResource( mod->BaseAddress, entry, (void**)&p, NULL )) return NULL;
+
+ for (i = 0; i < (lctype & 0x0f); i++) p += *p + 1;
+ return p;
+}
+
+static BOOL get_locale_info_number( LCID lcid, LCTYPE lctype, UINT* val )
+{
+ LPCWSTR p;
+ LPWSTR end, tmp;
+ BOOL ret;
+
+ p = get_locale_info_head(lcid, lctype);
+ if (!p) return FALSE;
+
+ tmp = RtlAllocateHeap( GetProcessHeap(), 0, (*p + 1) * sizeof(WCHAR) );
+ if (!tmp) return FALSE;
+ memcpy( tmp, p + 1, *p * sizeof(WCHAR) );
+ tmp[*p] = 0;
+ *val = strtolW( tmp, &end, 10 );
+ ret = !*end;
+ RtlFreeHeap( GetProcessHeap(), 0, tmp );
+
+ TRACE( "(lcid=0x%lx,lctype=0x%lx) returning number %d\n", lcid, lctype, *val );
+ return ret;
+}
+
+static UINT get_locale_info_str( LCID lcid, LCTYPE lctype, WCHAR* buffer, INT len)
+{
+ LPCWSTR p;
+ UINT efflen;
+
+ p = get_locale_info_head(lcid, lctype);
+ if (!p) return 0;
+
+ efflen = (lctype == LOCALE_FONTSIGNATURE) ? *p : *p + 1;
+
+ if (buffer && efflen <= len)
+ {
+ memcpy( buffer, p + 1, *p * sizeof(WCHAR) );
+ if (lctype != LOCALE_FONTSIGNATURE) buffer[efflen-1] = 0;
+
+ TRACE( "(lcid=0x%lx,lctype=0x%lx,%p,%d) returning %d %s\n",
+ lcid, lctype, buffer, len, efflen, debugstr_w(buffer) );
+ }
+ return efflen;
+}
+
+
+/* return a printable string for a language id */
+static const char *debugstr_lang( LANGID lang )
+{
+ WCHAR langW[4], countryW[4];
+ char buffer[8];
+ LCID lcid = MAKELCID( lang, SORT_DEFAULT );
+
+ get_locale_info_str(lcid, LOCALE_SISO639LANGNAME|LOCALE_NOUSEROVERRIDE, langW, sizeof(langW));
+ get_locale_info_str(lcid, LOCALE_SISO3166CTRYNAME|LOCALE_NOUSEROVERRIDE, countryW, sizeof(countryW));
+ strcpyWtoA( buffer, langW );
+ strcat( buffer, "_" );
+ strcpyWtoA( buffer + strlen(buffer), countryW );
+ return wine_dbg_sprintf( "%s", buffer );
+}
+
+/***********************************************************************
+ * get_lcid_codepage
+ *
+ * Retrieve the ANSI codepage for a given locale.
+ */
+inline static UINT get_lcid_codepage( LCID lcid )
+{
+ UINT ret;
+ if (!get_locale_info_number( lcid, LOCALE_IDEFAULTANSICODEPAGE, &ret ))
+ ret = 0;
+ return ret;
+}
+
+/***********************************************************************
+ * find_language_id_proc
+ */
+static BOOL find_language_id_proc( WORD LangID, LONG_PTR lParam )
+{
+ LANG_FIND_DATA *l_data = (LANG_FIND_DATA *)lParam;
+ LCID lcid = MAKELCID(LangID, SORT_DEFAULT);
+ WCHAR buf_language[128];
+ WCHAR buf_country[128];
+ WCHAR buf_en_language[128];
+
+ if (PRIMARYLANGID(LangID) == LANG_NEUTRAL)
+ return TRUE; /* continue search */
+
+ buf_language[0] = 0;
+ buf_country[0] = 0;
+
+ get_locale_info_str(lcid, LOCALE_SISO639LANGNAME, buf_language, sizeof(buf_language));
+ get_locale_info_str(lcid, LOCALE_SISO3166CTRYNAME, buf_country, sizeof(buf_country));
+
+ if (l_data->lang[0] && !strcmpiW(l_data->lang, buf_language))
+ {
+ if (l_data->country[0])
+ {
+ if (!strcmpiW(l_data->country, buf_country))
+ {
+ l_data->found_lang_id[0] = LangID;
+ l_data->n_found = 1;
+ TRACE("Found id %04X for lang %s country %s\n",
+ LangID, debugstr_w(l_data->lang), debugstr_w(l_data->country));
+ return FALSE; /* stop enumeration */
+ }
+ }
+ else goto found; /* l_data->country not specified */
+ }
+
+ /* Just in case, check LOCALE_SENGLANGUAGE too,
+ * in hope that possible alias name might have that value.
+ */
+ buf_en_language[0] = 0;
+ get_locale_info_str(lcid, LOCALE_SENGLANGUAGE, buf_en_language, sizeof(buf_en_language));
+
+ if (l_data->lang[0] && !strcmpiW(l_data->lang, buf_en_language)) goto found;
+ return TRUE; /* not found, continue search */
+
+found:
+ l_data->found_lang_id[l_data->n_found] = LangID;
+ strncpyW(l_data->found_country[l_data->n_found], buf_country, 3);
+ strncpyW(l_data->found_language[l_data->n_found], buf_language, 3);
+ l_data->n_found++;
+ TRACE("Found id %04X for lang %s\n", LangID, debugstr_w(l_data->lang));
+ return (l_data->n_found < NLS_MAX_LANGUAGES); /* continue search, unless we have enough */
+}
+
+static NTSTATUS enum_res_lang(HMODULE hmod, BOOL (*lpfun)(WORD, LONG_PTR), LONG_PTR lparam)
+{
+ int i;
+ NTSTATUS status = STATUS_INVALID_PARAMETER;
+ LDR_RESOURCE_INFO info;
+ const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
+
+ if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
+ goto done;
+ info.Type = (ULONG)RT_STRING;
+ info.Name = (ULONG)LOCALE_ILANGUAGE;
+ if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS)
+ goto done;
+
+ status = STATUS_SUCCESS;
+ et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
+ for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
+ {
+ if (!lpfun( et[i].u1.s2.Id, lparam )) break;
+ }
+done:
+ return status;
+}
+
+/***********************************************************************
+ * get_language_id
+ *
+ * INPUT:
+ * Lang: a string whose two first chars are the iso name of a language.
+ * Country: a string whose two first chars are the iso name of country
+ * Charset: a string defining the chosen charset encoding
+ * Dialect: a string defining a variation of the locale
+ *
+ * all those values are from the standardized format of locale
+ * name in unix which is: Lang[_Country][.Charset][@Dialect]
+ *
+ * RETURNS:
+ * the numeric code of the language used by Windows
+ *
+ * FIXME: Charset and Dialect are not handled
+ */
+static LANGID get_language_id(LPCSTR Lang, LPCSTR Country, LPCSTR Charset, LPCSTR Dialect)
+{
+ LANG_FIND_DATA l_data;
+ LDR_MODULE* mod;
+
+ if (!Lang)
+ {
+ l_data.found_lang_id[0] = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
+ goto END;
+ }
+
+ l_data.n_found = 0;
+ strcpynAtoW(l_data.lang, Lang, sizeof(l_data.lang));
+
+ if (Country) strcpynAtoW(l_data.country, Country, sizeof(l_data.country));
+ else l_data.country[0] = 0;
+
+ mod = CONTAINING_RECORD(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList.Flink->Flink, LDR_MODULE, InLoadOrderModuleList);
+
+ enum_res_lang(mod->BaseAddress, find_language_id_proc, (LPARAM)&l_data);
+
+ if (l_data.n_found == 1) goto END;
+
+ if (!l_data.n_found)
+ {
+ if (l_data.country[0])
+ {
+ /* retry without country name */
+ l_data.country[0] = 0;
+ enum_res_lang(mod->BaseAddress, find_language_id_proc, (LONG)&l_data);
+ if (!l_data.n_found)
+ {
+ MESSAGE("Warning: Language '%s_%s' was not recognized, defaulting to English.\n",
+ Lang, Country);
+ l_data.found_lang_id[0] = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
+ }
+ else MESSAGE("Warning: Language '%s_%s' was not recognized, defaulting to '%s'.\n",
+ Lang, Country, debugstr_lang(l_data.found_lang_id[0]) );
+ }
+ else
+ {
+ MESSAGE("Warning: Language '%s' was not recognized, defaulting to English.\n", Lang);
+ l_data.found_lang_id[0] = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
+ }
+ }
+ else
+ {
+ int i;
+
+ if (Country && Country[0])
+ MESSAGE("For language '%s_%s' several language ids were found:\n", Lang, Country);
+ else
+ MESSAGE("For language '%s' several language ids were found:\n", Lang);
+
+ /* print a list of languages with their description */
+ for (i = 0; i < l_data.n_found; i++)
+ {
+ WCHAR buffW[128];
+ char buffA[128];
+ get_locale_info_str( MAKELCID( l_data.found_lang_id[i], SORT_DEFAULT ),
+ LOCALE_SLANGUAGE, buffW, sizeof(buffW));
+ strcpyWtoA( buffA, buffW );
+ MESSAGE( " %s (%04X) - %s\n", debugstr_lang(l_data.found_lang_id[i]),
+ l_data.found_lang_id[i], buffA );
+ }
+ MESSAGE("Defaulting to '%s'. You should specify the exact language you want\n"
+ "by defining your LANG environment variable like this: LANG=%s\n",
+ debugstr_lang(l_data.found_lang_id[0]), debugstr_lang(l_data.found_lang_id[0]) );
+ }
+END:
+ TRACE("Returning %04X (%s)\n", l_data.found_lang_id[0], debugstr_lang(l_data.found_lang_id[0]));
+ return l_data.found_lang_id[0];
+}
+
+
+/***********************************************************************
+ * charset_cmp (internal)
+ */
+static int charset_cmp( const void *name, const void *entry )
+{
+ const struct charset_entry *charset = (struct charset_entry *)entry;
+ return strcasecmp( (char *)name, charset->charset_name );
+}
+
+/***********************************************************************
+ * init_default_lcid
+ */
+static LCID init_default_lcid( UINT *unix_cp )
+{
+ char *buf, *lang, *country, *charset, *dialect, *next;
+ LCID ret = 0;
+
+ if ((lang = getenv( "LC_ALL" )) ||
+ (lang = getenv( "LC_CTYPE" )) ||
+ (lang = getenv( "LANGUAGE" )) ||
+ (lang = getenv( "LC_MESSAGES" )) ||
+ (lang = getenv( "LANG" )))
+ {
+ if (!strcmp(lang, "POSIX") || !strcmp(lang, "C")) goto done;
+ if ((buf = RtlAllocateHeap( GetProcessHeap(), 0, strlen(lang) + 1 )))
+ strcpy( buf, lang );
+
+ for (lang = buf; lang && !ret; lang = next)
+ {
+ next = strchr(lang,':'); if (next) *next++ = '\0';
+ dialect = strchr(lang,'@'); if (dialect) *dialect++ = '\0';
+ charset = strchr(lang,'.'); if (charset) *charset++ = '\0';
+ country = strchr(lang,'_'); if (country) *country++ = '\0';
+
+ ret = get_language_id(lang, country, charset, dialect);
+ if (ret && charset)
+ {
+ const struct charset_entry *entry;
+ char charset_name[16];
+ size_t i, j;
+
+ /* remove punctuation characters from charset name */
+ for (i = j = 0; charset[i] && j < sizeof(charset_name)-1; i++)
+ if (isalnum(charset[i])) charset_name[j++] = charset[i];
+ charset_name[j] = 0;
+
+ entry = bsearch( charset_name, charset_names,
+ sizeof(charset_names)/sizeof(charset_names[0]),
+ sizeof(charset_names[0]), charset_cmp );
+ if (entry)
+ {
+ *unix_cp = entry->codepage;
+ TRACE("charset %s was mapped to cp %u\n", charset, *unix_cp);
+ }
+ else
+ FIXME("charset %s was not recognized\n", charset);
+ }
+ }
+
+ if (!ret) MESSAGE("Warning: language '%s' not recognized, defaulting to English\n", buf);
+ RtlFreeHeap( GetProcessHeap(), 0, buf );
+ }
+
+ done:
+ if (!ret) ret = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT) ;
+ return ret;
+}
+
+/******************************************************************************
+ * LOCALE_Init
+ */
+void LOCALE_Init(void)
+{
+ UINT ansi_cp = 1252, oem_cp = 437, unix_cp = ~0U;
+ LCID lcid;
+
+ lcid = init_default_lcid( &unix_cp );
+
+ NtSetDefaultLocale( FALSE, lcid );
+ NtSetDefaultLocale( TRUE, lcid );
+
+ ansi_cp = get_lcid_codepage(lcid);
+ get_locale_info_number( lcid, LOCALE_IDEFAULTCODEPAGE, &oem_cp );
+ if (unix_cp == ~0U)
+ get_locale_info_number( lcid, LOCALE_IDEFAULTUNIXCODEPAGE, &unix_cp );
+
+ if (!(ansi_cptable = wine_cp_get_table( ansi_cp )))
+ ansi_cptable = wine_cp_get_table( 1252 );
+ if (!(oem_cptable = wine_cp_get_table( oem_cp )))
+ oem_cptable = wine_cp_get_table( 437 );
+ if (unix_cp != CP_UTF8 && !(unix_cptable = wine_cp_get_table( unix_cp )))
+ unix_cptable = wine_cp_get_table( 28591 );
+
+ NlsAnsiCodePage = ansi_cptable->info.codepage;
+ NtCurrentTeb()->Peb->unix_code_page = unix_cp;
+
+ TRACE( "ansi=%03d oem=%03d unix=%03d\n",
+ ansi_cptable->info.codepage, oem_cptable->info.codepage, unix_cp );
+}
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll39/Makefile.in dlls/ntdll/Makefile.in
--- dlls/ntdll39/Makefile.in 2004-01-01 09:53:17.000000000 +0100
+++ dlls/ntdll/Makefile.in 2004-01-01 09:53:19.000000000 +0100
@@ -18,6 +18,7 @@
large_int.c \
loader.c \
loadorder.c \
+ locale.c \
misc.c \
nt.c \
om.c \
@@ -42,6 +43,8 @@
virtual.c \
wcstring.c
+RC_SRCS = locale_rc.rc
+
ASM_SRCS = relay32.s
EXTRA_OBJS = $(ASM_SRCS:.s=.o)
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll39/ntdll_misc.h dlls/ntdll/ntdll_misc.h
--- dlls/ntdll39/ntdll_misc.h 2004-01-01 09:53:17.000000000 +0100
+++ dlls/ntdll/ntdll_misc.h 2004-01-02 20:44:51.000000000 +0100
@@ -29,6 +29,7 @@
#include "winternl.h"
#include "thread.h"
#include "wine/server.h"
+#include "wine/unicode.h"
/* The per-thread signal stack size */
#ifdef __i386__
@@ -46,6 +47,8 @@
const LARGE_INTEGER *timeout );
/* init routines */
+extern BOOL build_initial_environment(void);
+extern void LOCALE_Init(void);
extern BOOL SIGNAL_Init(void);
extern void thread_init(void);
@@ -100,4 +103,16 @@
extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg);
extern DWORD VIRTUAL_HandleFault(LPCVOID addr);
+/* locale */
+extern const union cptable *ansi_cptable;
+extern const union cptable *oem_cptable;
+extern const union cptable *unix_cptable; /* NULL if UTF8 */
+
+static inline int ntdll_mbs2wcs(DWORD flags, const char* src, int srclen, WCHAR* dst, int dstlen)
+{
+ return (unix_cptable) ?
+ wine_cp_mbstowcs( unix_cptable, flags, src, srclen, dst, dstlen ) :
+ wine_utf8_mbstowcs( flags, src, srclen, dst, dstlen );
+}
+
#endif
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll39/ntdll.spec dlls/ntdll/ntdll.spec
--- dlls/ntdll39/ntdll.spec 2004-01-01 09:53:18.000000000 +0100
+++ dlls/ntdll/ntdll.spec 2004-01-01 09:53:20.000000000 +0100
@@ -1075,9 +1075,6 @@
@ cdecl wine_server_release_fd(long long)
@ cdecl wine_server_send_fd(long)
-# Codepages
-@ cdecl __wine_init_codepages(ptr ptr)
-
# signal handling
@ cdecl __wine_set_signal_handler(long ptr)
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll39/rtlstr.c dlls/ntdll/rtlstr.c
--- dlls/ntdll39/rtlstr.c 2004-01-01 09:53:17.000000000 +0100
+++ dlls/ntdll/rtlstr.c 2004-01-01 09:53:19.000000000 +0100
@@ -38,25 +38,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
-UINT NlsAnsiCodePage = 0;
-BYTE NlsMbCodePageTag = 0;
-BYTE NlsMbOemCodePageTag = 0;
-
-static const union cptable *ansi_table;
-static const union cptable *oem_table;
-
-/**************************************************************************
- * __wine_init_codepages (NTDLL.@)
- *
- * Set the code page once kernel32 is loaded. Should be done differently.
- */
-void __wine_init_codepages( const union cptable *ansi, const union cptable *oem )
-{
- ansi_table = ansi;
- oem_table = oem;
- NlsAnsiCodePage = ansi->info.codepage;
-}
-
/**************************************************************************
* RtlInitAnsiString (NTDLL.@)
@@ -706,7 +690,7 @@
LPCSTR src, DWORD srclen )
{
- int ret = wine_cp_mbstowcs( ansi_table, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
+ int ret = wine_cp_mbstowcs( ansi_cptable, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
if (reslen)
*reslen = (ret >= 0) ? ret*sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
return STATUS_SUCCESS;
@@ -719,7 +703,7 @@
NTSTATUS WINAPI RtlOemToUnicodeN( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
LPCSTR src, DWORD srclen )
{
- int ret = wine_cp_mbstowcs( oem_table, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
+ int ret = wine_cp_mbstowcs( oem_cptable, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
if (reslen)
*reslen = (ret >= 0) ? ret*sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
return STATUS_SUCCESS;
@@ -732,7 +716,7 @@
NTSTATUS WINAPI RtlUnicodeToMultiByteN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
LPCWSTR src, DWORD srclen )
{
- int ret = wine_cp_wcstombs( ansi_table, 0, src, srclen / sizeof(WCHAR),
+ int ret = wine_cp_wcstombs( ansi_cptable, 0, src, srclen / sizeof(WCHAR),
dst, dstlen, NULL, NULL );
if (reslen)
*reslen = (ret >= 0) ? ret : dstlen; /* overflow -> we filled up to dstlen */
@@ -746,7 +730,7 @@
NTSTATUS WINAPI RtlUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
LPCWSTR src, DWORD srclen )
{
- int ret = wine_cp_wcstombs( oem_table, 0, src, srclen / sizeof(WCHAR),
+ int ret = wine_cp_wcstombs( oem_cptable, 0, src, srclen / sizeof(WCHAR),
dst, dstlen, NULL, NULL );
if (reslen)
*reslen = (ret >= 0) ? ret : dstlen; /* overflow -> we filled up to dstlen */
@@ -1070,7 +1054,7 @@
*/
UINT WINAPI RtlOemStringToUnicodeSize( const STRING *str )
{
- int ret = wine_cp_mbstowcs( oem_table, 0, str->Buffer, str->Length, NULL, 0 );
+ int ret = wine_cp_mbstowcs( oem_cptable, 0, str->Buffer, str->Length, NULL, 0 );
return (ret + 1) * sizeof(WCHAR);
}
@@ -1112,7 +1096,7 @@
*/
NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, LPCSTR str, UINT len )
{
- *size = wine_cp_mbstowcs( ansi_table, 0, str, len, NULL, 0 ) * sizeof(WCHAR);
+ *size = wine_cp_mbstowcs( ansi_cptable, 0, str, len, NULL, 0 ) * sizeof(WCHAR);
return STATUS_SUCCESS;
}
@@ -1133,7 +1117,7 @@
*/
NTSTATUS WINAPI RtlUnicodeToMultiByteSize( PULONG size, LPCWSTR str, ULONG len )
{
- *size = wine_cp_wcstombs( ansi_table, 0, str, len / sizeof(WCHAR), NULL, 0, NULL, NULL );
+ *size = wine_cp_wcstombs( ansi_cptable, 0, str, len / sizeof(WCHAR), NULL, 0, NULL, NULL );
return STATUS_SUCCESS;
}
@@ -1174,7 +1158,7 @@
*/
DWORD WINAPI RtlUnicodeStringToOemSize( const UNICODE_STRING *str )
{
- return wine_cp_wcstombs( oem_table, 0, str->Buffer, str->Length / sizeof(WCHAR),
+ return wine_cp_wcstombs( oem_cptable, 0, str->Buffer, str->Length / sizeof(WCHAR),
NULL, 0, NULL, NULL ) + 1;
}
diff -u -N -r -x '*~' -x '.#*' -x CVS include39/winternl.h include/winternl.h
--- include39/winternl.h 2004-01-01 09:54:11.000000000 +0100
+++ include/winternl.h 2004-01-01 09:54:14.000000000 +0100
@@ -158,7 +158,8 @@
PRTL_BITMAP TlsBitmap; /* 40 */
ULONG TlsBitmapBits[2]; /* 44 */
BYTE __pad_4c[156]; /* 4c */
- PVOID Reserved3[59]; /* e8 */
+ PVOID Reserved3[58]; /* e8 */
+ unsigned int unix_code_page; /* 1d0 wine only */
ULONG SessionId; /* 1d4 */
} PEB, *PPEB;
More information about the wine-patches
mailing list