From b2ac498a52551df0076b9c43d8e6e1a33295672a Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Sun, 4 Jan 2026 18:30:31 +0000 Subject: [PATCH] Disable Windows Jump Lists to prevent shell crashes --- Generals/Code/Main/WinMain.cpp | 70 +++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/Generals/Code/Main/WinMain.cpp b/Generals/Code/Main/WinMain.cpp index 3c34a3e81cf..c5e49e53f7e 100644 --- a/Generals/Code/Main/WinMain.cpp +++ b/Generals/Code/Main/WinMain.cpp @@ -38,6 +38,9 @@ #include #include #include +#include +#include +#include // USER INCLUDES ////////////////////////////////////////////////////////////// #include "WinMain.h" @@ -766,6 +769,51 @@ static LONG WINAPI UnHandledExceptionFilter( struct _EXCEPTION_POINTERS* e_info return EXCEPTION_EXECUTE_HANDLER; } +// DisableWindowsJumpLists ==================================================== +/** Disable Windows Jump Lists to prevent corrupted Jump List cache files + * from causing crashes in Windows Shell code (CAutomaticDestinationList). + * This function clears automatic destinations and sets a unique AppUserModelID + * to prevent Windows from managing Jump Lists for this application. + */ +//============================================================================= +static void DisableWindowsJumpLists() +{ + // Set a unique AppUserModelID to prevent Windows from automatically managing Jump Lists + // Using the application name to make it specific to this game + HRESULT hr = SetCurrentProcessExplicitAppUserModelID(L"GeneralsOnline.Game.ZeroHour"); + if (FAILED(hr)) + { + DEBUG_LOG(("Failed to set AppUserModelID, HRESULT: 0x%08X", hr)); + return; + } + + // Clear any existing automatic destinations (Recent/Frequent items) to prevent + // corrupted cache files from being accessed by Windows Shell + IApplicationDestinations* pAppDest = NULL; + hr = CoCreateInstance(CLSID_ApplicationDestinations, NULL, CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&pAppDest)); + + if (SUCCEEDED(hr) && pAppDest != NULL) + { + // Clear all automatic destinations for this application + hr = pAppDest->RemoveAllDestinations(); + if (FAILED(hr)) + { + DEBUG_LOG(("Failed to clear automatic destinations, HRESULT: 0x%08X", hr)); + } + else + { + DEBUG_LOG(("Successfully disabled Windows Jump Lists")); + } + + pAppDest->Release(); + } + else + { + DEBUG_LOG(("Failed to create IApplicationDestinations, HRESULT: 0x%08X", hr)); + } +} + // WinMain ==================================================================== /** Application entry point */ //============================================================================= @@ -827,6 +875,24 @@ Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, // Initialize minidump facilities - requires TheGlobalData so performed after parseCommandLineForStartup MiniDumper::initMiniDumper(TheGlobalData->getPath_UserData()); #endif + + // Initialize COM early to enable Windows Shell API calls + // This is required for Jump List management and other COM-based Windows features + HRESULT hrCom = CoInitialize(NULL); + if (FAILED(hrCom)) + { + DEBUG_LOG(("Failed to initialize COM, HRESULT: 0x%08X", hrCom)); + } + else + { + DEBUG_LOG(("COM initialized successfully")); + + // Disable Windows Jump Lists to prevent crashes from corrupted Jump List cache files + // This prevents Windows Shell's CAutomaticDestinationList from accessing potentially + // corrupted automatic destination files that can cause access violations + DisableWindowsJumpLists(); + } + // register windows class and create application window if(!TheGlobalData->m_headless && initializeAppWindows(hInstance, nCmdShow, TheGlobalData->m_windowed) == false) return exitcode; @@ -886,8 +952,8 @@ Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, shutdownMemoryManager(); - // BGC - shut down COM - // OleUninitialize(); + // Uninitialize COM to clean up resources + CoUninitialize(); } catch (...) {