diff --git a/windows/src/buildtools/buildpkg/buildpkg.dpr b/windows/src/buildtools/buildpkg/buildpkg.dpr
index 0bf508a048..4b268d105b 100644
--- a/windows/src/buildtools/buildpkg/buildpkg.dpr
+++ b/windows/src/buildtools/buildpkg/buildpkg.dpr
@@ -35,7 +35,6 @@ uses
CRC32 in '..\..\global\delphi\general\CRC32.pas',
KeyNames in '..\..\global\delphi\general\KeyNames.pas',
wininet5 in '..\..\global\delphi\general\wininet5.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
GlobalProxySettings in '..\..\global\delphi\general\GlobalProxySettings.pas',
ErrorControlledRegistry in '..\..\global\delphi\vcl\ErrorControlledRegistry.pas',
utilexecute in '..\..\global\delphi\general\utilexecute.pas',
diff --git a/windows/src/buildtools/buildpkg/buildpkg.dproj b/windows/src/buildtools/buildpkg/buildpkg.dproj
index 3b0ea201a8..b30a69513f 100644
--- a/windows/src/buildtools/buildpkg/buildpkg.dproj
+++ b/windows/src/buildtools/buildpkg/buildpkg.dproj
@@ -122,7 +122,6 @@
-
diff --git a/windows/src/desktop/insthelp/insthelp.dpr b/windows/src/desktop/insthelp/insthelp.dpr
index f3da601363..a184fde2db 100644
--- a/windows/src/desktop/insthelp/insthelp.dpr
+++ b/windows/src/desktop/insthelp/insthelp.dpr
@@ -7,7 +7,6 @@ uses
klog in '..\..\global\delphi\general\klog.pas',
utilfiletypes in '..\..\global\delphi\general\utilfiletypes.pas',
RegistryKeys in '..\..\global\delphi\general\RegistryKeys.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
GetOsVersion in '..\..\global\delphi\general\GetOsVersion.pas',
VersionInfo in '..\..\global\delphi\general\VersionInfo.pas',
ErrorControlledRegistry in '..\..\global\delphi\vcl\ErrorControlledRegistry.pas',
diff --git a/windows/src/desktop/insthelp/insthelp.dproj b/windows/src/desktop/insthelp/insthelp.dproj
index d6dd863a77..8036956c57 100644
--- a/windows/src/desktop/insthelp/insthelp.dproj
+++ b/windows/src/desktop/insthelp/insthelp.dproj
@@ -7,7 +7,7 @@
1
Console
None
- 18.2
+ 18.4
Win32
@@ -90,7 +90,6 @@
-
diff --git a/windows/src/desktop/kmshell/kmshell.dpr b/windows/src/desktop/kmshell/kmshell.dpr
index db2fadbcee..d3e423a4f8 100644
--- a/windows/src/desktop/kmshell/kmshell.dpr
+++ b/windows/src/desktop/kmshell/kmshell.dpr
@@ -47,7 +47,6 @@ uses
utilxml in '..\..\global\delphi\general\utilxml.pas',
UfrmInstallKeyboardFromWeb in 'install\UfrmInstallKeyboardFromWeb.pas' {frmInstallKeyboardFromWeb},
UfrmWebContainer in '..\..\global\delphi\ui\UfrmWebContainer.pas' {frmWebContainer},
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
MessageIdentifierConsts in '..\..\global\delphi\cust\MessageIdentifierConsts.pas',
UfrmDownloadProgress in 'util\UfrmDownloadProgress.pas' {frmDownloadProgress},
kmcomapi_errors in '..\..\global\delphi\general\kmcomapi_errors.pas',
diff --git a/windows/src/desktop/kmshell/kmshell.dproj b/windows/src/desktop/kmshell/kmshell.dproj
index 057061fa82..759ef5a2ee 100644
--- a/windows/src/desktop/kmshell/kmshell.dproj
+++ b/windows/src/desktop/kmshell/kmshell.dproj
@@ -163,7 +163,6 @@
-
@@ -391,18 +390,18 @@
true
-
-
- .\
- true
-
-
kmshell.exe
true
+
+
+ .\
+ true
+
+
1
diff --git a/windows/src/desktop/setup/setup.dpr b/windows/src/desktop/setup/setup.dpr
index f613c8a6fd..71a67bcdec 100644
--- a/windows/src/desktop/setup/setup.dpr
+++ b/windows/src/desktop/setup/setup.dpr
@@ -11,7 +11,6 @@ uses
Upload_Settings in '..\..\global\delphi\general\Upload_Settings.pas',
DebugPaths in '..\..\global\delphi\general\DebugPaths.pas',
GetOsVersion in '..\..\global\delphi\general\GetOsVersion.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
TntDialogHelp in 'TntDialogHelp.pas',
httpuploader_messageprocessor_windows in 'httpuploader_messageprocessor_windows.pas',
SetupForm in 'SetupForm.pas',
diff --git a/windows/src/desktop/setup/setup.dproj b/windows/src/desktop/setup/setup.dproj
index ca85f7544b..3733512acf 100644
--- a/windows/src/desktop/setup/setup.dproj
+++ b/windows/src/desktop/setup/setup.dproj
@@ -104,7 +104,6 @@
-
diff --git a/windows/src/developer/TIKE/Tike.dpr b/windows/src/developer/TIKE/Tike.dpr
index 38dedb5374..3131c46b4e 100644
--- a/windows/src/developer/TIKE/Tike.dpr
+++ b/windows/src/developer/TIKE/Tike.dpr
@@ -146,11 +146,9 @@ uses
UfrmDebugStatus in 'child\UfrmDebugStatus.pas' {frmDebugStatus},
UfrmDebugStatus_Key in 'debug\UfrmDebugStatus_Key.pas' {frmDebugStatus_Key},
UfrmDebugStatus_Child in 'debug\UfrmDebugStatus_Child.pas' {frmDebugStatus_Child},
- DebugManager in '..\..\global\delphi\debug\DebugManager.pas',
OnlineUpdateCheck in '..\..\global\delphi\online\OnlineUpdateCheck.pas',
UfrmOnlineUpdateNewVersion in '..\..\global\delphi\online\UfrmOnlineUpdateNewVersion.pas' {frmOnlineUpdateNewVersion},
DebugPaths in '..\..\global\delphi\general\DebugPaths.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
MessageDefaults in 'kct\MessageDefaults.pas',
UfrmDownloadProgress in 'main\UfrmDownloadProgress.pas' {frmDownloadProgress},
UframeOnScreenKeyboardEditor in 'main\UframeOnScreenKeyboardEditor.pas' {frameOnScreenKeyboardEditor},
diff --git a/windows/src/developer/TIKE/Tike.dproj b/windows/src/developer/TIKE/Tike.dproj
index 41c3dc6455..1053483eb9 100644
--- a/windows/src/developer/TIKE/Tike.dproj
+++ b/windows/src/developer/TIKE/Tike.dproj
@@ -313,13 +313,11 @@
-
-
diff --git a/windows/src/developer/TIKE/main/UfrmMain.pas b/windows/src/developer/TIKE/main/UfrmMain.pas
index cc6fd1982d..2102297822 100644
--- a/windows/src/developer/TIKE/main/UfrmMain.pas
+++ b/windows/src/developer/TIKE/main/UfrmMain.pas
@@ -414,7 +414,6 @@ uses
Keyman.Developer.System.CEFManager,
CharMapDropTool,
- DebugManager,
HTMLHelpViewer,
KLog,
keymanapi_TLB,
@@ -530,15 +529,6 @@ begin
frmHelp := TfrmHelp.Create(Application);
- KL.Log('GetDebugManager start');
- try
- GetDebugManager(Handle);
- except
- on E:Exception do
- KL.LogError('GetDebugManager failed: '+E.Message);
- end;
- KL.Log('GetDebugManager finish');
-
Application.OnActivate := AppOnActivate;
LoadDockLayout;
diff --git a/windows/src/developer/kmcomp/kmcomp.dpr b/windows/src/developer/kmcomp/kmcomp.dpr
index 7961ced7a7..70913fe01f 100644
--- a/windows/src/developer/kmcomp/kmcomp.dpr
+++ b/windows/src/developer/kmcomp/kmcomp.dpr
@@ -31,7 +31,6 @@ uses
utilkeyboard in '..\..\global\delphi\general\utilkeyboard.pas',
unicode in '..\..\global\delphi\general\unicode.pas',
utilhttp in '..\..\global\delphi\general\utilhttp.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
GetOsVersion in '..\..\global\delphi\general\GetOsVersion.pas',
UfrmTike in '..\TIKE\main\UfrmTike.pas' {TikeForm: TTntForm},
CompilePackageInstaller in '..\..\global\delphi\general\CompilePackageInstaller.pas',
diff --git a/windows/src/developer/kmcomp/kmcomp.dproj b/windows/src/developer/kmcomp/kmcomp.dproj
index df5c58eaee..d9a5adc844 100644
--- a/windows/src/developer/kmcomp/kmcomp.dproj
+++ b/windows/src/developer/kmcomp/kmcomp.dproj
@@ -130,7 +130,6 @@
-
diff --git a/windows/src/developer/setup/setup.dpr b/windows/src/developer/setup/setup.dpr
index 51c515d53f..bb2b862ceb 100644
--- a/windows/src/developer/setup/setup.dpr
+++ b/windows/src/developer/setup/setup.dpr
@@ -12,7 +12,6 @@ uses
Upload_Settings in '..\..\global\delphi\general\Upload_Settings.pas',
DebugPaths in '..\..\global\delphi\general\DebugPaths.pas',
GetOsVersion in '..\..\global\delphi\general\GetOsVersion.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
TntDialogHelp in 'TntDialogHelp.pas',
httpuploader_messageprocessor_windows in 'httpuploader_messageprocessor_windows.pas',
SetupForm in 'SetupForm.pas',
diff --git a/windows/src/developer/setup/setup.dproj b/windows/src/developer/setup/setup.dproj
index 29cdf1de94..8e39ae65cc 100644
--- a/windows/src/developer/setup/setup.dproj
+++ b/windows/src/developer/setup/setup.dproj
@@ -93,7 +93,6 @@
-
diff --git a/windows/src/engine/.gitignore b/windows/src/engine/.gitignore
new file mode 100644
index 0000000000..045423e809
--- /dev/null
+++ b/windows/src/engine/.gitignore
@@ -0,0 +1,10 @@
+keyman32/MSG00001.bin
+keyman32/keyman-debug-etw.h
+keyman32/keyman-debug-etw.rc
+keyman32/keyman-debug-etw.res
+keyman32/keyman-debug-etwTEMP.BIN
+keyman64/MSG00001.bin
+keyman64/keyman-debug-etw.h
+keyman64/keyman-debug-etw.rc
+keyman64/keyman-debug-etw.res
+keyman64/keyman-debug-etwTEMP.BIN
diff --git a/windows/src/engine/inst/insthelper/insthelper.dpr b/windows/src/engine/inst/insthelper/insthelper.dpr
index 94ca20c8b9..db38baa832 100644
--- a/windows/src/engine/inst/insthelper/insthelper.dpr
+++ b/windows/src/engine/inst/insthelper/insthelper.dpr
@@ -20,7 +20,6 @@ uses
CRC32 in '..\..\..\global\delphi\general\CRC32.pas',
VersionInfo in '..\..\..\global\delphi\general\VersionInfo.pas',
GetOsVersion in '..\..\..\global\delphi\general\GetOsVersion.pas',
- SystemDebugPath in '..\..\..\global\delphi\general\SystemDebugPath.pas',
OnlineConstants in '..\..\..\global\delphi\productactivation\OnlineConstants.pas',
ErrorControlledRegistry in '..\..\..\global\delphi\vcl\ErrorControlledRegistry.pas',
Unicode in '..\..\..\global\delphi\general\Unicode.pas',
diff --git a/windows/src/engine/inst/insthelper/insthelper.dproj b/windows/src/engine/inst/insthelper/insthelper.dproj
index c4240ed200..e250ad58ca 100644
--- a/windows/src/engine/inst/insthelper/insthelper.dproj
+++ b/windows/src/engine/inst/insthelper/insthelper.dproj
@@ -7,7 +7,7 @@
1
Library
None
- 18.1
+ 18.4
Win32
@@ -74,7 +74,7 @@
Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
1033
- CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
insthelper_Icon.ico
@@ -86,7 +86,7 @@
RELEASE;$(DCC_Define)
- CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
1033
@@ -94,7 +94,7 @@
false
- CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
1033
@@ -106,7 +106,6 @@
-
@@ -175,6 +174,7 @@
+ False
True
False
diff --git a/windows/src/engine/keyman/GlobalKeyboardChangeManager.pas b/windows/src/engine/keyman/GlobalKeyboardChangeManager.pas
index 047515cd1c..e133a04567 100644
--- a/windows/src/engine/keyman/GlobalKeyboardChangeManager.pas
+++ b/windows/src/engine/keyman/GlobalKeyboardChangeManager.pas
@@ -30,7 +30,7 @@ type
implementation
uses
- DebugManager,
+ Keyman.System.DebugLogClient,
UfrmKeyman7Main;
const
@@ -78,7 +78,7 @@ begin
// ATOM construction copied from TLangSwitchKeyboard
s := IntToStr(TIP.Profile.langid) + '|' + GUIDToString(TGUID(TIP.Profile.clsid)) + '|' + GUIDToString(TGUID(TIP.Profile.guidProfile));
- TDebugManager.WriteMessage('TGlobalKeyboardChangeManager.PostChange: '+s, []);
+ TDebugLogClient.Instance.WriteMessage('TGlobalKeyboardChangeManager.PostChange: '+s, []);
if s <> FLastKeyboard then
begin
@@ -92,7 +92,7 @@ begin
WinKB := Keyboard as TLangSwitchKeyboard_WinKeyboard;
s := IntToStr(WinKB.HKL);
- TDebugManager.WriteMessage('TGlobalKeyboardChangeManager.PostChange: '+s, []);
+ TDebugLogClient.Instance.WriteMessage('TGlobalKeyboardChangeManager.PostChange: '+s, []);
if s <> FLastKeyboard then
begin
diff --git a/windows/src/engine/keyman/UfrmDebugNotify.dfm b/windows/src/engine/keyman/UfrmDebugNotify.dfm
deleted file mode 100644
index 299a6a649e..0000000000
--- a/windows/src/engine/keyman/UfrmDebugNotify.dfm
+++ /dev/null
@@ -1,80 +0,0 @@
-object frmDebugNotify: TfrmDebugNotify
- Left = 0
- Top = 0
- BorderIcons = [biSystemMenu]
- BorderStyle = bsDialog
- Caption = 'Keyman Debug Notification'
- ClientHeight = 321
- ClientWidth = 553
- Color = clBtnFace
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- FormStyle = fsStayOnTop
- OldCreateOrder = False
- Position = poScreenCenter
- OnShow = FormShow
- PixelsPerInch = 96
- TextHeight = 13
- object lblNotes: TLabel
- Left = 12
- Top = 17
- Width = 240
- Height = 13
- Caption = 'Note &details about this issue to store in the log file'
- FocusControl = memoNotes
- end
- object lblLogFileName: TLabel
- Left = 12
- Top = 259
- Width = 67
- Height = 13
- Caption = '&Log file name:'
- FocusControl = editLogFileName
- end
- object memoNotes: TMemo
- Left = 12
- Top = 36
- Width = 529
- Height = 209
- TabOrder = 0
- end
- object editLogFileName: TEdit
- Left = 92
- Top = 256
- Width = 449
- Height = 21
- TabStop = False
- ParentColor = True
- ReadOnly = True
- TabOrder = 1
- end
- object chkNotepad: TCheckBox
- Left = 92
- Top = 288
- Width = 133
- Height = 17
- Caption = 'Open log file in &Notepad'
- TabOrder = 2
- end
- object cmdOK: TButton
- Left = 472
- Top = 283
- Width = 73
- Height = 25
- Caption = 'OK'
- Default = True
- TabOrder = 4
- OnClick = cmdOKClick
- end
- object chkClipboard: TCheckBox
- Left = 244
- Top = 288
- Width = 145
- Height = 17
- Caption = '&Copy file to clipboard'
- TabOrder = 3
- end
-end
diff --git a/windows/src/engine/keyman/UfrmDebugNotify.pas b/windows/src/engine/keyman/UfrmDebugNotify.pas
deleted file mode 100644
index 3ea2a15fda..0000000000
--- a/windows/src/engine/keyman/UfrmDebugNotify.pas
+++ /dev/null
@@ -1,181 +0,0 @@
-(*
- Name: UfrmDebugNotify
- Copyright: Copyright (C) SIL International.
- Documentation:
- Description:
- Create Date: 4 May 2010
-
- Modified Date: 8 Jun 2012
- Authors: mcdurdin
- Related Files:
- Dependencies:
-
- Bugs:
- Todo:
- Notes:
- History: 04 May 2010 - mcdurdin - I2348 - Rework of debug log
- 04 May 2010 - mcdurdin - I2349 - Debug log capture hotkey
- 08 Jun 2012 - mcdurdin - I3349 - V9.0 - Consolidate all process creation into TUtilExecute
-*)
-unit UfrmDebugNotify;
-
-interface
-
-uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, UserMessages;
-
-type
- TfrmDebugNotify = class(TForm)
- memoNotes: TMemo;
- lblNotes: TLabel;
- editLogFileName: TEdit;
- chkNotepad: TCheckBox;
- cmdOK: TButton;
- lblLogFileName: TLabel;
- chkClipboard: TCheckBox;
- procedure FormShow(Sender: TObject);
- procedure cmdOKClick(Sender: TObject);
- private
- FLogFileHandle: THandle;
- FLogFileIndex: Integer;
- procedure SetLogFileIndex(const Value: Integer);
- procedure WMUserFormShown(var Message: TMessage); message WM_USER_FormShown;
- procedure SetClipboardToFilename(const Filename: string);
- { Private declarations }
- public
- { Public declarations }
- property LogFileHandle: THandle read FLogFileHandle write FLogFileHandle;
- property LogFileIndex: Integer read FLogFileIndex write SetLogFileIndex;
- end;
-
-implementation
-
-uses
- Clipbrd,
- DebugManager,
- ShellApi,
- ShlObj,
- utilexecute;
-
-{$R *.dfm}
-
-{ TfrmDebugNotify }
-
-////////////////////////////////////////////////////////////////
-// copies filenames from "Filenames" to the clipboard.
-// "Filenames" can contain file- and directory names.
-function Sto_CopyFilenamesToClipboard(Filenames: TStrings): Boolean;
-var
- sFilenames: String;
- iIndex: Integer;
- hBuffer: HGLOBAL;
- pBuffer: PDropFiles;
-begin
- // check entry conditions
- Result := (Filenames <> nil) and (Filenames.Count > 0);
- if (not Result) then Exit;
- // bring the filenames in a form,
- // separated by #0 and ending with a double #0#0
- sFilenames := '';
- for iIndex := 0 to Filenames.Count - 1 do
- sFilenames := sFilenames +
- ExcludeTrailingPathDelimiter(Filenames.Strings[iIndex]) + #0;
- sFilenames := sFilenames + #0;
- // allocate memory with the size of the "DropFiles" structure plus the
- // length of the filename buffer.
- hBuffer := GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT,
- SizeOf(DROPFILES) + Length(sFilenames));
- try
- Result := (hBuffer <> 0);
- if (Result) then
- begin
- pBuffer := GlobalLock(hBuffer);
- try
- // prepare the "DROPFILES" structure
- pBuffer^.pFiles := SizeOf(DROPFILES);
- // behind the "DROPFILES" structure we place the filenames
- pBuffer := Pointer(Integer(pBuffer) + SizeOf(DROPFILES));
- CopyMemory(pBuffer, PChar(sFilenames), Length(sFilenames));
- finally
- GlobalUnlock(hBuffer);
- end;
- // copy buffer to the clipboard
- Clipboard.Open;
- try
- Clipboard.SetAsHandle(CF_HDROP, hBuffer);
- finally
- Clipboard.Close;
- end;
- end;
- except
- Result := False;
- // free only if handle could not be passed to the clipboard
- GlobalFree(hBuffer);
- end;
-end;
-
-
-procedure TfrmDebugNotify.SetClipboardToFilename(const Filename: string);
-var
- s: TStrings;
-begin
- s := TSTringList.Create;
- try
- s.Add(Filename);
- Sto_CopyFilenamesToClipboard(s);
- finally
- s.Free;
- end;
-end;
-
-type
- TDebugManagerEx = class(TDebugManager)
- end;
-
-procedure TfrmDebugNotify.cmdOKClick(Sender: TObject);
-begin
- TDebugManagerEx.WriteString(FLogFileHandle, memoNotes.Text);
- {
- buf := PChar(memoNotes.Text);
- buflen := Length(buf);
- WriteFile(FLogFileHandle, PChar(buf)^, buflen, n, nil);
- WriteFile(FLogFileHandle, #13#10, 2, n, nil);
- }
- TDebugManagerEx.CloseLogFile(FLogFileHandle);
-
- if chkNotepad.Checked then
- if not TUtilExecute.Shell(Handle, editLogFileName.Text, GetCurrentDir) then // I3349
- ShowMessage(SysErrorMessage(GetLastError));
-
- if chkClipboard.Checked then
- SetClipboardToFilename(editLogFileName.Text);
-
- ModalResult := mrOk;
-end;
-
-procedure TfrmDebugNotify.FormShow(Sender: TObject);
-begin
- PostMessage(Handle, WM_USER_FormShown, 0, 0);
-end;
-
-procedure TfrmDebugNotify.SetLogFileIndex(const Value: Integer);
-begin
- FLogFileIndex := Value;
- editLogFileName.Text := TDebugManager.DebugLogFileName(Value);
-end;
-
-procedure TfrmDebugNotify.WMUserFormShown(var Message: TMessage);
-var
- FThreadID: DWord;
-begin
- FThreadID := GetWindowThreadProcessId(GetForegroundWindow);
- if FThreadID <> GetCurrentThreadId then
- AttachThreadInput(GetCurrentThreadId, FThreadID, True);
- BringToFront;
- SetFocus;
- if FThreadID <> GetCurrentThreadId then
- AttachThreadInput(GetCurrentThreadId, FThreadID, False);
-end;
-
-end.
diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas
index 0d1383ccaa..af78a66f57 100644
--- a/windows/src/engine/keyman/UfrmKeyman7Main.pas
+++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas
@@ -148,6 +148,9 @@ uses
Vcl.StdCtrls,
Vcl.ImgList,
+ Keyman.System.DebugLogClient,
+ Keyman.System.DebugLogManager,
+
keymanapi_TLB,
//TOUCH UfrmTouchKeyboard,
GlobalKeyboardChangeManager,
@@ -155,7 +158,6 @@ uses
KeymanTrayIcon,
KeymanMenuItem,
custinterfaces,
- DebugManager,
Menu_KeyboardItems,
UserMessages,
UfrmKeymanMenu,
@@ -240,7 +242,6 @@ type
procedure WMUserParameterPass(var Message: TMessage); message WM_USER_ParameterPass;
procedure WMUserSendFontChange(var Message: TMessage); message WM_USER_SendFontChange;
procedure WMUserPlatformComms(var Message: TMessage); message WM_USER_PlatformComms;
- procedure WMUserDebugNotify(var Message: TMessage); message WM_USER_DebugNotify;
procedure WMUserVisualKeyboardClosed(var Message: TMessage); message WM_USER_VisualKeyboardClosed; // I4243
procedure SetTrayIcon(rp: TRunningProduct; kbd: IKeymanKeyboardInstalled);
procedure TrayIconMouseUp(Sender: TObject; Button: TMouseButton;
@@ -378,7 +379,6 @@ uses
UfrmHelp,
UILanguages,
UfrmOSKCharacterMap,
- UfrmDebugNotify,
utilstr,
utilwow64,
KeymanEngineControl,
@@ -715,7 +715,7 @@ begin
end
else if Message.Msg = wm_keyman_globalswitch then
begin
- TDebugManager.WriteMessage('wm_keyman_globalswitch for Application Handle: %x %x', [Message.wParam, Message.lParam]);
+ TDebugLogClient.Instance.WriteMessage('wm_keyman_globalswitch for Application Handle: %x %x', [Message.wParam, Message.lParam]);
case Message.wParam of
skHKL, // A windows language has been selected so select the most appropriate Keyman keyboard
@@ -733,9 +733,9 @@ begin
Exit;
end;
- TDebugManager.WriteMessage('wm_keyman_control for Application Handle: %x %x', [Message.wParam, Message.lParam]);
+ TDebugLogClient.Instance.WriteMessage('wm_keyman_control for Application Handle: %x %x', [Message.wParam, Message.lParam]);
Message.Result := ProcessWMKeymanControl(LoWord(Message.WParam), HiWord(Message.WParam), Message.LParam); // I3961
- TDebugManager.WriteMessage('wm_keyman_control-exit for Application Handle: %x %x -> %x', [Message.wParam, Message.lParam, Message.Result]); // I3961
+ TDebugLogClient.Instance.WriteMessage('wm_keyman_control-exit for Application Handle: %x %x -> %x', [Message.wParam, Message.lParam, Message.Result]); // I3961
end
else
Result := False;
@@ -748,21 +748,21 @@ begin
gti.cbSize := SizeOf(gti);
if not GetGUIThreadInfo(0, gti) then
begin
- TDebugManager.WriteLastError('UpdateFocusInfo', 'GetGUIThreadInfo');
+ TDebugLogClient.Instance.WriteLastError('UpdateFocusInfo', 'GetGUIThreadInfo');
Exit;
end;
- TDebugManager.WriteMessage('UpdateFocusInfo: last focus=%x last active=%x', [FLastFocus, FLastActive]);
- TDebugManager.WriteMessage('UpdateFocusInfo: new focus=%x new active=%x', [gti.hwndFocus, gti.hwndActive]);
+ TDebugLogClient.Instance.WriteMessage('UpdateFocusInfo: last focus=%x last active=%x', [FLastFocus, FLastActive]);
+ TDebugLogClient.Instance.WriteMessage('UpdateFocusInfo: new focus=%x new active=%x', [gti.hwndFocus, gti.hwndActive]);
if IsControllerWindow(gti.hwndFocus) then // I4731
- TDebugManager.WriteMessage('UpdateFocusInfo: new focus is controller window, not updating', [])
+ TDebugLogClient.Instance.WriteMessage('UpdateFocusInfo: new focus is controller window, not updating', [])
else if IsSysTrayWindow(gti.hwndFocus) then // I4731
- TDebugManager.WriteMessage('UpdateFocusInfo: new focus is systray window, not updating', [])
+ TDebugLogClient.Instance.WriteMessage('UpdateFocusInfo: new focus is systray window, not updating', [])
else if IsControllerWindow(gti.hwndActive) then // I4731
- TDebugManager.WriteMessage('UpdateFocusInfo: new active is controller window, not updating', [])
+ TDebugLogClient.Instance.WriteMessage('UpdateFocusInfo: new active is controller window, not updating', [])
else if IsSysTrayWindow(gti.hwndActive) then // I4731
- TDebugManager.WriteMessage('UpdateFocusInfo: new active is systray window, not updating', [])
+ TDebugLogClient.Instance.WriteMessage('UpdateFocusInfo: new active is systray window, not updating', [])
else
begin
FLastFocus := gti.hwndFocus;
@@ -928,14 +928,14 @@ begin
if Assigned(kbd) then
begin
case kbd.ItemType of
- lsitWinKeyboard: TDebugManager.WriteMessage('LanguageSwitchFormHidden: kbd assigned, type = lsitWinKeyboard, value = %x', [(kbd as TLangSwitchKeyboard_WinKeyboard).HKL]);
- lsitTIP: TDebugManager.WriteMessage('LanguageSwitchFormHidden: kbd assigned, type = lsitTIP, value = %s', [(kbd as TLangSwitchKeyboard_TIP).Caption]);
- else TDebugManager.WriteMessage('LanguageSwitchFormHidden: kbd assigned, type = somthing else', []);
+ lsitWinKeyboard: TDebugLogClient.Instance.WriteMessage('LanguageSwitchFormHidden: kbd assigned, type = lsitWinKeyboard, value = %x', [(kbd as TLangSwitchKeyboard_WinKeyboard).HKL]);
+ lsitTIP: TDebugLogClient.Instance.WriteMessage('LanguageSwitchFormHidden: kbd assigned, type = lsitTIP, value = %s', [(kbd as TLangSwitchKeyboard_TIP).Caption]);
+ else TDebugLogClient.Instance.WriteMessage('LanguageSwitchFormHidden: kbd assigned, type = somthing else', []);
end;
kbd.Activate(hwnd);
end
else
- TDebugManager.WriteMessage('LanguageSwitchFormHidden: kbd NOT assigned',[]);
+ TDebugLogClient.Instance.WriteMessage('LanguageSwitchFormHidden: kbd NOT assigned',[]);
end;
procedure TfrmKeyman7Main.ShowMenu(Sender: TObject; Location: TCustomisationMenuItemLocation; NearTray: Boolean; IconRect: TRect); // I3990 // I3991
@@ -1155,18 +1155,6 @@ begin
end;
end;
-procedure TfrmKeyman7Main.WMUserDebugNotify(var Message: TMessage);
-begin
- with TfrmDebugNotify.Create(Self) do
- try
- LogFileHandle := Message.LParam;
- LogFileIndex := Message.WParam;
- ShowModal;
- finally
- Free;
- end;
-end;
-
procedure TfrmKeyman7Main.WMUserSendFontChange(var Message: TMessage);
begin
PostMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
@@ -1377,7 +1365,7 @@ procedure TfrmKeyman7Main.ActivateKeyboard(Keyboard: TLangSwitchKeyboard); //
var
hwnd: THandle;
begin
- TDebugManager.WriteMessage('ActivateKeyboard: LastFocus=%x LastActive=%x Keyboard=%s KeymanID=%d', [FLastFocus, FLastActive, Keyboard.Caption, Keyboard.KeymanID]); // I4674
+ TDebugLogClient.Instance.WriteMessage('ActivateKeyboard: LastFocus=%x LastActive=%x Keyboard=%s KeymanID=%d', [FLastFocus, FLastActive, Keyboard.Caption, Keyboard.KeymanID]); // I4674
hwnd := FLastFocus;
AllowSetForegroundWindow(ASFW_ANY); // I3933
PostMessage(FLastActive, wm_keyman_control_internal, KMCI_SETFOREGROUND, FLastFocus); // I3933
@@ -1405,23 +1393,23 @@ begin
tid := GetWindowThreadProcessId(FLastFocus, nil);
if tid = 0 then
begin
- TDebugManager.WriteLastError('SetLastFocus', 'GetWindowThreadProcessId');
+ TDebugLogClient.Instance.WriteLastError('SetLastFocus', 'GetWindowThreadProcessId');
Exit;
end;
if not AttachThreadInput(tid, GetCurrentThreadId, TRUE) then
begin
- TDebugManager.WriteLastError('SetLastFocus', 'AttachThreadInput:1');
+ TDebugLogClient.Instance.WriteLastError('SetLastFocus', 'AttachThreadInput:1');
Exit;
end;
//Windows.SetForegroundWindow(FLastFocus); //FLastActive);
if Winapi.Windows.SetFocus(FLastFocus) = 0 then
- TDebugManager.WriteLastError('SetLastFocus', 'SetFocus');
+ TDebugLogClient.Instance.WriteLastError('SetLastFocus', 'SetFocus');
if not AttachThreadInput(tid, GetCurrentThreadId, FALSE) then
begin
- TDebugManager.WriteLastError('SetLastFocus', 'AttachThreadInput:2');
+ TDebugLogClient.Instance.WriteLastError('SetLastFocus', 'AttachThreadInput:2');
Exit;
end;
end;
diff --git a/windows/src/engine/keyman/keyman.dpr b/windows/src/engine/keyman/keyman.dpr
index 40ecaf863a..25166911d9 100644
--- a/windows/src/engine/keyman/keyman.dpr
+++ b/windows/src/engine/keyman/keyman.dpr
@@ -52,11 +52,10 @@ uses
UfrmCharacterMapFilter in '..\..\global\delphi\charmap\UfrmCharacterMapFilter.pas' {frmCharacterMapFilter},
FixedTrackbar in '..\..\global\delphi\comp\FixedTrackbar.pas',
Menu_KeyboardItems in 'Menu_KeyboardItems.pas',
- DebugManager in '..\..\global\delphi\debug\DebugManager.pas',
+ Keyman.System.DebugLogManager in '..\..\global\delphi\debug\Keyman.System.DebugLogManager.pas',
PaintPanel in '..\..\global\delphi\comp\PaintPanel.pas',
exImageList in '..\..\global\delphi\comp\exImageList.pas',
utilhttp in '..\..\global\delphi\general\utilhttp.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
VistaMessages in 'VistaMessages.pas',
MessageIdentifierConsts in '..\..\global\delphi\cust\MessageIdentifierConsts.pas',
VisualKeyboardExportXML in '..\..\global\delphi\visualkeyboard\VisualKeyboardExportXML.pas',
@@ -93,7 +92,6 @@ uses
WebSoundControl in '..\..\global\delphi\general\WebSoundControl.pas',
VKeyChars in '..\..\global\delphi\general\VKeyChars.pas',
usp10 in '..\..\global\delphi\general\usp10.pas',
- UfrmDebugNotify in 'UfrmDebugNotify.pas' {frmDebugNotify},
UserMessages in '..\..\global\delphi\general\UserMessages.pas',
UfrmKeymanMenu in 'UfrmKeymanMenu.pas' {frmKeymanMenu},
UILanguages in '..\..\desktop\kmshell\util\UILanguages.pas',
@@ -139,7 +137,9 @@ uses
Keyman.System.Standards.BCP47SubtagRegistry in '..\..\global\delphi\standards\Keyman.System.Standards.BCP47SubtagRegistry.pas',
Keyman.System.Standards.BCP47SuppressScriptRegistry in '..\..\global\delphi\standards\Keyman.System.Standards.BCP47SuppressScriptRegistry.pas',
Keyman.System.Standards.LibPalasoAllTagsRegistry in '..\..\global\delphi\standards\Keyman.System.Standards.LibPalasoAllTagsRegistry.pas',
- Keyman.System.CanonicalLanguageCodeUtils in '..\..\global\delphi\general\Keyman.System.CanonicalLanguageCodeUtils.pas';
+ Keyman.System.CanonicalLanguageCodeUtils in '..\..\global\delphi\general\Keyman.System.CanonicalLanguageCodeUtils.pas',
+ Keyman.System.DebugLogClient in '..\..\global\delphi\debug\Keyman.System.DebugLogClient.pas',
+ Keyman.System.DebugLogCommon in '..\..\global\delphi\debug\Keyman.System.DebugLogCommon.pas';
{$R ICONS.RES}
{$R VERSION.RES}
diff --git a/windows/src/engine/keyman/keyman.dproj b/windows/src/engine/keyman/keyman.dproj
index e670ebf090..8893daced2 100644
--- a/windows/src/engine/keyman/keyman.dproj
+++ b/windows/src/engine/keyman/keyman.dproj
@@ -149,11 +149,10 @@
-
+
-
@@ -205,9 +204,6 @@
-
-
-
@@ -264,6 +260,8 @@
+
+
Cfg_2
diff --git a/windows/src/engine/keyman/langswitch/LangSwitchManager.pas b/windows/src/engine/keyman/langswitch/LangSwitchManager.pas
index cda4466df5..646807eac2 100644
--- a/windows/src/engine/keyman/langswitch/LangSwitchManager.pas
+++ b/windows/src/engine/keyman/langswitch/LangSwitchManager.pas
@@ -245,7 +245,7 @@ uses
// System.StrUtils,
- DebugManager,
+ Keyman.System.DebugLogClient,
glossary,
InterfaceHotkeys,
kmint,
@@ -361,18 +361,18 @@ var
ppEnum: IEnumTfInputProcessorProfiles;
FItem: TLangSwitchKeyboard;
begin
- TDebugManager.WriteMessage('[EnumTSFKeyboards] ENTER -------------', []);
+ TDebugLogClient.Instance.WriteMessage('[EnumTSFKeyboards] ENTER -------------', []);
Assert(Assigned(FProfileMgr)); // I2864 // I4220
for I := 0 to FLanguages.Count - 1 do
begin
- TDebugManager.WriteMessage('[EnumTSFKeyboards] LangID=%x', [FLanguages[i].LangID]);
+ TDebugLogClient.Instance.WriteMessage('[EnumTSFKeyboards] LangID=%x', [FLanguages[i].LangID]);
FProfileMgr.EnumProfiles(FLanguages[i].LangID, ppEnum);
hr := ppEnum.Next(1, profile, pcFetch);
while hr = S_OK do
begin
try
- TDebugManager.WriteMessage('[EnumTSFKeyboards] LangID=%x type=%d hkl=%x flags=%x', [FLanguages[i].LangID, profile.dwProfileType, profile.HKL, profile.dwFlags]);
+ TDebugLogClient.Instance.WriteMessage('[EnumTSFKeyboards] LangID=%x type=%d hkl=%x flags=%x', [FLanguages[i].LangID, profile.dwProfileType, profile.HKL, profile.dwFlags]);
if (profile.dwFlags and TF_IPP_FLAG_ENABLED) = 0 then // I4207
begin
@@ -382,12 +382,12 @@ begin
if profile.dwProfileType = TF_PROFILETYPE_KEYBOARDLAYOUT then
begin
FItem := TLangSwitchKeyboard_WinKeyboard.Create(Self, FLanguages[i], profile.HKL); //, (profile.dwFlags and TF_IPP_FLAG_ACTIVE) = TF_IPP_FLAG_ACTIVE); // I3961
- TDebugManager.WriteMessage('[EnumTSFKeyboards] Creating WinKeyboard hkl=%x, valid=%s', [profile.HKL, BoolToStr(FItem.Valid)]); // I4648
+ TDebugLogClient.Instance.WriteMessage('[EnumTSFKeyboards] Creating WinKeyboard hkl=%x, valid=%s', [profile.HKL, BoolToStr(FItem.Valid)]); // I4648
end
else if (profile.catid = GUID_TFCAT_TIP_KEYBOARD) then // I2826 // I3933 // I4005
begin
FItem := TLangSwitchKeyboard_TIP.Create(Self, FLanguages[i], profile); // I3961
- TDebugManager.WriteMessage('[EnumTSFKeyboards] Creating TSF TIP guid=%s keymanid=%d, valid=%s', [GuidToString(profile.guidProfile), FItem.KeymanID, BoolToStr(FItem.Valid)]); // I4648
+ TDebugLogClient.Instance.WriteMessage('[EnumTSFKeyboards] Creating TSF TIP guid=%s keymanid=%d, valid=%s', [GuidToString(profile.guidProfile), FItem.KeymanID, BoolToStr(FItem.Valid)]); // I4648
end
else
begin
@@ -402,7 +402,7 @@ begin
end;
end;
end;
- TDebugManager.WriteMessage('[EnumTSFKeyboards] EXIT ---------------', []);
+ TDebugLogClient.Instance.WriteMessage('[EnumTSFKeyboards] EXIT ---------------', []);
end;
procedure TLangSwitchManager.Refresh; // I3933
@@ -682,7 +682,7 @@ procedure TLangSwitchKeyboard_WinKeyboard.Activate(hwnd: THandle);
begin
// Assert(FValid); // I4715
FManager.SetActiveItem(Self); // I3933
- TDebugManager.WriteMessage('TLangSwitchKeyboard_WinKeyboard.Activate hwnd=%x keyboard=%x', [hwnd, FHKL]); // I4674
+ TDebugLogClient.Instance.WriteMessage('TLangSwitchKeyboard_WinKeyboard.Activate hwnd=%x keyboard=%x', [hwnd, FHKL]); // I4674
PostMessage(hwnd, wm_keyman_control_internal, KMCI_SELECTKEYBOARD, FHKL); // I3933
end;
@@ -773,7 +773,7 @@ begin
FManager.SetActiveItem(Self); // I3933
s := IntToStr(FProfile.langid) + '|' + GUIDToString(TGUID(FProfile.clsid)) + '|' + GUIDToString(TGUID(FProfile.guidProfile));
FAtom := GlobalAddAtom(PChar(s));
- TDebugManager.WriteMessage('TLangSwitchKeyboard_TIP.Activate hwnd=%x keyboard=%s', [hwnd, s]); // I4674
+ TDebugLogClient.Instance.WriteMessage('TLangSwitchKeyboard_TIP.Activate hwnd=%x keyboard=%s', [hwnd, s]); // I4674
PostMessage(hwnd, wm_keyman_control_internal, KMCI_SELECTKEYBOARD_TSF, FAtom); // I3933
end;
diff --git a/windows/src/engine/keyman/langswitch/UfrmLanguageSwitch.pas b/windows/src/engine/keyman/langswitch/UfrmLanguageSwitch.pas
index 820dce8971..c927ceae1a 100644
--- a/windows/src/engine/keyman/langswitch/UfrmLanguageSwitch.pas
+++ b/windows/src/engine/keyman/langswitch/UfrmLanguageSwitch.pas
@@ -146,7 +146,7 @@ implementation
uses
System.Math,
- DebugManager,
+ Keyman.System.DebugLogClient,
KeymanControlMessages,
keymanapi_TLB,
UfrmKeyman7Main,
@@ -261,7 +261,7 @@ procedure TfrmLanguageSwitch.FormKeyDown(Sender: TObject; var Key: Word;
end;
begin
- TDebugManager.WriteMessage('TfrmLanguageSwitch.FormKeyDown ENTER: %d [%d %d]', [Key, FSelectedLanguage, FSelectedKeyboard]);
+ TDebugLogClient.Instance.WriteMessage('TfrmLanguageSwitch.FormKeyDown ENTER: %d [%d %d]', [Key, FSelectedLanguage, FSelectedKeyboard]);
try
if FSelectedLanguage = -1 then FSelectedLanguage := 0;
if FSelectedKeyboard = -1 then FSelectedKeyboard := 0;
@@ -362,7 +362,7 @@ begin
EndCanvas;
end;
finally
- TDebugManager.WriteMessage('TfrmLanguageSwitch.FormKeyDown EXIT: %d [%d %d]', [Key, FSelectedLanguage, FSelectedKeyboard]);
+ TDebugLogClient.Instance.WriteMessage('TfrmLanguageSwitch.FormKeyDown EXIT: %d [%d %d]', [Key, FSelectedLanguage, FSelectedKeyboard]);
end;
Key := 0;
end;
@@ -389,7 +389,7 @@ begin
DrawLayer; // I2677
- TDebugManager.WriteMessage('TfrmLanguageSwitch.FormShow EXIT: [%d %d]', [FSelectedLanguage, FSelectedKeyboard]);
+ TDebugLogClient.Instance.WriteMessage('TfrmLanguageSwitch.FormShow EXIT: [%d %d]', [FSelectedLanguage, FSelectedKeyboard]);
end;
procedure TfrmLanguageSwitch.GetColors(y: Integer; var cc: array of Cardinal);
diff --git a/windows/src/engine/keyman32/K32_DBG.CPP b/windows/src/engine/keyman32/K32_DBG.CPP
index 3dd35f3db1..067751fc35 100644
--- a/windows/src/engine/keyman32/K32_DBG.CPP
+++ b/windows/src/engine/keyman32/K32_DBG.CPP
@@ -46,24 +46,33 @@
#include "keyman64.h"
#include
#include
+#include
+
+#include "keyman-debug-etw.h"
//#define _FILELOG
#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
#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)
-{
+void InitDebuggingEx(PKEYMAN64THREADDATA _td) {
RegistryReadOnly reg(HKEY_CURRENT_USER);
if(reg.OpenKeyReadOnly(REGSZ_KeymanCU)) {
_td->debug_KeymanLog = reg.ValueExists(REGSZ_Debug) && reg.ReadInteger(REGSZ_Debug);
@@ -75,55 +84,15 @@ void InitDebuggingEx(PKEYMAN64THREADDATA _td)
}
- if(_td->debug_KeymanLog)
- {
- if(_td->debug_hLogMailSlot != 0 && _td->debug_hLogMailSlot != INVALID_HANDLE_VALUE)
- CloseHandle(_td->debug_hLogMailSlot);
-
- _td->debug_hLogMailSlot = CreateFile("\\\\.\\mailslot\\Tavultesoft_KeymanEngine_Debug",
- GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, // required to write to a mailslot
- (LPSECURITY_ATTRIBUTES) NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,
- (HANDLE) NULL);
-
- if(_td->debug_hLogEvent) CloseHandle(_td->debug_hLogEvent);
- _td->debug_hLogEvent = CreateEvent(NULL, FALSE, FALSE, "Tavultesoft_KeymanEngine_DebugWrite");
-
- /*
- FILE *fp = fopen("c:\\keyman.log", "at");
- fprintf(fp, "opening log %d (error=%d)\n", hLogMailSlot, GetLastError());
- fclose(fp);*/
-
-#ifdef _FILELOG
- char filenamebuf[256];
- wsprintf(filenamebuf, "c:\\keymanlog\\system-%d-%d.log", GetCurrentProcessId(), GetCurrentThreadId());
- _td->debug_fp = (void*) fopen(filenamebuf, "at");
-#endif
-
- if (_td->debug_hLogMailSlot == INVALID_HANDLE_VALUE)
- {
- _td->debug_hLogMailSlot = 0;
- }
- }
- else
- {
- if(_td->debug_hLogMailSlot != 0) CloseHandle(_td->debug_hLogMailSlot);
- _td->debug_hLogMailSlot = 0;
- if(_td->debug_hLogEvent) CloseHandle(_td->debug_hLogEvent);
- _td->debug_hLogEvent = 0;
+ if(_td->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?
+ }
}
}
-inline void TestInitDebug(PKEYMAN64THREADDATA _td)
-{
- if(!_td->debug_DebugInit) InitDebuggingEx(_td);
- _td->debug_DebugInit = TRUE;
-}
-
-void InitDebugging()
-{
+void InitDebugging() {
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return;
@@ -164,30 +133,26 @@ void UninitDebuggingEx()
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return;
- if(_td->debug_hLogMailSlot) CloseHandle(_td->debug_hLogMailSlot);
- _td->debug_hLogMailSlot = 0;
- if(_td->debug_hLogEvent) CloseHandle(_td->debug_hLogEvent);
- _td->debug_hLogEvent = 0;
-#ifdef _FILELOG
- if(_td->debug_fp) fclose((FILE*)_td->debug_fp);
- _td->debug_fp = NULL;
-#endif
+ if (_td->etwRegHandle != NULL) {
+ EventUnregister(_td->etwRegHandle);
+ _td->etwRegHandle = NULL;
+ }
+
_td->debug_DebugInit = FALSE;
}
-void UninitDebugging()
-{
+void UninitDebugging() {
SendDebugMessage(0, sdmGlobal, 0, "--- UninitDebugging() - shutting down ---");
}
const TSDMState DebugState[] = {sdmInternat, sdmAIDefault, sdmMessage, sdmKeyboard, sdmGlobal, sdmMenu, sdmDebug, sdmLoad, sdmOther};
-BOOL ShouldDebug_1() //TSDMState state)
-{
+BOOL ShouldDebug_1() {
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return FALSE;
- TestInitDebug(_td);
+ if (!_td->debug_DebugInit) InitDebuggingEx(_td);
+ _td->debug_DebugInit = TRUE;
return _td->debug_KeymanLog;
}
@@ -245,47 +210,38 @@ int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, i
{
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(state); // I3569
+ UNREFERENCED_PARAMETER(kmn_lineno);
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return 0;
- if(_td->debug_KeymanLog)
- {
- OVERLAPPED ov;
- DWORD cbWritten;
- char windowinfo[1024];
+ if (msg == NULL) {
+ return 0;
+ }
- if(msg == NULL)
- {
- switch(kmn_lineno)
- {
- case -1: // Signal an event to the controller
- strcpy(windowinfo, "*");
- break;
- }
- }
- else
- {
- GUITHREADINFO gti;
- char
- //sClassName[32], sWindowText[32],
- //sFocusClassName[32], sFocusWindowText[32],
- //sActiveClassName[32], sActiveWindowText[32],
- sProcessPath[256], sProcessName[32];
+ if(_td->debug_KeymanLog) {
+ GUITHREADINFO gti;
+ char
+ //sClassName[32], sWindowText[32],
+ //sFocusClassName[32], sFocusWindowText[32],
+ //sActiveClassName[32], sActiveWindowText[32],
+ sProcessPath[256], sProcessName[32];
- gti.cbSize = sizeof(gti);
- GetGUIThreadInfo(GetCurrentThreadId(), >i);
+ gti.cbSize = sizeof(gti);
+ GetGUIThreadInfo(GetCurrentThreadId(), >i);
- //FillWindowInfo(hwnd, sClassName, sWindowText); // I3656
- //FillWindowInfo(gti.hwndActive, sActiveClassName, sActiveWindowText); // I3656
- //FillWindowInfo(gti.hwndFocus, sFocusClassName, sFocusWindowText); // I3656
+ //FillWindowInfo(hwnd, sClassName, sWindowText); // I3656
+ //FillWindowInfo(gti.hwndActive, sActiveClassName, sActiveWindowText); // I3656
+ //FillWindowInfo(gti.hwndFocus, sFocusClassName, sFocusWindowText); // I3656
- GetModuleFileName(NULL, sProcessPath, 256);
- _splitpath_s(sProcessPath, NULL, 0, NULL, 0, sProcessName, 32, NULL, 0);
- sProcessName[31] = 0;
+ GetModuleFileName(NULL, sProcessPath, 256);
+ _splitpath_s(sProcessPath, NULL, 0, NULL, 0, sProcessName, 32, NULL, 0);
+ sProcessName[31] = 0;
- if(strlen(msg) > 256) msg[255] = 0;
+ if(strlen(msg) > 256) msg[255] = 0;
- wsprintf(windowinfo,
+ if(_td->debug_ToConsole) { // I3951
+ char windowinfo[1024];
+ wsprintf(windowinfo,
DEBUG_PLATFORM_STRING TAB //"Platform" TAB
"%s" TAB //"Process" TAB
"%x" TAB //"PID" TAB
@@ -309,7 +265,7 @@ int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, i
"%8x" TAB //"ActiveHKL" TAB
"%s:%d" TAB //"SourceFile" TAB
"%s", //"Message"
-
+
sProcessName, //"Process" TAB
GetCurrentProcessId(), //"PID" TAB
GetCurrentThreadId(), //"TID" TAB
@@ -337,46 +293,53 @@ int SendDebugMessage_1(HWND hwnd, TSDMState state, int kmn_lineno, char *file, i
GetKeyboardLayout(0), //"ActiveHKL" TAB
file, line, //"SourceFile" TAB
msg); //"Message"
- }
-#ifdef _FILELOG
- if(_td->debug_fp)
- {
- fputs(windowinfo, (FILE*)_td->debug_fp);
- fputs("\n", (FILE*)_td->debug_fp);
- }
-#endif
- if(_td->debug_ToConsole) { // I3951
+
OutputDebugString(windowinfo); // I3570 // I3951
OutputDebugString("\n"); // I3570 // I3951
}
- if(_td->debug_hLogMailSlot != 0)
- {
- ov.Offset = 0;
- ov.OffsetHigh = 0;
- ov.hEvent = _td->debug_hLogEvent;
- if(!WriteFile(_td->debug_hLogMailSlot,
- windowinfo,
- (DWORD) strlen(windowinfo) + 1, // include terminating null
- &cbWritten,
- &ov))
- {
- switch(GetLastError()) // I2445 - Try and reconnect debug pipe on error
- {
- case ERROR_HANDLE_EOF:
- case ERROR_BROKEN_PIPE:
- UninitDebuggingEx();
- InitDebuggingEx(_td);
- if(WriteFile(_td->debug_hLogMailSlot,
- windowinfo,
- (DWORD) strlen(windowinfo) + 1, // include terminating null
- &cbWritten,
- &ov)) break;
- default:
- UninitDebuggingEx();
- _td->debug_KeymanLog = FALSE; /// Failed again - we could log to system log I guess
- }
+ if (_td->etwRegHandle != NULL) {
+#define MAX_DESCRIPTORS 12
+
+ // TODO: convert debugging to Unicode
+ PWSTR sProcessNameW = strtowstr(sProcessName);
+ PWSTR fileW = strtowstr(file);
+ PWSTR msgW = strtowstr(msg);
+ EVENT_DATA_DESCRIPTOR Descriptors[MAX_DESCRIPTORS];
+ DWORD pid = GetCurrentProcessId();
+ DWORD tid = GetCurrentThreadId();
+ DWORD shiftState = Globals::get_ShiftState();
+ DWORD actualShiftState = GetActualShiftState();
+ DWORD tickCount = GetTickCount();
+ HKL activeHKL = GetKeyboardLayout(0);
+
+#ifdef _WIN64
+ DWORD platform = 2;
+#else
+ DWORD platform = 1;
+#endif
+
+ // These must match the manifest template in keyman-debug-etw.man
+ EventDataDescCreate(&Descriptors[0], &platform, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[1], sProcessNameW, (ULONG) (wcslen(sProcessNameW) + 1) * sizeof(WCHAR)); //
+ EventDataDescCreate(&Descriptors[2], &pid, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[3], &tid, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[4], &shiftState, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[5], &actualShiftState, sizeof(DWORD)); //
+ 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[10], (PDWORD)&line, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[11], msgW, (ULONG) (wcslen(msgW)+1) * sizeof(WCHAR)); //
+
+ DWORD dwErr = EventWrite(_td->etwRegHandle, &DebugEvent, (ULONG)MAX_DESCRIPTORS, &Descriptors[0]);
+ if (dwErr != ERROR_SUCCESS) {
+ OutputDebugString("Keyman k32_dbg: Failed to call EventWrite");
}
+ delete sProcessNameW;
+ delete fileW;
+ delete msgW;
}
}
diff --git a/windows/src/engine/keyman32/Keyman32.vcxproj b/windows/src/engine/keyman32/Keyman32.vcxproj
index 0df1e6d7eb..3d7e089184 100644
--- a/windows/src/engine/keyman32/Keyman32.vcxproj
+++ b/windows/src/engine/keyman32/Keyman32.vcxproj
@@ -342,11 +342,24 @@
+
+ Document
+ false
+ false
+ mc %(FullPath)
+ Compiling keyman-debug-etw
+ %(Filename).rc;%(Filename.h);MSG00001.bin
+ mc %(FullPath)
+ Compiling keyman-debug-etw
+ %(Filename).rc;%(Filename.h);MSG00001.bin
+ Designer
+
+
%(PreprocessorDefinitions)
%(PreprocessorDefinitions)
@@ -368,6 +381,7 @@
+
diff --git a/windows/src/engine/keyman32/Keyman32.vcxproj.filters b/windows/src/engine/keyman32/Keyman32.vcxproj.filters
index 57bef006b2..ccd2d0a708 100644
--- a/windows/src/engine/keyman32/Keyman32.vcxproj.filters
+++ b/windows/src/engine/keyman32/Keyman32.vcxproj.filters
@@ -136,6 +136,9 @@
Source Files
+
+ Source Files
+
@@ -204,5 +207,11 @@
Header Files
+
+ Header Files
+
+
+
+
\ No newline at end of file
diff --git a/windows/src/engine/keyman32/globals.h b/windows/src/engine/keyman32/globals.h
index 0da5f9147d..aa8cb726cd 100644
--- a/windows/src/engine/keyman32/globals.h
+++ b/windows/src/engine/keyman32/globals.h
@@ -52,6 +52,8 @@
#ifndef _globals_h
#define _globals_h
+#include
+
#define GLOBAL_ContextStackSize 80
#define GLOBAL_MsgStackSize 80
#define GLOBAL_MaxKeyboards 32
@@ -216,13 +218,12 @@ typedef struct tagKEYMAN64THREADDATA
int CurrentAddin;
HWND CurrenthWnd;
- void *debug_fp;
- HANDLE debug_hLogMailSlot, debug_hLogEvent;
BOOL debug_DebugInit, debug_KeymanLog, debug_ToConsole; // I3951
char debug_buf[64];
// I3617 // I3618
+ REGHANDLE etwRegHandle;
/* TSF Manager Globals */
diff --git a/windows/src/engine/keyman32/keyman-debug-etw.man b/windows/src/engine/keyman32/keyman-debug-etw.man
new file mode 100644
index 0000000000..d327247f10
--- /dev/null
+++ b/windows/src/engine/keyman32/keyman-debug-etw.man
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/windows/src/engine/keyman64/keyman64.vcxproj b/windows/src/engine/keyman64/keyman64.vcxproj
index 7c3913e012..d784ceedf2 100644
--- a/windows/src/engine/keyman64/keyman64.vcxproj
+++ b/windows/src/engine/keyman64/keyman64.vcxproj
@@ -298,6 +298,7 @@
+
@@ -325,6 +326,7 @@
+
@@ -344,6 +346,25 @@
+
+ false
+ Document
+ false
+ false
+ false
+ mc %(FullPath)
+ %(Filename).rc;%(Filename).h;MSG00001.bin
+ mc %(FullPath)
+ %(Filename).rc;%(Filename).h;MSG00001.bin
+ mc %(FullPath)
+ %(Filename).rc;%(Filename).h;MSG00001.bin
+ mc %(FullPath)
+ %(Filename).rc;%(Filename).h;MSG00001.bin
+ Compiling %(Filename).man
+ Compiling %(Filename).man
+ Compiling %(Filename).man
+ Compiling %(Filename).man
+
diff --git a/windows/src/engine/keyman64/keyman64.vcxproj.filters b/windows/src/engine/keyman64/keyman64.vcxproj.filters
index c807c634b1..04bde3ac9e 100644
--- a/windows/src/engine/keyman64/keyman64.vcxproj.filters
+++ b/windows/src/engine/keyman64/keyman64.vcxproj.filters
@@ -113,6 +113,9 @@
Source Files
+
+ Source Files
+
@@ -232,6 +235,9 @@
Header Files
+
+ Source Files
+
@@ -240,5 +246,8 @@
Resource Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/windows/src/engine/kmcomapi/kmcomapi.dpr b/windows/src/engine/kmcomapi/kmcomapi.dpr
index f29b487960..2462e7d314 100644
--- a/windows/src/engine/kmcomapi/kmcomapi.dpr
+++ b/windows/src/engine/kmcomapi/kmcomapi.dpr
@@ -101,7 +101,6 @@ uses
utildir in '..\..\global\delphi\general\utildir.pas',
utiltsf in '..\..\global\delphi\general\utiltsf.pas',
OnlineConstants in '..\..\global\delphi\productactivation\OnlineConstants.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
MessageDefaults in '..\..\global\delphi\cust\MessageDefaults.pas',
MessageIdentifierConsts in '..\..\global\delphi\cust\MessageIdentifierConsts.pas',
KeymanEngineControl in '..\..\global\delphi\general\KeymanEngineControl.pas',
diff --git a/windows/src/engine/kmcomapi/kmcomapi.dproj b/windows/src/engine/kmcomapi/kmcomapi.dproj
index 9f79ae9c1a..bcbc444e56 100644
--- a/windows/src/engine/kmcomapi/kmcomapi.dproj
+++ b/windows/src/engine/kmcomapi/kmcomapi.dproj
@@ -238,7 +238,6 @@
-
diff --git a/windows/src/engine/tsysinfo/tsysinfo.dpr b/windows/src/engine/tsysinfo/tsysinfo.dpr
index 4babfd5905..2f81bbd891 100644
--- a/windows/src/engine/tsysinfo/tsysinfo.dpr
+++ b/windows/src/engine/tsysinfo/tsysinfo.dpr
@@ -31,7 +31,6 @@ uses
klog in '..\..\global\delphi\general\klog.pas',
utildir in '..\..\global\delphi\general\utildir.pas',
utilsystem in '..\..\global\delphi\general\utilsystem.pas',
- SystemDebugPath in '..\..\global\delphi\general\SystemDebugPath.pas',
ErrorControlledRegistry in '..\..\global\delphi\vcl\ErrorControlledRegistry.pas',
Unicode in '..\..\global\delphi\general\Unicode.pas',
utilexecute in '..\..\global\delphi\general\utilexecute.pas',
diff --git a/windows/src/engine/tsysinfo/tsysinfo.dproj b/windows/src/engine/tsysinfo/tsysinfo.dproj
index 3a884167a7..6cd10172b7 100644
--- a/windows/src/engine/tsysinfo/tsysinfo.dproj
+++ b/windows/src/engine/tsysinfo/tsysinfo.dproj
@@ -7,7 +7,7 @@
1
Application
VCL
- 18.3
+ 18.4
Win32
@@ -175,7 +175,6 @@
-
diff --git a/windows/src/ext/jedi/jwa/branches/2.3/Win32API/JwaEventTracing.pas b/windows/src/ext/jedi/jwa/branches/2.3/Win32API/JwaEventTracing.pas
index 36f324f8e5..2b2113e814 100644
--- a/windows/src/ext/jedi/jwa/branches/2.3/Win32API/JwaEventTracing.pas
+++ b/windows/src/ext/jedi/jwa/branches/2.3/Win32API/JwaEventTracing.pas
@@ -2001,7 +2001,7 @@ function FlushTrace; external advapi32 name 'FlushTrace'+AWSuffix;
{$ENDIF WINXP_UP}
function ControlTraceW; external advapi32 name 'ControlTraceW';
function ControlTraceA; external advapi32 name 'ControlTraceA';
-function ControlTrace; external advapi32 name 'ControlTraceA'+AWSuffix;
+function ControlTrace; external advapi32 name 'ControlTrace'+AWSuffix;
function QueryAllTracesW; external advapi32 name 'QueryAllTracesW';
function QueryAllTracesA; external advapi32 name 'QueryAllTracesA';
diff --git a/windows/src/global/delphi/debug/DebugManager.pas b/windows/src/global/delphi/debug/DebugManager.pas
deleted file mode 100644
index 3639895d79..0000000000
--- a/windows/src/global/delphi/debug/DebugManager.pas
+++ /dev/null
@@ -1,643 +0,0 @@
-(*
- Name: DebugManager
- 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 - Initial version
- 04 Jan 2007 - mcdurdin - Add ShouldDebug function
- 19 Jun 2007 - mcdurdin - Widestring it
- 19 Nov 2007 - mcdurdin - I1157 - const string parameters
- 04 May 2010 - mcdurdin - I2348 - Rework columns in debug log
- 04 May 2010 - mcdurdin - I2349 - Hotkey to capture debug log
- 04 May 2010 - mcdurdin - I2350 - Keyman.exe should be able to report events in debug log
- 04 May 2010 - mcdurdin - I2352 - Debug logging not reliable in some apps due to security
- 15 Jun 2010 - mcdurdin - I2423 - Fix crash in debug manager
- 24 Jun 2010 - mcdurdin - I2422 - Recreate, not rewrite existing log files
- 29 Jun 2010 - mcdurdin - I2446 - Keyman Engine crashes due to debug manager being freed late
- 17 Dec 2010 - mcdurdin - Add extra column to raw strings
- 11 Jan 2011 - mcdurdin - I2640 - Raise error at appropriate location so it isn't masked by cascading issue
- 31 Jan 2011 - mcdurdin - I2685 - Reduce registry noise from ShouldDebug function
- 31 Jan 2011 - mcdurdin - I2690 - Add foreground window info to debug log
- 31 Jan 2011 - mcdurdin - I2691 - Fix handle leaks
- 18 Feb 2011 - mcdurdin - I2685 : 9827 - Fix shoulddebug refresh counter not resetting
- 03 May 2011 - mcdurdin - I2890 - Record diagnostic data when encountering registry errors
- 18 May 2012 - mcdurdin - I3306 - V9.0 - Remove TntControls + Win9x support
- 08 Jun 2012 - mcdurdin - I3310 - V9.0 - Unicode in Delphi fixes
- 28 Nov 2012 - mcdurdin - I3601 - V9.0 - Debug messages were written partially Unicode, partially ANSI
- 13 Dec 2012 - mcdurdin - I3656 - V9.0 - Debug logs show too many columns for host messages
- 01 Jan 2013 - mcdurdin - I3692 - V9.0 - [host] entries in system.log out by 1 tabstop
- 09 Aug 2015 - mcdurdin - I4843 - Log reported modifier state as well as Keyman current modifier state
-*)
-unit DebugManager; // I3306
-
-interface
-
-uses
- Windows,
- Classes,
- SysUtils,
- UserMessages;
-
-type
- TDebugManagerMessageEvent = procedure(Sender: TObject; const Message: string) of object;
-
- TDebugManager = class(TThread)
- private
- FOwner: HWND;
- hLogFile, hMailSlot: THandle;
- hEvent: THandle;
- FDebugLogIndex: Integer;
- FOnMessage: TDebugManagerMessageEvent;
-
- const
- crlf: AnsiString = #13#10;
-
- procedure WriteHeadingString;
- procedure WriteMessage(buf: PAnsiChar; buflen: Integer); overload; // I3310
- procedure StartNewLogFile;
- procedure FindFirstLogFileName;
- protected
- procedure Execute; override;
-
- class procedure CloseLogFile(var Handle: THandle);
- class procedure WriteString(Handle: THandle; const s: string);
- class procedure WriteMessage(Handle: THandle; buf: PAnsiChar; buflen: Integer); overload; // I3310
- class procedure WriteRawString(Handle: THandle; const s: string); static;
- public
- constructor Create(AOwner: HWND); reintroduce;
- destructor Destroy; override;
-
- class procedure WriteLastError(const ParentMethod, FailingMethod: string; const Message: string = '');
- class procedure WriteMessage(const Format: string; const Args: array of const); overload;
-
-
- class function DebugLogFileName(n: Integer): WideString;
-
- property OnMessage: TDebugManagerMessageEvent read FOnMessage write FOnMessage;
- end;
-
-function GetDebugManager(AOwner: HWND): TDebugManager;
-
-implementation
-
-uses
- Accctrl,
- AclApi,
- ErrorControlledRegistry,
- RegistryKeys,
- SystemDebugPath,
- Unicode;
-
-var
- FDebugManager: TDebugManager = nil;
- FTerminating: Boolean = False;
-
- FShouldDebug: Boolean = False;
- FShouldDebugLastTick: Cardinal = 0;
-
-function ShouldDebug: Boolean;
-var
- t1: Cardinal;
-begin
- t1 := GetTickCount;
- if (t1 < FShouldDebugLastTick) or (t1 - FShouldDebugLastTick > 5000) then // I2685
- begin
- with TRegistryErrorControlled.Create do // I2890
- try
- if OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and ValueExists(SRegValue_KeymanDebug)
- then FShouldDebug := ReadBool(SRegValue_KeymanDebug)
- else FShouldDebug := False;
- finally
- Free;
- end;
- FShouldDebugLastTick := GetTickCount; // I2685:9827
- end;
-
- Result := FShouldDebug;
-end;
-
-function GetDebugManager(AOwner: HWND): TDebugManager;
-begin
- Assert(not FTerminating);
-
- if ShouldDebug then
- begin
- if not Assigned(FDebugManager) then
- FDebugManager := TDebugManager.Create(AOwner);
- Result := FDebugManager;
- end
- else
- Result := nil;
-end;
-
-{ TDebugManager }
-
-class procedure TDebugManager.CloseLogFile(var Handle: THandle);
-begin
- if Handle <> 0 then
- begin
- WriteString(Handle, '---- Log file closed '+FormatDateTime('C', now) + '----');
- CloseHandle(Handle);
- Handle := 0;
- end;
-end;
-
-
-const LOW_INTEGRITY_SDDL_SACL_W: WideString = 'S:(ML;;NW;;;LW)';
-const LABEL_SECURITY_INFORMATION = $00000010;
-const SDDL_REVISION_1 = 1;
-
-function ConvertStringSecurityDescriptorToSecurityDescriptor(
- {IN} StringSecurityDescriptor: LPCWSTR;
- {IN} StringSDRevision: DWORD;
- {OUT} var SecurityDescriptor: PSECURITY_DESCRIPTOR;
- {OUT} SecurityDescriptorSize: PULONG {OPTIONAL}
- ): BOOL; stdcall; external 'advapi32.dll' name 'ConvertStringSecurityDescriptorToSecurityDescriptorW';
-
-function SetObjectToLowIntegrity(hObject: THandle; _type: SE_OBJECT_TYPE = SE_KERNEL_OBJECT): BOOL;
-var
- dwErr: DWORD;
- pSD: PSECURITY_DESCRIPTOR;
- pSacl: PACL;
- fSaclPresent: BOOL;
- fSaclDefaulted: BOOL;
-begin
- //BOOL bRet = FALSE;
- //dwErr := ERROR_SUCCESS;
- Result := False;
-
- pSD := nil;
- pSacl := nil;
- fSaclPresent := FALSE;
- fSaclDefaulted := FALSE;
-
- if LOBYTE(LOWORD(GetVersion())) >= 6 then
- begin
- if ConvertStringSecurityDescriptorToSecurityDescriptor(PWideChar(LOW_INTEGRITY_SDDL_SACL_W), SDDL_REVISION_1, pSD, nil) then
- begin
- if GetSecurityDescriptorSacl(pSD, fSaclPresent, pSacl, fSaclDefaulted) then
- begin
- dwErr := SetSecurityInfo(
- hObject, _type, LABEL_SECURITY_INFORMATION,
- nil, nil, nil, pSacl);
- Result := ERROR_SUCCESS = dwErr;
- end;
- end;
-
- LocalFree(Cardinal(pSD));
- end
- else
- Result := True;
-end;
-
-constructor TDebugManager.Create(AOwner: HWND);
-const
- lpszSlotName: string = '\\.\mailslot\tavultesoft_keymanengine_debug';
-var
- pSD: PSECURITY_DESCRIPTOR;
- //sd: SECURITY_DESCRIPTOR;
- sa: SECURITY_ATTRIBUTES;
- //bSaclPresent: LongBool;
- //pSacl: PACL;
- //bSaclDefaulted: LongBool;
- //fSaclPresent: LongBool;
-begin
- FOwner := AOwner;
-
- if LOBYTE(LOWORD(GetVersion())) >= 6 then
- begin
- if ConvertStringSecurityDescriptorToSecurityDescriptor(PWideChar(LOW_INTEGRITY_SDDL_SACL_W), SDDL_REVISION_1, pSD, nil) then
- begin
- sa.nLength := sizeof(sa);
- sa.lpSecurityDescriptor := pSD;
- sa.bInheritHandle := FALSE;
-
- hMailSlot := CreateMailslot(PChar(lpszSlotName),
- 0, // no maximum message size
- 10, // 10 msec time-out for operations
- @sa);
- if hMailSlot = INVALID_HANDLE_VALUE then RaiseLastOSError; // I2640 - Raise error at appropriate location so it isn't masked by cascading issue
-
- // For some reason the mailslot does not have full access for everyone so we need to set it afterwards anyway!
- if SetSecurityInfo(hMailSlot, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, nil, nil) <> ERROR_SUCCESS then
- RaiseLastOSError;
-
- LocalFree(Cardinal(pSD));
- end
- else RaiseLastOSError;
- end
- else
- begin
- hMailSlot := CreateMailslot(PChar(lpszSlotName),
- 0, // no maximum message size
- 10, // 10 msec time-out for operations
- nil);
- if hMailSlot = INVALID_HANDLE_VALUE then RaiseLastOSError;
- end;
-
- try
- FindFirstLogFileName;
- StartNewLogFile;
-
- try
- hEvent := CreateEvent(nil, FALSE, FALSE, 'Tavultesoft_KeymanEngine_Debug');
- if hEvent = 0 then RaiseLastOSError;
- if not SetObjectToLowIntegrity(hEvent) then RaiseLastOSError;
-
- try
- SetFilePointer(hLogFile, 0, nil, FILE_END);
-
- FreeOnTerminate := False; // I2446 - Keyman Engine crashes due to debug manager being freed late
- inherited Create(False);
- except
- on E:Exception do
- begin
- CloseHandle(hEvent);
- hEvent := 0;
- raise;
- end;
- end;
- except
- on E:Exception do
- begin
- CloseHandle(hLogFile);
- hLogFile := 0;
- raise;
- end;
- end;
- except
- on E:Exception do
- begin
- CloseHandle(hMailSlot);
- hMailSlot := 0;
- raise;
- end;
- end;
-end;
-
-destructor TDebugManager.Destroy;
-begin
- CloseLogFile(hLogFile);
- if hMailSlot <> 0 then CloseHandle(hMailSlot);
- if hEvent <> 0 then CloseHandle(hEvent);
- inherited Destroy;
-end;
-
-const
- MAXDEBUGLOGS = 16;
-
-class function TDebugManager.DebugLogFileName(n: Integer): WideString;
-begin
- Result := GetSystemDebugPath + 'system' + IntToStr(n) + '.log';
-end;
-
-procedure TDebugManager.FindFirstLogFileName;
-var
- FSelectedTime: TDateTime;
- i: Integer;
- f: TSearchRec;
-begin
- FSelectedTime := MaxDateTime;
- FDebugLogIndex := 0;
-
- for i := 0 to MAXDEBUGLOGS - 1 do
- begin
- if FindFirst(DebugLogFileName(i), 0, f) = 0 then
- begin
- if f.TimeStamp < FSelectedTime then
- begin
- FDebugLogIndex := i;
- FSelectedTime := f.TimeStamp;
- end;
- FindClose(f);
- end
- else
- begin
- FDebugLogIndex := i;
- Break;
- end;
- end;
-
- Dec(FDebugLogIndex); // It will be immediately incremented by StartNewLogFile
-end;
-
-procedure TDebugManager.StartNewLogFile;
-var
- FDebugLogFileName: WideString;
-begin
- if hLogFile <> 0 then
- CloseHandle(hLogFile);
-
- Inc(FDebugLogIndex);
- if FDebugLogIndex > MAXDEBUGLOGS then
- FDebugLogIndex := 0;
-
- FDebugLogFileName := 'system' + IntToStr(FDebugLogIndex) + '.log';
-
- hLogFile := CreateFile(PChar(DebugLogFileName(FDebugLogIndex)), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_ALWAYS, 0, 0);
- if hLogFile = INVALID_HANDLE_VALUE then RaiseLastOSError;
-
- WriteHeadingString;
-end;
-
-procedure TDebugManager.Execute;
-var
- szBuffer, cbMessage, cMessage, cbRead: DWord;
- lpszBuffer: PAnsiChar; // I3310
- ov: TOverlapped;
-begin
- //
- try
- cbMessage := 0;
- cMessage := 0;
- cbRead := 0;
- szBuffer := 0;
- lpszBuffer := nil;
-
- ov.Offset := 0;
- ov.OffsetHigh := 0;
- ov.hEvent := hEvent;
-
- try
- repeat
- if not GetMailslotInfo(hMailSlot, // mailslot handle
- nil, // no maximum message size
- cbMessage, // size of next message
- @cMessage, // number of messages
- nil) then // no read time-out
- RaiseLastOSError;
-
- if cbMessage = MAILSLOT_NO_MESSAGE then { Sleep 10 msec }
- begin
- Sleep(10);
- Continue;
- end;
-
- while (cMessage > 0) and not Terminated do // retrieve all messages
- begin
- if szBuffer < cbMessage then
- begin
- if Assigned(lpszBuffer) then FreeMem(lpszBuffer);
- lpszBuffer := AllocMem(cbMessage);
- end;
- if not Assigned(lpszBuffer) then
- raise Exception.Create('Invalid buffer');
-
- lpszBuffer^ := #0;
-
- if not ReadFile(hMailSlot,
- lpszBuffer^,
- cbMessage,
- cbRead,
- @ov) then
- RaiseLastOSError;
-
- WriteMessage(lpszBuffer, cbRead - 1); // Ignore terminating nul
-
- // Concatenate the message and the message-number string.
-
- if not GetMailslotInfo(hMailSlot, // mailslot handle
- nil, // no maximum message size
- cbMessage, // size of next message
- @cMessage, // number of messages
- nil) then // no read time-out
- RaiseLastOSError;
- end;
- until Terminated;
- finally
- if Assigned(lpszBuffer) then FreeMem(lpszBuffer);
- end;
- except
- on E:Exception do
- WriteString(hLogFile, '*** Exception '+E.ClassName+' in TDebugManager: '+E.Message);
- end;
-end;
-
-procedure TDebugManager.WriteHeadingString;
-begin
- WriteRawString(hLogFile, // I3656
- 'Platform' + #9 +
- 'Process' + #9 +
- 'PID' + #9 +
- 'TID' + #9 +
- //'QueueStatus' + #9 +
- 'ShiftState' + #9 +
- 'ActualShiftState' + #9 + // I4843
- 'TickCount' + #9 +
- //'LogHWND' + #9 +
- //'LogWindowClassName' + #9 +
- //'LogWindowText' + #9 +
- 'FocusHWND' + #9 +
- //'FocusWindowClassName' + #9 +
- //'FocusWindowText' + #9 +
- //'ActiveHWND' + #9 +
- //'ActiveWindowClassName' + #9 +
- //'ActiveWindowText' + #9 +
- //'ForegroundHWND' + #9 + // I2690
- //'MessageType' + #9 +
- //'SourceLine' + #9 +
- 'ActiveHKL' + #9 +
- 'SourceFile' + #9 +
- 'Message');
- WriteString(hLogFile, '---- Log file opened '+FormatDateTime('C', now) + '----');
-end;
-
-var
- hLogMailSlot: THandle = 0;
- hLogEvent: THandle = 0;
-
-class procedure TDebugManager.WriteLastError(const ParentMethod, FailingMethod: string; const Message: string = '');
-var
- FLastError: DWord;
- FLastErrorString: string;
-begin
- FLastError := GetLastError;
- FLastErrorString := SysErrorMessage(GetLastError);
- WriteMessage('ERROR %d in %s [%s]: %s %s', [FLastError, FailingMethod, ParentMethod, FLastErrorString, Message]);
-end;
-
-class procedure TDebugManager.WriteMessage(const Format: string;
- const Args: array of const);
-var
- bufa: ansistring;
- buf: string;
- ov: OVERLAPPED;
- cbWritten: DWORD;
- gti: TGUIThreadInfo;
-begin
- if not ShouldDebug then Exit;
-
- if hLogMailSlot = 0 then
- begin
- hLogMailSlot := CreateFile('\\.\mailslot\Tavultesoft_KeymanEngine_Debug',
- GENERIC_WRITE,
- FILE_SHARE_READ or FILE_SHARE_WRITE, // required to write to a mailslot
- nil,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED or FILE_ATTRIBUTE_NORMAL,
- 0);
-
- hLogEvent := CreateEvent(nil, False, False, 'Tavultesoft_KeymanEngine_DebugWrite');
-
- if hLogMailSlot = 0 then Exit;
- if hLogEvent = 0 then Exit;
- end;
-
- gti.cbSize := SizeOf(TGUIThreadInfo); // I2690
- GetGUIThreadInfo(0, gti);
-
- buf :=
- SysUtils.Format( // I3656
- 'x86' + #9 +
- 'keyman[host]' + #9 +
- '%x' + #9 +
- '%x' + #9 +
- //'' + #9 +
- '' + #9 + // shift state
- '' + #9 + // actual shift state // I4843
- IntToStr(GetTickCount) + #9 +
- //'' + #9 +
- //'' + #9 +
- //'' + #9 +
- '%x' + #9 +
- //'' + #9 +
- //'' + #9 +
- //'%x' + #9 +
- //'' + #9 +
- //'' + #9 +
- //'%x' + #9 +
-
- //'' + #9 +
- //'' + #9 + // I3692
- '' + #9 +
- '' + #9,
- [GetCurrentProcessId,
- GetCurrentThreadId,
- gti.hwndFocus
- //gti.hwndActive,
- {GetForegroundWindow}]) +
- SysUtils.Format(Format, Args);
-
- ov.Offset := 0;
- ov.OffsetHigh := 0;
- ov.hEvent := hLogEvent;
-
- bufa := String_UtoA(buf); // I3601
-
- WriteFile(hLogMailSlot,
- bufa[1], // I3601
- Length(bufa) + 1,
- cbWritten,
- @ov);
-end;
-
-procedure TDebugManager.WriteMessage(buf: PAnsiChar; buflen: Integer); // I3310
-var
- Control: AnsiChar; // I3310
-begin
- if (buflen > 0) then Control := buf[0] else Control := #0;
-
- if Control = '*' then
- begin
- if FOwner <> 0 then
- begin
- if PostMessage(FOwner, WM_USER_DebugNotify, FDebugLogIndex, hLogFile) then
- hLogFile := 0;
- end;
- StartNewLogFile;
- end
- else
- begin
- if Assigned(FOnMessage) then
- begin
- FOnMessage(Self, string(Copy(buf, 1, buflen) + crlf));
- end;
-
- WriteMessage(hLogFile, buf, buflen);
- end;
-end;
-
-class procedure TDebugManager.WriteString(Handle: THandle; const s: string);
-var
- gti: TGUIThreadInfo;
-begin
- gti.cbSize := SizeOf(TGUIThreadInfo);
- GetGUIThreadInfo(0, gti); // I2690
-
- WriteRawString(Handle, // I3656
- SysUtils.Format(
- 'x86' + #9 +
- 'keyman[host]' + #9 +
- '%x' + #9 +
- '%x' + #9 +
- //'' + #9 +
- '' + #9 + // shift state
- '' + #9 + // actual shift state // I4843
- IntToStr(GetTickCount) + #9 +
- //'' + #9 +
- //'' + #9 +
- //'' + #9 +
- '%x' + #9 +
- //'' + #9 +
- //'' + #9 +
- //'%x' + #9 +
- //'' + #9 +
- //'' + #9 +
- //'%x' + #9 +
-
- //'' + #9 +
- //'' + #9 + // I3692
- '' + #9 +
- '' + #9,
- [GetCurrentProcessId,
- GetCurrentThreadId,
- gti.hwndFocus {,
- gti.hwndActive,
- GetForegroundWindow}]) +
- s);
-end;
-
-class procedure TDebugManager.WriteRawString(Handle: THandle; const s: string);
-var
- sa: AnsiString; // I3310
-begin
- sa := String_UtoA(s); // I3310
- WriteMessage(Handle, PAnsiChar(sa), Length(sa));
-end;
-
-class procedure TDebugManager.WriteMessage(Handle: THandle; buf: PAnsiChar; buflen: Integer); // I3310
-var
- n: DWord;
-begin
- if Handle = 0 then Exit;
-
- WriteFile(Handle, buf^, buflen, n, nil);
- WriteFile(Handle, PAnsiChar(crlf)^, 2, n, nil); // I3601
-end;
-
-procedure CloseHandles; // I2691
-begin
- if hLogEvent <> 0 then CloseHandle(hLogEvent);
- if hLogMailSlot <> 0 then CloseHandle(hLogMailSlot);
- hLogMailSlot := 0;
- hLogEvent := 0;
-end;
-
-initialization
-finalization
- FTerminating := True;
- if Assigned(FDebugManager) then // I2446 - Keyman Engine crashes due to debug manager being freed late
- FDebugManager.Terminate;
- FreeAndNil(FDebugManager);
- CloseHandles; // I2691
-end.
diff --git a/windows/src/global/delphi/debug/Keyman.System.DebugLogClient.pas b/windows/src/global/delphi/debug/Keyman.System.DebugLogClient.pas
new file mode 100644
index 0000000000..33e7998b2f
--- /dev/null
+++ b/windows/src/global/delphi/debug/Keyman.System.DebugLogClient.pas
@@ -0,0 +1,141 @@
+unit Keyman.System.DebugLogClient;
+
+interface
+
+uses
+ Winapi.Windows,
+ JwaEventDefs,
+ JwaEventTracing,
+ JwaEvntProv;
+
+type
+ TDebugLogClient = class
+ private
+ FRegHandle: TRegHandle;
+ class var FInstance: TDebugLogClient;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ procedure WriteLastError(const ParentMethod, FailingMethod: string; const Message: string = '');
+ procedure WriteMessage(const Format: string; const Args: array of const);
+
+ class function Instance: TDebugLogClient;
+ end;
+
+implementation
+
+uses
+ System.SysUtils,
+
+ Keyman.System.DebugLogCommon;
+
+{ TDebugLogClient }
+
+const
+ // This comes from keyman-debug-etw.h. If the event descriptor is ever changed,
+ // then this needs to be updated.
+ DebugEvent: EVENT_DESCRIPTOR = (
+ Id : $1;
+ Version : $0;
+ Channel : $10;
+ Level : $4;
+ Opcode : $0;
+ Task : $0;
+ Keyword : $8000000000000000
+ );
+
+constructor TDebugLogClient.Create;
+var
+ status: ULONG;
+begin
+ if ShouldDebug then
+ begin
+ status := EventRegister(@DebugLogProviderGuid, nil, nil, FRegHandle);
+ if ERROR_SUCCESS <> status then
+ begin
+ FRegHandle := 0;
+ RaiseLastOSError(status, 'EventRegister');
+ end;
+ end;
+end;
+
+destructor TDebugLogClient.Destroy;
+var
+ status: ULONG;
+begin
+ if FRegHandle <> 0 then
+ begin
+ status := EventUnregister(FRegHandle);
+ if ERROR_SUCCESS <> status then
+ OutputDebugString(PChar('EventUnregister failed with '+IntToStr(status)));
+ end;
+
+ inherited Destroy;
+end;
+
+class function TDebugLogClient.Instance: TDebugLogClient;
+begin
+ if not Assigned(FInstance) then
+ FInstance := TDebugLogClient.Create;
+
+ Result := FInstance;
+end;
+
+procedure TDebugLogClient.WriteLastError(const ParentMethod,
+ FailingMethod, Message: string);
+var
+ FLastError: DWord;
+ FLastErrorString: string;
+begin
+ FLastError := GetLastError;
+ FLastErrorString := SysErrorMessage(GetLastError);
+ WriteMessage('ERROR %d in %s [%s]: %s %s', [FLastError, FailingMethod, ParentMethod, FLastErrorString, Message]);
+end;
+
+procedure TDebugLogClient.WriteMessage(const Format: string;
+ const Args: array of const);
+const
+ MAX_DESCRIPTORS = 12;
+var
+ Descriptors: array[0..MAX_DESCRIPTORS-1] of EVENT_DATA_DESCRIPTOR;
+ dwPlatform: DWORD;
+ sDummy, sMsg, sProcessName: string;
+ pid, tid: DWORD;
+ dwTickCount, dwDummy: DWORD;
+ status: ULONG;
+begin
+ if not ShouldDebug then
+ Exit;
+
+ pid := GetCurrentProcessId;
+ tid := GetCurrentThreadId;
+ dwTickCount := GetTickCount;
+
+ dwPlatform := 1; // x86
+ dwDummy := 0;
+ sProcessName := 'keyman[host]';
+ sMsg := System.SysUtils.Format(Format, Args);
+
+ // These must match the manifest template in keyman-debug-etw.man
+ EventDataDescCreate(Descriptors[0], @dwPlatform, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[1], PChar(sProcessName), (Length(sProcessName) + 1) * sizeof(WCHAR)); //
+ EventDataDescCreate(&Descriptors[2], @pid, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[3], @tid, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[4], @dwDummy, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[5], @dwDummy, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[6], @dwTickCount, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[7], @dwDummy, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[8], @dwDummy, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[9], PChar(sDummy), sizeof(WCHAR)); //
+ EventDataDescCreate(&Descriptors[10], @dwDummy, sizeof(DWORD)); //
+ EventDataDescCreate(&Descriptors[11], PChar(sMsg), (Length(sMsg)+1) * sizeof(WCHAR)); //
+
+ status := EventWrite(FRegHandle, @DebugEvent, MAX_DESCRIPTORS, @Descriptors[0]);
+ if ERROR_SUCCESS <> status then
+ OutputDebugString(PChar('EventWrite failed with '+IntToStr(status)));
+end;
+
+initialization
+finalization
+ FreeAndNil(TDebugLogClient.FInstance);
+end.
diff --git a/windows/src/global/delphi/debug/Keyman.System.DebugLogCommon.pas b/windows/src/global/delphi/debug/Keyman.System.DebugLogCommon.pas
new file mode 100644
index 0000000000..690beaaafd
--- /dev/null
+++ b/windows/src/global/delphi/debug/Keyman.System.DebugLogCommon.pas
@@ -0,0 +1,36 @@
+unit Keyman.System.DebugLogCommon;
+
+interface
+
+const
+ // GUID that identifies the provider that you want
+ // to enable to your session.
+ DebugLogProviderGuid: TGUID = '{DA621615-E08B-4283-918E-D2502D3757AE}';
+
+function ShouldDebug: Boolean;
+
+implementation
+
+uses
+ System.Win.Registry,
+
+ RegistryKeys;
+
+var
+ FShouldDebug: Boolean;
+
+function ShouldDebug: Boolean;
+begin
+ Result := FShouldDebug;
+end;
+
+initialization
+ with TRegistry.Create do // I2890
+ try
+ if OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and ValueExists(SRegValue_KeymanDebug)
+ then FShouldDebug := ReadBool(SRegValue_KeymanDebug)
+ else FShouldDebug := False;
+ finally
+ Free;
+ end;
+end.
diff --git a/windows/src/global/delphi/debug/Keyman.System.DebugLogManager.pas b/windows/src/global/delphi/debug/Keyman.System.DebugLogManager.pas
new file mode 100644
index 0000000000..fe813047a6
--- /dev/null
+++ b/windows/src/global/delphi/debug/Keyman.System.DebugLogManager.pas
@@ -0,0 +1,289 @@
+(*
+ Name: DebugManager
+ 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 - Initial version
+ 04 Jan 2007 - mcdurdin - Add ShouldDebug function
+ 19 Jun 2007 - mcdurdin - Widestring it
+ 19 Nov 2007 - mcdurdin - I1157 - const string parameters
+ 04 May 2010 - mcdurdin - I2348 - Rework columns in debug log
+ 04 May 2010 - mcdurdin - I2349 - Hotkey to capture debug log
+ 04 May 2010 - mcdurdin - I2350 - Keyman.exe should be able to report events in debug log
+ 04 May 2010 - mcdurdin - I2352 - Debug logging not reliable in some apps due to security
+ 15 Jun 2010 - mcdurdin - I2423 - Fix crash in debug manager
+ 24 Jun 2010 - mcdurdin - I2422 - Recreate, not rewrite existing log files
+ 29 Jun 2010 - mcdurdin - I2446 - Keyman Engine crashes due to debug manager being freed late
+ 17 Dec 2010 - mcdurdin - Add extra column to raw strings
+ 11 Jan 2011 - mcdurdin - I2640 - Raise error at appropriate location so it isn't masked by cascading issue
+ 31 Jan 2011 - mcdurdin - I2685 - Reduce registry noise from ShouldDebug function
+ 31 Jan 2011 - mcdurdin - I2690 - Add foreground window info to debug log
+ 31 Jan 2011 - mcdurdin - I2691 - Fix handle leaks
+ 18 Feb 2011 - mcdurdin - I2685 : 9827 - Fix shoulddebug refresh counter not resetting
+ 03 May 2011 - mcdurdin - I2890 - Record diagnostic data when encountering registry errors
+ 18 May 2012 - mcdurdin - I3306 - V9.0 - Remove TntControls + Win9x support
+ 08 Jun 2012 - mcdurdin - I3310 - V9.0 - Unicode in Delphi fixes
+ 28 Nov 2012 - mcdurdin - I3601 - V9.0 - Debug messages were written partially Unicode, partially ANSI
+ 13 Dec 2012 - mcdurdin - I3656 - V9.0 - Debug logs show too many columns for host messages
+ 01 Jan 2013 - mcdurdin - I3692 - V9.0 - [host] entries in system.log out by 1 tabstop
+ 09 Aug 2015 - mcdurdin - I4843 - Log reported modifier state as well as Keyman current modifier state
+*)
+unit Keyman.System.DebugLogManager; // I3306
+
+interface
+
+uses
+ System.Classes,
+ System.SysUtils,
+ Winapi.Windows,
+ JwaWmiStr,
+ JwaEventTracing,
+
+ Keyman.System.DebugLogCommon,
+ UserMessages;
+
+type
+ TDebugLogManager = class
+ private
+ FOwner: HWND;
+ FDebugLogIndex: Integer;
+ FDebugLogFileName: string;
+
+ pSessionProperties: PEVENT_TRACE_PROPERTIES;
+ FSessionHandle: TRACEHANDLE;
+ FTraceRunning: Boolean;
+
+ procedure StartNewLogFile;
+ procedure FindFirstLogFileName;
+
+ function DebugLogFileName(n: Integer): string;
+ public
+ constructor Create(AOwner: HWND); reintroduce;
+ destructor Destroy; override;
+
+ end;
+
+function GetDebugManager(AOwner: HWND): TDebugLogManager;
+
+implementation
+
+uses
+ Accctrl,
+ AclApi,
+ ErrorControlledRegistry,
+ ErrLogPath,
+ RegistryKeys,
+ Unicode;
+
+var
+ FDebugManager: TDebugLogManager = nil;
+ FTerminating: Boolean = False;
+
+ FShouldDebug: Boolean = False;
+ FShouldDebugLastTick: Cardinal = 0;
+
+const
+ // GUID that identifies your trace session.
+ // Remember to create your own session GUID.
+ SessionGuid: TGUID = '{FADEA67E-0EE9-452B-AF04-22E342D1227A}';
+
+function GetDebugManager(AOwner: HWND): TDebugLogManager;
+begin
+ Assert(not FTerminating);
+
+ if ShouldDebug then
+ begin
+ if not Assigned(FDebugManager) then
+ FDebugManager := TDebugLogManager.Create(AOwner);
+ Result := FDebugManager;
+ end
+ else
+ Result := nil;
+end;
+
+{ TDebugManager }
+
+const LOGSESSION_NAME: string = 'Keyman Event Trace Session';
+
+function StringBufferSize(const s: string): Integer;
+begin
+ Result := (Length(s) + 1) * sizeof(WCHAR);
+end;
+
+constructor TDebugLogManager.Create(AOwner: HWND);
+var
+ BufferSize: ULONG;
+ status: ULONG;
+// BOOL TraceOn = TRUE;
+// BOOL bTraceAlreadyStarted = FALSE;
+begin
+ FOwner := AOwner;
+
+ FindFirstLogFileName;
+ StartNewLogFile;
+
+ // Allocate memory for the session properties. The memory must
+ // be large enough to include the log file name and session name,
+ // which get appended to the end of the session properties structure.
+
+ BufferSize := sizeof(EVENT_TRACE_PROPERTIES) + StringBufferSize(FDebugLogFileName) + StringBufferSize(LOGSESSION_NAME);
+ pSessionProperties := PEVENT_TRACE_PROPERTIES(AllocMem(BufferSize));
+
+ // Set the session properties. You only append the log file name
+ // to the properties structure; the StartTrace function appends
+ // the session name for you.
+
+ pSessionProperties.Wnode.BufferSize := BufferSize;
+ pSessionProperties.Wnode.Flags := WNODE_FLAG_TRACED_GUID;
+ pSessionProperties.Wnode.ClientContext := 1; //QPC clock resolution
+ pSessionProperties.Wnode.Guid := SessionGuid;
+ pSessionProperties.LogFileMode := EVENT_TRACE_FILE_MODE_SEQUENTIAL;
+ pSessionProperties.MaximumFileSize := 1; // 1 MB
+ pSessionProperties.LoggerNameOffset := sizeof(EVENT_TRACE_PROPERTIES);
+ pSessionProperties.LogFileNameOffset := sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME);
+ StrPCopy(PWideChar(PByte(pSessionProperties) + pSessionProperties.LoggerNameOffset), LOGSESSION_NAME);
+ StrPCopy(PWideChar(PByte(pSessionProperties) + pSessionProperties.LogFileNameOffset), FDebugLogFileName);
+// StringCbCopy((LPWSTR)((char*)pSessionProperties + pSessionProperties->LogFileNameOffset), sizeof(LOGFILE_PATH), LOGFILE_PATH);
+
+ status := StartTrace(@FSessionHandle, PWideChar(LOGSESSION_NAME), pSessionProperties^);
+ if ERROR_ALREADY_EXISTS = status then
+ begin
+ // The trace was already started, perhaps Keyman did not close down cleanly
+ // We'll stop it and restart it
+ status := ControlTraceW(FSessionHandle, PWideChar(LOGSESSION_NAME), pSessionProperties^, EVENT_TRACE_CONTROL_STOP);
+ if ERROR_SUCCESS <> status then
+ OutputDebugString(PChar('ControlTrace failed with '+IntToStr(status)));
+
+ status := StartTrace(@FSessionHandle, PWideChar(LOGSESSION_NAME), pSessionProperties^);
+ end;
+
+ if ERROR_SUCCESS <> status then
+ RaiseLastOSError(status, 'StartTrace');
+
+ // Enable the providers that you want to log events to your session.
+
+ status := EnableTraceEx(
+ @DebugLogProviderGuid,
+ @SessionGuid,
+ FSessionHandle,
+ 1, // Enable
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ nil
+ );
+
+ if ERROR_SUCCESS <> status then
+ RaiseLastOSError(status, 'EnableTraceEx');
+
+ FTraceRunning := True;
+end;
+
+destructor TDebugLogManager.Destroy;
+var
+ status: ULONG;
+begin
+ if FSessionHandle <> 0 then
+ begin
+ if FTraceRunning then
+ begin
+ status := EnableTraceEx(
+ @DebugLogProviderGuid,
+ @SessionGuid,
+ FSessionHandle,
+ 0, // Disable
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ nil
+ );
+ if ERROR_SUCCESS <> status then
+ OutputDebugString(PChar('EnableTraceEx(FALSE) failed with '+IntToStr(status)));
+
+ FTraceRunning := False;
+ end;
+
+ // We use ControlTraceW because JwaEventTracing has a typo for ControlTrace
+ status := ControlTraceW(FSessionHandle, PWideChar(LOGSESSION_NAME), pSessionProperties^, EVENT_TRACE_CONTROL_STOP);
+ if ERROR_SUCCESS <> status then
+ OutputDebugString(PChar('ControlTrace failed with '+IntToStr(status)));
+
+ FSessionHandle := 0;
+ end;
+
+ if pSessionProperties <> nil then
+ begin
+ FreeMem(pSessionProperties);
+ pSessionProperties := nil;
+ end;
+
+ inherited Destroy;
+end;
+
+const
+ MAXDEBUGLOGS = 16;
+
+function TDebugLogManager.DebugLogFileName(n: Integer): string;
+begin
+ Result := GetErrLogPath + 'system' + IntToStr(n) + '.etl';
+end;
+
+procedure TDebugLogManager.FindFirstLogFileName;
+var
+ FSelectedTime: TDateTime;
+ i: Integer;
+ f: TSearchRec;
+begin
+ FSelectedTime := MaxDateTime;
+ FDebugLogIndex := 0;
+
+ for i := 0 to MAXDEBUGLOGS - 1 do
+ begin
+ if FindFirst(DebugLogFileName(i), 0, f) = 0 then
+ begin
+ if f.TimeStamp < FSelectedTime then
+ begin
+ FDebugLogIndex := i;
+ FSelectedTime := f.TimeStamp;
+ end;
+ System.SysUtils.FindClose(f);
+ end
+ else
+ begin
+ FDebugLogIndex := i;
+ Break;
+ end;
+ end;
+
+ Dec(FDebugLogIndex); // It will be immediately incremented by StartNewLogFile
+end;
+
+procedure TDebugLogManager.StartNewLogFile;
+begin
+ Inc(FDebugLogIndex);
+ if FDebugLogIndex > MAXDEBUGLOGS then
+ FDebugLogIndex := 0;
+
+ FDebugLogFileName := DebugLogFileName(FDebugLogIndex);
+ if FileExists(FDebugLogFileName) then
+ System.SysUtils.DeleteFile(FDebugLogFileName);
+end;
+
+
+initialization
+finalization
+ FTerminating := True;
+ FreeAndNil(FDebugManager);
+end.
diff --git a/windows/src/global/delphi/general/SystemDebugPath.pas b/windows/src/global/delphi/general/SystemDebugPath.pas
deleted file mode 100644
index 3a417f7586..0000000000
--- a/windows/src/global/delphi/general/SystemDebugPath.pas
+++ /dev/null
@@ -1,74 +0,0 @@
-(*
- Name: SystemDebugPath
- Copyright: Copyright (C) SIL International.
- Documentation:
- Description:
- Create Date: 4 Dec 2006
-
- Modified Date: 26 Jun 2012
- Authors: mcdurdin
- Related Files:
- Dependencies:
-
- Bugs:
- Todo:
- Notes:
- History: 04 Dec 2006 - mcdurdin - Initial version
- 19 Jun 2007 - mcdurdin - Widestrings
- 03 May 2011 - mcdurdin - I2890 - Record diagnostic data when encountering registry errors
- 04 May 2012 - mcdurdin - I3306 - V9.0 - Remove TntControls
- 26 Jun 2012 - mcdurdin - I3379 - KM9 - Remove old Winapi references now in Delphi libraries
-*)
-unit SystemDebugPath; // I3306
-
-interface
-
-function GetSystemDebugPath: WideString;
-
-implementation
-
-uses
- ActiveX, ShellApi, ShlObj, ErrorControlledRegistry, SysUtils, Windows;
-
-function GetFolderPath(csidl: Integer): WideString;
-var
- buf: array[0..260] of WideChar;
- idl: PItemIDList;
- mm: IMalloc;
-begin
- Result := '';
- if SHGetMalloc(mm) = NOERROR then
- begin
- if SHGetSpecialFolderLocation(0, csidl, idl) = NOERROR then
- begin
- if SHGetPathFromIDList(idl, buf) then
- begin
- Result := Buf;
- end;
- mm.Free(idl);
- end;
- mm._Release;
- end;
-
- if (Result = '') and (csidl = CSIDL_PROGRAM_FILES) then
- with TRegistryErrorControlled.Create do // I2890
- try
- RootKey := HKEY_LOCAL_MACHINE;
- if not OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion') then // I2890
- RaiseLastRegistryError;
- Result := ReadString('ProgramFilesDir');
- finally
- Free;
- end;
- if Result <> '' then Result := IncludeTrailingPathDelimiter(Result);
- if Result[Length(Result)] <> '\' then Result := Result + '\';
-end;
-
-function GetSystemDebugPath: WideString;
-begin
- Result := GetFolderPath(CSIDL_DESKTOPDIRECTORY) + 'keymanlog';
- if not DirectoryExists(Result) then CreateDir(Result); // assumes write permissions!
- Result := Result + '\';
-end;
-
-end.
diff --git a/windows/src/global/delphi/general/UserMessages.pas b/windows/src/global/delphi/general/UserMessages.pas
index 609acc1851..1deb856767 100644
--- a/windows/src/global/delphi/general/UserMessages.pas
+++ b/windows/src/global/delphi/general/UserMessages.pas
@@ -32,7 +32,6 @@ const
WM_USER_ParameterPass = WM_USER+100;
WM_USER_SendFontChange = WM_USER+102;
WM_USER_PlatformComms = WM_USER+103;
- WM_USER_DebugNotify = WM_USER+104;
WM_USER_VisualKeyboardClosed = WM_USER+105; // I4242
const