mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-27 18:17:40 +00:00
* Keyman for Windows 10.0 Open Source * Squashed 'windows/src/ext/jedi/jedi/' content from commit f444ad2 git-subtree-dir: windows/src/ext/jedi/jedi git-subtree-split: f444ad2da4693851e523f1ea6bd541f701904c24 * Squashed 'windows/src/ext/jedi/jcl/' content from commit d63d3c9fd git-subtree-dir: windows/src/ext/jedi/jcl git-subtree-split: d63d3c9fd9ff84efdd8159084ec6a60313644243 * Squashed 'windows/src/ext/jedi/jvcl/' content from commit bee19f3b4 git-subtree-dir: windows/src/ext/jedi/jvcl git-subtree-split: bee19f3b46909fde2fa92c06cd2706f41d99f6c3 * Add required .res files * Add required .res files * Add docbook files (forced) * Add required libxslt * Add required jedi files * Add installation files * Tweak .gitignore for open * CI * Remove KMW from Developer source (#122) * Remove KMW from Developer source (copies during build) * Remove KMW from Developer source (copies during build) * Remove KMW from Developer source (copies during build) * Fixup release build and copy license, readme from kmw during build * Remove obsolete build help documentation * Keyman Engine 10 on Windows regression for shift states (#129) * Improve #128 -- cleaner debug messages * Fixes #127, shift state now resets correctly; and more work for #128 * Fixes #130 (#131)
156 lines
3.7 KiB
C++
156 lines
3.7 KiB
C++
#include "stdafx.h"
|
|
|
|
|
|
static BOOL LoadKeyboardFile(LPSTR fileName, LPKEYBOARD *lpKeyboard);
|
|
BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz);
|
|
|
|
LPKEYBOARD FixupKeyboard(PBYTE bufp, PBYTE base, DWORD dwFileSize);
|
|
|
|
void Err(wchar_t *s) {
|
|
LogError(L"LoadKeyboard: %s, last error = %d\n", s, GetLastError());
|
|
}
|
|
|
|
BOOL LoadKeyboard(LPWSTR fileName, LPKEYBOARD *lpKeyboard) {
|
|
DWORD sz;
|
|
LPBYTE buf;
|
|
HANDLE hFile;
|
|
LPKEYBOARD kbp;
|
|
PBYTE filebase;
|
|
|
|
if(!fileName || !lpKeyboard) {
|
|
Err(L"Bad Filename");
|
|
return FALSE;
|
|
}
|
|
|
|
hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
if(hFile == INVALID_HANDLE_VALUE) {
|
|
Err(L"Could not open file");
|
|
return FALSE;
|
|
}
|
|
|
|
sz = GetFileSize(hFile, NULL);
|
|
|
|
buf = new BYTE[sz];
|
|
|
|
if(!buf) {
|
|
Err(L"Not allocmem");
|
|
CloseHandle(hFile);
|
|
return FALSE;
|
|
}
|
|
|
|
filebase = buf;
|
|
|
|
ReadFile(hFile, filebase, sz, &sz, NULL);
|
|
CloseHandle(hFile);
|
|
|
|
if(!VerifyKeyboard(filebase, sz)) {
|
|
Err(L"errVerifyKeyboard");
|
|
delete buf;
|
|
return FALSE;
|
|
}
|
|
|
|
kbp = FixupKeyboard(buf, filebase, sz);
|
|
if(!kbp) {
|
|
Err(L"errFixupKeyboard");
|
|
delete buf;
|
|
return FALSE;
|
|
}
|
|
|
|
if(kbp->dwIdentifier != FILEID_COMPILED) {
|
|
Err(L"errNotFileID");
|
|
delete buf;
|
|
return FALSE;
|
|
}
|
|
|
|
*lpKeyboard = kbp;
|
|
return TRUE;
|
|
}
|
|
|
|
PWCHAR StringOffset(PBYTE base, DWORD offset) {
|
|
if(offset == 0) return NULL;
|
|
return (PWCHAR)(base + offset);
|
|
}
|
|
|
|
LPKEYBOARD FixupKeyboard(PBYTE bufp, PBYTE base, DWORD dwFileSize) {
|
|
UNREFERENCED_PARAMETER(dwFileSize);
|
|
|
|
DWORD i, j;
|
|
PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD) base;
|
|
PCOMP_GROUP cgp;
|
|
PCOMP_STORE csp;
|
|
PCOMP_KEY ckp;
|
|
LPKEYBOARD kbp = (LPKEYBOARD) bufp;
|
|
LPSTORE sp;
|
|
LPGROUP gp;
|
|
LPKEY kp;
|
|
|
|
kbp->dpStoreArray = (LPSTORE) (base + ckbp->dpStoreArray);
|
|
kbp->dpGroupArray = (LPGROUP) (base + ckbp->dpGroupArray);
|
|
|
|
for(sp = kbp->dpStoreArray, csp = (PCOMP_STORE) sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) {
|
|
sp->dpName = StringOffset(base, csp->dpName);
|
|
sp->dpString = StringOffset(base, csp->dpString);
|
|
}
|
|
|
|
for(gp = kbp->dpGroupArray, cgp = (PCOMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) {
|
|
gp->dpName = StringOffset(base, cgp->dpName);
|
|
gp->dpKeyArray = (LPKEY) (base + cgp->dpKeyArray);
|
|
if(cgp->dpMatch != NULL) gp->dpMatch = (PWSTR) (base + cgp->dpMatch);
|
|
if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PWSTR) (base + cgp->dpNoMatch);
|
|
|
|
for(kp = gp->dpKeyArray, ckp = (PCOMP_KEY) kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) {
|
|
kp->dpOutput = (PWSTR) (base + ckp->dpOutput);
|
|
kp->dpContext = (PWSTR) (base + ckp->dpContext);
|
|
}
|
|
}
|
|
|
|
return kbp;
|
|
}
|
|
|
|
BOOL VerifyChecksum(LPBYTE buf, DWORD sz) {
|
|
DWORD tempcs;
|
|
PCOMP_KEYBOARD ckbp;
|
|
|
|
ckbp = (PCOMP_KEYBOARD) buf;
|
|
|
|
tempcs = ckbp->dwCheckSum;
|
|
ckbp->dwCheckSum = 0;
|
|
|
|
return tempcs == CalculateBufferCRC(sz, buf);
|
|
}
|
|
|
|
BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz) {
|
|
DWORD i;
|
|
PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD) filebase;
|
|
PCOMP_STORE csp;
|
|
|
|
/* Check file version */
|
|
|
|
if(ckbp->dwFileVersion < VERSION_MIN ||
|
|
ckbp->dwFileVersion > VERSION_MAX) {
|
|
/* Old or new version -- identify the desired program version */
|
|
if(VerifyChecksum(filebase, sz)) {
|
|
for(csp = (PCOMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) {
|
|
if(csp->dwSystemID == TSS_COMPILEDVERSION) {
|
|
wchar_t buf2[256];
|
|
if(csp->dpString == 0) {
|
|
wsprintf(buf2, L"errWrongFileVersion:NULL");
|
|
} else {
|
|
wsprintf(buf2, L"errWrongFileVersion:%10.10ls", StringOffset(filebase, csp->dpString));
|
|
}
|
|
Err(buf2);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
Err(L"errWrongFileVersion");
|
|
return FALSE;
|
|
}
|
|
|
|
if(!VerifyChecksum(filebase, sz)) {
|
|
Err(L"errBadChecksum");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|