#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"
va_start(ap, fmt);
vfprintf(stream, fmt, ap);
vDbgPrintEx(-1, DPFLTR_ERROR_LEVEL, fmt, ap);
+ va_end(ap);
}
{
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);
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());
xfprintf(output, NEWLINE "State Dump for Thread Id 0x%x" NEWLINE NEWLINE, it->first);
const CONTEXT& ctx = it->second.Context;
- if (ctx.ContextFlags & CONTEXT_INTEGER)
+ if ((ctx.ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+ {
+#if defined(_M_IX86)
xfprintf(output, "eax:%p ebx:%p ecx:%p edx:%p esi:%p edi:%p" NEWLINE,
ctx.Eax, ctx.Ebx, ctx.Ecx, ctx.Edx, ctx.Esi, ctx.Edi);
- if (ctx.ContextFlags & CONTEXT_CONTROL)
+#elif defined(_M_AMD64)
+ xfprintf(output, "rax:%p rbx:%p rcx:%p rdx:%p rsi:%p rdi:%p" NEWLINE,
+ ctx.Rax, ctx.Rbx, ctx.Rcx, ctx.Rdx, ctx.Rsi, ctx.Rdi);
+ xfprintf(output, "r8:%p r9:%p r10:%p r11:%p r12:%p r13:%p r14:%p r15:%p" NEWLINE,
+ ctx.R8, ctx.R9, ctx.R10, ctx.R11, ctx.R12, ctx.R13, ctx.R14, ctx.R15);
+#else
+#error Unknown architecture
+#endif
+ }
+ if ((ctx.ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+ {
+#if defined(_M_IX86)
xfprintf(output, "eip:%p esp:%p ebp:%p" NEWLINE,
ctx.Eip, ctx.Esp, ctx.Ebp);
- if (ctx.ContextFlags & CONTEXT_DEBUG_REGISTERS)
+#elif defined(_M_AMD64)
+ xfprintf(output, "rip:%p rsp:%p rbp:%p" NEWLINE,
+ ctx.Rip, ctx.Rsp, ctx.Rbp);
+#else
+#error Unknown architecture
+#endif
+ }
+ if ((ctx.ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+ {
+#if defined(_M_IX86) || defined(_M_AMD64)
xfprintf(output, "dr0:%p dr1:%p dr2:%p dr3:%p dr6:%p dr7:%p" NEWLINE,
ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr6, ctx.Dr7);
+#else
+#error Unknown architecture
+#endif
+ }
PrintStackBacktrace(output, data, it->second);
}
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;
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);
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;
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);
}