Leaked source code of windows server 2003
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.
 
 
 
 
 
 

743 lines
19 KiB

/**************************************************************************\
* Module Name: kcodecnv.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* This module contains all the code for the Korean code conversion functions.
*
* History:
* 15-Jul-1995
* 22-Feb-1996 bklee
\**************************************************************************/
#include "precomp.h"
#pragma hdrstop
#define IDD_2BEOL 100
#define IDD_3BEOL1 101
#define IDD_3BEOL2 102
#define lpSource(lpks) (LPSTR)((LPSTR)lpks+lpks->dchSource)
#define lpDest(lpks) (LPSTR)((LPSTR)lpks+lpks->dchDest)
#define JOHAB_CP 1361
#define WANSUNG_CP 949
#define TWO_BYTE 2
#define ONE_WORD 1
typedef struct tagHIGH_LOW // For high byte and low byte
{
BYTE low, high;
} HIGH_LOW;
typedef union tagWANSUNG // For Wansung character code
{
HIGH_LOW e;
WORD w;
} WANSUNG;
/* Hanguel Mnemonic Table for 2 BeolSik and 3 BeolSik */
CONST WORD HMNTable[3][96] =
{
// For 2 Beolsik.
{
/* 20 SP */ 0xA1A1,
/* 21 ! */ 0xA3A1,
/* 22 " */ 0xA1A8,
/* 23 # */ 0xA3A3,
/* 24 $ */ 0xA3A4,
/* 25 % */ 0xA3A5,
/* 26 & */ 0xA3A6,
/* 27 ` */ 0xA1AE, /* A1AE ? AiA2 */
/* 28 ( */ 0xA3A8,
/* 29 ) */ 0xA3A9,
/* 2A * */ 0xA3AA,
/* 2B + */ 0xA3AB,
/* 2C ' */ 0xA3A7,
/* 2D - */ 0xA3AD,
/* 2E . */ 0xA3AE,
/* 2F / */ 0xA3AF,
/* 30 0 */ 0xA3B0,
/* 31 1 */ 0xA3B1,
/* 32 2 */ 0xA3B2,
/* 33 3 */ 0xA3B3,
/* 34 4 */ 0xA3B4,
/* 35 5 */ 0xA3B5,
/* 36 6 */ 0xA3B6,
/* 37 7 */ 0xA3B7,
/* 38 8 */ 0xA3B8,
/* 39 9 */ 0xA3B9,
/* 3A : */ 0xA3BA,
/* 3B ; */ 0xA3BB,
/* 3C < */ 0xA3BC,
/* 3D = */ 0xA3BD,
/* 3E > */ 0xA3BE,
/* 3F ? */ 0xA3BF,
/* 40 @ */ 0xA3C0,
/* 41 A */ 0xA4B1,
/* 42 B */ 0xA4D0,
/* 43 C */ 0xA4BA,
/* 44 D */ 0xA4B7,
/* 45 E */ 0xA4A8,
/* 46 F */ 0xA4A9,
/* 47 G */ 0xA4BE,
/* 48 H */ 0xA4C7,
/* 49 I */ 0xA4C1,
/* 4A J */ 0xA4C3,
/* 4B K */ 0xA4BF,
/* 4C L */ 0xA4D3,
/* 4D M */ 0xA4D1,
/* 4E N */ 0xA4CC,
/* 4F O */ 0xA4C2,
/* 50 P */ 0xA4C6,
/* 51 Q */ 0xA4B3,
/* 52 R */ 0xA4A2,
/* 53 S */ 0xA4A4,
/* 54 T */ 0xA4B6,
/* 55 U */ 0xA4C5,
/* 56 V */ 0xA4BD,
/* 57 W */ 0xA4B9,
/* 58 X */ 0xA4BC,
/* 59 Y */ 0xA4CB,
/* 5A Z */ 0xA4BB,
/* 5B [ */ 0xA3DB,
/* 5C \ */ 0xA1AC,
/* 5D ] */ 0xA3DD,
/* 5E ^ */ 0xA3DE,
/* 5F _ */ 0xA3DF,
/* 60 ` */ 0xA1A2, /* A1AE ? AiA2 */
/* 61 a */ 0xA4B1,
/* 62 b */ 0xA4D0,
/* 63 c */ 0xA4BA,
/* 64 d */ 0xA4B7,
/* 65 e */ 0xA4A7,
/* 66 f */ 0xA4A9,
/* 67 g */ 0xA4BE,
/* 68 h */ 0xA4C7,
/* 69 i */ 0xA4C1,
/* 6A j */ 0xA4C3,
/* 6B k */ 0xA4BF,
/* 6C l */ 0xA4D3,
/* 6D m */ 0xA4D1,
/* 6E n */ 0xA4CC,
/* 6F o */ 0xA4C0,
/* 70 p */ 0xA4C4,
/* 71 q */ 0xA4B2,
/* 72 r */ 0xA4A1,
/* 73 s */ 0xA4A4,
/* 74 t */ 0xA4B5,
/* 75 u */ 0xA4C5,
/* 76 v */ 0xA4BD,
/* 77 w */ 0xA4B8,
/* 78 x */ 0xA4BC,
/* 79 y */ 0xA4CB,
/* 7A z */ 0xA4BB,
/* 7B { */ 0xA3FB,
/* 7C | */ 0xA3FC,
/* 7D } */ 0xA3FD,
/* 7E ~ */ 0xA1AD,
0x0000
},
// For KT390.
{
/* Hex Code KSC Code */
/* 20 SP */ 0xA1A1,
/* 21 ! */ 0xA4B8,
/* 22 " */ 0xA1A8,
/* 23 # */ 0xA3A3,
/* 24 $ */ 0xA3A4,
/* 25 % */ 0xA3A5,
/* 26 & */ 0xA3A6,
/* 27 ` */ 0xA1AE,
/* 28 ( */ 0xA3A8,
/* 29 ) */ 0xA3A9,
/* 2A * */ 0xA3AA,
/* 2B + */ 0xA3AB,
/* 2C ' */ 0xA4BC,
/* 2D - */ 0xA3AD,
/* 2E . */ 0xA3AE,
/* 2F / */ 0xA4C7,
/* 30 0 */ 0xA4BB,
/* 31 1 */ 0xA4BE,
/* 32 2 */ 0xA4B6,
/* 33 3 */ 0xA4B2,
/* 34 4 */ 0xA4CB,
/* 35 5 */ 0xA4D0,
/* 36 6 */ 0xA4C1,
/* 37 7 */ 0xA4C6,
/* 38 8 */ 0xA4D2,
/* 39 9 */ 0xA4CC,
/* 3A : */ 0xA3BA,
/* 3B ; */ 0xA4B2,
/* 3C < */ 0xA3B2,
/* 3D = */ 0xA3BD,
/* 3E > */ 0xA3B3,
/* 3F ? */ 0xA3BF,
/* 40 @ */ 0xA3C0,
/* 41 A */ 0xA4A7,
/* 42 B */ 0xA3A1,
/* 43 C */ 0xA4AB,
/* 44 D */ 0xA4AA,
/* 45 E */ 0xA4BB,
/* 46 F */ 0xA4A2,
/* 47 G */ 0xA3AF,
/* 48 H */ 0xA1AF,
/* 49 I */ 0xA3B8,
/* 4A J */ 0xA3B4,
/* 4B K */ 0xA3B5,
/* 4C L */ 0xA3B6,
/* 4D M */ 0xA3B1,
/* 4E N */ 0xA3B0,
/* 4F O */ 0xA3B9,
/* 50 P */ 0xA3BE,
/* 51 Q */ 0xA4BD,
/* 52 R */ 0xA4C2,
/* 53 S */ 0xA4A6,
/* 54 T */ 0xA4C3,
/* 55 U */ 0xA3B7,
/* 56 V */ 0xA4B0,
/* 57 W */ 0xA4BC,
/* 58 X */ 0xA4B4,
/* 59 Y */ 0xA3BC,
/* 5A Z */ 0xA4BA,
/* 5B [ */ 0xA3DB,
/* 5C \ */ 0xA3DC,
/* 5D ] */ 0xA3DD,
/* 5E ^ */ 0xA3DE,
/* 5F _ */ 0xA3DF,
/* 60 ` */ 0xA1AE,
/* 61 a */ 0xA4B7,
/* 62 b */ 0xA4CC,
/* 63 c */ 0xA4C4,
/* 64 d */ 0xA4D3,
/* 65 e */ 0xA4C5,
/* 66 f */ 0xA4BF,
/* 67 g */ 0xA4D1,
/* 68 h */ 0xA4A4,
/* 69 i */ 0xA4B1,
/* 6A j */ 0xA4B7,
/* 6B k */ 0xA4A1,
/* 6C l */ 0xA4B8,
/* 6D m */ 0xA4BE,
/* 6E n */ 0xA4B5,
/* 6F o */ 0xA4BA,
/* 70 p */ 0xA4BD,
/* 71 q */ 0xA4B5,
/* 72 r */ 0xA4C0,
/* 73 s */ 0xA4A4,
/* 74 t */ 0xA4C3,
/* 75 u */ 0xA4A7,
/* 76 v */ 0xA4C7,
/* 77 w */ 0xA4A9,
/* 78 x */ 0xA4A1,
/* 79 y */ 0xA4A9,
/* 7A z */ 0xA4B1,
/* 7B { */ 0xA3FB,
/* 7C | */ 0xA3FC,
/* 7D } */ 0xA3FD,
/* 7E ~ */ 0xA1AD,
0x0000
},
// For 3 Beolsik Final.
{
/* Hex Code KSC Code */
/* 20 SP */ 0xA1A1,
/* 21 ! */ 0xA4A2,
/* 22 " */ 0xA3AE,
/* 23 # */ 0xA4B8,
/* 24 $ */ 0xA4AF,
/* 25 % */ 0xA4AE,
/* 26 & */ 0xA1B0,
/* 27 ` */ 0xA3AA,
/* 28 ( */ 0xA1A2,
/* 29 ) */ 0xA1AD,
/* 2A * */ 0xA1B1,
/* 2B + */ 0xA3AB,
/* 2C ' */ 0xA4BC,
/* 2D - */ 0xA3A9,
/* 2E . */ 0xA3AE,
/* 2F / */ 0xA4C7,
/* 30 0 */ 0xA4BB,
/* 31 1 */ 0xA4BE,
/* 32 2 */ 0xA4B6,
/* 33 3 */ 0xA4B2,
/* 34 4 */ 0xA4CB,
/* 35 5 */ 0xA4D0,
/* 36 6 */ 0xA4C1,
/* 37 7 */ 0xA4C6,
/* 38 8 */ 0xA4D2,
/* 39 9 */ 0xA4CC, //0x0000
/* 3A : */ 0xA3B4,
/* 3B ; */ 0xA4B2,
/* 3C < */ 0xA3A7,
/* 3D = */ 0xA1B5,
/* 3E > */ 0xA3AE,
/* 3F ? */ 0xA3A1,
/* 40 @ */ 0xA4AA,
/* 41 A */ 0xA4A7,
/* 42 B */ 0xA3BF,
/* 43 C */ 0xA4BC,
/* 44 D */ 0xA4AC,
/* 45 E */ 0xA4A5,
/* 46 F */ 0xA4AB,
/* 47 G */ 0xA4C2,
/* 48 H */ 0xA3B0,
/* 49 I */ 0xA3B7,
/* 4A J */ 0xA3B1,
/* 4B K */ 0xA3B2,
/* 4C L */ 0xA3B3,
/* 4D M */ 0xA1A8,
/* 4E N */ 0xA3AD,
/* 4F O */ 0xA3B8,
/* 50 P */ 0xA3B9,
/* 51 Q */ 0xA4BD,
/* 52 R */ 0xA4B0,
/* 53 S */ 0xA4A6,
/* 54 T */ 0xA4AD,
/* 55 U */ 0xA3B6,
/* 56 V */ 0xA4A3,
/* 57 W */ 0xA4BC,
/* 58 X */ 0xA4B4,
/* 59 Y */ 0xA3B5,
/* 5A Z */ 0xA4BA,
/* 5B [ */ 0xA3A8,
/* 5C \ */ 0xA3BA,
/* 5D ] */ 0xA1B4,
/* 5E ^ */ 0xA3BD,
/* 5F _ */ 0xA3BB,
/* 60 ` */ 0xA3AA,
/* 61 a */ 0xA4B7,
/* 62 b */ 0xA4CC,
/* 63 c */ 0xA4C4,
/* 64 d */ 0xA4D3,
/* 65 e */ 0xA4C5,
/* 66 f */ 0xA4BF,
/* 67 g */ 0xA4D1,
/* 68 h */ 0xA4A4,
/* 69 i */ 0xA4B1,
/* 6A j */ 0xA4B7,
/* 6B k */ 0xA4A1,
/* 6C l */ 0xA4B8,
/* 6D m */ 0xA4BE,
/* 6E n */ 0xA4B5,
/* 6F o */ 0xA4BA,
/* 70 p */ 0xA4BD,
/* 71 q */ 0xA4B5,
/* 72 r */ 0xA4C0,
/* 73 s */ 0xA4A4,
/* 74 t */ 0xA4C3,
/* 75 u */ 0xA4A7,
/* 76 v */ 0xA4C7,
/* 77 w */ 0xA4A9,
/* 78 x */ 0xA4A1,
/* 79 y */ 0xA4B1,
/* 7A z */ 0xA4B1,
/* 7B { */ 0xA3A5,
/* 7C | */ 0xA3CC,
/* 7D } */ 0xA3AF,
/* 7E ~ */ 0xA1AD,
0x0000
}
};
CONST WORD wKSCompCode[51] = // from 'GiYuk' to 'Yi'.
{
0x8841,0x8C41,0x8444,0x9041,0x8446,0x8447,0x9441,0x9841,0x9C41,0x844A,
0x844B,0x844C,0x844D,0x844E,0x844F,0x8450,0xA041,0xA441,0xA841,0x8454,
0xAC41,0xB041,0xB441,0xB841,0xBC41,0xC041,0xC441,0xC841,0xCC41,0xD041,
0x8461,0x8481,0x84A1,0x84C1,0x84E1,0x8541,0x8561,0x8581,0x85A1,0x85C1,
0x85E1,0x8641,0x8661,0x8681,0x86A1,0x86C1,0x86E1,0x8741,0x8761,0x8781,
0x87A1
};
CONST WORD wKSCompCode2[30] = // from 'GiYuk' to 'HiEut'.
{
0x8442,0x8443,0x8444,0x8445,0x8446,0x8447,0x8448,0x9841,0x8449,0x844A,
0x844B,0x844C,0x844D,0x844E,0x844F,0x8450,0x8451,0x8453,0xA841,0x8454,
0x8455,0x8456,0x8457,0x8458,0xBC41,0x8459,0x845A,0x845B,0x845C,0x845D
};
WORD
JunjaToBanja(
LPSTR lpSrc,
LPSTR lpDest
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
WANSUNG wsCode;
WORD wCount = 0;
while (*lpSrc)
{
if ((BYTE)(*lpSrc) < (BYTE)0x80)
{
*lpDest++ = *lpSrc++;
wCount++;
}
else
{
wsCode.e.high = *lpSrc++;
wsCode.e.low = *lpSrc++;
if (wsCode.w == 0xA1A1)
{
*lpDest++ = ' ';
wCount++;
}
else if (wsCode.w >= 0xA3A1 && wsCode.w <= 0xA3FE)
{
*lpDest++ = wsCode.e.low - (BYTE)0x80;
wCount++;
}
else
{
*lpDest++ = wsCode.e.high;
*lpDest++ = wsCode.e.low;
wCount += 2;
}
}
}
*lpDest = '\0';
return (wCount);
}
WORD
BanjaToJunja(
LPSTR lpSrc,
LPSTR lpDest
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
WORD wCount = 0;
while (*lpSrc)
{
if ((BYTE)(*lpSrc) < (BYTE)0x80)
{
if (*lpSrc++ == ' ')
{
*lpDest++ = (BYTE)0xA1;
*lpDest++ = (BYTE)0xA1;
wCount += 2;
}
else
{
*lpDest++ = (BYTE)0xA3;
*lpDest++ = *(lpSrc - 1) + (BYTE)0x80;
wCount += 2;
}
}
else
{
*lpDest++ = *lpSrc++;
*lpDest++ = *lpSrc++;
wCount += 2;
}
}
*lpDest = '\0';
return (wCount);
}
WORD
JohabToKs(
LPSTR lpSrc,
LPSTR lpDest
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
WORD wCount = 0;
#if defined(OLD_CONV)
WANSUNG wsSCode, wsDCode;
int iHead = 0, iTail = 2349, iMid;
BYTE bCount;
#endif
while (*lpSrc)
{
if ((BYTE)(*lpSrc) < (BYTE)0x80)
{
*lpDest++ = *lpSrc++;
wCount++;
}
else
#if defined(OLD_CONV)
{
wsSCode.e.high = *lpSrc++;
wsSCode.e.low = *lpSrc++;
for (bCount = 0; bCount < 51 && wKSCompCode[bCount] != wsSCode.w; bCount++)
;
wsDCode.w = (bCount == 51)? 0: bCount + 0xA4A1;
if (wsDCode.w)
{
*lpDest++ = wsDCode.e.high;
*lpDest++ = wsDCode.e.low;
wCount += 2;
continue;
}
for (bCount = 0; bCount < 30 && wKSCompCode2[bCount] != wsSCode.w; bCount++)
;
wsDCode.w = (bCount == 30)? 0: bCount + 0xA4A1;
if (wsDCode.w)
{
*lpDest++ = wsDCode.e.high;
*lpDest++ = wsDCode.e.low;
wCount += 2;
continue;
}
while (iHead <= iTail && !wsDCode.w)
{
iMid = (iHead + iTail) / 2;
if (wKSCharCode[iMid] > wsSCode.w)
iTail = iMid - 1;
else if (wKSCharCode[iMid] < wsSCode.w)
iHead = iMid + 1;
else
wsDCode.w = ((iMid / 94 + 0xB0) << 8) | (iMid % 94 + 0xA1);
}
if (wsDCode.w)
{
*lpDest++ = wsDCode.e.high;
*lpDest++ = wsDCode.e.low;
wCount += 2;
}
else
{
*lpDest++ = wsSCode.e.high;
*lpDest++ = wsSCode.e.low;
wCount += 2;
}
}
#else
{
// for simple implementation, converting one character by character
// we have to change it string to string conversion.
WCHAR wUni;
CHAR chTmp[2];
chTmp[0] = *lpSrc++;
chTmp[1] = *lpSrc++;
MultiByteToWideChar(JOHAB_CP, MB_PRECOMPOSED, chTmp, TWO_BYTE, &wUni, ONE_WORD);
WideCharToMultiByte(WANSUNG_CP, 0, &wUni, ONE_WORD, chTmp, TWO_BYTE, NULL, NULL);
*lpDest++ = chTmp[0];
*lpDest++ = chTmp[1];
wCount += 2;
}
#endif
}
*lpDest = '\0';
return (wCount);
}
WORD
KsToJohab(
LPSTR lpSrc,
LPSTR lpDest
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
#if defined(OLD_CONV)
WANSUNG wsSCode, wsDCode;
WORD wCount = 0, wLoc;
#else
WORD wCount = 0;
#endif
while (*lpSrc)
{
if ((BYTE)(*lpSrc) < (BYTE)0x80)
{
*lpDest++ = *lpSrc++;
wCount++;
}
else
#if defined(OLD_CONV)
{
wsSCode.e.high = *lpSrc++;
wsSCode.e.low = *lpSrc++;
if (wsSCode.w >= (WORD)0xA4A1 && wsSCode.w <= (WORD)0xA4D3)
{
wsDCode.w = wKSCompCode[wsSCode.w - 0xA4A1];
*lpDest++ = wsDCode.e.high;
*lpDest++ = wsDCode.e.low;
}
else if (wsSCode.w >= (WORD)0xB0A1 && wsSCode.w <= (WORD)0xC8FE
&& wsSCode.e.low != (BYTE)0xFF)
{
wLoc = (wsSCode.e.high - 176) * 94;
wLoc += wsSCode.e.low - 161;
wsDCode.w = wKSCharCode[wLoc];
*lpDest++ = wsDCode.e.high;
*lpDest++ = wsDCode.e.low;
}
else
{
*lpDest++ = wsSCode.e.high;
*lpDest++ = wsSCode.e.low;
}
wCount += 2;
}
#else
{
WCHAR wUni;
CHAR chTmp[2];
chTmp[0] = *lpSrc++;
chTmp[1] = *lpSrc++;
MultiByteToWideChar(WANSUNG_CP, MB_PRECOMPOSED, chTmp, TWO_BYTE, &wUni, ONE_WORD);
WideCharToMultiByte(JOHAB_CP, 0, &wUni, ONE_WORD, chTmp, TWO_BYTE, NULL, NULL);
*lpDest++ = chTmp[0];
*lpDest++ = chTmp[1];
wCount += 2;
}
#endif
}
*lpDest = '\0';
return (wCount);
}
LRESULT
TransCodeConvert(
HIMC hIMC,
LPIMESTRUCT lpIme
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
UNREFERENCED_PARAMETER(hIMC);
switch (lpIme->wParam)
{
case IME_JUNJAtoBANJA:
lpIme->wCount = JunjaToBanja(lpSource(lpIme), lpDest(lpIme));
break;
case IME_BANJAtoJUNJA:
lpIme->wCount = BanjaToJunja(lpSource(lpIme), lpDest(lpIme));
break;
case IME_JOHABtoKS:
lpIme->wCount = JohabToKs(lpSource(lpIme), lpDest(lpIme));
break;
case IME_KStoJOHAB:
lpIme->wCount = KsToJohab(lpSource(lpIme), lpDest(lpIme));
break;
default:
lpIme->wCount = 0;
}
return (lpIme->wCount);
}
LRESULT TransConvertList( HIMC hImc, LPIMESTRUCT lpIme)
{
LPSTR lpSrc;
LPSTR lpDst;
HGLOBAL hCandList;
LPCANDIDATELIST lpCandList;
LPSTR lpCandStr;
UINT i, uBufLen;
LRESULT lRet = 0;
lpSrc = lpSource(lpIme);
lpDst = lpDest(lpIme);
uBufLen = ImmGetConversionListA(GetKeyboardLayout(0), hImc, (LPCSTR)lpSrc,
NULL, 0, GCL_CONVERSION);
if (uBufLen)
{
hCandList = GlobalAlloc(GHND, uBufLen);
lpCandList = (LPCANDIDATELIST)GlobalLock(hCandList);
if (lpCandList == NULL) {
return 0;
}
lRet = ImmGetConversionListA(GetKeyboardLayout(0), hImc, (LPCSTR)lpSrc,
lpCandList, uBufLen, GCL_CONVERSION);
for (i = 0; i < lpCandList->dwCount; i++)
{
lpCandStr = (LPSTR)lpCandList + lpCandList->dwOffset[i];
*lpDst++ = *lpCandStr++;
*lpDst++ = *lpCandStr++;
}
*lpDst = '\0';
lpIme->wCount = (WORD)lpCandList->dwCount * 2;
GlobalUnlock(hCandList);
GlobalFree(hCandList);
}
return (lRet);
}
LRESULT TransGetMNTable( HIMC hImc, LPIMESTRUCT lpIme)
{
LPSTR lpMnemonic;
int iCount, iCIM;
UNREFERENCED_PARAMETER(hImc);
lpMnemonic = (LPSTR)(lpIme->lParam1);
// Better place would be Registry instead of WIN.INI,
// but leave it for now.
iCIM = GetProfileInt(L"WANSUNG", L"InputMethod", IDD_2BEOL) - IDD_2BEOL;
for (iCount = 0; iCount < 96; iCount++, lpMnemonic += 2)
{
*lpMnemonic = LOBYTE(HMNTable[iCIM][iCount]);
*(lpMnemonic+1) = HIBYTE(HMNTable[iCIM][iCount]);
}
return TRUE;
}