mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-10 01:27:43 +00:00
321 lines
10 KiB
C++
321 lines
10 KiB
C++
/*
|
|
Name: K32_DBG
|
|
Copyright: Copyright (C) SIL International.
|
|
Documentation:
|
|
Description:
|
|
Create Date: 14 Sep 2006
|
|
|
|
Modified Date: 9 Aug 2015
|
|
Authors: mcdurdin
|
|
Related Files:
|
|
Dependencies:
|
|
|
|
Bugs:
|
|
Todo:
|
|
Notes:
|
|
History: 14 Sep 2006 - mcdurdin - Rework internal debugging to use mailslot passing to Keyman
|
|
05 Dec 2006 - mcdurdin - Disable temporary file-based logging
|
|
15 Jan 2007 - mcdurdin - Use _FILELOG define
|
|
16 Jan 2009 - mcdurdin - Clearer logging of key messages
|
|
30 Jan 2009 - mcdurdin - I1835 - Improve performance of debugging
|
|
11 Mar 2009 - mcdurdin - I1894 - Fix threading bugs introduced in I1888
|
|
07 Sep 2009 - mcdurdin - I2098 - Some debug messages lost in multithreaded apps
|
|
30 Nov 2009 - mcdurdin - I2157 - Deletion of buffer crash if LIBRARY_NAME has no version info
|
|
11 Dec 2009 - mcdurdin - I934 - x64 - Initial version
|
|
11 Dec 2009 - mcdurdin - I934 - identify x64 debugging
|
|
12 Mar 2010 - mcdurdin - I934 - x64 - Complete
|
|
12 Mar 2010 - mcdurdin - I2229 - Remove hints and warnings
|
|
22 Mar 2010 - mcdurdin - I2248 - Crash in Keyman Engine outputting log information
|
|
29 Mar 2010 - mcdurdin - I2263 - Show thread and process info in debug log
|
|
19 Apr 2010 - mcdurdin - I2310 - system.log needs to be reformatted for simple import into database
|
|
04 May 2010 - mcdurdin - I2348 - Debug log needs some reworking
|
|
04 May 2010 - mcdurdin - I2349 - Pause key to send debug log event
|
|
04 May 2010 - mcdurdin - I2352 - Debug logging not reliable in some apps
|
|
04 May 2010 - mcdurdin - I2353 - Need to report Win32 failures more reliably
|
|
28 Jun 2010 - mcdurdin - I2445 - Try and reconnect debug pipe on error
|
|
31 Jan 2011 - mcdurdin - I2690 - Add ForegroundWindow info to debug log
|
|
12 May 2011 - mcdurdin - I2908 - Fix double strike issue - clear up logging
|
|
05 Nov 2012 - mcdurdin - I3547 - V9.0 Use _countof to tidyup code
|
|
17 Nov 2012 - mcdurdin - I3569 - V9.0 - Simplify debug logs by removing unused data
|
|
17 Nov 2012 - mcdurdin - I3570 - V9.0 - Output debug log to debug console
|
|
13 Dec 2012 - mcdurdin - I3656 - V9.0 - Debug logs show too many columns for host messages
|
|
07 Nov 2013 - mcdurdin - I3951 - V9.0 - Add debug-to-console hidden option for Keyman32
|
|
24 Apr 2014 - mcdurdin - I4196 - V9.0 - wm_kmmoreposting must be refactored for TIP work as it is not sequential
|
|
09 Aug 2015 - mcdurdin - I4843 - Log reported modifier state as well as Keyman current modifier state
|
|
*/
|
|
#include "pch.h"
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <evntprov.h>
|
|
|
|
//#define _FILELOG
|
|
|
|
#ifdef _FILELOG
|
|
//FILE *fp = NULL;
|
|
#endif
|
|
|
|
// {DA621615-E08B-4283-918E-D2502D3757AE}
|
|
static const GUID guid_EtwProviderId =
|
|
{ 0xda621615, 0xe08b, 0x4283, { 0x91, 0x8e, 0xd2, 0x50, 0x2d, 0x37, 0x57, 0xae } };
|
|
|
|
|
|
enum {NO_DEBUG_WINDOWS=100, UNABLE_TO_CREATE_FILE_MAPPING, UNABLE_TO_MAP_VIEW_OF_FILE};
|
|
|
|
extern void GetWindowsVersion(char *buf);
|
|
|
|
void InitDebuggingEx(PKEYMAN64THREADDATA _td) {
|
|
if(Globals::get_debug_KeymanLog()) {
|
|
DWORD dwErr = EventRegister(&guid_EtwProviderId, NULL, NULL, &_td->etwRegHandle);
|
|
if (dwErr != ERROR_SUCCESS) {
|
|
OutputDebugString("Keyman k32_dbg: Failed to EventRegister");//TODO: Build a helper function with GLE?
|
|
}
|
|
}
|
|
}
|
|
|
|
void InitDebugging() {
|
|
PKEYMAN64THREADDATA _td = ThreadGlobals();
|
|
if(!_td) return;
|
|
|
|
InitDebuggingEx(_td);
|
|
_td->debug_DebugInit = TRUE;
|
|
|
|
if(Globals::get_debug_KeymanLog())
|
|
{
|
|
VS_FIXEDFILEINFO *ffi;
|
|
DWORD sz;
|
|
UINT ffilen;
|
|
char *buf = new char[1024], fname[260];
|
|
|
|
GetWindowsVersion(buf);
|
|
SendDebugMessage(0, sdmKeyboard, 0, buf);
|
|
delete buf;
|
|
|
|
GetModuleFileName(GetModuleHandle(LIBRARY_NAME), fname, 260);
|
|
sz = GetFileVersionInfoSize(fname, 0);
|
|
if(sz > 0)
|
|
{
|
|
buf = new char[sz];
|
|
GetFileVersionInfo(fname, 0, sz, buf);
|
|
VerQueryValue(buf, "\\", (void **) &ffi, &ffilen);
|
|
|
|
SendDebugMessageFormat(0, sdmKeyboard, 0, "Keyman version: %d.%d.%d.%d",
|
|
HIWORD(ffi->dwProductVersionMS), LOWORD(ffi->dwProductVersionMS),
|
|
HIWORD(ffi->dwProductVersionLS), LOWORD(ffi->dwProductVersionLS));
|
|
delete buf; // I2157
|
|
}
|
|
else
|
|
SendDebugMessage(0, sdmKeyboard, 0, "Keyman version: damaged");
|
|
}
|
|
}
|
|
|
|
void UninitDebuggingEx()
|
|
{
|
|
PKEYMAN64THREADDATA _td = ThreadGlobals();
|
|
if(!_td) return;
|
|
|
|
if (_td->etwRegHandle != NULL) {
|
|
EventUnregister(_td->etwRegHandle);
|
|
_td->etwRegHandle = NULL;
|
|
}
|
|
|
|
_td->debug_DebugInit = FALSE;
|
|
}
|
|
|
|
void UninitDebugging() {
|
|
SendDebugMessage(0, sdmGlobal, 0, "--- UninitDebugging() - shutting down ---");
|
|
}
|
|
|
|
const TSDMState DebugState[] = {sdmInternat, sdmAIDefault, sdmMessage, sdmKeyboard, sdmGlobal, sdmMenu, sdmDebug, sdmLoad, sdmOther};
|
|
|
|
BOOL ShouldDebug_1() {
|
|
PKEYMAN64THREADDATA _td = ThreadGlobals();
|
|
if(!_td) return FALSE;
|
|
|
|
if (!_td->debug_DebugInit) InitDebuggingEx(_td);
|
|
_td->debug_DebugInit = TRUE;
|
|
return Globals::get_debug_KeymanLog();
|
|
}
|
|
|
|
int SendDebugMessageFormat_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, int line, char *fmt, ...)
|
|
{
|
|
char fmtbuf[256];
|
|
|
|
va_list vars;
|
|
va_start(vars, fmt);
|
|
vsnprintf_s(fmtbuf, _countof(fmtbuf), _TRUNCATE, fmt, vars); // I2248 // I3547
|
|
fmtbuf[255] = 0;
|
|
SendDebugMessage_1(hwnd, state, kmn_lineno, file, line, fmtbuf);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*void FillWindowInfo(HWND hwnd, char *sClassName, char *sWindowText)
|
|
{
|
|
if(hwnd == 0 || !GetClassName(hwnd, sClassName, 32))
|
|
sClassName[0] = 0;
|
|
else
|
|
sClassName[31] = 0;
|
|
|
|
WCHAR wsWindowText[32];
|
|
|
|
if(hwnd == 0 || !InternalGetWindowText(hwnd, wsWindowText, 32))
|
|
sWindowText[0] = 0;
|
|
else
|
|
{
|
|
WideCharToMultiByte(CP_ACP, 0, wsWindowText, -1, sWindowText, 32, NULL, NULL);
|
|
sWindowText[31] = 0;
|
|
}
|
|
}*/
|
|
|
|
|
|
int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, int line, char *msg)
|
|
{
|
|
UNREFERENCED_PARAMETER(hwnd);
|
|
UNREFERENCED_PARAMETER(state); // I3569
|
|
UNREFERENCED_PARAMETER(kmn_lineno);
|
|
|
|
// TODO: convert debugging to Unicode
|
|
PWSTR msgW = strtowstr(msg);
|
|
Keyman_WriteDebugEvent(file, line, msgW);
|
|
delete msgW;
|
|
|
|
return 0;
|
|
}
|
|
|
|
const
|
|
char *msgnames[] = {
|
|
"WM_KEYDOWN",
|
|
"WM_KEYUP",
|
|
"WM_CHAR",
|
|
"WM_DEADCHAR",
|
|
"WM_SYSKEYDOWN",
|
|
"WM_SYSKEYUP",
|
|
"WM_SYSCHAR",
|
|
"WM_SYSDEADCHAR",
|
|
"WM_x108",
|
|
"WM_UNICHAR"
|
|
};
|
|
|
|
void DebugMessage(LPMSG msg, WPARAM wParam) // I2908
|
|
{
|
|
char ds[256];
|
|
|
|
if(msg->message == wm_keymankeydown)
|
|
wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
|
|
Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
|
|
else if(msg->message == wm_keymankeyup)
|
|
wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
|
|
Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
|
|
else if (msg->message == wm_keyman_keyevent)
|
|
wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
|
|
Debug_VirtualKey((WORD)msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
|
|
else if(msg->message == WM_KEYDOWN || msg->message == WM_KEYUP || msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP)
|
|
wsprintf(ds, "DebugMessage(%x, %s, wParam: %s, lParam: %X) [message flags: %x time: %d extra: %x]",
|
|
PtrToInt(msg->hwnd),
|
|
msgnames[msg->message-WM_KEYDOWN],
|
|
Debug_VirtualKey((WORD) msg->wParam),
|
|
(unsigned int) msg->lParam,
|
|
wParam,
|
|
(int) msg->time,
|
|
(unsigned int) GetMessageExtraInfo());
|
|
else if(msg->message >= WM_KEYDOWN && msg->message <= WM_UNICHAR)
|
|
wsprintf(ds, "DebugMessage(%x, %s, wParam: '%c' (U+%04X), lParam: %X) [message flags: %x time: %d extra: %x]",
|
|
PtrToInt(msg->hwnd),
|
|
msgnames[msg->message-WM_KEYDOWN],
|
|
msg->wParam,
|
|
msg->wParam,
|
|
(unsigned int) msg->lParam,
|
|
wParam,
|
|
(int) msg->time,
|
|
(unsigned int) GetMessageExtraInfo());
|
|
else
|
|
wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", PtrToInt(msg->hwnd), msg->message, msg->wParam, (unsigned int) msg->lParam, wParam, (int) msg->time);
|
|
|
|
SendDebugMessage(msg->hwnd, sdmMessage, 0, ds);
|
|
}
|
|
|
|
void DebugShift(char *function, char *point)
|
|
{
|
|
BYTE kbd[256];
|
|
GetKeyboardState(kbd);
|
|
|
|
SendDebugMessageFormat(0, sdmKeyboard, 0, "%s - %s Alt: [%x] %x %x Ctrl: [%x] %x %x Shift: %x",
|
|
function, point,
|
|
kbd[VK_MENU],
|
|
kbd[VK_LMENU],
|
|
kbd[VK_RMENU],
|
|
kbd[VK_CONTROL],
|
|
kbd[VK_LCONTROL],
|
|
kbd[VK_RCONTROL],
|
|
kbd[VK_SHIFT]);
|
|
}
|
|
|
|
BOOL DebugSignalPause(BOOL fIsUp)
|
|
{
|
|
if(ShouldDebug(sdmDebug))
|
|
{
|
|
if(fIsUp)
|
|
{
|
|
SendDebugMessage_1(NULL, sdmDebug, -1, NULL, 0, NULL); // Signals an event to the controller
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void DebugLastError_1(DWORD err, char *context, char *file, int line, char *func)
|
|
{
|
|
if(ShouldDebug(sdmDebug))
|
|
{
|
|
char msg[256];
|
|
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, err, 0, msg, sizeof(msg), NULL) == 0) msg[0] = 0;
|
|
for (char *p = msg; *p; p++) {
|
|
if (*p == '\r' || *p == '\n') *p = ' ';
|
|
}
|
|
SendDebugMessageFormat_1(NULL, sdmDebug, 0, file, line, "ERROR %d in %s calling %s: %s", err, func, context, msg);
|
|
}
|
|
}
|
|
|
|
char *Debug_VirtualKey(WORD vk) {
|
|
__declspec(thread) static char buf[256];
|
|
if (!ShouldDebug(sdmDebug)) {
|
|
return "";
|
|
}
|
|
|
|
if (vk < 256) {
|
|
wsprintf(buf, "['%s' 0x%x]", KeyNames[vk], vk);
|
|
}
|
|
else {
|
|
wsprintf(buf, "[0x%x]", vk);
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
char *Debug_UnicodeString(PWSTR s, int x) {
|
|
if (!ShouldDebug(sdmDebug)) {
|
|
return "";
|
|
}
|
|
__declspec(thread) static char bufout[2][128 * 7];
|
|
WCHAR *p;
|
|
char *q;
|
|
for (p = s, q = bufout[x]; *p && (p - s < 128); p++)
|
|
{
|
|
wsprintf(q, "U+%4.4X ", *p); q = strchr(q, 0);
|
|
}
|
|
//WideCharToMultiByte(CP_ACP, 0, buf, -1, bufout, 128, NULL, NULL);
|
|
return bufout[x];
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void _OutputThreadDebugString(char *s) {
|
|
char buf[256];
|
|
sprintf_s(buf, "[%d]: %s\n", GetCurrentThreadId(), s);
|
|
OutputDebugString(buf);
|
|
}
|
|
#endif
|
|
|
|
void WINAPI Keyman_Diagnostic(int mode) {
|
|
if (mode == 0) {
|
|
RaiseException(0xDEADBEEF, EXCEPTION_NONCONTINUABLE, 0, NULL);
|
|
}
|
|
}
|