You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.8 KiB
177 lines
5.8 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: nlsconv.c *
|
|
* *
|
|
* NLS conversion routines. *
|
|
* *
|
|
* Created: 08-Sep-1991 15:56:30 *
|
|
* Author: Bodin Dresevic [BodinD] *
|
|
* *
|
|
* Copyright (c) 1991-1999 Microsoft Corporation *
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bGetANSISetMap *
|
|
* *
|
|
* Tries to get a simple translation table from ANSI to UNICODE. Returns *
|
|
* TRUE on success. Sets the gbDBCSCodePage flag if it thinks the char set *
|
|
* MIGHT be DBCS. *
|
|
* *
|
|
* *
|
|
* Mon 11-Jan-1993 14:13:34 -by- Charles Whitmer [chuckwh] *
|
|
* Wrote it. I'm clearly assuming that by the time this is called, the *
|
|
* char set is well defined, and will not change. *
|
|
\**************************************************************************/
|
|
|
|
WCHAR *gpwcANSICharSet = NULL;
|
|
WCHAR *gpwcDBCSCharSet = NULL;
|
|
|
|
BOOL bGetANSISetMap()
|
|
{
|
|
CHAR ch[256];
|
|
ULONG *pul;
|
|
ULONG ii,jj;
|
|
NTSTATUS st;
|
|
ULONG cjResult;
|
|
WCHAR *pwc;
|
|
WCHAR *pwcSBC;
|
|
|
|
// See if we know the answers already. (The client should not have called!)
|
|
|
|
if (gpwcANSICharSet != (WCHAR *) NULL)
|
|
return(TRUE);
|
|
|
|
// Create a mapping.
|
|
|
|
// Make an ANSI source char set. This funny way of initialization takes
|
|
// about 180 instructions to execute rather than over 1000.
|
|
|
|
pul = (ULONG *) ch;
|
|
|
|
for (ii=0x03020100L,jj=0; jj<64; jj+=4)
|
|
{
|
|
pul[jj+0] = ii;
|
|
ii += 0x04040404L;
|
|
pul[jj+1] = ii;
|
|
ii += 0x04040404L;
|
|
pul[jj+2] = ii;
|
|
ii += 0x04040404L;
|
|
pul[jj+3] = ii;
|
|
ii += 0x04040404L;
|
|
}
|
|
|
|
// Allocate the UNICODE buffer but don't write the pointer in until the
|
|
// table is valid, in case we're racing another thread.
|
|
|
|
pwc = LOCALALLOC(512 * sizeof(WCHAR));
|
|
pwcSBC = &pwc[256];
|
|
|
|
if (pwc == (WCHAR *) NULL)
|
|
return(FALSE);
|
|
|
|
// Convert the characters.
|
|
|
|
pwc[0] = 0;
|
|
st = RtlMultiByteToUnicodeN
|
|
(
|
|
&pwc[1], // OUT PWCH UnicodeString
|
|
255 * sizeof(WCHAR), // IN ULONG MaxBytesInUnicodeString
|
|
&cjResult, // OUT PULONG BytesInUnicodeString
|
|
&ch[1], // IN PCH MultiByteString
|
|
255 // IN ULONG BytesInMultiByteString
|
|
);
|
|
|
|
if( !NT_SUCCESS(st) )
|
|
{
|
|
// Clean up and forget about accelerations.
|
|
|
|
WARNING("GDI32: RtlMultiByteToUnicodeN error.");
|
|
LOCALFREE(pwc);
|
|
return(FALSE);
|
|
}
|
|
|
|
if( cjResult != 255 * sizeof(WCHAR) )
|
|
{
|
|
// There must be a DBCS code page so gpwcANSIMap takes on new meaning.
|
|
// It is used for fonts with ANSI,OEM, and SYMBOL charsets. Also,
|
|
// another table, gpwcDBCS is constructed that is used to map the SBCS
|
|
// of SHIFT-JIS fonts.
|
|
|
|
WARNING("GDI32:Assuming DBCS code page.\n");
|
|
|
|
st = MultiByteToWideChar
|
|
(
|
|
1252, // code page to use
|
|
0, // flags
|
|
&ch[1], // characters to translate
|
|
255, // number of multibyte characters
|
|
&pwc[1], // unicode values of characters
|
|
255 // number of wide characters
|
|
);
|
|
|
|
if( !NT_SUCCESS(st) )
|
|
{
|
|
// Clean up and forget about accelerations.
|
|
|
|
WARNING("GDI32: MultiByteToWideChar error.");
|
|
LOCALFREE(pwc);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Okay now make a table for SBC bytes. Mark DBCS lead bytes
|
|
// with 0xFFFF.
|
|
|
|
for( jj = 0; jj < 256; jj++ )
|
|
{
|
|
if( IsDBCSLeadByte( (UCHAR)jj ))
|
|
{
|
|
pwcSBC[jj] = (WCHAR) 0xFFFF;
|
|
}
|
|
else
|
|
{
|
|
st = RtlMultiByteToUnicodeN
|
|
(
|
|
&pwcSBC[jj],
|
|
sizeof(WCHAR),
|
|
&cjResult,
|
|
&ch[jj],
|
|
1
|
|
);
|
|
|
|
if( !NT_SUCCESS(st) )
|
|
{
|
|
WARNING("GDI32: RtlMultByteToUnicodeN error.");
|
|
LOCALFREE(pwc);
|
|
return(FALSE);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// The table is good, jam it in. Watch out for another thread running this
|
|
// routine simultaneously.
|
|
|
|
ENTERCRITICALSECTION(&semLocal);
|
|
{
|
|
if (gpwcANSICharSet == (WCHAR *) NULL)
|
|
{
|
|
gpwcANSICharSet = pwc;
|
|
gpwcDBCSCharSet = pwcSBC;
|
|
pwc = (WCHAR *) NULL;
|
|
}
|
|
}
|
|
LEAVECRITICALSECTION(&semLocal);
|
|
|
|
// If we collided with another thread, clean up our extra space.
|
|
|
|
if (pwc != (WCHAR *) NULL)
|
|
LOCALFREE(pwc);
|
|
|
|
// At this point we have a valid mapping.
|
|
|
|
return(TRUE);
|
|
}
|