|
|
#include <windows.h>
#include <setupapi.h>
#include "common.h"
#include "cht.h"
extern TCHAR ImeDataDirectory[MAX_PATH]; extern TCHAR szMsgBuf[];
struct { ULONG PtrLen95; ULONG PhraseLen95; HANDLE hPtrBuf95; HANDLE hPhraseBuf95; ULONG PtrLenNT; ULONG PhraseLenNT; HANDLE hPtrBufNT; HANDLE hPhraseBufNT; } LCData = {0,0,0,0,0,0,0,0};
/******************************Public*Routine******************************\
* InitImeDataCht * * Get Win95 IME phrase data from system directory. * * Arguments: * * Return Value: * * BOOL: TRUE-Success, FALSE-FAIL. * * History: * \**************************************************************************/
BOOL InitImeDataCht(void) {
HFILE hfLCPtr,hfLCPhrase; TCHAR szLCPtrName[MAX_PATH]; TCHAR szLCPhraseName[MAX_PATH]; UCHAR *szLCPtrBuf,*szLCPhraseBuf; UINT len;
// Get system directory
lstrcpy(szLCPtrName, ImeDataDirectory);
DebugMsg(("InitImeDataCht, ImeDataDirectory = %s!\r\n",ImeDataDirectory));
len = lstrlen(ImeDataDirectory); if (szLCPtrName[len - 1] != '\\') { // consider C:\ ;
szLCPtrName[len++] = '\\'; szLCPtrName[len] = 0; } lstrcpy(szLCPhraseName, szLCPtrName); //
// at this step, szLCPhraseName == szLCPtrName
//
lstrcat(szLCPtrName, LCPTRFILE); lstrcat(szLCPhraseName, LCPHRASEFILE);
DebugMsg(("InitImeDataCht, szLCPtrName = %s!\r\n",szLCPtrName));
DebugMsg(("InitImeDataCht, szLCPhraseName = %s!\r\n",szLCPhraseName));
// Open LC pointer file
hfLCPtr=_lopen(szLCPtrName,OF_READ); if(hfLCPtr == -1){ DebugMsg(("InitImeDataCht, open %s failed!\r\n",szLCPtrName));
return FALSE; } DebugMsg(("InitImeDataCht, open %s OK!\r\n",szLCPtrName));
// Open LC phrase file
hfLCPhrase=_lopen(szLCPhraseName,OF_READ); if(hfLCPhrase == -1){ DebugMsg(("InitImeDataCht, open %s failed!\r\n",szLCPhraseName)); _lclose(hfLCPtr); return FALSE; } DebugMsg(("InitImeDataCht, open %s OK!\r\n",szLCPhraseName));
// get file length
LCData.PtrLen95 = _llseek(hfLCPtr,0L,2);
// Allocate Memory
LCData.hPtrBuf95 = GlobalAlloc(GMEM_FIXED, LCData.PtrLen95); if(!LCData.hPtrBuf95) { _lclose(hfLCPtr); _lclose(hfLCPhrase); return FALSE; } szLCPtrBuf = GlobalLock(LCData.hPtrBuf95);
//set to beginning
_llseek(hfLCPtr,0L,0);
if(LCData.PtrLen95 != _lread(hfLCPtr,szLCPtrBuf,LCData.PtrLen95)) { _lclose(hfLCPtr); _lclose(hfLCPhrase); return FALSE; }
//release handle for PTR data
_lclose(hfLCPtr); GlobalUnlock(LCData.hPtrBuf95);
//get file length
LCData.PhraseLen95=_llseek(hfLCPhrase,0L,2);
// Allocate Memory
LCData.hPhraseBuf95 = GlobalAlloc(GMEM_MOVEABLE, LCData.PhraseLen95); if(!LCData.hPhraseBuf95) { _lclose(hfLCPhrase); return FALSE; } szLCPhraseBuf = GlobalLock(LCData.hPhraseBuf95);
_llseek(hfLCPhrase,0L,0); //set to beginning
if(LCData.PhraseLen95 != _lread(hfLCPhrase,szLCPhraseBuf,LCData.PhraseLen95)) { _lclose(hfLCPhrase); return FALSE; }
_lclose(hfLCPhrase); GlobalUnlock(LCData.hPhraseBuf95);
LCData.hPhraseBufNT = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, LCData.PhraseLen95*2); if(!LCData.hPhraseBufNT) { return FALSE; }
LCData.PtrLenNT = LCData.PtrLen95/PTRRECLEN95*PTRRECLENNT*sizeof(WCHAR); LCData.hPtrBufNT = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, LCData.PtrLenNT); if(!LCData.hPtrBufNT) { return FALSE; }
return TRUE;
}
/******************************Private*Routine******************************\
* PtrDataCompare * * Quick sort serve program. * * Arguments: * * const void * arg1 - element 1 * const void * arg2 - element 2 * * Return Value: * * int: 1 >, -1 <, 0 =. * * History: * \**************************************************************************/
int __cdecl PtrDataCompare(const void * arg1, const void * arg2) { if (*((WORD*)arg1) > *((WORD*)arg2)) return 1; else if (*((WORD*)arg1) < *((WORD*)arg2)) return -1; return 0; }
/******************************Private*Routine******************************\
* AddPhrase * * Add a phrase section to buffer. * * Arguments: * * WORD wStart - Start address of a LC phrase section * WORD wEnd - End address of a LC phrase section * * Return Value: * * int: phrase section count. * * History: * \**************************************************************************/
int AddPhrase( WORD wStart, WORD wEnd ) { UINT i,count=0; WORD wWord; UCHAR cchar[2], *szPhraseBuf95; WCHAR *szPhraseBufNT;
szPhraseBuf95 = GlobalLock(LCData.hPhraseBuf95);
szPhraseBufNT = GlobalLock(LCData.hPhraseBufNT);
for(i=wStart; i < wEnd; i++) { wWord=*((WORD *)&szPhraseBuf95[i*2]); wWord |= END_PHRASE; cchar[0]=HIBYTE(wWord); cchar[1]=LOBYTE(wWord); MultiByteToWideChar(950, MB_PRECOMPOSED, cchar, 2, (LPWSTR)(szPhraseBufNT+LCData.PhraseLenNT), 1); LCData.PhraseLenNT++; count++;
// If end of phrase append zero
if( !( (*((WORD *)&szPhraseBuf95[i*2])) & END_PHRASE) ) { szPhraseBufNT[LCData.PhraseLenNT]=0; LCData.PhraseLenNT++; count++; }
}
GlobalUnlock(LCData.hPhraseBuf95); GlobalUnlock(LCData.hPhraseBufNT); return count; }
/******************************Private*Routine******************************\
* PtrBinSearch * * Search end counter of a phrase section. * * Arguments: * * WORD wStart - start address of a LC phrase section * * Return Value: * * WORD: end address of a LC phrase section. * * History: * \**************************************************************************/
WORD PtrBinSeach(WORD wStart) { int mid, low=PTRRECLEN95, high=LCData.PtrLen95; UCHAR *szPtrBuf95 = GlobalLock(LCData.hPtrBuf95);
while (low <= high) { mid = (low+high)/PTRRECLEN95/2*PTRRECLEN95; if (wStart > *((WORD*)&szPtrBuf95[mid+2])) low = mid+PTRRECLEN95; else if (wStart < *((WORD*)&szPtrBuf95[mid+2])) high = mid-PTRRECLEN95; else { GlobalUnlock(LCData.hPtrBuf95); return *((WORD*)&szPtrBuf95[mid+2+PTRRECLEN95]); } } GlobalUnlock(LCData.hPtrBuf95); return 0; }
/******************************Public*Routine******************************\
* ImeDataConvertCht * * Convert Windows 95 IME phrase data to Windows NT 5.0 phrase data format. * * Arguments: * * Return Value: * * BOOL: TRUE-Success, FALSE-FAIL. * * History: * \**************************************************************************/
BOOL ImeDataConvertCht(void) {
WCHAR *szLCPtrBufNT; UCHAR *szLCPtrBuf95, TmpChar; UINT i=PTRRECLEN95, j=PTRRECLENNT; unsigned long count;
szLCPtrBuf95 = GlobalLock(LCData.hPtrBuf95); szLCPtrBufNT = GlobalLock(LCData.hPtrBufNT);
// Convert PTR data to UNICODE
// Keep offset value unchanged
while (i< LCData.PtrLen95 ) { TmpChar = *(szLCPtrBuf95+i); *(szLCPtrBuf95+i) = *(szLCPtrBuf95+i+1); *(szLCPtrBuf95+i+1) = TmpChar; MultiByteToWideChar(950, MB_PRECOMPOSED, (LPCSTR)(szLCPtrBuf95+i), 2, (LPWSTR)(szLCPtrBufNT+j), 1); szLCPtrBufNT[j+1] = *((WORD*)&szLCPtrBuf95[i+2]); i+=PTRRECLEN95; j+=PTRRECLENNT; }
// Sort PTR data - UNICODE, ascending
qsort( (void *)szLCPtrBufNT, (size_t) (LCData.PtrLenNT/sizeof(WCHAR)/PTRRECLENNT), (size_t)PTRRECLENNT*sizeof(WCHAR), PtrDataCompare);
// Get phrase data
i = PTRRECLENNT; LCData.PhraseLenNT = 0; while (i < LCData.PtrLenNT/sizeof(WCHAR)) { count=AddPhrase(szLCPtrBufNT[i+1],PtrBinSeach(szLCPtrBufNT[i+1])); *((unsigned long *)&szLCPtrBufNT[i+1]) = LCData.PhraseLenNT-count; i+=PTRRECLENNT; } LCData.PhraseLenNT=LCData.PhraseLenNT*sizeof(WCHAR);
GlobalUnlock(LCData.hPtrBuf95); GlobalUnlock(LCData.hPtrBufNT);
return TRUE;
}
/******************************Public*Routine******************************\
* FreeResCht * * Release global data used by IME conversion. * * Arguments: * * Return Value: * * * History: * \**************************************************************************/
void FreeResCht(void) { if (LCData.hPtrBuf95) { GlobalFree(LCData.hPtrBuf95); LCData.hPtrBuf95 = NULL; }
if (LCData.hPtrBufNT) { GlobalFree(LCData.hPtrBufNT); LCData.hPtrBufNT = NULL; }
if (LCData.hPhraseBuf95) { GlobalFree(LCData.hPhraseBuf95); LCData.hPhraseBuf95 = NULL; }
if (LCData.hPhraseBufNT) { LCData.hPhraseBufNT = NULL; GlobalFree(LCData.hPhraseBufNT); } }
// Test above routines.
int ConvertChtImeData(void) { LONG fsize; HANDLE f1; WCHAR *szLCPtrBufNT, *szLCPhraseBufNT; UINT len1,len2; TCHAR FilePath[MAX_PATH]; TCHAR szName[MAX_PATH];
if (!InitImeDataCht()) { DebugMsg(("ConvertChtImeData, calling InitImeDataCht failed!\r\n")); FreeResCht(); return 0; } if (!ImeDataConvertCht()) { DebugMsg(("ConvertChtImeData, calling ImeDataConvertCht failed!\r\n")); FreeResCht(); return 0; }
szLCPtrBufNT = GlobalLock(LCData.hPtrBufNT); szLCPhraseBufNT = GlobalLock(LCData.hPhraseBufNT);
len1 = GetSystemDirectory((LPSTR)szName, sizeof(szName)); if (!len1) { DebugMsg(("ConvertChtImeData, calling GetSystemDirectory failed!\r\n")); return 0; } DebugMsg(("ConvertChtImeData, System directory is %s !\r\n",szName));
if (szName[len1 - 1] != '\\') { szName[len1++] = '\\'; szName[len1] = 0; } DebugMsg(("ConvertChtImeData, Backsplash checking, System directory is %s !\r\n",szName));
len2 = lstrlen(ImeDataDirectory); lstrcpy(FilePath, ImeDataDirectory);
lstrcat(FilePath, "lcptr.tbl"); lstrcat(szName,"lcptr.tbl");
//_asm {int 3}
f1 = CreateFile(szName, GENERIC_WRITE, 0, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE, NULL); DebugMsg(("ConvertChtImeData, CreateFile %s !\r\n",szName)); if (f1 == INVALID_HANDLE_VALUE) { DebugMsg(("ConvertChtImeData, Create file %s, failed!\r\n",szName)); } szName[len1]=0; FilePath[len2]=0; if (! WriteFile(f1, szLCPtrBufNT, LCData.PtrLenNT, &fsize, NULL) ) { DebugMsg(("ConvertChtImeData, Write file %s failed!\r\n",szName)); } else { DebugMsg(("ConvertChtImeData, Write file, %s OK!\r\n",szName)); }
CloseHandle(f1);
lstrcat(FilePath, "lcphrase.tbl"); lstrcat(szName,"lcphrase.tbl"); //_asm {int 3}
f1 = CreateFile(szName, GENERIC_WRITE, 0, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE, NULL); DebugMsg(("ConvertChtImeData, CreateFile %s !\r\n",szName)); if (f1 == INVALID_HANDLE_VALUE) { DebugMsg(("ConvertChtImeData, Create file %s, failed!\r\n",szName)); }
if (! WriteFile(f1, szLCPhraseBufNT, LCData.PhraseLenNT, &fsize, NULL)) { DebugMsg(("ConvertChtImeData, Write file %s, failed!\r\n",szName)); } else { DebugMsg(("ConvertChtImeData, Create file %s OK!\r\n",szName)); }
CloseHandle(f1); GlobalUnlock(LCData.hPtrBufNT); GlobalUnlock(LCData.hPhraseBufNT);
FreeResCht(); return 1; }
|