From 47e2bb2dccd9286198de57e8278e29753bf1e3bb Mon Sep 17 00:00:00 2001 From: gremat <50012463+gremat@users.noreply.github.com> Date: Tue, 24 Mar 2026 13:45:39 +0100 Subject: [PATCH] feat: improve WER report details --- thorlog/v3/file.go | 4 +-- thorlog/v3/wer.go | 63 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/thorlog/v3/file.go b/thorlog/v3/file.go index 2c88710..eb0c422 100644 --- a/thorlog/v3/file.go +++ b/thorlog/v3/file.go @@ -55,8 +55,8 @@ type File struct { // RecycleBinInfo contains information about the file if it was in the recycle bin RecycleBinInfo *RecycleBinIndexFile `json:"recycle_bin_info,omitempty" textlog:",expand,omitempty"` - // WerInfo contains information about the file if it was a Windows Error Reporting crash report - WerInfo *WerCrashReport `json:"wer_info,omitempty" textlog:",expand,omitempty"` + // WERInfo contains information about the file if it was a Windows Error Reporting crash report + WERInfo *WERCrashReport `json:"wer_info,omitempty" textlog:",expand,omitempty"` // Content contains extracts from the content of the file, typically focusing on any matched patterns. Content *SparseData `json:"content,omitempty" textlog:"content,expand,omitempty"` diff --git a/thorlog/v3/wer.go b/thorlog/v3/wer.go index f677687..65113eb 100644 --- a/thorlog/v3/wer.go +++ b/thorlog/v3/wer.go @@ -4,13 +4,62 @@ import ( "time" ) -type WerCrashReport struct { - Type string `json:"-" textlog:"-"` - Exe string `json:"exe" textlog:"exe"` - Date time.Time `json:"date" textlog:"date"` - AppPath string `json:"app_path" textlog:"apppath"` - Error string `json:"error" textlog:"error"` - FaultModule string `json:"fault_in_module" textlog:"fault_in_module"` +// WERCrashReport represents a crash report generated by Windows Error +// Reporting (WER). +// +// For details consult the official documentation [1] and in particular the +// werapi.h reference [2]. +// +// There are plenty of fields to consider in the WER report, but the focus is +// on the WER_REPORT_INFORMATION structure required to create a report +// (WerReportCreate()) and the WER_REPORT_UI enumeration that holds additional +// error details if present. +// +// [1] https://learn.microsoft.com/en-us/windows/win32/api/werapi/ns-werapi-wer_report_information +// [2] https://learn.microsoft.com/en-us/windows/win32/api/werapi/ . +type WERCrashReport struct { + ReportType WERReportType `json:"type" textlog:"reporttype"` + // Event name as used in the file name of the WER report (which seems to be deduced from Sig[0].Value), e.g., "evilservice.exe", "Update;", "10.0.19041.1371_", etc. + EventName string `json:"event_name" textlog:"eventname"` + // Event type, e.g., "WindowsWcpOtherFailure3", "StoreAgentScanForUpdatesFailure0", etc. + EventType string `json:"event_type" textlog:"eventtype"` + Date time.Time `json:"date" textlog:"date"` + AppPath string `json:"app_path" textlog:"apppath"` + AppName string `json:"app_name" textlog:"appname"` + // Name of executable from field OriginalFilename + Exe string `json:"exe,omitempty" textlog:"exe,omitempty"` + // Specific error details from UI block: "UI[2] / UI[8]" or "UI[8]" if present. + Error string `json:"error,omitempty" textlog:"error,omitempty"` + // Fault module name from Sig block if present. + FaultModule string `json:"fault_in_module,omitempty" textlog:"fault_in_module,omitempty"` +} + +// WERReportType represents the type of a WER report. +// +// From WerApi.h: +// typedef enum _WER_REPORT_TYPE +// +// { +// WerReportNonCritical = 0, +// WerReportCritical = 1, +// WerReportApplicationCrash = 2, +// WerReportApplicationHang = 3, +// WerReportKernel = 4, +// WerReportInvalid +// } WER_REPORT_TYPE; +type WERReportType string + +const ( + WERReportNonCritical WERReportType = "NonCritical" + WERReportCritical WERReportType = "Critical" + WERReportApplicationCrash WERReportType = "AppCrash" + WERReportApplicationHang WERReportType = "AppHang" + WERReportKernel WERReportType = "Kernel" + WERReportInvalid WERReportType = "Invalid" +) + +func (r WERReportType) String() string { + return string(r) } type AnalysisResult struct {