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.
292 lines
8.5 KiB
292 lines
8.5 KiB
/****************************************************************************
|
|
HANJA.CPP
|
|
|
|
Owner: cslim
|
|
Copyright (c) 1997-1999 Microsoft Corporation
|
|
|
|
Hanja conversion and dictionary lookup functions. Dictionary index is
|
|
stored as globally shared memory.
|
|
|
|
History:
|
|
26-APR-1999 cslim Modified for Multibox Applet Tooltip display
|
|
14-JUL-1999 cslim Copied from IME98 source tree
|
|
*****************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "hwxobj.h"
|
|
#include "lexheader.h"
|
|
#include "hanja.h"
|
|
#include "common.h"
|
|
#include "immsec.h"
|
|
#include "dbg.h"
|
|
|
|
// NT5 Globally shared memory.
|
|
const TCHAR IMEKR_LEX_SHAREDDATA_MUTEX_NAME[] = TEXT("ImeKrLex.Mutex");
|
|
const TCHAR IMEKR_LEX_SHAREDDATA_NAME[] = TEXT("ImeKrLexHanjaToHangul.SharedMemory");
|
|
|
|
|
|
UINT vuNumofK0=0, vuNumofK1=0;
|
|
WCHAR vwcHangul=0;
|
|
|
|
// Private data
|
|
static BOOL vfLexOpen = FALSE;
|
|
static HANDLE vhLex=0;
|
|
static HANDLE vhLexIndexTbl=0;
|
|
static UINT vuNumOfHanjaEntry=0;
|
|
static DWORD viBufferStart=0; // seek point
|
|
|
|
// Private functions
|
|
static BOOL OpenLex();
|
|
//static VOID ClearHanjaSenseArray();
|
|
static INT SearchHanjaIndex(WCHAR wHChar, HanjaToHangulIndex *pLexIndexTbl);
|
|
|
|
BOOL EnsureHanjaLexLoaded()
|
|
{
|
|
_DictHeader *pLexHeader;
|
|
HKEY hKey;
|
|
DWORD dwReadBytes;
|
|
CHAR szLexFileName[MAX_PATH], szLexPathExpanded[MAX_PATH];
|
|
DWORD dwCb, dwType;
|
|
|
|
if (vfLexOpen)
|
|
return TRUE;
|
|
|
|
// Get Lex file path
|
|
szLexFileName[0] = 0;
|
|
szLexPathExpanded[0] = 0;
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szIMERootKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
dwCb = sizeof(szLexFileName);
|
|
dwType = REG_SZ;
|
|
|
|
if (RegQueryValueEx(hKey, g_szDictionary, NULL, &dwType, (LPBYTE)szLexFileName, &dwCb) == ERROR_SUCCESS)
|
|
ExpandEnvironmentStrings(szLexFileName, szLexPathExpanded, sizeof(szLexPathExpanded));
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
DBGAssert(szLexPathExpanded[0] != 0);
|
|
if (szLexPathExpanded[0] == 0)
|
|
return FALSE;
|
|
|
|
vhLex = CreateFile(szLexPathExpanded, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
|
|
if (vhLex==INVALID_HANDLE_VALUE)
|
|
{
|
|
DBGAssert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
pLexHeader = new _DictHeader;
|
|
if (!pLexHeader)
|
|
return FALSE;
|
|
|
|
if (ReadFile(vhLex, pLexHeader, sizeof(_DictHeader), &dwReadBytes, 0) == 0 || (dwReadBytes != sizeof(_DictHeader)))
|
|
{
|
|
DBGAssert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
// Set member vars
|
|
vuNumOfHanjaEntry = pLexHeader->uiNumofHanja;
|
|
viBufferStart = pLexHeader->iBufferStart;
|
|
|
|
if (pLexHeader->Version < LEX_VERSION || pLexHeader->Version > LEX_COMPATIBLE_VERSION_LIMIT )
|
|
{
|
|
delete pLexHeader;
|
|
DBGAssert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
if (lstrcmpA(pLexHeader->COPYRIGHT_HEADER, COPYRIGHT_STR))
|
|
{
|
|
delete pLexHeader;
|
|
DBGAssert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
// Read Index table
|
|
SetFilePointer(vhLex, pLexHeader->iHanjaToHangulIndex, 0, FILE_BEGIN);
|
|
delete pLexHeader;
|
|
|
|
return OpenLex();
|
|
}
|
|
|
|
__inline BOOL DoEnterCriticalSection(HANDLE hMutex)
|
|
{
|
|
if(WAIT_FAILED==WaitForSingleObject(hMutex, 3000)) // Wait 3 seconds
|
|
return(FALSE);
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL OpenLex()
|
|
{
|
|
BOOL fRet = FALSE;
|
|
HanjaToHangulIndex* pHanjaToHangulIndex;
|
|
HANDLE hMutex;
|
|
DWORD dwReadBytes;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Mapping Lex file
|
|
// The dictionary index is shared data between all IME instance
|
|
hMutex=CreateMutex(GetIMESecurityAttributes(), FALSE, IMEKR_LEX_SHAREDDATA_MUTEX_NAME);
|
|
|
|
if (hMutex != NULL)
|
|
{
|
|
if (DoEnterCriticalSection(hMutex) == FALSE)
|
|
goto ExitOpenLexCritSection;
|
|
|
|
vhLexIndexTbl = OpenFileMapping(FILE_MAP_READ, TRUE, IMEKR_LEX_SHAREDDATA_NAME);
|
|
|
|
if(vhLexIndexTbl)
|
|
{
|
|
Dbg(("CHanja::OpenLex() - File mapping already exists"));
|
|
fRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// if no file mapping exist
|
|
vhLexIndexTbl = CreateFileMapping(INVALID_HANDLE_VALUE,
|
|
GetIMESecurityAttributes(),
|
|
PAGE_READWRITE,
|
|
0,
|
|
sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry),
|
|
IMEKR_LEX_SHAREDDATA_NAME);
|
|
|
|
if (vhLexIndexTbl)
|
|
{
|
|
Dbg(("CHanja::OpenLex() - File mapping Created"));
|
|
pHanjaToHangulIndex = (HanjaToHangulIndex*)MapViewOfFile(vhLexIndexTbl, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
|
if (!pHanjaToHangulIndex)
|
|
goto ExitOpenLexCritSection;
|
|
|
|
if (ReadFile(vhLex, pHanjaToHangulIndex, sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry), &dwReadBytes, 0) != 0 &&
|
|
dwReadBytes == sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry))
|
|
{
|
|
fRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
fRet = FALSE;
|
|
}
|
|
|
|
UnmapViewOfFile(pHanjaToHangulIndex);
|
|
}
|
|
#ifdef _DEBUG
|
|
else
|
|
DBGAssert(0);
|
|
#endif
|
|
}
|
|
|
|
ExitOpenLexCritSection:
|
|
ReleaseMutex(hMutex);
|
|
CloseHandle(hMutex);
|
|
}
|
|
|
|
FreeIMESecurityAttributes();
|
|
|
|
vfLexOpen = fRet;
|
|
return fRet;
|
|
}
|
|
|
|
BOOL CloseLex()
|
|
{
|
|
//ClearHanjaSenseArray();
|
|
|
|
if (vhLexIndexTbl)
|
|
{
|
|
CloseHandle(vhLexIndexTbl);
|
|
vhLexIndexTbl = 0;
|
|
}
|
|
|
|
if (vhLex)
|
|
{
|
|
CloseHandle(vhLex);
|
|
vhLex = 0;
|
|
}
|
|
|
|
vfLexOpen = FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL GetMeaningAndProunc(WCHAR wch, LPWSTR lpwstrTip, INT cchMax)
|
|
{
|
|
HanjaToHangulIndex* pHanjaToHangulIndex;
|
|
INT iMapHanjaInfo;
|
|
WCHAR wcHanja;
|
|
BYTE cchMeaning = 0;
|
|
WCHAR wszMeaning[MAX_SENSE_LENGTH];
|
|
DWORD dwReadBytes;
|
|
BOOL fRet = FALSE;
|
|
|
|
Dbg(("GetMeaningAndProunc"));
|
|
|
|
if (!EnsureHanjaLexLoaded())
|
|
return FALSE;
|
|
|
|
pHanjaToHangulIndex = (HanjaToHangulIndex*)MapViewOfFile(vhLexIndexTbl, FILE_MAP_READ, 0, 0, 0);
|
|
if (!pHanjaToHangulIndex)
|
|
{
|
|
DBGAssert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
// Search index
|
|
if ((iMapHanjaInfo = SearchHanjaIndex(wch, pHanjaToHangulIndex)) >= 0)
|
|
{
|
|
// Seek to mapping Hanja
|
|
SetFilePointer(vhLex, viBufferStart + pHanjaToHangulIndex[iMapHanjaInfo].iOffset, 0, FILE_BEGIN);
|
|
|
|
// Read Hanja Info
|
|
if (ReadFile(vhLex, &wcHanja, sizeof(WCHAR), &dwReadBytes, 0) == 0)
|
|
{
|
|
goto GetMeaningAndProuncExit;
|
|
}
|
|
DBGAssert(wch == wcHanja);
|
|
if (ReadFile(vhLex, &cchMeaning, sizeof(BYTE), &dwReadBytes, 0) == 0)
|
|
{
|
|
goto GetMeaningAndProuncExit;
|
|
}
|
|
|
|
if (cchMeaning)
|
|
{
|
|
if (ReadFile(vhLex, wszMeaning, cchMeaning, &dwReadBytes, 0) == 0)
|
|
{
|
|
goto GetMeaningAndProuncExit;
|
|
}
|
|
}
|
|
wszMeaning[cchMeaning>>1] = L'\0';
|
|
|
|
swprintf(lpwstrTip, L"%s %c\nU+%04X", wszMeaning, pHanjaToHangulIndex[iMapHanjaInfo].wchHangul, wch);
|
|
|
|
fRet = TRUE;
|
|
}
|
|
|
|
GetMeaningAndProuncExit:
|
|
UnmapViewOfFile(pHanjaToHangulIndex);
|
|
return fRet;
|
|
}
|
|
|
|
INT SearchHanjaIndex(WCHAR wHChar, HanjaToHangulIndex *pLexIndexTbl)
|
|
{
|
|
int iHead = 0, iTail = vuNumOfHanjaEntry-1, iMid;
|
|
|
|
while (iHead <= iTail)
|
|
{
|
|
iMid = (iHead + iTail) >> 1;
|
|
|
|
Dbg(("SearchHanjaIndex iMid=%d, pLexIndexTbl[iMid].wchHanja = 0x%04X", iMid, pLexIndexTbl[iMid].wchHanja));
|
|
|
|
if (pLexIndexTbl[iMid].wchHanja > wHChar)
|
|
iTail = iMid - 1;
|
|
else
|
|
if (pLexIndexTbl[iMid].wchHanja < wHChar)
|
|
iHead = iMid + 1;
|
|
else
|
|
return (iMid);
|
|
}
|
|
|
|
return (-1);
|
|
}
|
|
|