From b7a4bda3d6b2c18fad834ea768333656a195ff26 Mon Sep 17 00:00:00 2001
From: xezon <4720891+xezon@users.noreply.github.com>
Date: Sat, 14 Jun 2025 22:58:12 +0200
Subject: [PATCH 1/3] [GEN][ZH] Prevent AMD/ATI driver crash on game launch by
temporarily unloading and renaming dbghelp.dll
---
CMakeLists.txt | 1 -
.../Source/WWVegas/WWLib/CMakeLists.txt | 7 +
.../Source/WWVegas/WWLib/DbgHelpGuard.cpp | 63 ++++
.../Source/WWVegas/WWLib/DbgHelpGuard.h | 47 +++
.../Source/WWVegas/WWLib/DbgHelpLoader.cpp | 283 ++++++++++++++++++
.../Source/WWVegas/WWLib/DbgHelpLoader.h | 187 ++++++++++++
.../Source/WWVegas/WWLib/MallocAllocator.h | 129 ++++++++
.../WWVegas/WWLib/ScopedFileRenamer.cpp | 98 ++++++
.../Source/WWVegas/WWLib/ScopedFileRenamer.h | 47 +++
Core/Tools/ImagePacker/CMakeLists.txt | 1 -
Core/Tools/MapCacheBuilder/CMakeLists.txt | 1 -
Core/Tools/PATCHGET/CMakeLists.txt | 1 -
.../Source/Common/System/StackDump.cpp | 122 ++++----
.../Source/WWVegas/WW3D2/dx8wrapper.cpp | 32 +-
Generals/Code/Main/CMakeLists.txt | 1 -
Generals/Code/Tools/GUIEdit/CMakeLists.txt | 1 -
.../Code/Tools/ParticleEditor/CMakeLists.txt | 1 -
Generals/Code/Tools/W3DView/CMakeLists.txt | 1 -
.../Code/Tools/WorldBuilder/CMakeLists.txt | 1 -
.../Source/Common/System/StackDump.cpp | 122 ++++----
.../Source/WWVegas/WW3D2/dx8wrapper.cpp | 32 +-
GeneralsMD/Code/Main/CMakeLists.txt | 1 -
GeneralsMD/Code/Tools/GUIEdit/CMakeLists.txt | 1 -
.../Code/Tools/ParticleEditor/CMakeLists.txt | 1 -
GeneralsMD/Code/Tools/W3DView/CMakeLists.txt | 1 -
.../Code/Tools/WorldBuilder/CMakeLists.txt | 1 -
GeneralsMD/Code/Tools/wdump/CMakeLists.txt | 1 -
cmake/dbghelp.cmake | 7 -
28 files changed, 1007 insertions(+), 184 deletions(-)
create mode 100644 Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
create mode 100644 Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
create mode 100644 Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp
create mode 100644 Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h
create mode 100644 Core/Libraries/Source/WWVegas/WWLib/MallocAllocator.h
create mode 100644 Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp
create mode 100644 Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h
delete mode 100644 cmake/dbghelp.cmake
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b9bb8bf6b..7ef78f39bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,7 +43,6 @@ if((WIN32 OR "${CMAKE_SYSTEM}" MATCHES "Windows") AND ${CMAKE_SIZEOF_VOID_P} EQU
include(cmake/miles.cmake)
include(cmake/bink.cmake)
include(cmake/dx8.cmake)
- include(cmake/dbghelp.cmake)
endif()
# Define a dummy stlport target when not on VC6.
diff --git a/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt b/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt
index 88a0c0b3ab..ad507d6b68 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt
+++ b/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt
@@ -32,6 +32,10 @@ set(WWLIB_SRC
#crcstraw.h
cstraw.cpp
cstraw.h
+ DbgHelpGuard.cpp
+ DbgHelpGuard.h
+ DbgHelpLoader.cpp
+ DbgHelpLoader.h
Except.cpp
Except.h
FastAllocator.cpp
@@ -66,6 +70,7 @@ set(WWLIB_SRC
#lzostraw.cpp
#lzostraw.h
#lzo_conf.h
+ MallocAllocator.h
#md5.cpp
#md5.h
mempool.h
@@ -98,6 +103,8 @@ set(WWLIB_SRC
#regexpr.cpp
#regexpr.h
#search.h
+ ScopedFileRenamer.cpp
+ ScopedFileRenamer.h
sharebuf.h
Signaler.h
simplevec.h
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
new file mode 100644
index 0000000000..9a0acc8214
--- /dev/null
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
@@ -0,0 +1,63 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#include "DbgHelpGuard.h"
+
+#include "DbgHelpLoader.h"
+
+
+DbgHelpGuard::DbgHelpGuard()
+{
+ deactivate();
+}
+
+DbgHelpGuard::~DbgHelpGuard()
+{
+ reactivate();
+}
+
+void DbgHelpGuard::deactivate()
+{
+ DbgHelpLoader::blockLoad();
+
+ if (DbgHelpLoader::isLoadedFromSystem())
+ {
+ // This is ok. Do nothing.
+ }
+ else if (DbgHelpLoader::isLoaded())
+ {
+ DbgHelpLoader::unload();
+ m_wasLoaded = true;
+ m_dbgHelpRenamer.rename("dbghelp.dll", "dbghelp.dll.bak");
+ }
+ else
+ {
+ m_dbgHelpRenamer.rename("dbghelp.dll", "dbghelp.dll.bak");
+ }
+}
+
+void DbgHelpGuard::reactivate()
+{
+ m_dbgHelpRenamer.revert();
+ DbgHelpLoader::unblockLoad();
+
+ if (m_wasLoaded)
+ {
+ DbgHelpLoader::load();
+ }
+}
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
new file mode 100644
index 0000000000..243f4ed1cf
--- /dev/null
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
@@ -0,0 +1,47 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#pragma once
+
+#include "always.h"
+
+#include "ScopedFileRenamer.h"
+
+
+// This class temporarily unloads dbghelp.dll and prevents it from loading during its lifetime.
+// This helps avoid crashing on boot using recent AMD/ATI drivers, which attempt to load and use
+// dbghelp.dll from the game install directory but are unable to do so correctly because
+// the dbghelp.dll that ships with the game is very old and the AMD/ATI code does not handle
+// that correctly. This workaround is not required if the dbghelp.dll was loaded from the system
+// directory.
+
+class DbgHelpGuard
+{
+public:
+
+ DbgHelpGuard();
+ ~DbgHelpGuard();
+
+ void deactivate();
+ void reactivate();
+
+private:
+
+ ScopedFileRenamer m_dbgHelpRenamer;
+ bool m_wasLoaded;
+};
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp
new file mode 100644
index 0000000000..b99ae06be7
--- /dev/null
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp
@@ -0,0 +1,283 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#include "DbgHelpLoader.h"
+
+
+int DbgHelpLoader::BlockLoadCounter = 0;
+DbgHelpLoader* DbgHelpLoader::Inst = NULL;
+
+DbgHelpLoader::DbgHelpLoader()
+ : m_symInitialize(NULL)
+ , m_symCleanup(NULL)
+ , m_symLoadModule(NULL)
+ , m_symUnloadModule(NULL)
+ , m_symGetModuleBase(NULL)
+ , m_symGetSymFromAddr(NULL)
+ , m_symGetLineFromAddr(NULL)
+ , m_symSetOptions(NULL)
+ , m_symFunctionTableAccess(NULL)
+ , m_stackWalk(NULL)
+ , m_dllModule(HMODULE(0))
+ , m_failed(false)
+ , m_loadedFromSystem(false)
+{
+}
+
+DbgHelpLoader::~DbgHelpLoader()
+{
+}
+
+bool DbgHelpLoader::isLoaded()
+{
+ return Inst != NULL && Inst->m_dllModule != HMODULE(0);
+}
+
+bool DbgHelpLoader::isLoadedFromSystem()
+{
+ return Inst != NULL && Inst->m_loadedFromSystem;
+}
+
+void DbgHelpLoader::blockLoad()
+{
+ ++BlockLoadCounter;
+}
+
+bool DbgHelpLoader::unblockLoad()
+{
+ return --BlockLoadCounter == 0;
+}
+
+bool DbgHelpLoader::load()
+{
+ if (BlockLoadCounter > 0)
+ return false;
+
+ if (Inst == NULL)
+ {
+ // Cannot use new/delete here when this is loaded during game memory initialization.
+ void* p = ::malloc(sizeof(DbgHelpLoader));
+ Inst = new (p) DbgHelpLoader();
+ }
+
+ // Optimization: return early if it failed before.
+ if (Inst->m_failed)
+ return false;
+
+ // Try load dbghelp.dll from the system directory first.
+ char dllFilename[MAX_PATH];
+ ::GetSystemDirectoryA(dllFilename, ARRAY_SIZE(dllFilename));
+ strcat(dllFilename, "\\dbghelp.dll");
+
+ Inst->m_dllModule = ::LoadLibraryA(dllFilename);
+ if (Inst->m_dllModule == HMODULE(0))
+ {
+ // Not found. Try load dbghelp.dll from the work directory.
+ Inst->m_dllModule = ::LoadLibraryA("dbghelp.dll");
+ if (Inst->m_dllModule == HMODULE(0))
+ {
+ Inst->m_failed = true;
+ return false;
+ }
+ }
+ else
+ {
+ Inst->m_loadedFromSystem = true;
+ }
+
+ Inst->m_symInitialize = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymInitialize"));
+ Inst->m_symCleanup = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymCleanup"));
+ Inst->m_symLoadModule = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymLoadModule"));
+ Inst->m_symUnloadModule = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymUnloadModule"));
+ Inst->m_symGetModuleBase = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymGetModuleBase"));
+ Inst->m_symGetSymFromAddr = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymGetSymFromAddr"));
+ Inst->m_symGetLineFromAddr = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymGetLineFromAddr"));
+ Inst->m_symSetOptions = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymSetOptions"));
+ Inst->m_symFunctionTableAccess = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "SymFunctionTableAccess"));
+ Inst->m_stackWalk = reinterpret_cast(::GetProcAddress(Inst->m_dllModule, "StackWalk"));
+
+ if (Inst->m_symInitialize == NULL || Inst->m_symCleanup == NULL)
+ {
+ unload();
+ Inst->m_failed = true;
+ return false;
+ }
+
+ return true;
+}
+
+bool DbgHelpLoader::reload()
+{
+ unload();
+ return load();
+}
+
+void DbgHelpLoader::unload()
+{
+ if (Inst == NULL)
+ return;
+
+ while (!Inst->m_initializedProcesses.empty())
+ {
+ symCleanup(*Inst->m_initializedProcesses.begin());
+ }
+
+ if (Inst->m_dllModule != HMODULE(0))
+ {
+ ::FreeLibrary(Inst->m_dllModule);
+ Inst->m_dllModule = HMODULE(0);
+ }
+
+ Inst->~DbgHelpLoader();
+ ::free(Inst);
+ Inst = NULL;
+}
+
+BOOL DbgHelpLoader::symInitialize(
+ HANDLE hProcess,
+ LPSTR UserSearchPath,
+ BOOL fInvadeProcess)
+{
+ if (Inst == NULL)
+ return FALSE;
+
+ if (Inst->m_initializedProcesses.find(hProcess) != Inst->m_initializedProcesses.end())
+ return FALSE;
+
+ if (Inst->m_symInitialize)
+ {
+ if (Inst->m_symInitialize(hProcess, UserSearchPath, fInvadeProcess) != FALSE)
+ {
+ Inst->m_initializedProcesses.insert(hProcess);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL DbgHelpLoader::symCleanup(
+ HANDLE hProcess)
+{
+ if (Inst == NULL)
+ return FALSE;
+
+ // @todo stl::find_and_erase
+ Processes::iterator it = Inst->m_initializedProcesses.find(hProcess);
+ if (it != Inst->m_initializedProcesses.end())
+ Inst->m_initializedProcesses.erase(it);
+
+ if (Inst->m_symCleanup)
+ return Inst->m_symCleanup(hProcess);
+
+ return FALSE;
+}
+
+BOOL DbgHelpLoader::symLoadModule(
+ HANDLE hProcess,
+ HANDLE hFile,
+ LPSTR ImageName,
+ LPSTR ModuleName,
+ DWORD BaseOfDll,
+ DWORD SizeOfDll)
+{
+ if (Inst != NULL && Inst->m_symLoadModule)
+ return Inst->m_symLoadModule(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll);
+
+ return FALSE;
+}
+
+DWORD DbgHelpLoader::symGetModuleBase(
+ HANDLE hProcess,
+ DWORD dwAddr)
+{
+ if (Inst != NULL && Inst->m_symGetModuleBase)
+ return Inst->m_symGetModuleBase(hProcess, dwAddr);
+
+ return 0u;
+}
+
+BOOL DbgHelpLoader::symUnloadModule(
+ HANDLE hProcess,
+ DWORD BaseOfDll)
+{
+ if (Inst != NULL && Inst->m_symUnloadModule)
+ return Inst->m_symUnloadModule(hProcess, BaseOfDll);
+
+ return FALSE;
+}
+
+BOOL DbgHelpLoader::symGetSymFromAddr(
+ HANDLE hProcess,
+ DWORD Address,
+ LPDWORD Displacement,
+ PIMAGEHLP_SYMBOL Symbol)
+{
+ if (Inst != NULL && Inst->m_symGetSymFromAddr)
+ return Inst->m_symGetSymFromAddr(hProcess, Address, Displacement, Symbol);
+
+ return FALSE;
+}
+
+BOOL DbgHelpLoader::symGetLineFromAddr(
+ HANDLE hProcess,
+ DWORD dwAddr,
+ PDWORD pdwDisplacement,
+ PIMAGEHLP_LINE Line)
+{
+ if (Inst != NULL && Inst->m_symGetLineFromAddr)
+ return Inst->m_symGetLineFromAddr(hProcess, dwAddr, pdwDisplacement, Line);
+
+ return FALSE;
+}
+
+DWORD DbgHelpLoader::symSetOptions(
+ DWORD SymOptions)
+{
+ if (Inst != NULL && Inst->m_symSetOptions)
+ return Inst->m_symSetOptions(SymOptions);
+
+ return 0u;
+}
+
+LPVOID DbgHelpLoader::symFunctionTableAccess(
+ HANDLE hProcess,
+ DWORD AddrBase)
+{
+ if (Inst != NULL && Inst->m_symFunctionTableAccess)
+ return Inst->m_symFunctionTableAccess(hProcess, AddrBase);
+
+ return NULL;
+}
+
+BOOL DbgHelpLoader::stackWalk(
+ DWORD MachineType,
+ HANDLE hProcess,
+ HANDLE hThread,
+ LPSTACKFRAME StackFrame,
+ LPVOID ContextRecord,
+ PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
+ PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
+ PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
+ PTRANSLATE_ADDRESS_ROUTINE TranslateAddress)
+{
+ if (Inst != NULL && Inst->m_stackWalk)
+ return Inst->m_stackWalk(MachineType, hProcess, hThread, StackFrame, ContextRecord, ReadMemoryRoutine, FunctionTableAccessRoutine, GetModuleBaseRoutine, TranslateAddress);
+
+ return FALSE;
+}
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h
new file mode 100644
index 0000000000..8b6079e3c8
--- /dev/null
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h
@@ -0,0 +1,187 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#pragma once
+
+#include "always.h"
+
+#include
+#include // Must be included after Windows.h
+#include
+
+#include "MallocAllocator.h"
+
+// This static class can load and unload dbghelp.dll
+// Internally it must not use new and delete because it can be created during game memory initialization.
+
+class DbgHelpLoader
+{
+private:
+
+ static int BlockLoadCounter;
+ static DbgHelpLoader* Inst; // Is singleton class
+
+ DbgHelpLoader();
+ ~DbgHelpLoader();
+
+public:
+
+ // Returns whether dbghelp.dll is loaded
+ static bool isLoaded();
+
+ // Returns whether dbghelp.dll is loaded from the system directory
+ static bool isLoadedFromSystem();
+
+ // Blocks loading a dbghelp.dll
+ static void blockLoad();
+
+ // Unblocks loading a dbghelp.dll. Returns true if unblocked.
+ static bool unblockLoad();
+
+ static bool load();
+ static bool reload();
+ static void unload();
+
+ static BOOL WINAPI symInitialize(
+ HANDLE hProcess,
+ LPSTR UserSearchPath,
+ BOOL fInvadeProcess);
+
+ static BOOL WINAPI symCleanup(
+ HANDLE hProcess);
+
+ static BOOL WINAPI symLoadModule(
+ HANDLE hProcess,
+ HANDLE hFile,
+ LPSTR ImageName,
+ LPSTR ModuleName,
+ DWORD BaseOfDll,
+ DWORD SizeOfDll);
+
+ static DWORD WINAPI symGetModuleBase(
+ HANDLE hProcess,
+ DWORD dwAddr);
+
+ static BOOL WINAPI symUnloadModule(
+ HANDLE hProcess,
+ DWORD BaseOfDll);
+
+ static BOOL WINAPI symGetSymFromAddr(
+ HANDLE hProcess,
+ DWORD Address,
+ LPDWORD Displacement,
+ PIMAGEHLP_SYMBOL Symbol);
+
+ static BOOL WINAPI symGetLineFromAddr(
+ HANDLE hProcess,
+ DWORD dwAddr,
+ PDWORD pdwDisplacement,
+ PIMAGEHLP_LINE Line);
+
+ static DWORD WINAPI symSetOptions(
+ DWORD SymOptions);
+
+ static LPVOID WINAPI symFunctionTableAccess(
+ HANDLE hProcess,
+ DWORD AddrBase);
+
+ static BOOL WINAPI stackWalk(
+ DWORD MachineType,
+ HANDLE hProcess,
+ HANDLE hThread,
+ LPSTACKFRAME StackFrame,
+ LPVOID ContextRecord,
+ PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
+ PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
+ PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
+ PTRANSLATE_ADDRESS_ROUTINE TranslateAddress);
+
+private:
+
+ typedef BOOL (WINAPI *SymInitialize_t) (
+ HANDLE hProcess,
+ LPSTR UserSearchPath,
+ BOOL fInvadeProcess);
+
+ typedef BOOL (WINAPI *SymCleanup_t) (
+ HANDLE hProcess);
+
+ typedef BOOL (WINAPI *SymLoadModule_t) (
+ HANDLE hProcess,
+ HANDLE hFile,
+ LPSTR ImageName,
+ LPSTR ModuleName,
+ DWORD BaseOfDll,
+ DWORD SizeOfDll);
+
+ typedef DWORD (WINAPI *SymGetModuleBase_t) (
+ HANDLE hProcess,
+ DWORD dwAddr);
+
+ typedef BOOL (WINAPI *SymUnloadModule_t) (
+ HANDLE hProcess,
+ DWORD BaseOfDll);
+
+ typedef BOOL (WINAPI *SymGetSymFromAddr_t) (
+ HANDLE hProcess,
+ DWORD Address,
+ LPDWORD Displacement,
+ PIMAGEHLP_SYMBOL Symbol);
+
+ typedef BOOL (WINAPI* SymGetLineFromAddr_t) (
+ HANDLE hProcess,
+ DWORD dwAddr,
+ PDWORD pdwDisplacement,
+ PIMAGEHLP_LINE Line);
+
+ typedef DWORD (WINAPI *SymSetOptions_t) (
+ DWORD SymOptions);
+
+ typedef LPVOID (WINAPI *SymFunctionTableAccess_t) (
+ HANDLE hProcess,
+ DWORD AddrBase);
+
+ typedef BOOL (WINAPI *StackWalk_t) (
+ DWORD MachineType,
+ HANDLE hProcess,
+ HANDLE hThread,
+ LPSTACKFRAME StackFrame,
+ LPVOID ContextRecord,
+ PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
+ PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
+ PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
+ PTRANSLATE_ADDRESS_ROUTINE TranslateAddress);
+
+ SymInitialize_t m_symInitialize;
+ SymCleanup_t m_symCleanup;
+ SymLoadModule_t m_symLoadModule;
+ SymUnloadModule_t m_symUnloadModule;
+ SymGetModuleBase_t m_symGetModuleBase;
+ SymGetSymFromAddr_t m_symGetSymFromAddr;
+ SymGetLineFromAddr_t m_symGetLineFromAddr;
+ SymSetOptions_t m_symSetOptions;
+ SymFunctionTableAccess_t m_symFunctionTableAccess;
+ StackWalk_t m_stackWalk;
+
+ typedef std::set, stl::malloc_allocator > Processes;
+
+ Processes m_initializedProcesses;
+ HMODULE m_dllModule;
+ bool m_failed;
+ bool m_loadedFromSystem;
+};
diff --git a/Core/Libraries/Source/WWVegas/WWLib/MallocAllocator.h b/Core/Libraries/Source/WWVegas/WWLib/MallocAllocator.h
new file mode 100644
index 0000000000..e465b0ad5d
--- /dev/null
+++ b/Core/Libraries/Source/WWVegas/WWLib/MallocAllocator.h
@@ -0,0 +1,129 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#pragma once
+
+#include // malloc, free
+#include // std::size_t, std::ptrdiff_t
+#include // std::bad_alloc
+
+
+namespace stl
+{
+
+// STL allocator that uses malloc and free. Useful if allocations are meant to bypass new and delete.
+
+template
+class malloc_allocator
+{
+public:
+
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ template
+ struct rebind
+ {
+ typedef malloc_allocator other;
+ };
+
+ malloc_allocator() throw() {}
+
+#if !(defined(_MSC_VER) && _MSC_VER < 1300)
+ malloc_allocator(const malloc_allocator&) throw() {}
+#endif
+
+ template
+ malloc_allocator(const malloc_allocator&) throw() {}
+
+ ~malloc_allocator() throw() {}
+
+ pointer address(reference x) const { return &x; }
+ const_pointer address(const_reference x) const { return &x; }
+
+ pointer allocate(size_type n, const void* = 0)
+ {
+ if (n > max_size())
+ throw std::bad_alloc();
+
+ void* p = ::malloc(n * sizeof(T));
+ if (!p)
+ throw std::bad_alloc();
+ return static_cast(p);
+ }
+
+ void deallocate(pointer p, size_type)
+ {
+ ::free(p);
+ }
+
+ void construct(pointer p, const T& val)
+ {
+ new (static_cast(p)) T(val);
+ }
+
+ void destroy(pointer p)
+ {
+ p->~T();
+ }
+
+ size_type max_size() const throw()
+ {
+ return ~size_type(0) / sizeof(T);
+ }
+};
+
+// Allocators of same type are always equal
+template
+bool operator==(const malloc_allocator&, const malloc_allocator&) throw() {
+ return true;
+}
+
+template
+bool operator!=(const malloc_allocator&, const malloc_allocator&) throw() {
+ return false;
+}
+
+} // namespace stl
+
+
+#if defined(USING_STLPORT)
+
+// This tells STLport how to rebind malloc_allocator
+namespace std
+{
+ template
+ struct __stl_alloc_rebind_helper;
+
+ template
+ inline stl::malloc_allocator& __stl_alloc_rebind(stl::malloc_allocator& a, const Tp2*) {
+ return *reinterpret_cast*>(&a);
+ }
+
+ template
+ inline const stl::malloc_allocator& __stl_alloc_rebind(const stl::malloc_allocator& a, const Tp2*) {
+ return *reinterpret_cast*>(&a);
+ }
+}
+
+#endif
diff --git a/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp b/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp
new file mode 100644
index 0000000000..d13c089426
--- /dev/null
+++ b/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp
@@ -0,0 +1,98 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#include "ScopedFileRenamer.h"
+
+
+ScopedFileRenamer::ScopedFileRenamer()
+ : m_file(NULL)
+{
+}
+
+ScopedFileRenamer::ScopedFileRenamer(const char* oldName, const char* newName)
+ : m_file(NULL)
+{
+ this->rename(oldName, newName);
+}
+
+ScopedFileRenamer::~ScopedFileRenamer()
+{
+ revert();
+}
+
+bool ScopedFileRenamer::rename(const char* oldName, const char* newName)
+{
+ revert();
+
+ m_oldName = oldName;
+ m_newName = newName;
+
+ if (0 == ::rename(m_oldName.c_str(), m_newName.c_str()))
+ {
+ // Creates an empty *.tmp dummy file to remember that this program has renamed the file.
+ // If the program would crash before the file was renamed back to the previous name, then
+ // the rename condition will be able to recover the next time this code runs successfully.
+ std::string tmpFilename = createTmpName();
+ m_file = ::fopen(tmpFilename.c_str(), "wb");
+
+ return true;
+ }
+
+ return false;
+}
+
+bool ScopedFileRenamer::revert()
+{
+ if (m_oldName.empty())
+ return false;
+
+ bool success = false;
+ std::string tmpName;
+
+ if (m_file == NULL)
+ {
+ tmpName = createTmpName();
+ m_file = ::fopen(tmpName.c_str(), "rb");
+ }
+
+ if (m_file != NULL)
+ {
+ ::fclose(m_file);
+ m_file = NULL;
+
+ if (0 == ::rename(m_newName.c_str(), m_oldName.c_str()))
+ success = true;
+
+ if (tmpName.empty())
+ tmpName = createTmpName();
+
+ ::remove(tmpName.c_str());
+ }
+
+ m_oldName.clear();
+ m_newName.clear();
+
+ return success;
+}
+
+std::string ScopedFileRenamer::createTmpName() const
+{
+ std::string tmpFilename = m_oldName;
+ tmpFilename.append(".tmp");
+ return tmpFilename;
+}
diff --git a/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h b/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h
new file mode 100644
index 0000000000..594192eceb
--- /dev/null
+++ b/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h
@@ -0,0 +1,47 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#pragma once
+
+#include "always.h"
+
+#include
+#include
+
+
+class ScopedFileRenamer
+{
+public:
+
+ ScopedFileRenamer();
+ ScopedFileRenamer(const char* oldName, const char* newName);
+ ~ScopedFileRenamer();
+
+ bool rename(const char* oldName, const char* newName);
+ bool revert();
+
+private:
+
+ std::string createTmpName() const;
+
+private:
+
+ std::string m_oldName;
+ std::string m_newName;
+ FILE* m_file;
+};
diff --git a/Core/Tools/ImagePacker/CMakeLists.txt b/Core/Tools/ImagePacker/CMakeLists.txt
index 3b30d71bb9..f1f52a59ed 100644
--- a/Core/Tools/ImagePacker/CMakeLists.txt
+++ b/Core/Tools/ImagePacker/CMakeLists.txt
@@ -30,7 +30,6 @@ target_link_libraries(corei_imagepacker INTERFACE
comctl32
core_debug
core_profile
- dbghelplib
imm32
vfw32
winmm
diff --git a/Core/Tools/MapCacheBuilder/CMakeLists.txt b/Core/Tools/MapCacheBuilder/CMakeLists.txt
index 5d390853a8..bdb38951a5 100644
--- a/Core/Tools/MapCacheBuilder/CMakeLists.txt
+++ b/Core/Tools/MapCacheBuilder/CMakeLists.txt
@@ -17,7 +17,6 @@ target_link_libraries(corei_mapcachebuilder INTERFACE
comctl32
core_debug
core_profile
- dbghelplib
imm32
vfw32
winmm
diff --git a/Core/Tools/PATCHGET/CMakeLists.txt b/Core/Tools/PATCHGET/CMakeLists.txt
index 265a74c785..d2822c3ddb 100644
--- a/Core/Tools/PATCHGET/CMakeLists.txt
+++ b/Core/Tools/PATCHGET/CMakeLists.txt
@@ -25,7 +25,6 @@ target_link_libraries(corei_patchgrabber INTERFACE
comctl32
core_debug
core_profile
- dbghelplib
gamespy::gamespy
imm32
vfw32
diff --git a/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp b/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp
index 1c0a319e14..f5bcc80893 100644
--- a/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp
+++ b/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp
@@ -31,6 +31,7 @@
#include "Common/StackDump.h"
#include "Common/Debug.h"
+#include "DbgHelpLoader.h"
//*****************************************************************************
// Prototypes
@@ -45,14 +46,6 @@ void WriteStackLine(void*address, void (*callback)(const char*));
// Mis-named globals :-)
//*****************************************************************************
static CONTEXT gsContext;
-static Bool gsInit=FALSE;
-
-BOOL (__stdcall *gsSymGetLineFromAddr)(
- IN HANDLE hProcess,
- IN DWORD dwAddr,
- OUT PDWORD pdwDisplacement,
- OUT PIMAGEHLP_LINE Line
- );
//*****************************************************************************
@@ -72,7 +65,8 @@ void StackDump(void (*callback)(const char*))
callback = StackDumpDefaultHandler;
}
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
DWORD myeip,myesp,myebp;
@@ -101,7 +95,8 @@ void StackDumpFromContext(DWORD eip,DWORD esp,DWORD ebp, void (*callback)(const
callback = StackDumpDefaultHandler;
}
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
MakeStackTrace(eip,esp,ebp, 0, callback);
}
@@ -111,27 +106,20 @@ void StackDumpFromContext(DWORD eip,DWORD esp,DWORD ebp, void (*callback)(const
//*****************************************************************************
BOOL InitSymbolInfo()
{
- if (gsInit == TRUE)
+ if (DbgHelpLoader::isLoaded())
return TRUE;
- gsInit = TRUE;
+ if (!DbgHelpLoader::load())
+ return FALSE;
atexit(UninitSymbolInfo);
- // See if we have the line from address function
- // We use GetProcAddress to stop link failures at dll loadup
- HINSTANCE hInstDebugHlp = GetModuleHandle("dbghelp.dll");
-
- gsSymGetLineFromAddr = (BOOL (__stdcall *)( IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_LINE))
- GetProcAddress(hInstDebugHlp , "SymGetLineFromAddr");
-
char pathname[_MAX_PATH+1];
char drive[10];
char directory[_MAX_PATH+1];
HANDLE process;
-
- ::SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST);
+ DbgHelpLoader::symSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST);
process = GetCurrentProcess();
@@ -145,18 +133,18 @@ BOOL InitSymbolInfo()
// append the current directory to build a search path for SymInit
::lstrcat(pathname, ";.;");
- if(::SymInitialize(process, pathname, FALSE))
+ if(DbgHelpLoader::symInitialize(process, pathname, FALSE))
{
// regenerate the name of the app
::GetModuleFileName(NULL, pathname, _MAX_PATH);
- if(::SymLoadModule(process, NULL, pathname, NULL, 0, 0))
+ if(DbgHelpLoader::symLoadModule(process, NULL, pathname, NULL, 0, 0))
{
//Load any other relevant modules (ie dlls) here
return TRUE;
}
- ::SymCleanup(process);
}
+ DbgHelpLoader::unload();
return(FALSE);
}
@@ -165,14 +153,7 @@ BOOL InitSymbolInfo()
//*****************************************************************************
void UninitSymbolInfo(void)
{
- if (gsInit == FALSE)
- {
- return;
- }
-
- gsInit = FALSE;
-
- ::SymCleanup(GetCurrentProcess());
+ DbgHelpLoader::unload();
}
@@ -217,14 +198,14 @@ stack_frame.AddrFrame.Offset = myebp;
unsigned int skip = skipFrames;
while (b_ret&&skip)
{
- b_ret = StackWalk( IMAGE_FILE_MACHINE_I386,
+ b_ret = DbgHelpLoader::stackWalk( IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL);
skip--;
}
@@ -233,14 +214,14 @@ stack_frame.AddrFrame.Offset = myebp;
while(b_ret&&skip)
{
- b_ret = StackWalk( IMAGE_FILE_MACHINE_I386,
+ b_ret = DbgHelpLoader::stackWalk( IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL);
@@ -256,7 +237,9 @@ stack_frame.AddrFrame.Offset = myebp;
//*****************************************************************************
void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* linenumber, unsigned int* address)
{
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
+
if (name)
{
strcpy(name, "");
@@ -285,8 +268,8 @@ void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* l
psymbol->SizeOfStruct = sizeof(symbol_buffer);
psymbol->MaxNameLength = 512;
- if (SymGetSymFromAddr(process, (DWORD) pointer, &displacement, psymbol))
- {
+ if (DbgHelpLoader::symGetSymFromAddr(process, (DWORD) pointer, &displacement, psymbol))
+ {
if (name)
{
strcpy(name, psymbol->Name);
@@ -294,32 +277,27 @@ void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* l
}
// Get line now
- if (gsSymGetLineFromAddr)
- {
- // Unsupported for win95/98 at least with my current dbghelp.dll
- IMAGEHLP_LINE line;
- memset(&line,0,sizeof(line));
- line.SizeOfStruct = sizeof(line);
+ IMAGEHLP_LINE line;
+ memset(&line,0,sizeof(line));
+ line.SizeOfStruct = sizeof(line);
-
- if (gsSymGetLineFromAddr(process, (DWORD) pointer, &displacement, &line))
+ if (DbgHelpLoader::symGetLineFromAddr(process, (DWORD) pointer, &displacement, &line))
+ {
+ if (filename)
+ {
+ strcpy(filename, line.FileName);
+ }
+ if (linenumber)
{
- if (filename)
- {
- strcpy(filename, line.FileName);
- }
- if (linenumber)
- {
- *linenumber = (unsigned int)line.LineNumber;
- }
- if (address)
- {
- *address = (unsigned int)line.Address;
- }
- }
+ *linenumber = (unsigned int)line.LineNumber;
+ }
+ if (address)
+ {
+ *address = (unsigned int)line.Address;
+ }
}
- }
+ }
}
@@ -328,7 +306,8 @@ void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* l
//*****************************************************************************
void FillStackAddresses(void**addresses, unsigned int count, unsigned int skip)
{
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
STACKFRAME stack_frame;
@@ -378,28 +357,28 @@ stack_frame.AddrFrame.Offset = myebp;
// Skip some?
while (stillgoing&&skip)
{
- stillgoing = StackWalk(IMAGE_FILE_MACHINE_I386,
+ stillgoing = DbgHelpLoader::stackWalk(IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL) != 0;
skip--;
}
while(stillgoing&&count)
{
- stillgoing = StackWalk(IMAGE_FILE_MACHINE_I386,
+ stillgoing = DbgHelpLoader::stackWalk(IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL) != 0;
if (stillgoing)
{
@@ -438,7 +417,8 @@ void StackDumpFromAddresses(void**addresses, unsigned int count, void (*callback
callback = StackDumpDefaultHandler;
}
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
while ((count--) && (*addresses!=NULL))
{
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
index ee887eb836..a12fb92e04 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
@@ -81,6 +81,7 @@
#include "dx8texman.h"
#include "bound.h"
#include "dx8webbrowser.h"
+#include "DbgHelpGuard.h"
const int DEFAULT_RESOLUTION_WIDTH = 640;
@@ -312,7 +313,12 @@ bool DX8Wrapper::Init(void * hwnd, bool lite)
** Create the D3D interface object
*/
WWDEBUG_SAY(("Create Direct3D8\n"));
- D3DInterface = Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases...
+ {
+ // TheSuperHackers @bugfix xezon 13/06/2025 Temporarily unload dbghelp.dll and prevent it from loading.
+ DbgHelpGuard dbgHelpGuard;
+
+ D3DInterface = Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases...
+ }
if (D3DInterface == NULL) {
return(false);
}
@@ -560,15 +566,21 @@ bool DX8Wrapper::Create_Device(void)
Vertex_Processing_Behavior|=D3DCREATE_FPU_PRESERVE;
#endif
- HRESULT hr=D3DInterface->CreateDevice
- (
- CurRenderDevice,
- WW3D_DEVTYPE,
- _Hwnd,
- Vertex_Processing_Behavior,
- &_PresentParameters,
- &D3DDevice
- );
+ HRESULT hr;
+ {
+ // TheSuperHackers @bugfix xezon 13/06/2025 Temporarily unload dbghelp.dll and prevent it from loading.
+ DbgHelpGuard dbgHelpGuard;
+
+ hr=D3DInterface->CreateDevice
+ (
+ CurRenderDevice,
+ WW3D_DEVTYPE,
+ _Hwnd,
+ Vertex_Processing_Behavior,
+ &_PresentParameters,
+ &D3DDevice
+ );
+ }
if (FAILED(hr))
{
diff --git a/Generals/Code/Main/CMakeLists.txt b/Generals/Code/Main/CMakeLists.txt
index b4cf515569..0dcc45a271 100644
--- a/Generals/Code/Main/CMakeLists.txt
+++ b/Generals/Code/Main/CMakeLists.txt
@@ -12,7 +12,6 @@ target_link_libraries(g_generals PRIVATE
comctl32
d3d8
d3dx8
- dbghelplib
dinput8
dxguid
g_gameengine
diff --git a/Generals/Code/Tools/GUIEdit/CMakeLists.txt b/Generals/Code/Tools/GUIEdit/CMakeLists.txt
index 5a7b0eb877..c347a19ad7 100644
--- a/Generals/Code/Tools/GUIEdit/CMakeLists.txt
+++ b/Generals/Code/Tools/GUIEdit/CMakeLists.txt
@@ -49,7 +49,6 @@ target_link_libraries(g_guiedit PRIVATE
benchmark
comctl32
d3d8lib
- dbghelplib
g_gameengine
g_gameenginedevice
g_wwvegas
diff --git a/Generals/Code/Tools/ParticleEditor/CMakeLists.txt b/Generals/Code/Tools/ParticleEditor/CMakeLists.txt
index bf7005ea58..0ea7325438 100644
--- a/Generals/Code/Tools/ParticleEditor/CMakeLists.txt
+++ b/Generals/Code/Tools/ParticleEditor/CMakeLists.txt
@@ -42,7 +42,6 @@ target_link_libraries(g_particleeditor PRIVATE
corei_libraries_source_wwvegas
corei_libraries_source_wwvegas_wwlib
d3d8lib
- dbghelplib
gi_gameengine_include
gi_always
gi_libraries_source_wwvegas
diff --git a/Generals/Code/Tools/W3DView/CMakeLists.txt b/Generals/Code/Tools/W3DView/CMakeLists.txt
index 80ab604011..7a3f14db37 100644
--- a/Generals/Code/Tools/W3DView/CMakeLists.txt
+++ b/Generals/Code/Tools/W3DView/CMakeLists.txt
@@ -8,7 +8,6 @@ target_link_libraries(g_w3dview PRIVATE
d3d8
d3d8lib
d3dx8
- dbghelplib
imm32
milesstub
Version
diff --git a/Generals/Code/Tools/WorldBuilder/CMakeLists.txt b/Generals/Code/Tools/WorldBuilder/CMakeLists.txt
index 325820e235..17c9f5a314 100644
--- a/Generals/Code/Tools/WorldBuilder/CMakeLists.txt
+++ b/Generals/Code/Tools/WorldBuilder/CMakeLists.txt
@@ -206,7 +206,6 @@ target_compile_definitions(g_worldbuilder PRIVATE _AFXDLL)
target_link_libraries(g_worldbuilder PRIVATE
d3d8lib
- dbghelplib
core_browserdispatch
g_gameengine
g_gameenginedevice
diff --git a/GeneralsMD/Code/GameEngine/Source/Common/System/StackDump.cpp b/GeneralsMD/Code/GameEngine/Source/Common/System/StackDump.cpp
index a0ed36025f..1364a34953 100644
--- a/GeneralsMD/Code/GameEngine/Source/Common/System/StackDump.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/Common/System/StackDump.cpp
@@ -31,6 +31,7 @@
#include "Common/StackDump.h"
#include "Common/Debug.h"
+#include "DbgHelpLoader.h"
//*****************************************************************************
// Prototypes
@@ -45,14 +46,6 @@ void WriteStackLine(void*address, void (*callback)(const char*));
// Mis-named globals :-)
//*****************************************************************************
static CONTEXT gsContext;
-static Bool gsInit=FALSE;
-
-BOOL (__stdcall *gsSymGetLineFromAddr)(
- IN HANDLE hProcess,
- IN DWORD dwAddr,
- OUT PDWORD pdwDisplacement,
- OUT PIMAGEHLP_LINE Line
- );
//*****************************************************************************
@@ -72,7 +65,8 @@ void StackDump(void (*callback)(const char*))
callback = StackDumpDefaultHandler;
}
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
DWORD myeip,myesp,myebp;
@@ -101,7 +95,8 @@ void StackDumpFromContext(DWORD eip,DWORD esp,DWORD ebp, void (*callback)(const
callback = StackDumpDefaultHandler;
}
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
MakeStackTrace(eip,esp,ebp, 0, callback);
}
@@ -111,27 +106,20 @@ void StackDumpFromContext(DWORD eip,DWORD esp,DWORD ebp, void (*callback)(const
//*****************************************************************************
BOOL InitSymbolInfo()
{
- if (gsInit == TRUE)
+ if (DbgHelpLoader::isLoaded())
return TRUE;
- gsInit = TRUE;
+ if (!DbgHelpLoader::load())
+ return FALSE;
atexit(UninitSymbolInfo);
- // See if we have the line from address function
- // We use GetProcAddress to stop link failures at dll loadup
- HINSTANCE hInstDebugHlp = GetModuleHandle("dbghelp.dll");
-
- gsSymGetLineFromAddr = (BOOL (__stdcall *)( IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_LINE))
- GetProcAddress(hInstDebugHlp , "SymGetLineFromAddr");
-
char pathname[_MAX_PATH+1];
char drive[10];
char directory[_MAX_PATH+1];
HANDLE process;
-
- ::SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST);
+ DbgHelpLoader::symSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST);
process = GetCurrentProcess();
@@ -145,18 +133,18 @@ BOOL InitSymbolInfo()
// append the current directory to build a search path for SymInit
::lstrcat(pathname, ";.;");
- if(::SymInitialize(process, pathname, FALSE))
+ if(DbgHelpLoader::symInitialize(process, pathname, FALSE))
{
// regenerate the name of the app
::GetModuleFileName(NULL, pathname, _MAX_PATH);
- if(::SymLoadModule(process, NULL, pathname, NULL, 0, 0))
+ if(DbgHelpLoader::symLoadModule(process, NULL, pathname, NULL, 0, 0))
{
//Load any other relevant modules (ie dlls) here
return TRUE;
}
- ::SymCleanup(process);
}
+ DbgHelpLoader::unload();
return(FALSE);
}
@@ -165,14 +153,7 @@ BOOL InitSymbolInfo()
//*****************************************************************************
void UninitSymbolInfo(void)
{
- if (gsInit == FALSE)
- {
- return;
- }
-
- gsInit = FALSE;
-
- ::SymCleanup(GetCurrentProcess());
+ DbgHelpLoader::unload();
}
@@ -217,14 +198,14 @@ stack_frame.AddrFrame.Offset = myebp;
unsigned int skip = skipFrames;
while (b_ret&&skip)
{
- b_ret = StackWalk( IMAGE_FILE_MACHINE_I386,
+ b_ret = DbgHelpLoader::stackWalk( IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL);
skip--;
}
@@ -233,14 +214,14 @@ stack_frame.AddrFrame.Offset = myebp;
while(b_ret&&skip)
{
- b_ret = StackWalk( IMAGE_FILE_MACHINE_I386,
+ b_ret = DbgHelpLoader::stackWalk( IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL);
@@ -256,7 +237,9 @@ stack_frame.AddrFrame.Offset = myebp;
//*****************************************************************************
void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* linenumber, unsigned int* address)
{
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
+
if (name)
{
strcpy(name, "");
@@ -285,8 +268,8 @@ void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* l
psymbol->SizeOfStruct = sizeof(symbol_buffer);
psymbol->MaxNameLength = 512;
- if (SymGetSymFromAddr(process, (DWORD) pointer, &displacement, psymbol))
- {
+ if (DbgHelpLoader::symGetSymFromAddr(process, (DWORD) pointer, &displacement, psymbol))
+ {
if (name)
{
strcpy(name, psymbol->Name);
@@ -294,32 +277,27 @@ void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* l
}
// Get line now
- if (gsSymGetLineFromAddr)
- {
- // Unsupported for win95/98 at least with my current dbghelp.dll
- IMAGEHLP_LINE line;
- memset(&line,0,sizeof(line));
- line.SizeOfStruct = sizeof(line);
+ IMAGEHLP_LINE line;
+ memset(&line,0,sizeof(line));
+ line.SizeOfStruct = sizeof(line);
-
- if (gsSymGetLineFromAddr(process, (DWORD) pointer, &displacement, &line))
+ if (DbgHelpLoader::symGetLineFromAddr(process, (DWORD) pointer, &displacement, &line))
+ {
+ if (filename)
+ {
+ strcpy(filename, line.FileName);
+ }
+ if (linenumber)
{
- if (filename)
- {
- strcpy(filename, line.FileName);
- }
- if (linenumber)
- {
- *linenumber = (unsigned int)line.LineNumber;
- }
- if (address)
- {
- *address = (unsigned int)line.Address;
- }
- }
+ *linenumber = (unsigned int)line.LineNumber;
+ }
+ if (address)
+ {
+ *address = (unsigned int)line.Address;
+ }
}
- }
+ }
}
@@ -328,7 +306,8 @@ void GetFunctionDetails(void *pointer, char*name, char*filename, unsigned int* l
//*****************************************************************************
void FillStackAddresses(void**addresses, unsigned int count, unsigned int skip)
{
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
STACKFRAME stack_frame;
@@ -378,28 +357,28 @@ stack_frame.AddrFrame.Offset = myebp;
// Skip some?
while (stillgoing&&skip)
{
- stillgoing = StackWalk(IMAGE_FILE_MACHINE_I386,
+ stillgoing = DbgHelpLoader::stackWalk(IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL) != 0;
skip--;
}
while(stillgoing&&count)
{
- stillgoing = StackWalk(IMAGE_FILE_MACHINE_I386,
+ stillgoing = DbgHelpLoader::stackWalk(IMAGE_FILE_MACHINE_I386,
process,
thread,
&stack_frame,
NULL, //&gsContext,
NULL,
- SymFunctionTableAccess,
- SymGetModuleBase,
+ DbgHelpLoader::symFunctionTableAccess,
+ DbgHelpLoader::symGetModuleBase,
NULL) != 0;
if (stillgoing)
{
@@ -438,7 +417,8 @@ void StackDumpFromAddresses(void**addresses, unsigned int count, void (*callback
callback = StackDumpDefaultHandler;
}
- InitSymbolInfo();
+ if (!InitSymbolInfo())
+ return;
while ((count--) && (*addresses!=NULL))
{
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
index 2a9b3cf063..4455fcbf68 100644
--- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
+++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
@@ -85,6 +85,7 @@
#include "dx8texman.h"
#include "bound.h"
#include "dx8webbrowser.h"
+#include "DbgHelpGuard.h"
#include "shdlib.h"
@@ -331,7 +332,12 @@ bool DX8Wrapper::Init(void * hwnd, bool lite)
** Create the D3D interface object
*/
WWDEBUG_SAY(("Create Direct3D8\n"));
- D3DInterface = Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases...
+ {
+ // TheSuperHackers @bugfix xezon 13/06/2025 Temporarily unload dbghelp.dll and prevent it from loading.
+ DbgHelpGuard dbgHelpGuard;
+
+ D3DInterface = Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases...
+ }
if (D3DInterface == NULL) {
return(false);
}
@@ -592,15 +598,21 @@ bool DX8Wrapper::Create_Device(void)
Vertex_Processing_Behavior|=D3DCREATE_FPU_PRESERVE;
#endif
- HRESULT hr=D3DInterface->CreateDevice
- (
- CurRenderDevice,
- WW3D_DEVTYPE,
- _Hwnd,
- Vertex_Processing_Behavior,
- &_PresentParameters,
- &D3DDevice
- );
+ HRESULT hr;
+ {
+ // TheSuperHackers @bugfix xezon 13/06/2025 Temporarily unload dbghelp.dll and prevent it from loading.
+ DbgHelpGuard dbgHelpGuard;
+
+ hr=D3DInterface->CreateDevice
+ (
+ CurRenderDevice,
+ WW3D_DEVTYPE,
+ _Hwnd,
+ Vertex_Processing_Behavior,
+ &_PresentParameters,
+ &D3DDevice
+ );
+ }
if (FAILED(hr))
{
diff --git a/GeneralsMD/Code/Main/CMakeLists.txt b/GeneralsMD/Code/Main/CMakeLists.txt
index 2ef80b3e87..f6eabb5ffd 100644
--- a/GeneralsMD/Code/Main/CMakeLists.txt
+++ b/GeneralsMD/Code/Main/CMakeLists.txt
@@ -14,7 +14,6 @@ target_link_libraries(z_generals PRIVATE
core_profile
d3d8
d3dx8
- dbghelplib
dinput8
dxguid
imm32
diff --git a/GeneralsMD/Code/Tools/GUIEdit/CMakeLists.txt b/GeneralsMD/Code/Tools/GUIEdit/CMakeLists.txt
index e401d8d335..dc0f0b8d63 100644
--- a/GeneralsMD/Code/Tools/GUIEdit/CMakeLists.txt
+++ b/GeneralsMD/Code/Tools/GUIEdit/CMakeLists.txt
@@ -51,7 +51,6 @@ target_link_libraries(z_guiedit PRIVATE
core_debug
core_profile
d3d8lib
- dbghelplib
imm32
stlport
vfw32
diff --git a/GeneralsMD/Code/Tools/ParticleEditor/CMakeLists.txt b/GeneralsMD/Code/Tools/ParticleEditor/CMakeLists.txt
index 0b410f3470..4d09c98ec2 100644
--- a/GeneralsMD/Code/Tools/ParticleEditor/CMakeLists.txt
+++ b/GeneralsMD/Code/Tools/ParticleEditor/CMakeLists.txt
@@ -42,7 +42,6 @@ target_link_libraries(z_particleeditor PRIVATE
corei_libraries_source_wwvegas
corei_libraries_source_wwvegas_wwlib
d3d8lib
- dbghelplib
imm32
core_config
stlport
diff --git a/GeneralsMD/Code/Tools/W3DView/CMakeLists.txt b/GeneralsMD/Code/Tools/W3DView/CMakeLists.txt
index 7225e63bd5..9f321bc93d 100644
--- a/GeneralsMD/Code/Tools/W3DView/CMakeLists.txt
+++ b/GeneralsMD/Code/Tools/W3DView/CMakeLists.txt
@@ -8,7 +8,6 @@ target_link_libraries(z_w3dview PRIVATE
d3d8
d3d8lib
d3dx8
- dbghelplib
imm32
milesstub
Version
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt b/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt
index c24f97e585..ff7c99e375 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt
+++ b/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt
@@ -213,7 +213,6 @@ target_link_libraries(z_worldbuilder PRIVATE
core_debug
core_profile
d3d8lib
- dbghelplib
imm32
vfw32
winmm
diff --git a/GeneralsMD/Code/Tools/wdump/CMakeLists.txt b/GeneralsMD/Code/Tools/wdump/CMakeLists.txt
index a363e40260..65d190703e 100644
--- a/GeneralsMD/Code/Tools/wdump/CMakeLists.txt
+++ b/GeneralsMD/Code/Tools/wdump/CMakeLists.txt
@@ -21,7 +21,6 @@ target_link_libraries(z_wdump PRIVATE
core_config
core_utility
core_wwstub # avoid linking GameEngine
- dbghelplib
imm32
vfw32
winmm
diff --git a/cmake/dbghelp.cmake b/cmake/dbghelp.cmake
deleted file mode 100644
index 7940400e3e..0000000000
--- a/cmake/dbghelp.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-FetchContent_Declare(
- dbghelp
- GIT_REPOSITORY https://github.com/TheSuperHackers/dbghelp-import-lib.git
- GIT_TAG afeb423d4597167c8fa94215f4574f3ae310f920
-)
-
-FetchContent_MakeAvailable(dbghelp)
\ No newline at end of file
From f55b298dd02bb474956565584f1517794b99a50f Mon Sep 17 00:00:00 2001
From: xezon <4720891+xezon@users.noreply.github.com>
Date: Sat, 14 Jun 2025 23:42:59 +0200
Subject: [PATCH 2/3] Minor improvement in DbgHelpGuard
---
Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp | 5 +++--
Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
index 9a0acc8214..16c705c8b5 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
@@ -42,7 +42,7 @@ void DbgHelpGuard::deactivate()
else if (DbgHelpLoader::isLoaded())
{
DbgHelpLoader::unload();
- m_wasLoaded = true;
+ m_requiresLoad = true;
m_dbgHelpRenamer.rename("dbghelp.dll", "dbghelp.dll.bak");
}
else
@@ -56,8 +56,9 @@ void DbgHelpGuard::reactivate()
m_dbgHelpRenamer.revert();
DbgHelpLoader::unblockLoad();
- if (m_wasLoaded)
+ if (m_requiresLoad)
{
DbgHelpLoader::load();
+ m_requiresLoad = false;
}
}
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
index 243f4ed1cf..ddb534c520 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
@@ -43,5 +43,5 @@ class DbgHelpGuard
private:
ScopedFileRenamer m_dbgHelpRenamer;
- bool m_wasLoaded;
+ bool m_requiresLoad;
};
From c235db4c1f2cbfb1183d6431ef3f3939ac206668 Mon Sep 17 00:00:00 2001
From: xezon <4720891+xezon@users.noreply.github.com>
Date: Wed, 18 Jun 2025 18:35:48 +0200
Subject: [PATCH 3/3] Remove ScopeFileRenamer and use dbghelp front loading
strategy instead of file renaming
---
.../Source/WWVegas/WWLib/CMakeLists.txt | 2 -
.../Source/WWVegas/WWLib/DbgHelpGuard.cpp | 27 +++--
.../Source/WWVegas/WWLib/DbgHelpGuard.h | 13 +--
.../Source/WWVegas/WWLib/DbgHelpLoader.cpp | 14 ---
.../Source/WWVegas/WWLib/DbgHelpLoader.h | 7 --
.../WWVegas/WWLib/ScopedFileRenamer.cpp | 98 -------------------
.../Source/WWVegas/WWLib/ScopedFileRenamer.h | 47 ---------
7 files changed, 16 insertions(+), 192 deletions(-)
delete mode 100644 Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp
delete mode 100644 Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h
diff --git a/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt b/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt
index ad507d6b68..708dcd6edf 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt
+++ b/Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt
@@ -103,8 +103,6 @@ set(WWLIB_SRC
#regexpr.cpp
#regexpr.h
#search.h
- ScopedFileRenamer.cpp
- ScopedFileRenamer.h
sharebuf.h
Signaler.h
simplevec.h
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
index 16c705c8b5..f53b89adcc 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.cpp
@@ -22,43 +22,38 @@
DbgHelpGuard::DbgHelpGuard()
+ : m_hasLoaded(false)
{
- deactivate();
+ activate();
}
DbgHelpGuard::~DbgHelpGuard()
{
- reactivate();
+ deactivate();
}
-void DbgHelpGuard::deactivate()
+void DbgHelpGuard::activate()
{
- DbgHelpLoader::blockLoad();
-
if (DbgHelpLoader::isLoadedFromSystem())
{
// This is ok. Do nothing.
}
else if (DbgHelpLoader::isLoaded())
{
- DbgHelpLoader::unload();
- m_requiresLoad = true;
- m_dbgHelpRenamer.rename("dbghelp.dll", "dbghelp.dll.bak");
+ // This is maybe not ok. But do nothing until this becomes a user facing problem.
}
else
{
- m_dbgHelpRenamer.rename("dbghelp.dll", "dbghelp.dll.bak");
+ // Front load the DLL now to prevent other code from loading the potentially wrong DLL.
+ m_hasLoaded = DbgHelpLoader::load();
}
}
-void DbgHelpGuard::reactivate()
+void DbgHelpGuard::deactivate()
{
- m_dbgHelpRenamer.revert();
- DbgHelpLoader::unblockLoad();
-
- if (m_requiresLoad)
+ if (m_hasLoaded)
{
- DbgHelpLoader::load();
- m_requiresLoad = false;
+ DbgHelpLoader::unload();
+ m_hasLoaded = false;
}
}
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
index ddb534c520..c613cb3b4c 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpGuard.h
@@ -20,15 +20,13 @@
#include "always.h"
-#include "ScopedFileRenamer.h"
-
-// This class temporarily unloads dbghelp.dll and prevents it from loading during its lifetime.
+// This class temporarily loads and unloads dbghelp.dll from the desired location to prevent
+// other code from potentially loading it from an undesired location.
// This helps avoid crashing on boot using recent AMD/ATI drivers, which attempt to load and use
// dbghelp.dll from the game install directory but are unable to do so correctly because
// the dbghelp.dll that ships with the game is very old and the AMD/ATI code does not handle
-// that correctly. This workaround is not required if the dbghelp.dll was loaded from the system
-// directory.
+// that correctly.
class DbgHelpGuard
{
@@ -37,11 +35,10 @@ class DbgHelpGuard
DbgHelpGuard();
~DbgHelpGuard();
+ void activate();
void deactivate();
- void reactivate();
private:
- ScopedFileRenamer m_dbgHelpRenamer;
- bool m_requiresLoad;
+ bool m_hasLoaded;
};
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp
index b99ae06be7..4449ff15a6 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp
@@ -19,7 +19,6 @@
#include "DbgHelpLoader.h"
-int DbgHelpLoader::BlockLoadCounter = 0;
DbgHelpLoader* DbgHelpLoader::Inst = NULL;
DbgHelpLoader::DbgHelpLoader()
@@ -53,21 +52,8 @@ bool DbgHelpLoader::isLoadedFromSystem()
return Inst != NULL && Inst->m_loadedFromSystem;
}
-void DbgHelpLoader::blockLoad()
-{
- ++BlockLoadCounter;
-}
-
-bool DbgHelpLoader::unblockLoad()
-{
- return --BlockLoadCounter == 0;
-}
-
bool DbgHelpLoader::load()
{
- if (BlockLoadCounter > 0)
- return false;
-
if (Inst == NULL)
{
// Cannot use new/delete here when this is loaded during game memory initialization.
diff --git a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h
index 8b6079e3c8..3a7d9cafa9 100644
--- a/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h
+++ b/Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h
@@ -33,7 +33,6 @@ class DbgHelpLoader
{
private:
- static int BlockLoadCounter;
static DbgHelpLoader* Inst; // Is singleton class
DbgHelpLoader();
@@ -47,12 +46,6 @@ class DbgHelpLoader
// Returns whether dbghelp.dll is loaded from the system directory
static bool isLoadedFromSystem();
- // Blocks loading a dbghelp.dll
- static void blockLoad();
-
- // Unblocks loading a dbghelp.dll. Returns true if unblocked.
- static bool unblockLoad();
-
static bool load();
static bool reload();
static void unload();
diff --git a/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp b/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp
deleted file mode 100644
index d13c089426..0000000000
--- a/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 TheSuperHackers
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-#include "ScopedFileRenamer.h"
-
-
-ScopedFileRenamer::ScopedFileRenamer()
- : m_file(NULL)
-{
-}
-
-ScopedFileRenamer::ScopedFileRenamer(const char* oldName, const char* newName)
- : m_file(NULL)
-{
- this->rename(oldName, newName);
-}
-
-ScopedFileRenamer::~ScopedFileRenamer()
-{
- revert();
-}
-
-bool ScopedFileRenamer::rename(const char* oldName, const char* newName)
-{
- revert();
-
- m_oldName = oldName;
- m_newName = newName;
-
- if (0 == ::rename(m_oldName.c_str(), m_newName.c_str()))
- {
- // Creates an empty *.tmp dummy file to remember that this program has renamed the file.
- // If the program would crash before the file was renamed back to the previous name, then
- // the rename condition will be able to recover the next time this code runs successfully.
- std::string tmpFilename = createTmpName();
- m_file = ::fopen(tmpFilename.c_str(), "wb");
-
- return true;
- }
-
- return false;
-}
-
-bool ScopedFileRenamer::revert()
-{
- if (m_oldName.empty())
- return false;
-
- bool success = false;
- std::string tmpName;
-
- if (m_file == NULL)
- {
- tmpName = createTmpName();
- m_file = ::fopen(tmpName.c_str(), "rb");
- }
-
- if (m_file != NULL)
- {
- ::fclose(m_file);
- m_file = NULL;
-
- if (0 == ::rename(m_newName.c_str(), m_oldName.c_str()))
- success = true;
-
- if (tmpName.empty())
- tmpName = createTmpName();
-
- ::remove(tmpName.c_str());
- }
-
- m_oldName.clear();
- m_newName.clear();
-
- return success;
-}
-
-std::string ScopedFileRenamer::createTmpName() const
-{
- std::string tmpFilename = m_oldName;
- tmpFilename.append(".tmp");
- return tmpFilename;
-}
diff --git a/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h b/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h
deleted file mode 100644
index 594192eceb..0000000000
--- a/Core/Libraries/Source/WWVegas/WWLib/ScopedFileRenamer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 TheSuperHackers
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-#pragma once
-
-#include "always.h"
-
-#include
-#include
-
-
-class ScopedFileRenamer
-{
-public:
-
- ScopedFileRenamer();
- ScopedFileRenamer(const char* oldName, const char* newName);
- ~ScopedFileRenamer();
-
- bool rename(const char* oldName, const char* newName);
- bool revert();
-
-private:
-
- std::string createTmpName() const;
-
-private:
-
- std::string m_oldName;
- std::string m_newName;
- FILE* m_file;
-};