mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-18 14:27:43 +00:00
fix(windows): support unicode strings properly in logs
Fixes #10604. Note: does not address limitations in etl2log yet, but allows us to emit unicode strings to the logs.
This commit is contained in:
parent
dadbf050c2
commit
810ed35a8a
8 changed files with 93 additions and 45 deletions
|
|
@ -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)); // <data name = "Platform" inType = "Platform" / >
|
||||
|
|
@ -115,7 +123,7 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i
|
|||
EventDataDescCreate(&Descriptors[6], &tickCount, sizeof(DWORD)); // <data name = "TickCount" inType = "win:UInt32" / >
|
||||
EventDataDescCreate(&Descriptors[7], (PDWORD)>i.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[9], file, (ULONG)(wcslen(file) + 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" / >
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ EXPORTS
|
|||
Keyman_ResetInitialisation
|
||||
|
||||
Keyman_WriteDebugEvent
|
||||
Keyman_WriteDebugEventW
|
||||
|
||||
Keyman_UpdateTouchPanelVisibility
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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...
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue