From 0a2447dee7fcfc4c001584679f52eff23f8d2563 Mon Sep 17 00:00:00 2001 From: BramTeurlings Date: Thu, 29 Aug 2024 14:03:01 +0200 Subject: [PATCH] WIP: Started adding error handling when modules are not loaded --- gamebridge_reshade/CMakelists.txt | 1 - gamebridge_reshade/src/delayLoader.h | 23 +++++++----- gamebridge_reshade/src/directx11weaver.cpp | 13 +++++++ gamebridge_reshade/src/directx11weaver.h | 1 + gamebridge_reshade/src/dllmain.cpp | 9 ++++- gamebridge_reshade/src/pathGetter.h | 42 ---------------------- 6 files changed, 36 insertions(+), 53 deletions(-) delete mode 100644 gamebridge_reshade/src/pathGetter.h diff --git a/gamebridge_reshade/CMakelists.txt b/gamebridge_reshade/CMakelists.txt index 82f53b7..2002b41 100644 --- a/gamebridge_reshade/CMakelists.txt +++ b/gamebridge_reshade/CMakelists.txt @@ -21,7 +21,6 @@ add_library(${PROJECT_NAME} SHARED src/hotkeymanager.cpp src/hotkeymanager.h src/delayLoader.h - src/pathGetter.h ) if (WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4) diff --git a/gamebridge_reshade/src/delayLoader.h b/gamebridge_reshade/src/delayLoader.h index 9d73275..6bf3346 100644 --- a/gamebridge_reshade/src/delayLoader.h +++ b/gamebridge_reshade/src/delayLoader.h @@ -4,18 +4,17 @@ #pragma once -#include "directx10weaver.h" -#include "pathGetter.h" - #include #include +static bool allDLLsLoaded = true; // Todo: This can just be a single string instead, checking this for each DLL seems horribly inefficient. std::vector sr_dll_names = {"Glog.dll", "Opencv_world343.dll", "DimencoWeaving.dll", "SimulatedRealityCore.dll", "SimulatedRealityDisplays.dll", "SimulatedRealityFacetrackers.dll", "SimulatedRealityDirectX.dll", "DimencoWeaving32.dll", "SimulatedRealityCore32.dll", "SimulatedRealityDisplays32.dll", "SimulatedRealityFacetrackers32.dll", "SimulatedRealityDirectX32.dll"}; FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) { + std::string requested_dll; switch (dliNotify) { - case dliStartProcessing : + case dliStartProcessing: // If you want to return control to the helper, return 0. // Otherwise, return a pointer to a FARPROC helper function @@ -31,15 +30,20 @@ FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) { // helper instead of having it call LoadLibrary itself. // Check if the DLL in question is one we want to delayed load. - std::string requested_dll = pdli->szDll; + requested_dll = pdli->szDll; for (int i = 0; i < sr_dll_names.size(); i++) { if (sr_dll_names[i].find(requested_dll) != std::string::npos) { // DLL matches one we want to load, let's load it - auto path_getter = PathGetter(); - std::string sr_bin_path = path_getter.getSRBinPath(); - HMODULE hModule LoadLibraryA((requested_dll + ".dll").c_str()); + const HMODULE hModule = LoadLibraryA((requested_dll + ".dll").c_str()); + const DWORD errorCode = GetLastError(); + if (errorCode == ERROR_MOD_NOT_FOUND) { + std::cout << "Module not found (ERROR_MOD_NOT_FOUND)" << std::endl; + allDLLsLoaded = false; + // Todo: Stop the addon somehow and put it in an inactive state + display an error message. + return 0; + } if (hModule) { - return (FARPROC)hModule; + return reinterpret_cast(hModule); } } } @@ -65,6 +69,7 @@ FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) { // the alternate DLL. The helper will continue execution with // this alternate DLL and attempt to find the // requested entrypoint via GetProcAddress. + throw std::runtime_error("Failed to load library"); break; diff --git a/gamebridge_reshade/src/directx11weaver.cpp b/gamebridge_reshade/src/directx11weaver.cpp index b183e8f..01b719d 100644 --- a/gamebridge_reshade/src/directx11weaver.cpp +++ b/gamebridge_reshade/src/directx11weaver.cpp @@ -54,6 +54,11 @@ bool DirectX11Weaver::create_effect_copy_buffer(const reshade::api::resource_des } bool DirectX11Weaver::init_weaver(reshade::api::effect_runtime* runtime, reshade::api::resource rtv, reshade::api::command_list* cmd_list) { + if (!sr_ddls_loaded) { + // Trick the addon into + return false; + } + if (weaver_initialized) { return weaver_initialized; } @@ -90,6 +95,14 @@ bool DirectX11Weaver::init_weaver(reshade::api::effect_runtime* runtime, reshade reshade::log_message(reshade::log_level::info, e.what()); return false; } + catch (std::runtime_error &e) { + if (e.what() == "Failed to load library") { + // Todo: Disable the addon since we are missing an SR DLL. + // Todo: Set the error message in the overlay to INACTIVE with reason "SR Platform not found, please (re)install it". + // Todo: Do this by chaning the method signature of this method to an int for error codes and then the dllmain can set dll_failed_to_load to true. + sr_ddls_loaded = false; + } + } catch (...) { reshade::log_message(reshade::log_level::info, "Couldn't initialize weaver"); return false; diff --git a/gamebridge_reshade/src/directx11weaver.h b/gamebridge_reshade/src/directx11weaver.h index 637e9f9..f03bd18 100644 --- a/gamebridge_reshade/src/directx11weaver.h +++ b/gamebridge_reshade/src/directx11weaver.h @@ -17,6 +17,7 @@ class DirectX11Weaver: public IGraphicsApi { uint32_t last_latency_frame_time_set = default_weaver_latency; uint32_t effect_frame_copy_x = 0, effect_frame_copy_y = 0; + bool sr_ddls_loaded = true; bool weaver_initialized = false; bool weaving_enabled = false; bool popup_window_visible = false; diff --git a/gamebridge_reshade/src/dllmain.cpp b/gamebridge_reshade/src/dllmain.cpp index 52eb027..3068bfd 100644 --- a/gamebridge_reshade/src/dllmain.cpp +++ b/gamebridge_reshade/src/dllmain.cpp @@ -16,6 +16,7 @@ #include "hotkeymanager.h" #include "directx10weaver.h" #include "directx9weaver.h" +#include "delayLoader.h" #include #include @@ -34,6 +35,7 @@ SR::SwitchableLensHint* lens_hint = nullptr; HotKeyManager* hotKey_manager = nullptr; // Currently we use this string to determine if we should toggle this shader on press of the shortcut. We can expand this to a list later. +static bool dll_failed_to_load = false; static const std::string depth_3D_shader_name = "SuperDepth3D"; static const std::string sr_shader_name = "SR"; static char char_buffer[CHAR_BUFFER_SIZE]; @@ -183,7 +185,12 @@ static void draw_status_overlay(reshade::api::effect_runtime* runtime) { std::string status_string = "Status: \n"; if (sr_context == nullptr) { // Unable to connect to the SR Service. Fall back to drawing the overlay UI ourselves. - status_string += "INACTIVE - NO SR SERVICE DETECTED, MAKE SURE THE SR PLATFORM IS INSTALLED AND RUNNING\nwww.srappstore.com\n"; + status_string += "INACTIVE - NO SR SERVICE DETECTED, MAKE SURE THE SR PLATFORM IS INSTALLED AND RUNNING\nhttps://github.com/LeiaInc/leiainc.github.io/tree/master/SRSDK\n"; + printStatusInWeaver = false; + } + else if (dll_failed_to_load) { + // Unable to load at least one of the SR DLLs + status_string += "INACTIVE - UNABLE TO LOAD ALL SR DLLS, MAKE SURE THE SR PLATFORM IS INSTALLED AND RUNNING\nhttps://github.com/LeiaInc/leiainc.github.io/tree/master/SRSDK\n"; printStatusInWeaver = false; } else if (weaver_implementation) { diff --git a/gamebridge_reshade/src/pathGetter.h b/gamebridge_reshade/src/pathGetter.h deleted file mode 100644 index 1218dca..0000000 --- a/gamebridge_reshade/src/pathGetter.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by BramTeurlings on 22-8-2024. -// - -#pragma once - -#include -#include - -class PathGetter { -public: - PathGetter() = default; - - std::string getSRBinPath() { - std::regex path_regex("^Path"); - std::string path_environment_variable = std::getenv("PATH"); - //std::cout << path_environment_variable << "\n"; - - std::regex path_search_regex("[a-zA-Z0-9+_\\-\\.:%()\\s\\\\]+"); - std::smatch match_results; - std::regex_search(path_environment_variable, match_results, path_search_regex); - - auto words_begin = std::sregex_iterator(path_environment_variable.begin(), path_environment_variable.end(), path_search_regex); - auto words_end = std::sregex_iterator(); - - std::string simulated_reality_bin_path; - for (std::sregex_iterator i = words_begin; i != words_end; ++i) - { - std::smatch match = *i; - std::string match_str = match.str(); - std::cout << match_str << '\n'; - // Todo: Change this match based on if we're running 32 bit or 64 bit. - if(match_str.find("Program Files\\Simulated Reality") != std::string::npos) - { - simulated_reality_bin_path = match_str; - break; - } - } - - return simulated_reality_bin_path; - } -};