diff --git a/windows/src/engine/keyman32/DebugEventTrace.cpp b/windows/src/engine/keyman32/DebugEventTrace.cpp index 3ff479a3a6..6784a31026 100644 --- a/windows/src/engine/keyman32/DebugEventTrace.cpp +++ b/windows/src/engine/keyman32/DebugEventTrace.cpp @@ -30,6 +30,16 @@ int GetActualShiftState() { // I4843 } extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, int line, PWCHAR msg) { + // This function exists solely to provide a stable transition between versions + // of Keyman, so that things don't crash if an older version of kmtip.dll + // happens to call this function in a newer installation. It is not used in + // current versions of Keyman. This change came in around 17.0.260-alpha + PWCHAR fileW = strtowstr(file); + Keyman_WriteDebugEventW(fileW, line, msg); + delete[] fileW; +} + +extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEventW(PWCHAR file, int line, PWCHAR msg) { if (file == NULL || msg == NULL) { return; } @@ -102,8 +112,6 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i 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)); // @@ -115,7 +123,7 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i EventDataDescCreate(&Descriptors[6], &tickCount, sizeof(DWORD)); // EventDataDescCreate(&Descriptors[7], (PDWORD)>i.hwndFocus, sizeof(DWORD)); // EventDataDescCreate(&Descriptors[8], (PDWORD)&activeHKL, sizeof(DWORD)); // - EventDataDescCreate(&Descriptors[9], fileW, (ULONG)(wcslen(fileW) + 1) * sizeof(WCHAR)); // + EventDataDescCreate(&Descriptors[9], file, (ULONG)(wcslen(file) + 1) * sizeof(WCHAR)); // EventDataDescCreate(&Descriptors[10], (PDWORD)&line, sizeof(DWORD)); // EventDataDescCreate(&Descriptors[11], msg, (ULONG)(wcslen(msg) + 1) * sizeof(WCHAR)); // @@ -124,6 +132,5 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i OutputDebugString("Keyman k32_dbg: Failed to call EventWrite"); } - delete fileW; } } diff --git a/windows/src/engine/keyman32/k32_dbg.cpp b/windows/src/engine/keyman32/k32_dbg.cpp index 9785bad5d7..9492ee2f0e 100644 --- a/windows/src/engine/keyman32/k32_dbg.cpp +++ b/windows/src/engine/keyman32/k32_dbg.cpp @@ -137,7 +137,7 @@ BOOL ShouldDebug_1() { return Globals::get_debug_KeymanLog(); } -int SendDebugMessageFormat_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, int line, char *fmt, ...) +int SendDebugMessageFormat_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t*file, int line, char *fmt, ...) { char fmtbuf[256]; @@ -150,6 +150,19 @@ int SendDebugMessageFormat_1(HWND hwnd, TSDMState state, int kmn_lineno, char *f return 0; } +int SendDebugMessageFormatW_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t* file, int line, wchar_t* fmt, ...) +{ + wchar_t fmtbuf[256]; + + va_list vars; + va_start(vars, fmt); + _vsnwprintf_s(fmtbuf, _countof(fmtbuf), _TRUNCATE, fmt, vars); // I2248 // I3547 + fmtbuf[255] = 0; + SendDebugMessageW_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)) @@ -169,7 +182,18 @@ int SendDebugMessageFormat_1(HWND hwnd, TSDMState state, int kmn_lineno, char *f }*/ -int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, int line, char *msg) +int SendDebugMessageW_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t*file, int line, wchar_t* msg) +{ + UNREFERENCED_PARAMETER(hwnd); + UNREFERENCED_PARAMETER(state); // I3569 + UNREFERENCED_PARAMETER(kmn_lineno); + + Keyman_WriteDebugEventW(file, line, msg); + + return 0; +} + +int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t*file, int line, char *msg) { UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(state); // I3569 @@ -177,8 +201,8 @@ int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, i // TODO: convert debugging to Unicode PWSTR msgW = strtowstr(msg); - Keyman_WriteDebugEvent(file, line, msgW); - delete msgW; + Keyman_WriteDebugEventW(file, line, msgW); + delete [] msgW; return 0; } @@ -264,7 +288,7 @@ BOOL DebugSignalPause(BOOL fIsUp) return FALSE; } -void DebugLastError_1(DWORD err, char *context, char *file, int line, char *func) +void DebugLastError_1(DWORD err, char *context, wchar_t *file, int line, char *func) { if(ShouldDebug(sdmDebug)) { @@ -308,7 +332,7 @@ char *Debug_UnicodeString(PWSTR s, int x) { return bufout[x]; } -BOOL DebugAssert_1(BOOL condition, char *message, char *file, int line) +BOOL DebugAssert_1(BOOL condition, char *message, wchar_t *file, int line) { if (!(condition)) { SendDebugMessage_1(0, sdmGlobal, 0, file, line, message); diff --git a/windows/src/engine/keyman32/keyman32.def b/windows/src/engine/keyman32/keyman32.def index 2fa0e767c5..3a3abf8ee4 100644 --- a/windows/src/engine/keyman32/keyman32.def +++ b/windows/src/engine/keyman32/keyman32.def @@ -33,6 +33,7 @@ EXPORTS Keyman_ResetInitialisation Keyman_WriteDebugEvent + Keyman_WriteDebugEventW Keyman_UpdateTouchPanelVisibility diff --git a/windows/src/engine/keyman32/keymanengine.h b/windows/src/engine/keyman32/keymanengine.h index 9befcb302a..401a2b41eb 100644 --- a/windows/src/engine/keyman32/keymanengine.h +++ b/windows/src/engine/keyman32/keymanengine.h @@ -158,24 +158,35 @@ void InitDebugging(); void UninitDebugging(); extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char* file, int line, PWCHAR msg); +extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEventW(PWCHAR file, int line, PWCHAR msg); -#define SendDebugMessage(hwnd,state,kmn_lineno,msg) (ShouldDebug((state)) ? SendDebugMessage_1((hwnd),(state),(kmn_lineno), __FILE__, __LINE__, (msg)) : 0) -#define SendDebugMessageFormat(hwnd,state,kmn_lineno,msg,...) (ShouldDebug((state)) ? SendDebugMessageFormat_1((hwnd),(state),(kmn_lineno), __FILE__, __LINE__, (msg),__VA_ARGS__) : 0) +// Following macros widen a constant string, ugly it is true +#define __WFILE2__(m) L ## m +#define __WFILE1__(m) __WFILE2__(m) +#define __WFILE__ __WFILE1__(__FILE__) + +#define SendDebugMessageW(hwnd,state,kmn_lineno,msg) (ShouldDebug((state)) ? SendDebugMessageW_1((hwnd),(state),(kmn_lineno), __WFILE__, __LINE__, (msg)) : 0) +#define SendDebugMessageFormatW(hwnd,state,kmn_lineno,msg,...) (ShouldDebug((state)) ? SendDebugMessageFormatW_1((hwnd),(state),(kmn_lineno), __WFILE__, __LINE__, (msg),__VA_ARGS__) : 0) + +#define SendDebugMessage(hwnd,state,kmn_lineno,msg) (ShouldDebug((state)) ? SendDebugMessage_1((hwnd),(state),(kmn_lineno), __WFILE__, __LINE__, (msg)) : 0) +#define SendDebugMessageFormat(hwnd,state,kmn_lineno,msg,...) (ShouldDebug((state)) ? SendDebugMessageFormat_1((hwnd),(state),(kmn_lineno), __WFILE__, __LINE__, (msg),__VA_ARGS__) : 0) #define ShouldDebug(state) ShouldDebug_1() -#define DebugLastError(context) (DebugLastError_1(GetLastError(), (context), __FILE__,__LINE__,__FUNCTION__)) -#define DebugLastError0(error, context) (DebugLastError_1((error), (context), __FILE__,__LINE__,__FUNCTION__)) +#define DebugLastError(context) (DebugLastError_1(GetLastError(), (context), __WFILE__, __LINE__,__FUNCTION__)) +#define DebugLastError0(error, context) (DebugLastError_1((error), (context), __WFILE__, __LINE__,__FUNCTION__)) // On failed condition log "message", return FALSE // and assert if a debugger is attached for a debug build. -#define DebugAssert(condition, message) (DebugAssert_1((condition),(message), __FILE__, __LINE__)) -int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, char* file, int line, char* msg); -int SendDebugMessageFormat_1(HWND hwnd, TSDMState state, int kmn_lineno, char* file, int line, char* fmt, ...); -void DebugLastError_1(DWORD err, char* context, char* file, int line, char* func); +#define DebugAssert(condition, message) (DebugAssert_1((condition),(message), __WFILE__, __LINE__)) +int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t* file, int line, char* msg); +int SendDebugMessageFormat_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t* file, int line, char* fmt, ...); +int SendDebugMessageW_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t* file, int line, wchar_t* msg); +int SendDebugMessageFormatW_1(HWND hwnd, TSDMState state, int kmn_lineno, wchar_t* file, int line, wchar_t* fmt, ...); +void DebugLastError_1(DWORD err, char* context, wchar_t* file, int line, char* func); void DebugMessage(LPMSG msg, WPARAM wParam); void DebugShift(char* function, char* point); BOOL DebugSignalPause(BOOL fIsUp); char* Debug_VirtualKey(WORD vk); char* Debug_UnicodeString(PWSTR s, int x = 0); -BOOL DebugAssert_1(BOOL condition, char* msg, char* file, int line); +BOOL DebugAssert_1(BOOL condition, char* msg, wchar_t* file, int line); BOOL ShouldDebug_1(); // TSDMState state); #endif diff --git a/windows/src/engine/kmtip/debug.cpp b/windows/src/engine/kmtip/debug.cpp index fea8998a65..250ac232af 100644 --- a/windows/src/engine/kmtip/debug.cpp +++ b/windows/src/engine/kmtip/debug.cpp @@ -1,18 +1,18 @@ /* Name: K32_DBG Copyright: Copyright (C) SIL International. - Documentation: - Description: + Documentation: + Description: Create Date: 14 Sep 2006 Modified Date: 23 Feb 2016 Authors: mcdurdin - Related Files: - Dependencies: + Related Files: + Dependencies: - Bugs: - Todo: - Notes: + 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 @@ -85,7 +85,7 @@ void InitDebugging() { } } -int SendDebugMessageFormat_1(char *file, int line, PWCHAR fmt, ...) { +int SendDebugMessageFormat_1(wchar_t *file, int line, PWCHAR fmt, ...) { if (ShouldDebug()) { WCHAR fmtbuf[256]; @@ -100,14 +100,14 @@ int SendDebugMessageFormat_1(char *file, int line, PWCHAR fmt, ...) { return 0; } -int SendDebugMessage_1(char *file, int line, PWCHAR msg) { +int SendDebugMessage_1(wchar_t *file, int line, PWCHAR msg) { if (ShouldDebug()) { Keyman32Interface::WriteDebugEvent(file, line, msg); } return 0; } -void DebugLastError_1(char *file, int line, char *func, PWCHAR msg, DWORD err) { +void DebugLastError_1(wchar_t *file, int line, char *func, PWCHAR msg, DWORD err) { if(ShouldDebug()) { WCHAR buf[256]; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, err, 0, buf, _countof(buf), NULL); @@ -121,7 +121,7 @@ void WINAPI Keyman_Diagnostic(int mode) { } } -BOOL _LogSUCCEEDED(char *file, int line, PWSTR caller, PSTR callee, HRESULT hr) { +BOOL _LogSUCCEEDED(wchar_t *file, int line, PWSTR caller, PSTR callee, HRESULT hr) { BOOL result = SUCCEEDED(hr); if (!result) { SendDebugMessageFormat_1(file, line, L"CKMTipTextService::Log: call in %s to %hs failed with %x", caller, callee, hr); diff --git a/windows/src/engine/kmtip/globals.h b/windows/src/engine/kmtip/globals.h index 3990251765..e2bc01ce4e 100644 --- a/windows/src/engine/kmtip/globals.h +++ b/windows/src/engine/kmtip/globals.h @@ -52,24 +52,29 @@ void GetDeadkeyFlags(TfEditCookie ec, ITfContext *pContext, PWSTR buf, int n); // Logging functions // +// Following macros widen a constant string, ugly it is true +#define __WFILE2__(m) L ## m +#define __WFILE1__(m) __WFILE2__(m) +#define __WFILE__ __WFILE1__(__FILE__) + void Log(WCHAR *fmt, ...); BOOL ShouldDebug(); -int SendDebugMessage_1(char *file, int line, PWCHAR msg); // I4379 -int SendDebugMessageFormat_1(char *file, int line, PWCHAR fmt, ...); // I4379 -void DebugLastError_1(char *file, int line, char *func, PWCHAR msg, DWORD err); +int SendDebugMessage_1(wchar_t *file, int line, PWCHAR msg); // I4379 +int SendDebugMessageFormat_1(wchar_t *file, int line, PWCHAR fmt, ...); // I4379 +void DebugLastError_1(wchar_t *file, int line, char *func, PWCHAR msg, DWORD err); -#define SendDebugMessage(msg) (SendDebugMessage_1(__FILE__, __LINE__, (msg))) -#define SendDebugMessageFormat(msg,...) (SendDebugMessageFormat_1(__FILE__, __LINE__, (msg),__VA_ARGS__)) +#define SendDebugMessage(msg) (SendDebugMessage_1(__WFILE__, __LINE__, (msg))) +#define SendDebugMessageFormat(msg,...) (SendDebugMessageFormat_1(__WFILE__, __LINE__, (msg),__VA_ARGS__)) -#define DebugLastError(msg) (DebugLastError_1(__FILE__,__LINE__,__FUNCTION__,(msg),GetLastError())) -#define DebugLastError0(msg,err) (DebugLastError_1(__FILE__,__LINE__,__FUNCTION__,(msg),(err))) +#define DebugLastError(msg) (DebugLastError_1(__WFILE__,__LINE__,__FUNCTION__,(msg),GetLastError())) +#define DebugLastError0(msg,err) (DebugLastError_1(__WFILE__,__LINE__,__FUNCTION__,(msg),(err))) -#define LogSUCCEEDED(hr) _LogSUCCEEDED(__FILE__, __LINE__, __FUNCTIONW__, (#hr), (hr)) -BOOL _LogSUCCEEDED(char *file, int line, PWSTR caller, PSTR callee, HRESULT hr); +#define LogSUCCEEDED(hr) _LogSUCCEEDED(__WFILE__, __LINE__, __FUNCTIONW__, (#hr), (hr)) +BOOL _LogSUCCEEDED(wchar_t *file, int line, PWSTR caller, PSTR callee, HRESULT hr); -//#define LogEnter() (SendDebugMessageFormat_1(__FILE__, __LINE__, L"%hs ENTER", __FUNCTION__)) -//#define LogExit() (SendDebugMessageFormat_1(__FILE__, __LINE__, L"%hs EXIT", __FUNCTION__)) +//#define LogEnter() (SendDebugMessageFormat_1(__WFILE__, __LINE__, L"%hs ENTER", __FUNCTION__)) +//#define LogExit() (SendDebugMessageFormat_1(__WFILE__, __LINE__, L"%hs EXIT", __FUNCTION__)) #define LogEnter() #define LogExit() diff --git a/windows/src/engine/kmtip/keyman32interface.cpp b/windows/src/engine/kmtip/keyman32interface.cpp index 3ec6b9a51f..f160c2d1bc 100644 --- a/windows/src/engine/kmtip/keyman32interface.cpp +++ b/windows/src/engine/kmtip/keyman32interface.cpp @@ -2,7 +2,7 @@ #include "kmtip.h" extern "C" { - BOOL WINAPI Keyman_WriteDebugEvent(char *file, int line, PWCHAR msg); + BOOL WINAPI Keyman_WriteDebugEventW(PWCHAR file, int line, PWCHAR msg); BOOL WINAPI TIPActivateEx(BOOL fActivate); BOOL WINAPI TIPActivateKeyboard(GUID *profile); @@ -15,8 +15,8 @@ extern "C" { BOOL WINAPI TIPIsKeymanRunning(); }; -void Keyman32Interface::WriteDebugEvent(char *file, int line, PWCHAR msg) { - ::Keyman_WriteDebugEvent(file, line, msg); +void Keyman32Interface::WriteDebugEvent(PWCHAR file, int line, PWCHAR msg) { + ::Keyman_WriteDebugEventW(file, line, msg); // Don't DebugLastError here because it depends on WriteDebugEvent... } diff --git a/windows/src/engine/kmtip/kmtip.h b/windows/src/engine/kmtip/kmtip.h index 3ab425891d..ef1d5bafa2 100644 --- a/windows/src/engine/kmtip/kmtip.h +++ b/windows/src/engine/kmtip/kmtip.h @@ -143,7 +143,7 @@ typedef HRESULT(WINAPI *PKEYMANGETCONTEXTFUNC)(int n, PWSTR buf); // I3567 class Keyman32Interface { public: - static void WriteDebugEvent(char *file, int line, PWCHAR msg); + static void WriteDebugEvent(PWCHAR file, int line, PWCHAR msg); static BOOL TIPActivateEx(BOOL fActivate); static BOOL TIPActivateKeyboard(GUID *profile);