https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1d10606fadb62e6472f3c6194674e90b639c9b3e
commit 1d10606fadb62e6472f3c6194674e90b639c9b3e Author: William Kent <wjk...@gmail.com> AuthorDate: Thu Mar 8 20:50:29 2018 +0100 Commit: Mark Jansen <mark.jan...@reactos.org> CommitDate: Sat Mar 10 00:04:57 2018 +0100 [DRWTSN32] Various improvements * Convert to wWinMain() * Add a resource file * Use a slightly friendlier application name * Add code to load the output path from the Registry * Add localized string resources --- base/applications/drwtsn32/CMakeLists.txt | 8 ++- base/applications/drwtsn32/drwtsn32.cpp | 8 +-- base/applications/drwtsn32/drwtsn32.h | 4 +- base/applications/drwtsn32/drwtsn32.rc | 21 ++++++ base/applications/drwtsn32/lang/en-US.rc | 12 ++++ base/applications/drwtsn32/main.cpp | 105 ++++++++++++++++++++++-------- base/applications/drwtsn32/resource.h | 11 ++++ base/applications/drwtsn32/sysinfo.cpp | 2 +- 8 files changed, 133 insertions(+), 38 deletions(-) diff --git a/base/applications/drwtsn32/CMakeLists.txt b/base/applications/drwtsn32/CMakeLists.txt index 3a7e93f736..66dbdab1f7 100644 --- a/base/applications/drwtsn32/CMakeLists.txt +++ b/base/applications/drwtsn32/CMakeLists.txt @@ -2,6 +2,7 @@ PROJECT(drwtsn32) set_cpp(WITH_RUNTIME WITH_EXCEPTIONS WITH_STL) +include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl) list(APPEND CPP_SOURCE drwtsn32.cpp @@ -11,8 +12,9 @@ list(APPEND CPP_SOURCE drwtsn32.h precomp.h) -add_executable(drwtsn32 ${CPP_SOURCE}) +add_executable(drwtsn32 ${CPP_SOURCE} drwtsn32.rc) add_pch(drwtsn32 precomp.h CPP_SOURCE) -set_module_type(drwtsn32 win32gui) -add_importlibs(drwtsn32 dbghelp psapi advapi32 shell32 msvcrt user32 kernel32 ntdll) +set_module_type(drwtsn32 win32gui UNICODE) +target_link_libraries(drwtsn32 atlnew) +add_importlibs(drwtsn32 dbghelp psapi advapi32 shell32 shlwapi msvcrt user32 kernel32 ntdll) add_cd_file(TARGET drwtsn32 DESTINATION reactos/system32 FOR all) diff --git a/base/applications/drwtsn32/drwtsn32.cpp b/base/applications/drwtsn32/drwtsn32.cpp index b667dd723c..598e4f0b6b 100644 --- a/base/applications/drwtsn32/drwtsn32.cpp +++ b/base/applications/drwtsn32/drwtsn32.cpp @@ -59,18 +59,18 @@ bool UpdateFromEvent(DEBUG_EVENT& evt, DumpData& data) { case CREATE_PROCESS_DEBUG_EVENT: { - data.ProcessPath.resize(MAX_PATH); - DWORD len = GetModuleFileNameExA(evt.u.CreateProcessInfo.hProcess, NULL, &data.ProcessPath[0], data.ProcessPath.size()); + data.ProcessPath.resize(MAX_PATH*2); + DWORD len = GetModuleFileNameExW(evt.u.CreateProcessInfo.hProcess, NULL, &data.ProcessPath[0], data.ProcessPath.size()); if (len) { data.ProcessPath.resize(len); - std::string::size_type pos = data.ProcessPath.find_last_of("\\/"); + std::string::size_type pos = data.ProcessPath.find_last_of(L"\\/"); if (pos != std::string::npos) data.ProcessName = data.ProcessPath.substr(pos+1); } else { - data.ProcessPath = "??"; + data.ProcessPath = L"??"; } if (data.ProcessName.empty()) data.ProcessName = data.ProcessPath; diff --git a/base/applications/drwtsn32/drwtsn32.h b/base/applications/drwtsn32/drwtsn32.h index 4d161ffe2a..a16b2f3f00 100644 --- a/base/applications/drwtsn32/drwtsn32.h +++ b/base/applications/drwtsn32/drwtsn32.h @@ -36,8 +36,8 @@ typedef std::map<DWORD, ThreadData> ThreadMap; class DumpData { public: - std::string ProcessPath; - std::string ProcessName; + std::wstring ProcessPath; + std::wstring ProcessName; DWORD ProcessID; DWORD ThreadID; HANDLE ProcessHandle; diff --git a/base/applications/drwtsn32/drwtsn32.rc b/base/applications/drwtsn32/drwtsn32.rc new file mode 100644 index 0000000000..0f3e2108af --- /dev/null +++ b/base/applications/drwtsn32/drwtsn32.rc @@ -0,0 +1,21 @@ +/* + * PROJECT: Dr. Watson crash reporter + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Main resource file + * COPYRIGHT: Copyright 2018 William Kent (wjk011 [at] gmail [dot] com) + */ + +#include <windef.h> +#include <winuser.h> +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Crash Reporter" +#define REACTOS_STR_INTERNAL_NAME "drwtsn32" +#define REACTOS_STR_ORIGINAL_FILENAME "drwtsn32.exe" +#include <reactos/version.rc> + +#include <reactos/manifest_exe.rc> + +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif diff --git a/base/applications/drwtsn32/lang/en-US.rc b/base/applications/drwtsn32/lang/en-US.rc new file mode 100644 index 0000000000..d681297c2a --- /dev/null +++ b/base/applications/drwtsn32/lang/en-US.rc @@ -0,0 +1,12 @@ +/* + * PROJECT: Dr. Watson crash reporter + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: en-US resource file + * COPYRIGHT: Copyright 2018 William Kent (wjk011 [at] gmail [dot] com) + */ + +STRINGTABLE +BEGIN + IDS_APP_TITLE "ReactOS Crash Reporter" + IDS_USER_ALERT_MESSAGE "The application %ls has crashed. Information about this crash has been saved to:\r\n\r\n%ls" +END diff --git a/base/applications/drwtsn32/main.cpp b/base/applications/drwtsn32/main.cpp index 65c7dc1995..1224b7554e 100644 --- a/base/applications/drwtsn32/main.cpp +++ b/base/applications/drwtsn32/main.cpp @@ -9,9 +9,15 @@ #include <winuser.h> #include <algorithm> #include <shlobj.h> +#include <shlwapi.h> +#include <tchar.h> #include <strsafe.h> #include <tlhelp32.h> +#include <dbghelp.h> #include <conio.h> +#include <atlbase.h> +#include <atlstr.h> +#include "resource.h" static const char szUsage[] = "Usage: DrWtsn32 [-i] [-g] [-p dddd] [-e dddd] [-?]\n" @@ -56,7 +62,7 @@ void PrintBugreport(FILE* output, DumpData& data) { do { - xfprintf(output, "%5d: %s" NEWLINE, pe.th32ProcessID, pe.szExeFile); + xfprintf(output, "%5d: %ls" NEWLINE, pe.th32ProcessID, pe.szExeFile); } while (Process32Next(hSnap, &pe)); } CloseHandle(hSnap); @@ -67,7 +73,7 @@ void PrintBugreport(FILE* output, DumpData& data) ModuleData mainModule(NULL); mainModule.Update(data.ProcessHandle); - xfprintf(output, "(%p - %p) %s" NEWLINE, + xfprintf(output, "(%p - %p) %ls" NEWLINE, mainModule.BaseAddress, (PBYTE)mainModule.BaseAddress + mainModule.Size, data.ProcessPath.c_str()); @@ -144,11 +150,41 @@ int abort(FILE* output, int err) return err; } -int main(int argc, char* argv[]) +std::wstring Settings_GetOutputPath(void) { + WCHAR Buffer[MAX_PATH] = L""; + ULONG BufferSize = _countof(Buffer); + BOOL UseDefaultPath = FALSE; + + CRegKey key; + if (key.Open(HKEY_CURRENT_USER, L"SOFTWARE\\ReactOS\\Crash Reporter", KEY_READ) != ERROR_SUCCESS) + { + UseDefaultPath = TRUE; + } + + if (key.QueryStringValue(L"Dump Directory", Buffer, &BufferSize) != ERROR_SUCCESS) + { + UseDefaultPath = TRUE; + } + + if (UseDefaultPath) + { + if (FAILED(SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, Buffer))) + { + return std::wstring(); + } + } + + return std::wstring(Buffer); +} + +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR cmdLine, INT) +{ + int argc; + WCHAR **argv = CommandLineToArgvW(cmdLine, &argc); + DWORD pid = 0; - char Buffer[MAX_PATH+55]; - char Filename[50]; + WCHAR Filename[50]; FILE* output = NULL; SYSTEMTIME st; DumpData data; @@ -156,37 +192,37 @@ int main(int argc, char* argv[]) for (int n = 0; n < argc; ++n) { - char* arg = argv[n]; + WCHAR* arg = argv[n]; - if (!strcmp(arg, "-i")) + if (!wcscmp(arg, L"-i")) { /* FIXME: Installs as the postmortem debugger. */ } - else if (!strcmp(arg, "-g")) + else if (!wcscmp(arg, L"-g")) { } - else if (!strcmp(arg, "-p")) + else if (!wcscmp(arg, L"-p")) { if (n + 1 < argc) { - pid = strtoul(argv[n+1], NULL, 10); + pid = wcstoul(argv[n+1], NULL, 10); n++; } } - else if (!strcmp(arg, "-e")) + else if (!wcscmp(arg, L"-e")) { if (n + 1 < argc) { - data.Event = (HANDLE)strtoul(argv[n+1], NULL, 10); + data.Event = (HANDLE)wcstoul(argv[n+1], NULL, 10); n++; } } - else if (!strcmp(arg, "-?")) + else if (!wcscmp(arg, L"-?")) { - MessageBoxA(NULL, szUsage, "DrWtsn32", MB_OK); + MessageBoxA(NULL, szUsage, "ReactOS Crash Reporter", MB_OK); return abort(output, 0); } - else if (!strcmp(arg, "/?")) + else if (!wcscmp(arg, L"/?")) { xfprintf(stdout, "%s\n", szUsage); return abort(stdout, 0); @@ -195,19 +231,33 @@ int main(int argc, char* argv[]) if (!pid) { - MessageBoxA(NULL, szUsage, "DrWtsn32", MB_OK); + MessageBoxA(NULL, szUsage, "ReactOS Crash Reporter", MB_OK); return abort(stdout, 0); } GetLocalTime(&st); - if (SHGetFolderPathA(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, Buffer) == S_OK && - SUCCEEDED(StringCchPrintfA(Filename, _countof(Filename), "Appcrash_%d-%02d-%02d_%02d-%02d-%02d.txt", + std::wstring OutputPath = Settings_GetOutputPath(); + BOOL HasPath = (OutputPath.size() != 0); + + if (!PathIsDirectoryW(OutputPath.c_str())) + { + int res = SHCreateDirectoryExW(NULL, OutputPath.c_str(), NULL); + if (res != ERROR_SUCCESS && res != ERROR_ALREADY_EXISTS) + { + xfprintf(stdout, "Could not create output directory, not writing dump\n"); + MessageBoxA(NULL, "Could not create directory to write crash report.", "ReactOS Crash Reporter", MB_ICONERROR | MB_OK); + return abort(stdout, 0); + } + } + + if (HasPath && + SUCCEEDED(StringCchPrintfW(Filename, _countof(Filename), L"Appcrash_%d-%02d-%02d_%02d-%02d-%02d.txt", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond))) { - StringCchCatA(Buffer, _countof(Buffer), "\\"); - StringCchCatA(Buffer, _countof(Buffer), Filename); - output = fopen(Buffer, "wb"); + OutputPath += L"\\"; + OutputPath += Filename; + output = _wfopen(OutputPath.c_str(), L"wb"); } if (!output) output = stdout; @@ -237,13 +287,12 @@ int main(int argc, char* argv[]) TerminateProcess(data.ProcessHandle, data.ExceptionInfo.ExceptionRecord.ExceptionCode); - std::string Message = "The application '"; - Message += data.ProcessName; - Message += "' has just crashed :(\n"; - Message += "Information about this crash is saved to:\n"; - Message += Filename; - Message += "\nThis file is stored on your desktop."; - MessageBoxA(NULL, Message.c_str(), "Sorry!", MB_OK); + CStringW FormattedMessage; + FormattedMessage.Format(IDS_USER_ALERT_MESSAGE, data.ProcessName.c_str(), OutputPath.c_str()); + CStringW DialogTitle; + DialogTitle.LoadString(hInstance, IDS_APP_TITLE); + + MessageBoxW(NULL, FormattedMessage.GetString(), DialogTitle.GetString(), MB_OK); return abort(output, 0); } diff --git a/base/applications/drwtsn32/resource.h b/base/applications/drwtsn32/resource.h new file mode 100644 index 0000000000..064207ea64 --- /dev/null +++ b/base/applications/drwtsn32/resource.h @@ -0,0 +1,11 @@ +/* + * PROJECT: Dr. Watson crash reporter + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Resource file header + * COPYRIGHT: Copyright 2018 William Kent (wjk011 [at] gmail [dot] com) + */ + +#pragma once + +#define IDS_APP_TITLE 101 +#define IDS_USER_ALERT_MESSAGE 102 diff --git a/base/applications/drwtsn32/sysinfo.cpp b/base/applications/drwtsn32/sysinfo.cpp index 7cad0cab5a..7148163b15 100644 --- a/base/applications/drwtsn32/sysinfo.cpp +++ b/base/applications/drwtsn32/sysinfo.cpp @@ -54,7 +54,7 @@ void PrintSystemInfo(FILE* output, DumpData& data) GetLocalTime(&LocalTime); xfprintf(output, NEWLINE "ReactOS " KERNEL_VERSION_STR " DrWtsn32" NEWLINE NEWLINE); xfprintf(output, "Application exception occurred:" NEWLINE); - xfprintf(output, " App: %s (pid=%d, tid=0x%x)" NEWLINE, data.ProcessName.c_str(), data.ProcessID, data.ThreadID); + xfprintf(output, " App: %ls (pid=%d, tid=0x%x)" NEWLINE, data.ProcessName.c_str(), data.ProcessID, data.ThreadID); xfprintf(output, " When: %d/%d/%d @ %02d:%02d:%02d.%d" NEWLINE, LocalTime.wDay, LocalTime.wMonth, LocalTime.wYear, LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond, LocalTime.wMilliseconds);