spiegel-keyman/windows/src/engine/keyman32/DebugEventTrace.cpp
2020-10-05 09:30:55 +11:00

129 lines
4.9 KiB
C++

#include "pch.h"
#include "keyman-debug-etw.h"
#ifdef _WIN64
#define DEBUG_PLATFORM_STRING "x64"
#define DEBUG_PLATFORM_STRINGW L"x64"
#else
#define DEBUG_PLATFORM_STRING "x86"
#define DEBUG_PLATFORM_STRINGW L"x86"
#endif
#define TAB L"\t"
int GetActualShiftState() { // I4843
int state = 0;
if (GetKeyState(VK_NUMLOCK) & 1) state |= NUMLOCKFLAG;
if (GetKeyState(VK_CAPITAL) & 1) state |= CAPITALFLAG;
if (GetKeyState(VK_SHIFT) < 0) state |= K_SHIFTFLAG;
if (GetKeyState(VK_RCONTROL) < 0) state |= RCTRLFLAG;
if (GetKeyState(VK_LCONTROL) < 0) state |= LCTRLFLAG;
if (GetKeyState(VK_LMENU) < 0) state |= LALTFLAG;
if (GetKeyState(VK_RMENU) < 0) state |= RALTFLAG;
if (GetKeyState(VK_LSHIFT) < 0) state |= 0x10000;
if (GetKeyState(VK_RSHIFT) < 0) state |= 0x20000;
return state;
}
extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, int line, PWCHAR msg) {
if (file == NULL || msg == NULL) {
return;
}
PKEYMAN64THREADDATA _td = ThreadGlobals();
if (!_td) {
return;
}
if (!Globals::get_debug_KeymanLog()) {
return;
}
GUITHREADINFO gti;
WCHAR sProcessPath[256], sProcessName[32];
gti.cbSize = sizeof(gti);
GetGUIThreadInfo(GetCurrentThreadId(), &gti);
GetModuleFileNameW(NULL, sProcessPath, 256);
_wsplitpath_s(sProcessPath, NULL, 0, NULL, 0, sProcessName, 32, NULL, 0);
sProcessName[31] = 0;
if (wcslen(msg) > 256) {
msg[255] = 0;
}
DWORD pid = GetCurrentProcessId();
DWORD tid = GetCurrentThreadId();
DWORD shiftState = Globals::get_ShiftState();
DWORD actualShiftState = GetActualShiftState();
DWORD tickCount = GetTickCount();
HKL activeHKL = GetKeyboardLayout(0);
if (Globals::get_debug_ToConsole()) { // I3951
WCHAR windowinfo[1024];
wsprintfW(windowinfo,
DEBUG_PLATFORM_STRINGW TAB //"Platform" TAB
L"%ls" TAB //"Process" TAB
L"%x" TAB //"PID" TAB
L"%x" TAB //"TID" TAB
L"%x" TAB //"ShiftState" TAB
L"%x" TAB //"ActualShiftState" TAB
L"%d" TAB //"TickCount" TAB
L"%x" TAB //"FocusHWND" TAB
L"%8x" TAB //"ActiveHKL" TAB
L"%hs:%d" TAB //"SourceFile" TAB
L"%ls\n", //"Message"
sProcessName, //"Process" TAB
(unsigned int) pid, //"PID" TAB
(unsigned int) tid, //"TID" TAB
(unsigned int) shiftState, //"ShiftState" TAB
(unsigned int) actualShiftState, // ActualShiftState TAB
(int) tickCount, //"TickCount" TAB
PtrToInt(gti.hwndFocus), //"FocusHWND" TAB
PtrToInt(activeHKL), //"ActiveHKL" TAB
file, line, //"SourceFile" TAB
msg); //"Message"
OutputDebugStringW(windowinfo);
}
if (_td->etwRegHandle != NULL) {
#define MAX_DESCRIPTORS 12
EVENT_DATA_DESCRIPTOR Descriptors[MAX_DESCRIPTORS];
#ifdef _WIN64
DWORD platform = 2;
#else
DWORD platform = 1;
#endif
// TODO Convert to Unicode
PWCHAR fileW = strtowstr(file);
// These must match the manifest template in keyman-debug-etw.man
EventDataDescCreate(&Descriptors[0], &platform, sizeof(DWORD)); // <data name = "Platform" inType = "Platform" / >
EventDataDescCreate(&Descriptors[1], sProcessName, (ULONG)(wcslen(sProcessName) + 1) * sizeof(WCHAR)); // <data name = "Process" inType = "win:UnicodeString" / >
EventDataDescCreate(&Descriptors[2], &pid, sizeof(DWORD)); // <data name = "PID" inType = "win:UInt32" / >
EventDataDescCreate(&Descriptors[3], &tid, sizeof(DWORD)); // <data name = "TID" inType = "win:UInt32" / >
EventDataDescCreate(&Descriptors[4], &shiftState, sizeof(DWORD)); // <data name = "ShiftState" inType = "ShiftState" / >
EventDataDescCreate(&Descriptors[5], &actualShiftState, sizeof(DWORD)); // <data name = "ActualShiftState" inType = "ShiftState" / >
EventDataDescCreate(&Descriptors[6], &tickCount, sizeof(DWORD)); // <data name = "TickCount" inType = "win:UInt32" / >
EventDataDescCreate(&Descriptors[7], (PDWORD)&gti.hwndFocus, sizeof(DWORD)); // <data name = "FocusHWND" inType = "win:UInt32" / >
EventDataDescCreate(&Descriptors[8], (PDWORD)&activeHKL, sizeof(DWORD)); // <data name = "ActiveHKL" inType = "win:UInt32" / >
EventDataDescCreate(&Descriptors[9], fileW, (ULONG)(wcslen(fileW) + 1) * sizeof(WCHAR)); // <data name = "SourceFile" inType = "win:UnicodeString" / >
EventDataDescCreate(&Descriptors[10], (PDWORD)&line, sizeof(DWORD)); // <data name = "SourceLine" inType = "win:UInt32" / >
EventDataDescCreate(&Descriptors[11], msg, (ULONG)(wcslen(msg) + 1) * sizeof(WCHAR)); // <data name = "Message" inType = "win:UnicodeString" / >
DWORD dwErr = EventWrite(_td->etwRegHandle, &DebugEvent, (ULONG)MAX_DESCRIPTORS, &Descriptors[0]);
if (dwErr != ERROR_SUCCESS) {
OutputDebugString("Keyman k32_dbg: Failed to call EventWrite");
}
delete fileW;
}
}