kernel32: Use MultiByteToWideChar() and WideCharToMultiByte() from kernelbase.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a2c107fca3
commit
830de63139
|
@ -1096,7 +1096,7 @@
|
|||
@ stdcall MoveFileWithProgressA(str str ptr ptr long)
|
||||
@ stdcall MoveFileWithProgressW(wstr wstr ptr ptr long)
|
||||
@ stdcall MulDiv(long long long)
|
||||
@ stdcall MultiByteToWideChar(long long str long ptr long)
|
||||
@ stdcall -import MultiByteToWideChar(long long str long ptr long)
|
||||
@ stdcall -import NeedCurrentDirectoryForExePathA(str)
|
||||
@ stdcall -import NeedCurrentDirectoryForExePathW(wstr)
|
||||
# @ stub NlsCheckPolicy
|
||||
|
@ -1601,7 +1601,7 @@
|
|||
# @ stub WerpNotifyLoadStringResourceEx
|
||||
# @ stub WerpNotifyUseStringResource
|
||||
# @ stub WerpStringLookup
|
||||
@ stdcall WideCharToMultiByte(long long wstr long ptr long ptr ptr)
|
||||
@ stdcall -import WideCharToMultiByte(long long wstr long ptr long ptr ptr)
|
||||
@ stdcall WinExec(str long)
|
||||
@ stdcall Wow64EnableWow64FsRedirection(long) KERNEL32_Wow64EnableWow64FsRedirection
|
||||
@ stdcall -import Wow64DisableWow64FsRedirection(ptr)
|
||||
|
|
|
@ -72,9 +72,6 @@ extern void ENV_CopyStartupInformation(void) DECLSPEC_HIDDEN;
|
|||
/* computername.c */
|
||||
extern void COMPUTERNAME_Init(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/* locale.c */
|
||||
extern void LOCALE_Init(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/* time.c */
|
||||
extern void TIMEZONE_InitRegistry(void) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -50,9 +50,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(nls);
|
|||
|
||||
#define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|\
|
||||
LOCALE_RETURN_NUMBER|LOCALE_RETURN_GENITIVE_NAMES)
|
||||
#define MB_FLAGSMASK (MB_PRECOMPOSED|MB_COMPOSITE|MB_USEGLYPHCHARS|MB_ERR_INVALID_CHARS)
|
||||
#define WC_FLAGSMASK (WC_DISCARDNS|WC_SEPCHARS|WC_DEFAULTCHAR|WC_ERR_INVALID_CHARS|\
|
||||
WC_COMPOSITECHECK|WC_NO_BEST_FIT_CHARS)
|
||||
|
||||
extern BOOL WINAPI Internal_EnumCalendarInfo( CALINFO_ENUMPROCW proc, LCID lcid, CALID id,
|
||||
CALTYPE type, BOOL unicode, BOOL ex,
|
||||
|
@ -69,12 +66,6 @@ extern BOOL WINAPI Internal_EnumTimeFormats( TIMEFMT_ENUMPROCW proc, LCID lcid,
|
|||
extern BOOL WINAPI Internal_EnumUILanguages( UILANGUAGE_ENUMPROCW proc, DWORD flags,
|
||||
LONG_PTR param, BOOL unicode );
|
||||
|
||||
/* current code pages */
|
||||
static const union cptable *ansi_cptable;
|
||||
static const union cptable *oem_cptable;
|
||||
static const union cptable *mac_cptable;
|
||||
static const union cptable *unix_cptable; /* NULL if UTF8 */
|
||||
|
||||
static const WCHAR iCalendarTypeW[] = {'i','C','a','l','e','n','d','a','r','T','y','p','e',0};
|
||||
static const WCHAR iCountryW[] = {'i','C','o','u','n','t','r','y',0};
|
||||
static const WCHAR iCurrDigitsW[] = {'i','C','u','r','r','D','i','g','i','t','s',0};
|
||||
|
@ -199,44 +190,6 @@ static inline UINT get_lcid_codepage( LCID lcid )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_codepage_table
|
||||
*
|
||||
* Find the table for a given codepage, handling CP_ACP etc. pseudo-codepages
|
||||
*/
|
||||
static const union cptable *get_codepage_table( unsigned int codepage )
|
||||
{
|
||||
const union cptable *ret = NULL;
|
||||
|
||||
assert( ansi_cptable ); /* init must have been done already */
|
||||
|
||||
switch(codepage)
|
||||
{
|
||||
case CP_ACP:
|
||||
return ansi_cptable;
|
||||
case CP_OEMCP:
|
||||
return oem_cptable;
|
||||
case CP_MACCP:
|
||||
return mac_cptable;
|
||||
case CP_UTF7:
|
||||
case CP_UTF8:
|
||||
break;
|
||||
case CP_THREAD_ACP:
|
||||
if (NtCurrentTeb()->CurrentLocale == GetUserDefaultLCID()) return ansi_cptable;
|
||||
codepage = get_lcid_codepage( NtCurrentTeb()->CurrentLocale );
|
||||
if (!codepage) return ansi_cptable;
|
||||
/* fall through */
|
||||
default:
|
||||
if (codepage == ansi_cptable->info.codepage) return ansi_cptable;
|
||||
if (codepage == oem_cptable->info.codepage) return oem_cptable;
|
||||
if (codepage == mac_cptable->info.codepage) return mac_cptable;
|
||||
ret = wine_cp_get_table( codepage );
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* is_genitive_name_supported
|
||||
*
|
||||
|
@ -905,518 +858,6 @@ BOOL WINAPI EnumSystemCodePagesA( CODEPAGE_ENUMPROCA proc, DWORD flags )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* utf7_write_w
|
||||
*
|
||||
* Helper for utf7_mbstowcs
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE on success, FALSE on error
|
||||
*/
|
||||
static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
|
||||
{
|
||||
if (dstlen > 0)
|
||||
{
|
||||
if (*index >= dstlen)
|
||||
return FALSE;
|
||||
|
||||
dst[*index] = character;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* utf7_mbstowcs
|
||||
*
|
||||
* UTF-7 to UTF-16 string conversion, helper for MultiByteToWideChar
|
||||
*
|
||||
* RETURNS
|
||||
* On success, the number of characters written
|
||||
* On dst buffer overflow, -1
|
||||
*/
|
||||
static int utf7_mbstowcs(const char *src, int srclen, WCHAR *dst, int dstlen)
|
||||
{
|
||||
static const signed char base64_decoding_table[] =
|
||||
{
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
|
||||
};
|
||||
|
||||
const char *source_end = src + srclen;
|
||||
int dest_index = 0;
|
||||
|
||||
DWORD byte_pair = 0;
|
||||
short offset = 0;
|
||||
|
||||
while (src < source_end)
|
||||
{
|
||||
if (*src == '+')
|
||||
{
|
||||
src++;
|
||||
if (src >= source_end)
|
||||
break;
|
||||
|
||||
if (*src == '-')
|
||||
{
|
||||
/* just a plus sign escaped as +- */
|
||||
if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
|
||||
return -1;
|
||||
src++;
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
signed char sextet = *src;
|
||||
if (sextet == '-')
|
||||
{
|
||||
/* skip over the dash and end base64 decoding
|
||||
* the current, unfinished byte pair is discarded */
|
||||
src++;
|
||||
offset = 0;
|
||||
break;
|
||||
}
|
||||
if (sextet < 0)
|
||||
{
|
||||
/* the next character of src is < 0 and therefore not part of a base64 sequence
|
||||
* the current, unfinished byte pair is NOT discarded in this case
|
||||
* this is probably a bug in Windows */
|
||||
break;
|
||||
}
|
||||
|
||||
sextet = base64_decoding_table[sextet];
|
||||
if (sextet == -1)
|
||||
{
|
||||
/* -1 means that the next character of src is not part of a base64 sequence
|
||||
* in other words, all sextets in this base64 sequence have been processed
|
||||
* the current, unfinished byte pair is discarded */
|
||||
offset = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
byte_pair = (byte_pair << 6) | sextet;
|
||||
offset += 6;
|
||||
|
||||
if (offset >= 16)
|
||||
{
|
||||
/* this byte pair is done */
|
||||
if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
|
||||
return -1;
|
||||
offset -= 16;
|
||||
}
|
||||
|
||||
src++;
|
||||
}
|
||||
while (src < source_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we have to convert to unsigned char in case *src < 0 */
|
||||
if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
|
||||
return -1;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
return dest_index;
|
||||
}
|
||||
|
||||
static int mbstowcs_utf8( DWORD flags, LPCSTR src, INT srclen, LPWSTR dst, INT dstlen )
|
||||
{
|
||||
DWORD reslen;
|
||||
NTSTATUS status;
|
||||
|
||||
if (flags & ~MB_FLAGSMASK)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
if (!dstlen) dst = NULL;
|
||||
status = RtlUTF8ToUnicodeN( dst, dstlen * sizeof(WCHAR), &reslen, src, srclen );
|
||||
if (status == STATUS_SOME_NOT_MAPPED)
|
||||
{
|
||||
if (flags & MB_ERR_INVALID_CHARS)
|
||||
{
|
||||
SetLastError( ERROR_NO_UNICODE_TRANSLATION );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (!set_ntstatus( status )) reslen = 0;
|
||||
|
||||
return reslen / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MultiByteToWideChar (KERNEL32.@)
|
||||
*
|
||||
* Convert a multibyte character string into a Unicode string.
|
||||
*
|
||||
* PARAMS
|
||||
* page [I] Codepage character set to convert from
|
||||
* flags [I] Character mapping flags
|
||||
* src [I] Source string buffer
|
||||
* srclen [I] Length of src (in bytes), or -1 if src is NUL terminated
|
||||
* dst [O] Destination buffer
|
||||
* dstlen [I] Length of dst (in WCHARs), or 0 to compute the required length
|
||||
*
|
||||
* RETURNS
|
||||
* Success: If dstlen > 0, the number of characters written to dst.
|
||||
* If dstlen == 0, the number of characters needed to perform the
|
||||
* conversion. In both cases the count includes the terminating NUL.
|
||||
* Failure: 0. Use GetLastError() to determine the cause. Possible errors are
|
||||
* ERROR_INSUFFICIENT_BUFFER, if not enough space is available in dst
|
||||
* and dstlen != 0; ERROR_INVALID_PARAMETER, if an invalid parameter
|
||||
* is passed, and ERROR_NO_UNICODE_TRANSLATION if no translation is
|
||||
* possible for src.
|
||||
*/
|
||||
INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
|
||||
LPWSTR dst, INT dstlen )
|
||||
{
|
||||
const union cptable *table;
|
||||
int ret;
|
||||
|
||||
if (!src || !srclen || (!dst && dstlen) || dstlen < 0)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (srclen < 0) srclen = strlen(src) + 1;
|
||||
|
||||
switch(page)
|
||||
{
|
||||
case CP_SYMBOL:
|
||||
if (flags)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
ret = wine_cpsymbol_mbstowcs( src, srclen, dst, dstlen );
|
||||
break;
|
||||
case CP_UTF7:
|
||||
if (flags)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
ret = utf7_mbstowcs( src, srclen, dst, dstlen );
|
||||
break;
|
||||
case CP_UTF8:
|
||||
return mbstowcs_utf8( flags, src, srclen, dst, dstlen );
|
||||
case CP_UNIXCP:
|
||||
if (unix_cptable)
|
||||
{
|
||||
ret = wine_cp_mbstowcs( unix_cptable, flags, src, srclen, dst, dstlen );
|
||||
break;
|
||||
}
|
||||
ret = mbstowcs_utf8( flags, src, srclen, dst, dstlen );
|
||||
#ifdef __APPLE__ /* work around broken Mac OS X filesystem that enforces decomposed Unicode */
|
||||
if (ret && dstlen) ret = wine_compose_string( dst, ret );
|
||||
#endif
|
||||
return ret;
|
||||
default:
|
||||
if (!(table = get_codepage_table( page )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (flags & ~MB_FLAGSMASK)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
ret = wine_cp_mbstowcs( table, flags, src, srclen, dst, dstlen );
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
switch(ret)
|
||||
{
|
||||
case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
|
||||
case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
TRACE("cp %d %s -> %s, ret = %d\n",
|
||||
page, debugstr_an(src, srclen), debugstr_wn(dst, ret), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* utf7_can_directly_encode
|
||||
*
|
||||
* Helper for utf7_wcstombs
|
||||
*/
|
||||
static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
|
||||
{
|
||||
static const BOOL directly_encodable_table[] =
|
||||
{
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
|
||||
1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
|
||||
};
|
||||
|
||||
return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* utf7_write_c
|
||||
*
|
||||
* Helper for utf7_wcstombs
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE on success, FALSE on error
|
||||
*/
|
||||
static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
|
||||
{
|
||||
if (dstlen > 0)
|
||||
{
|
||||
if (*index >= dstlen)
|
||||
return FALSE;
|
||||
|
||||
dst[*index] = character;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* utf7_wcstombs
|
||||
*
|
||||
* UTF-16 to UTF-7 string conversion, helper for WideCharToMultiByte
|
||||
*
|
||||
* RETURNS
|
||||
* On success, the number of characters written
|
||||
* On dst buffer overflow, -1
|
||||
*/
|
||||
static int utf7_wcstombs(const WCHAR *src, int srclen, char *dst, int dstlen)
|
||||
{
|
||||
static const char base64_encoding_table[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
const WCHAR *source_end = src + srclen;
|
||||
int dest_index = 0;
|
||||
|
||||
while (src < source_end)
|
||||
{
|
||||
if (*src == '+')
|
||||
{
|
||||
if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
|
||||
return -1;
|
||||
if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
|
||||
return -1;
|
||||
src++;
|
||||
}
|
||||
else if (utf7_can_directly_encode(*src))
|
||||
{
|
||||
if (!utf7_write_c(dst, dstlen, &dest_index, *src))
|
||||
return -1;
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
DWORD byte_pair = 0;
|
||||
|
||||
if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
|
||||
return -1;
|
||||
|
||||
while (src < source_end && !utf7_can_directly_encode(*src))
|
||||
{
|
||||
byte_pair = (byte_pair << 16) | *src;
|
||||
offset += 16;
|
||||
while (offset >= 6)
|
||||
{
|
||||
if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
|
||||
return -1;
|
||||
offset -= 6;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
|
||||
if (offset)
|
||||
{
|
||||
/* Windows won't create a padded base64 character if there's no room for the - sign
|
||||
* as well ; this is probably a bug in Windows */
|
||||
if (dstlen > 0 && dest_index + 1 >= dstlen)
|
||||
return -1;
|
||||
|
||||
byte_pair <<= (6 - offset);
|
||||
if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Windows always explicitly terminates the base64 sequence
|
||||
even though RFC 2152 (page 3, rule 2) does not require this */
|
||||
if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return dest_index;
|
||||
}
|
||||
|
||||
static int wcstombs_utf8( DWORD flags, LPCWSTR src, INT srclen, LPSTR dst, INT dstlen )
|
||||
{
|
||||
DWORD reslen;
|
||||
NTSTATUS status;
|
||||
|
||||
if (flags & ~WC_FLAGSMASK)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
if (!dstlen) dst = NULL;
|
||||
status = RtlUnicodeToUTF8N( dst, dstlen, &reslen, src, srclen * sizeof(WCHAR) );
|
||||
if (status == STATUS_SOME_NOT_MAPPED)
|
||||
{
|
||||
if (flags & WC_ERR_INVALID_CHARS)
|
||||
{
|
||||
SetLastError( ERROR_NO_UNICODE_TRANSLATION );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (!set_ntstatus( status )) reslen = 0;
|
||||
return reslen;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* WideCharToMultiByte (KERNEL32.@)
|
||||
*
|
||||
* Convert a Unicode character string into a multibyte string.
|
||||
*
|
||||
* PARAMS
|
||||
* page [I] Code page character set to convert to
|
||||
* flags [I] Mapping Flags (MB_ constants from "winnls.h").
|
||||
* src [I] Source string buffer
|
||||
* srclen [I] Length of src (in WCHARs), or -1 if src is NUL terminated
|
||||
* dst [O] Destination buffer
|
||||
* dstlen [I] Length of dst (in bytes), or 0 to compute the required length
|
||||
* defchar [I] Default character to use for conversion if no exact
|
||||
* conversion can be made
|
||||
* used [O] Set if default character was used in the conversion
|
||||
*
|
||||
* RETURNS
|
||||
* Success: If dstlen > 0, the number of characters written to dst.
|
||||
* If dstlen == 0, number of characters needed to perform the
|
||||
* conversion. In both cases the count includes the terminating NUL.
|
||||
* Failure: 0. Use GetLastError() to determine the cause. Possible errors are
|
||||
* ERROR_INSUFFICIENT_BUFFER, if not enough space is available in dst
|
||||
* and dstlen != 0, and ERROR_INVALID_PARAMETER, if an invalid
|
||||
* parameter was given.
|
||||
*/
|
||||
INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
|
||||
LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
|
||||
{
|
||||
const union cptable *table;
|
||||
int ret, used_tmp;
|
||||
|
||||
if (!src || !srclen || (!dst && dstlen) || dstlen < 0)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (srclen < 0) srclen = strlenW(src) + 1;
|
||||
|
||||
switch(page)
|
||||
{
|
||||
case CP_SYMBOL:
|
||||
/* when using CP_SYMBOL, ERROR_INVALID_FLAGS takes precedence */
|
||||
if (flags)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
if (defchar || used)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
ret = wine_cpsymbol_wcstombs( src, srclen, dst, dstlen );
|
||||
break;
|
||||
case CP_UTF7:
|
||||
/* when using CP_UTF7, ERROR_INVALID_PARAMETER takes precedence */
|
||||
if (defchar || used)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (flags)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
ret = utf7_wcstombs( src, srclen, dst, dstlen );
|
||||
break;
|
||||
case CP_UNIXCP:
|
||||
if (unix_cptable)
|
||||
{
|
||||
ret = wine_cp_wcstombs( unix_cptable, flags, src, srclen, dst, dstlen,
|
||||
defchar, used ? &used_tmp : NULL );
|
||||
if (used) *used = used_tmp;
|
||||
break;
|
||||
}
|
||||
if (used) *used = FALSE;
|
||||
return wcstombs_utf8( flags, src, srclen, dst, dstlen );
|
||||
case CP_UTF8:
|
||||
if (defchar || used)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
return wcstombs_utf8( flags, src, srclen, dst, dstlen );
|
||||
default:
|
||||
if (!(table = get_codepage_table( page )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (flags & ~WC_FLAGSMASK)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
ret = wine_cp_wcstombs( table, flags, src, srclen, dst, dstlen,
|
||||
defchar, used ? &used_tmp : NULL );
|
||||
if (used) *used = used_tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
switch(ret)
|
||||
{
|
||||
case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
|
||||
case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
TRACE("cp %d %s -> %s, ret = %d\n",
|
||||
page, debugstr_wn(src, srclen), debugstr_an(dst, ret), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetStringTypeW (KERNEL32.@)
|
||||
*
|
||||
|
@ -2345,36 +1786,6 @@ INT WINAPI CompareStringA(LCID lcid, DWORD flags,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* LOCALE_Init
|
||||
*/
|
||||
void LOCALE_Init(void)
|
||||
{
|
||||
extern UINT CDECL __wine_get_unix_codepage(void);
|
||||
|
||||
UINT ansi_cp = 1252, oem_cp = 437, mac_cp = 10000, unix_cp;
|
||||
|
||||
ansi_cp = get_lcid_codepage( LOCALE_SYSTEM_DEFAULT );
|
||||
GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
|
||||
(LPWSTR)&mac_cp, sizeof(mac_cp)/sizeof(WCHAR) );
|
||||
GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTCODEPAGE | LOCALE_RETURN_NUMBER,
|
||||
(LPWSTR)&oem_cp, sizeof(oem_cp)/sizeof(WCHAR) );
|
||||
|
||||
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 (!(mac_cptable = wine_cp_get_table( mac_cp )))
|
||||
mac_cptable = wine_cp_get_table( 10000 );
|
||||
|
||||
unix_cp = __wine_get_unix_codepage();
|
||||
if (unix_cp != CP_UTF8) unix_cptable = wine_cp_get_table( unix_cp );
|
||||
|
||||
TRACE( "ansi=%03d oem=%03d mac=%03d unix=%03d\n",
|
||||
ansi_cptable->info.codepage, oem_cptable->info.codepage,
|
||||
mac_cptable->info.codepage, unix_cp );
|
||||
}
|
||||
|
||||
static HANDLE NLS_RegOpenKey(HANDLE hRootKey, LPCWSTR szKeyName)
|
||||
{
|
||||
UNICODE_STRING keyName;
|
||||
|
|
|
@ -173,8 +173,6 @@ void * CDECL __wine_kernel_init(void)
|
|||
kernel32_handle = GetModuleHandleW(kernel32W);
|
||||
RtlSetUnhandledExceptionFilter( UnhandledExceptionFilter );
|
||||
|
||||
LOCALE_Init();
|
||||
|
||||
return start_process_wrapper;
|
||||
}
|
||||
|
||||
|
|
|
@ -1118,7 +1118,10 @@ static inline int is_valid_dbcs_mapping( const CPTABLEINFO *info, DWORD flags,
|
|||
WCHAR wch, unsigned short ch )
|
||||
{
|
||||
if ((flags & WC_NO_BEST_FIT_CHARS) || ch == info->DefaultChar)
|
||||
return info->DBCSOffsets[info->DBCSOffsets[ch >> 8] + (ch & 0xff)] == wch;
|
||||
{
|
||||
if (ch >> 8) return info->DBCSOffsets[info->DBCSOffsets[ch >> 8] + (ch & 0xff)] == wch;
|
||||
return info->MultiByteTable[ch] == wch;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue