Skip to content

Commit

Permalink
Add in verbose error message and telemetry for SetWindowsHookEx failu…
Browse files Browse the repository at this point in the history
…re (#6454)

* Updated error message when SetWindowsHookEx fails to show correct error message

* Added telemetry for exception in SG, FZ and KBM

* Rename exception to error
  • Loading branch information
arjunbalgovind committed Sep 9, 2020
1 parent f61e9d3 commit fb1888f
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 45 deletions.
10 changes: 2 additions & 8 deletions src/common/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "shlwapi.lib")

namespace localized_strings
{
const wchar_t LAST_ERROR_FORMAT_STRING[] = L"%s failed with error %d: %s";
const wchar_t LAST_ERROR_TITLE_STRING[] = L"Error";
}

std::optional<RECT> get_window_pos(HWND hwnd)
{
RECT window;
Expand Down Expand Up @@ -91,7 +85,7 @@ std::optional<std::wstring> get_last_error_message(const DWORD dw)
return message;
}

void show_last_error_message(LPCWSTR lpszFunction, DWORD dw)
void show_last_error_message(LPCWSTR lpszFunction, DWORD dw, LPCWSTR errorTitle)
{
const auto system_message = get_last_error_message(dw);
if (!system_message.has_value())
Expand All @@ -107,7 +101,7 @@ void show_last_error_message(LPCWSTR lpszFunction, DWORD dw)
lpszFunction,
dw,
system_message->c_str());
MessageBoxW(NULL, (LPCTSTR)lpDisplayBuf, localized_strings::LAST_ERROR_TITLE_STRING, MB_OK);
MessageBoxW(NULL, (LPCTSTR)lpDisplayBuf, errorTitle, MB_OK | MB_ICONERROR);
LocalFree(lpDisplayBuf);
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
#include <memory>
#include <vector>


namespace localized_strings
{
const wchar_t LAST_ERROR_FORMAT_STRING[] = L"%s failed with error %d: %s";
const wchar_t LAST_ERROR_TITLE_STRING[] = L"Error";
}

// Gets position of given window.
std::optional<RECT> get_window_pos(HWND hwnd);

Expand All @@ -16,7 +23,7 @@ bool is_system_window(HWND hwnd, const char* class_name);
int run_message_loop(const bool until_idle = false, const std::optional<uint32_t> timeout_seconds = {});

std::optional<std::wstring> get_last_error_message(const DWORD dw);
void show_last_error_message(LPCWSTR lpszFunction, DWORD dw);
void show_last_error_message(LPCWSTR lpszFunction, DWORD dw, LPCWSTR errorTitle = localized_strings::LAST_ERROR_TITLE_STRING);

enum WindowState
{
Expand Down
4 changes: 3 additions & 1 deletion src/common/interop/KeyboardHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <msclr\marshal.h>
#include <msclr\marshal_cppstd.h>
#include <common/debug_control.h>
#include <common/common.h>

using namespace interop;
using namespace System::Runtime::InteropServices;
Expand Down Expand Up @@ -46,7 +47,8 @@ void KeyboardHook::Start()
0);
if (hookHandle == nullptr)
{
throw std::exception("SetWindowsHookEx failed.");
DWORD errorCode = GetLastError();
show_last_error_message(L"SetWindowsHookEx", errorCode, L"PowerToys - Interop");
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/modules/fancyzones/dll/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ class FancyZonesModule : public PowertoyModuleIface
s_llKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL);
if (!s_llKeyboardHook)
{
MessageBoxW(NULL,
GET_RESOURCE_STRING(IDS_KEYBOARD_LISTENER_ERROR).c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK | MB_ICONERROR);
DWORD errorCode = GetLastError();
show_last_error_message(L"SetWindowsHookEx", errorCode, GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str());
auto errorMessage = get_last_error_message(errorCode);
Trace::FancyZones::Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"enable.SetWindowsHookEx");
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/modules/fancyzones/lib/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,19 @@ void Trace::FancyZones::EditorLaunched(int value) noexcept
TraceLoggingInt32(value, EditorLaunchValueKey));
}

// Log if an error occurs in FZ
void Trace::FancyZones::Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept
{
TraceLoggingWrite(
g_hProvider,
"FancyZones_Error",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingValue(methodName.c_str(), "MethodName"),
TraceLoggingValue(errorCode, "ErrorCode"),
TraceLoggingValue(errorMessage.c_str(), "ErrorMessage"));
}

void Trace::SettingsChanged(const Settings& settings) noexcept
{
const auto& editorHotkey = settings.editorHotkey;
Expand Down
1 change: 1 addition & 0 deletions src/modules/fancyzones/lib/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Trace
static void OnKeyDown(DWORD vkCode, bool win, bool control, bool inMoveSize) noexcept;
static void DataChanged() noexcept;
static void EditorLaunched(int value) noexcept;
static void Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept;
};

static void SettingsChanged(const Settings& settings) noexcept;
Expand Down
13 changes: 13 additions & 0 deletions src/modules/keyboardmanager/common/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,16 @@ void Trace::ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific)
}
}
}

// Log if an error occurs in KBM
void Trace::Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept
{
TraceLoggingWrite(
g_hProvider,
"KeyboardManager_Error",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingValue(methodName.c_str(), "MethodName"),
TraceLoggingValue(errorCode, "ErrorCode"),
TraceLoggingValue(errorMessage.c_str(), "ErrorMessage"));
}
3 changes: 3 additions & 0 deletions src/modules/keyboardmanager/common/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ class Trace

// Log if a shortcut remap has been invoked
static void ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) noexcept;

// Log if an error occurs in KBM
static void Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept;
};
5 changes: 4 additions & 1 deletion src/modules/keyboardmanager/dll/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,10 @@ class KeyboardManager : public PowertoyModuleIface
hook_handle_copy = hook_handle;
if (!hook_handle)
{
throw std::runtime_error("Cannot install keyboard listener");
DWORD errorCode = GetLastError();
show_last_error_message(L"SetWindowsHookEx", errorCode, L"PowerToys - Keyboard Manager");
auto errorMessage = get_last_error_message(errorCode);
Trace::Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"start_lowlevel_keyboard_hook.SetWindowsHookEx");
}
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 18 additions & 18 deletions src/modules/launcher/PowerLauncher/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions src/modules/shortcut_guide/shortcut_guide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <common/common.h>
#include <common/settings_objects.h>
#include <common/debug_control.h>
#include <sstream>

extern "C" IMAGE_DOS_HEADER __ImageBase;

Expand Down Expand Up @@ -84,8 +85,8 @@ namespace
// For now, since ShortcutGuide can only disable entire "Windows Controls"
// group, we require that the window supports all the options.
result.snappable = ((style & WS_MAXIMIZEBOX) == WS_MAXIMIZEBOX) &&
((style & WS_MINIMIZEBOX) == WS_MINIMIZEBOX) &&
((style & WS_THICKFRAME) == WS_THICKFRAME);
((style & WS_MINIMIZEBOX) == WS_MINIMIZEBOX) &&
((style & WS_THICKFRAME) == WS_THICKFRAME);
return result;
}
}
Expand Down Expand Up @@ -224,7 +225,10 @@ void OverlayWindow::enable()
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL);
if (!hook_handle)
{
MessageBoxW(NULL, L"Cannot install keyboard listener.", L"PowerToys - Shortcut Guide", MB_OK | MB_ICONERROR);
DWORD errorCode = GetLastError();
show_last_error_message(L"SetWindowsHookEx", errorCode, L"PowerToys - Shortcut Guide");
auto errorMessage = get_last_error_message(errorCode);
Trace::Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"OverlayWindow.enable.SetWindowsHookEx");
}
}
RegisterHotKey(winkey_popup->get_window_handle(), alternative_switch_hotkey_id, alternative_switch_modifier_mask, alternative_switch_vk_code);
Expand Down
13 changes: 13 additions & 0 deletions src/modules/shortcut_guide/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,16 @@ void Trace::SettingsChanged(const int press_delay_time, const int overlay_opacit
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}

// Log if an error occurs in Shortcut Guide
void Trace::Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept
{
TraceLoggingWrite(
g_hProvider,
"ShortcutGuide_Error",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingValue(methodName.c_str(), "MethodName"),
TraceLoggingValue(errorCode, "ErrorCode"),
TraceLoggingValue(errorMessage.c_str(), "ErrorMessage"));
}
1 change: 1 addition & 0 deletions src/modules/shortcut_guide/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ class Trace
static void HideGuide(const __int64 duration_ms, std::vector<int>& key_pressed) noexcept;
static void EnableShortcutGuide(const bool enabled) noexcept;
static void SettingsChanged(const int press_delay_time, const int overlay_opacity, const std::wstring& theme) noexcept;
static void Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept;
};

0 comments on commit fb1888f

Please sign in to comment.