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/ConfigTransparency.h>
|
||||||
#include <Config/Settings/CpuAffinity.h>
|
#include <Config/Settings/CpuAffinity.h>
|
||||||
#include <Config/Settings/CpuAffinityRotation.h>
|
#include <Config/Settings/CpuAffinityRotation.h>
|
||||||
|
#include <Config/Settings/CrashDump.h>
|
||||||
#include <Config/Settings/DepthFormat.h>
|
#include <Config/Settings/DepthFormat.h>
|
||||||
#include <Config/Settings/DesktopColorDepth.h>
|
#include <Config/Settings/DesktopColorDepth.h>
|
||||||
#include <Config/Settings/DesktopResolution.h>
|
#include <Config/Settings/DesktopResolution.h>
|
||||||
@ -62,6 +63,7 @@ namespace Config
|
|||||||
Settings::ConfigTransparency configTransparency;
|
Settings::ConfigTransparency configTransparency;
|
||||||
Settings::CpuAffinity cpuAffinity;
|
Settings::CpuAffinity cpuAffinity;
|
||||||
Settings::CpuAffinityRotation cpuAffinityRotation;
|
Settings::CpuAffinityRotation cpuAffinityRotation;
|
||||||
|
Settings::CrashDump crashDump;
|
||||||
Settings::DepthFormat depthFormat;
|
Settings::DepthFormat depthFormat;
|
||||||
Settings::DisplayAspectRatio displayAspectRatio;
|
Settings::DisplayAspectRatio displayAspectRatio;
|
||||||
Settings::DesktopColorDepth desktopColorDepth;
|
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))
|
if ("OpenAdapter" == std::string(lpProcName))
|
||||||
{
|
{
|
||||||
g_origOpenAdapter = reinterpret_cast<PFND3DDDI_OPENADAPTER>(
|
g_origOpenAdapter = reinterpret_cast<PFND3DDDI_OPENADAPTER>(
|
||||||
CALL_ORIG_FUNC(GetProcAddress)(hModule, lpProcName));
|
GetProcAddress(hModule, lpProcName));
|
||||||
if (g_origOpenAdapter)
|
if (g_origOpenAdapter)
|
||||||
{
|
{
|
||||||
static std::set<HMODULE> hookedModules;
|
static std::set<HMODULE> hookedModules;
|
||||||
@ -89,14 +89,14 @@ namespace
|
|||||||
else if ("GetPrivateDDITable" == std::string(lpProcName))
|
else if ("GetPrivateDDITable" == std::string(lpProcName))
|
||||||
{
|
{
|
||||||
g_origGetPrivateDdiTable = reinterpret_cast<decltype(&getPrivateDdiTable)>(
|
g_origGetPrivateDdiTable = reinterpret_cast<decltype(&getPrivateDdiTable)>(
|
||||||
CALL_ORIG_FUNC(GetProcAddress)(hModule, lpProcName));
|
GetProcAddress(hModule, lpProcName));
|
||||||
if (g_origGetPrivateDdiTable)
|
if (g_origGetPrivateDdiTable)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<FARPROC>(&getPrivateDdiTable);
|
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)
|
HRESULT APIENTRY kmtPresent(HANDLE hDevice, D3DKMT_PRESENT* pKMTArgs)
|
||||||
|
@ -174,6 +174,7 @@
|
|||||||
<ClInclude Include="Config\Settings\ConfigTransparency.h" />
|
<ClInclude Include="Config\Settings\ConfigTransparency.h" />
|
||||||
<ClInclude Include="Config\Settings\CpuAffinity.h" />
|
<ClInclude Include="Config\Settings\CpuAffinity.h" />
|
||||||
<ClInclude Include="Config\Settings\CpuAffinityRotation.h" />
|
<ClInclude Include="Config\Settings\CpuAffinityRotation.h" />
|
||||||
|
<ClInclude Include="Config\Settings\CrashDump.h" />
|
||||||
<ClInclude Include="Config\Settings\DepthFormat.h" />
|
<ClInclude Include="Config\Settings\DepthFormat.h" />
|
||||||
<ClInclude Include="Config\Settings\DesktopColorDepth.h" />
|
<ClInclude Include="Config\Settings\DesktopColorDepth.h" />
|
||||||
<ClInclude Include="Config\Settings\DesktopResolution.h" />
|
<ClInclude Include="Config\Settings\DesktopResolution.h" />
|
||||||
|
@ -702,6 +702,9 @@
|
|||||||
<ClInclude Include="Config\Settings\ConfigRows.h">
|
<ClInclude Include="Config\Settings\ConfigRows.h">
|
||||||
<Filter>Header Files\Config\Settings</Filter>
|
<Filter>Header Files\Config\Settings</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Config\Settings\CrashDump.h">
|
||||||
|
<Filter>Header Files\Config\Settings</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Gdi\Gdi.cpp">
|
<ClCompile Include="Gdi\Gdi.cpp">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <DbgHelp.h>
|
||||||
#include <ShellScalingApi.h>
|
#include <ShellScalingApi.h>
|
||||||
#include <timeapi.h>
|
#include <timeapi.h>
|
||||||
#include <Uxtheme.h>
|
#include <Uxtheme.h>
|
||||||
@ -8,8 +9,10 @@
|
|||||||
#include <Common/Hook.h>
|
#include <Common/Hook.h>
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
#include <Common/Path.h>
|
#include <Common/Path.h>
|
||||||
|
#include <Common/ScopedCriticalSection.h>
|
||||||
#include <Common/Time.h>
|
#include <Common/Time.h>
|
||||||
#include <Config/Parser.h>
|
#include <Config/Parser.h>
|
||||||
|
#include <Config/Settings/CrashDump.h>
|
||||||
#include <Config/Settings/DesktopResolution.h>
|
#include <Config/Settings/DesktopResolution.h>
|
||||||
#include <Config/Settings/DpiAwareness.h>
|
#include <Config/Settings/DpiAwareness.h>
|
||||||
#include <Config/Settings/FullscreenMode.h>
|
#include <Config/Settings/FullscreenMode.h>
|
||||||
@ -37,6 +40,9 @@ namespace
|
|||||||
{
|
{
|
||||||
const DWORD DISABLE_MAX_WINDOWED_MODE = 12;
|
const DWORD DISABLE_MAX_WINDOWED_MODE = 12;
|
||||||
|
|
||||||
|
Compat::CriticalSection g_crashDumpCs;
|
||||||
|
std::filesystem::path g_crashDumpPath;
|
||||||
|
|
||||||
template <typename Result, typename... Params>
|
template <typename Result, typename... Params>
|
||||||
using FuncPtr = Result(WINAPI*)(Params...);
|
using FuncPtr = Result(WINAPI*)(Params...);
|
||||||
|
|
||||||
@ -238,6 +244,71 @@ namespace
|
|||||||
|
|
||||||
logDpiAwareness(SetProcessDPIAware(), DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, "SetProcessDPIAware");
|
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) \
|
#define LOAD_ORIG_PROC(proc) \
|
||||||
@ -276,6 +347,25 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||||||
Config::Parser::loadAllConfigFiles(processPath);
|
Config::Parser::loadAllConfigFiles(processPath);
|
||||||
Compat::Log::initLogging(processPath, Config::logLevel.get());
|
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());
|
auto systemPath(Compat::getSystemPath());
|
||||||
if (Compat::isEqual(currentDllPath.parent_path(), systemPath))
|
if (Compat::isEqual(currentDllPath.parent_path(), systemPath))
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user