mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-06 17:05:34 +00:00
Updated various places in Keyman Developer to show the full VersionWithTag rather than the short version number we had been previously showing: - About dialog - Welcome screen - Installer - kmcomp help - kmconvert help - kmanalyze help - kmdecomp help This should help when testing to verify that we are testing the right version. Also fixed the keymansentry path when running command line C++ programs from source repo.
218 lines
5.5 KiB
C++
218 lines
5.5 KiB
C++
/*
|
|
Name: kmdecomp
|
|
Copyright: Copyright (C) 2003-2017 SIL International.
|
|
Documentation:
|
|
Description:
|
|
Create Date: 12 Oct 2012
|
|
|
|
Modified Date: 12 Oct 2012
|
|
Authors: mcdurdin
|
|
Related Files:
|
|
Dependencies:
|
|
|
|
Bugs:
|
|
Todo:
|
|
Notes:
|
|
History: 12 Oct 2012 - mcdurdin - I3467 - V9.0 - Upgrade KMDECOMP to compile with KM9 source tree
|
|
*/
|
|
|
|
#include "pch.h"
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "../../../common/windows/cpp/include/keymansentry.h"
|
|
#include "../../../common/windows/cpp/include/keymanversion.h"
|
|
#include "../../../common/windows/cpp/include/legacy_kmx_memory.h"
|
|
#include "../../../common/windows/cpp/include/legacy_kmx_file.h"
|
|
|
|
BOOL LoadKeyboard(LPSTR fileName, LPKEYBOARD *lpKeyboard, LPBYTE *lpBitmap, DWORD *cbBitmap);
|
|
|
|
extern BOOL VerifyChecksum(LPBYTE buf, LPDWORD CheckSum, DWORD sz);
|
|
void Err(char *p);
|
|
int SaveKeyboardSource(LPKEYBOARD kbd, LPBYTE lpBitmap, DWORD cbBitmap, char *filename, char *bmpfile);
|
|
int run(int argc, char *argv[]);
|
|
|
|
/*
|
|
* Keyman
|
|
*
|
|
* Version 6.0
|
|
*
|
|
* KMDFILE compiled file loading
|
|
*
|
|
*/
|
|
|
|
#define KEYMAN_SENTRY_LOGGER_DEVELOPER_TOOLS_KMDECOMP KEYMAN_SENTRY_LOGGER_DEVELOPER_TOOLS ".kmdecomp"
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
return keyman_sentry_main(TRUE, KEYMAN_SENTRY_LOGGER_DEVELOPER_TOOLS_KMDECOMP, argc, argv, run);
|
|
}
|
|
|
|
int run(int argc, char *argv[])
|
|
{
|
|
LPKEYBOARD kbd;
|
|
LPBYTE lpBitmap;
|
|
DWORD cbBitmap;
|
|
char buf[_MAX_PATH], buf2[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], filename[_MAX_FNAME];
|
|
|
|
if(argc < 2 || !strcmp(argv[1], "--help"))
|
|
{
|
|
printf(
|
|
"KMDECOMP: Decompile Keyman .kmx keyboard\n"
|
|
"Version %s, %s\n"
|
|
"Usage: KMDECOMP <filename> [output]\n"
|
|
"Will create a.kmn and optionally a.bmp / .ico with the same filename and in the same location as the input",
|
|
KEYMAN_VersionWithTag, KEYMAN_Copyright
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
if(!LoadKeyboard(argv[1], &kbd, &lpBitmap, &cbBitmap)) return 2;
|
|
|
|
if (argc < 3) {
|
|
_splitpath_s(argv[1], drive, _MAX_DRIVE, dir, _MAX_DIR, filename, _MAX_FNAME, NULL, 0);
|
|
}
|
|
else {
|
|
_splitpath_s(argv[2], drive, _MAX_DRIVE, dir, _MAX_DIR, filename, _MAX_FNAME, NULL, 0);
|
|
}
|
|
|
|
_makepath_s(buf, _MAX_PATH, drive, dir, filename, ".kmn");
|
|
_makepath_s(buf2, _MAX_PATH, drive, dir, filename, ".bmp");
|
|
|
|
int n = SaveKeyboardSource(kbd, lpBitmap, cbBitmap, buf, buf2);
|
|
|
|
if(lpBitmap) delete lpBitmap;
|
|
|
|
delete kbd;
|
|
return n;
|
|
}
|
|
|
|
|
|
void Err(char *p)
|
|
{
|
|
printf("Fatal Error: %s\n", p);
|
|
}
|
|
|
|
BOOL LoadKeyboard(LPSTR fileName, LPKEYBOARD *lpKeyboard, LPBYTE *lpBitmap, DWORD *cbBitmap)
|
|
{
|
|
DWORD sz, i, j;
|
|
LPBYTE buf;
|
|
HANDLE hFile;
|
|
PCOMP_KEYBOARD ckbp;
|
|
PCOMP_GROUP cgp;
|
|
PCOMP_STORE csp;
|
|
PCOMP_KEY ckp;
|
|
LPKEYBOARD kbp;
|
|
LPGROUP gp;
|
|
LPSTORE sp;
|
|
LPKEY kp;
|
|
|
|
if(!lpKeyboard)
|
|
{
|
|
Err("Internal error 001");
|
|
return FALSE;
|
|
}
|
|
|
|
if(!fileName)
|
|
{
|
|
Err("Bad Filename");
|
|
return FALSE;
|
|
}
|
|
|
|
hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
if(hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
Err("Could not open file");
|
|
return FALSE;
|
|
}
|
|
|
|
sz = GetFileSize(hFile, NULL);
|
|
|
|
buf = new BYTE[sz];
|
|
|
|
if(!buf)
|
|
{
|
|
CloseHandle(hFile);
|
|
Err("Could not allocate memory");
|
|
return FALSE;
|
|
}
|
|
|
|
ReadFile(hFile, buf, sz, &sz, NULL);
|
|
|
|
CloseHandle(hFile);
|
|
|
|
kbp = (LPKEYBOARD) buf;
|
|
ckbp = (PCOMP_KEYBOARD) buf;
|
|
|
|
if(kbp->dwIdentifier != FILEID_COMPILED) { delete buf; Err("errNotFileID"); return FALSE; }
|
|
|
|
/* Check file version */
|
|
|
|
if(ckbp->dwFileVersion < VERSION_MIN ||
|
|
ckbp->dwFileVersion > VERSION_MAX)
|
|
{
|
|
/* Old or new version -- identify the desired program version */
|
|
if(VerifyChecksum(buf, &kbp->dwCheckSum, sz))
|
|
{
|
|
kbp->dpStoreArray = (LPSTORE) (buf + ckbp->dpStoreArray);
|
|
for(sp = kbp->dpStoreArray, i = 0; i < kbp->cxStoreArray; i++, sp++)
|
|
if(sp->dwSystemID == TSS_COMPILEDVERSION)
|
|
{
|
|
char buf2[256];
|
|
wsprintf(buf2, "Wrong File Version: file version is %ls", ((PBYTE)kbp) + (INT_PTR)sp->dpString);
|
|
delete buf;
|
|
Err(buf2);
|
|
return FALSE;
|
|
}
|
|
}
|
|
delete buf; Err("Unknown File Version: try using the latest version of KMDECOMP");
|
|
return FALSE;
|
|
}
|
|
|
|
if(!VerifyChecksum(buf, &kbp->dwCheckSum, sz)) { delete buf; Err("Bad Checksum in file"); return FALSE; }
|
|
|
|
kbp->dpStoreArray = (LPSTORE) (buf + ckbp->dpStoreArray);
|
|
kbp->dpGroupArray = (LPGROUP) (buf + ckbp->dpGroupArray);
|
|
|
|
//kbp->dpName = (PWSTR) (buf + ckbp->dpName);
|
|
//kbp->dpCopyright = (PWSTR) (buf + ckbp->dpCopyright);
|
|
//kbp->dpMessage = (PWSTR) (buf + ckbp->dpMessage);
|
|
//kbp->dpLanguageName = (PWSTR) (buf + ckbp->dpLanguageName);
|
|
|
|
if(ckbp->dwBitmapSize > 0)
|
|
{
|
|
*lpBitmap = new BYTE[ckbp->dwBitmapSize];
|
|
*cbBitmap = ckbp->dwBitmapSize;
|
|
memcpy(*lpBitmap, buf + ckbp->dpBitmapOffset, *cbBitmap);
|
|
}
|
|
else
|
|
{
|
|
*lpBitmap = NULL;
|
|
*cbBitmap = 0;
|
|
}
|
|
|
|
for(sp = kbp->dpStoreArray, csp = (PCOMP_STORE) sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++)
|
|
{
|
|
if(csp->dpName > 0) sp->dpName = (PWSTR) (buf + csp->dpName); else sp->dpName = NULL;
|
|
sp->dpString = (PWSTR) (buf + csp->dpString);
|
|
}
|
|
|
|
for(gp = kbp->dpGroupArray, cgp = (PCOMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++)
|
|
{
|
|
if(cgp->dpName > 0) gp->dpName = (PWSTR) (buf + cgp->dpName); else gp->dpName = NULL;
|
|
gp->dpKeyArray = (LPKEY) (buf + cgp->dpKeyArray);
|
|
if(cgp->dpMatch != NULL) gp->dpMatch = (PWSTR) (buf + cgp->dpMatch);
|
|
if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PWSTR) (buf + cgp->dpNoMatch);
|
|
|
|
for(kp = gp->dpKeyArray, ckp = (PCOMP_KEY) kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++)
|
|
{
|
|
kp->dpOutput = (PWSTR) (buf + ckp->dpOutput);
|
|
kp->dpContext = (PWSTR) (buf + ckp->dpContext);
|
|
}
|
|
}
|
|
|
|
*lpKeyboard = kbp;
|
|
|
|
return TRUE;
|
|
}
|
|
|