mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added CrashDump setting
This commit is contained in:
parent
8931394562
commit
d734c41443
@ -9,6 +9,7 @@
|
||||
#include <Config/Settings/ConfigTransparency.h>
|
||||
#include <Config/Settings/CpuAffinity.h>
|
||||
#include <Config/Settings/CpuAffinityRotation.h>
|
||||
#include <Config/Settings/CrashDump.h>
|
||||
#include <Config/Settings/DepthFormat.h>
|
||||
#include <Config/Settings/DesktopColorDepth.h>
|
||||
#include <Config/Settings/DesktopResolution.h>
|
||||
@ -62,6 +63,7 @@ namespace Config
|
||||
Settings::ConfigTransparency configTransparency;
|
||||
Settings::CpuAffinity cpuAffinity;
|
||||
Settings::CpuAffinityRotation cpuAffinityRotation;
|
||||
Settings::CrashDump crashDump;
|
||||
Settings::DepthFormat depthFormat;
|
||||
Settings::DisplayAspectRatio displayAspectRatio;
|
||||
Settings::DesktopColorDepth desktopColorDepth;
|
||||
|
36
DDrawCompat/Config/Settings/CrashDump.h
Normal file
36
DDrawCompat/Config/Settings/CrashDump.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#include <Config/MappedSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class CrashDump : public MappedSetting<UINT>
|
||||
{
|
||||
public:
|
||||
static const UINT OFF = 0;
|
||||
|
||||
static const UINT MINI =
|
||||
MiniDumpWithDataSegs |
|
||||
MiniDumpWithUnloadedModules |
|
||||
MiniDumpWithProcessThreadData;
|
||||
|
||||
static const UINT FULL =
|
||||
MiniDumpWithFullMemory |
|
||||
MiniDumpWithHandleData |
|
||||
MiniDumpWithUnloadedModules |
|
||||
MiniDumpWithFullMemoryInfo |
|
||||
MiniDumpWithThreadInfo |
|
||||
MiniDumpIgnoreInaccessibleMemory;
|
||||
|
||||
CrashDump() : MappedSetting("CrashDump", "off", { {"off", OFF}, {"mini", MINI}, {"full", FULL} })
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
extern Settings::CrashDump crashDump;
|
||||
}
|
@ -73,7 +73,7 @@ namespace
|
||||
if ("OpenAdapter" == std::string(lpProcName))
|
||||
{
|
||||
g_origOpenAdapter = reinterpret_cast<PFND3DDDI_OPENADAPTER>(
|
||||
CALL_ORIG_FUNC(GetProcAddress)(hModule, lpProcName));
|
||||
GetProcAddress(hModule, lpProcName));
|
||||
if (g_origOpenAdapter)
|
||||
{
|
||||
static std::set<HMODULE> hookedModules;
|
||||
@ -89,14 +89,14 @@ namespace
|
||||
else if ("GetPrivateDDITable" == std::string(lpProcName))
|
||||
{
|
||||
g_origGetPrivateDdiTable = reinterpret_cast<decltype(&getPrivateDdiTable)>(
|
||||
CALL_ORIG_FUNC(GetProcAddress)(hModule, lpProcName));
|
||||
GetProcAddress(hModule, lpProcName));
|
||||
if (g_origGetPrivateDdiTable)
|
||||
{
|
||||
return reinterpret_cast<FARPROC>(&getPrivateDdiTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
return LOG_RESULT(CALL_ORIG_FUNC(GetProcAddress)(hModule, lpProcName));
|
||||
return LOG_RESULT(GetProcAddress(hModule, lpProcName));
|
||||
}
|
||||
|
||||
HRESULT APIENTRY kmtPresent(HANDLE hDevice, D3DKMT_PRESENT* pKMTArgs)
|
||||
|
@ -174,6 +174,7 @@
|
||||
<ClInclude Include="Config\Settings\ConfigTransparency.h" />
|
||||
<ClInclude Include="Config\Settings\CpuAffinity.h" />
|
||||
<ClInclude Include="Config\Settings\CpuAffinityRotation.h" />
|
||||
<ClInclude Include="Config\Settings\CrashDump.h" />
|
||||
<ClInclude Include="Config\Settings\DepthFormat.h" />
|
||||
<ClInclude Include="Config\Settings\DesktopColorDepth.h" />
|
||||
<ClInclude Include="Config\Settings\DesktopResolution.h" />
|
||||
|
@ -702,6 +702,9 @@
|
||||
<ClInclude Include="Config\Settings\ConfigRows.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\CrashDump.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <string>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <DbgHelp.h>
|
||||
#include <ShellScalingApi.h>
|
||||
#include <timeapi.h>
|
||||
#include <Uxtheme.h>
|
||||
@ -8,8 +9,10 @@
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Common/Path.h>
|
||||
#include <Common/ScopedCriticalSection.h>
|
||||
#include <Common/Time.h>
|
||||
#include <Config/Parser.h>
|
||||
#include <Config/Settings/CrashDump.h>
|
||||
#include <Config/Settings/DesktopResolution.h>
|
||||
#include <Config/Settings/DpiAwareness.h>
|
||||
#include <Config/Settings/FullscreenMode.h>
|
||||
@ -37,6 +40,9 @@ namespace
|
||||
{
|
||||
const DWORD DISABLE_MAX_WINDOWED_MODE = 12;
|
||||
|
||||
Compat::CriticalSection g_crashDumpCs;
|
||||
std::filesystem::path g_crashDumpPath;
|
||||
|
||||
template <typename Result, typename... Params>
|
||||
using FuncPtr = Result(WINAPI*)(Params...);
|
||||
|
||||
@ -238,6 +244,71 @@ namespace
|
||||
|
||||
logDpiAwareness(SetProcessDPIAware(), DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, "SetProcessDPIAware");
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI setUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
|
||||
{
|
||||
LOG_FUNC("SetUnhandledExceptionFilter", Compat::funcPtrToStr(lpTopLevelExceptionFilter));
|
||||
LOG_ONCE("Suppressed new unhandled exception filter: " << Compat::funcPtrToStr(lpTopLevelExceptionFilter));
|
||||
return LOG_RESULT(nullptr);
|
||||
}
|
||||
|
||||
LONG WINAPI unhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo)
|
||||
{
|
||||
Compat::ScopedCriticalSection lock(g_crashDumpCs);
|
||||
BOOL result = FALSE;
|
||||
DWORD error = 0;
|
||||
HANDLE dumpFile = INVALID_HANDLE_VALUE;
|
||||
|
||||
LOG_INFO << "Terminating application due to unhandled exception: "
|
||||
<< Compat::hex(ExceptionInfo->ExceptionRecord->ExceptionCode);
|
||||
|
||||
const auto writeDump = reinterpret_cast<decltype(&MiniDumpWriteDump)>(
|
||||
GetProcAddress(GetModuleHandle("dbghelp"), "MiniDumpWriteDump"));
|
||||
|
||||
if (writeDump)
|
||||
{
|
||||
dumpFile = CreateFileW(g_crashDumpPath.native().c_str(),
|
||||
GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (INVALID_HANDLE_VALUE == dumpFile)
|
||||
{
|
||||
error = GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION mei = {};
|
||||
mei.ThreadId = GetCurrentThreadId();
|
||||
mei.ExceptionPointers = ExceptionInfo;
|
||||
result = writeDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile,
|
||||
static_cast<MINIDUMP_TYPE>(Config::crashDump.get()), &mei, nullptr, nullptr);
|
||||
if (!result)
|
||||
{
|
||||
error = GetLastError();
|
||||
}
|
||||
CloseHandle(dumpFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
LOG_INFO << "Crash dump has been written to: " << g_crashDumpPath.native().c_str();
|
||||
}
|
||||
else if (!writeDump)
|
||||
{
|
||||
LOG_INFO << "Failed to load procedure MiniDumpWriteDump to create a crash dump";
|
||||
}
|
||||
else if (INVALID_HANDLE_VALUE == dumpFile)
|
||||
{
|
||||
LOG_INFO << "Failed to create crash dump file: " << Compat::hex(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO << "Failed to write crash dump: " << Compat::hex(error);
|
||||
}
|
||||
|
||||
TerminateProcess(GetCurrentProcess(), 0);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
}
|
||||
|
||||
#define LOAD_ORIG_PROC(proc) \
|
||||
@ -276,6 +347,25 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
Config::Parser::loadAllConfigFiles(processPath);
|
||||
Compat::Log::initLogging(processPath, Config::logLevel.get());
|
||||
|
||||
if (Config::Settings::CrashDump::OFF != Config::crashDump.get())
|
||||
{
|
||||
g_crashDumpPath = processPath;
|
||||
if (Compat::isEqual(g_crashDumpPath.extension(), ".exe"))
|
||||
{
|
||||
g_crashDumpPath.replace_extension();
|
||||
}
|
||||
g_crashDumpPath.replace_filename(L"DDrawCompat-" + g_crashDumpPath.filename().native());
|
||||
g_crashDumpPath += ".dmp";
|
||||
|
||||
HOOK_FUNCTION(kernel32, SetUnhandledExceptionFilter, setUnhandledExceptionFilter);
|
||||
LOG_INFO << "Installing unhandled exception filter for automatic crash dumps";
|
||||
auto prevFilter = CALL_ORIG_FUNC(SetUnhandledExceptionFilter)(&unhandledExceptionFilter);
|
||||
if (prevFilter)
|
||||
{
|
||||
LOG_INFO << "Replaced previous unhandled exception filter: " << Compat::funcPtrToStr(prevFilter);
|
||||
}
|
||||
}
|
||||
|
||||
auto systemPath(Compat::getSystemPath());
|
||||
if (Compat::isEqual(currentDllPath.parent_path(), systemPath))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user