Skip to content

Commit

Permalink
Delayed loading works!
Browse files Browse the repository at this point in the history
One problem is that the service gets in a strange state when we delayed load. We need to handle all of the dwitch cases in delayLoader.h properly to resolve this.
  • Loading branch information
BramTeurlings committed Aug 23, 2024
1 parent 4ec3575 commit 2698f16
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 0 deletions.
97 changes: 97 additions & 0 deletions gamebridge_reshade/src/delayLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// Created by BramTeurlings on 22-8-2024.
//

#pragma once

#include "directx10weaver.h"
#include "pathGetter.h"

#include <Windows.h>
#include <delayimp.h>

// Todo: This can just be a single string instead, checking this for each DLL seems horribly inefficient.
std::vector<std::string> 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) {
switch (dliNotify) {
case dliStartProcessing :

// If you want to return control to the helper, return 0.
// Otherwise, return a pointer to a FARPROC helper function
// that will be used instead, thereby bypassing the rest
// of the helper.

// Check if the DLL in question is one we want to delayed load.
std::string 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();
LoadLibraryA((requested_dll + ".dll").c_str());
}
}

break;

case dliNotePreLoadLibrary:

// If you want to return control to the helper, return 0.
// Otherwise, return your own HMODULE to be used by the
// helper instead of having it call LoadLibrary itself.

break;

case dliNotePreGetProcAddress:

// If you want to return control to the helper, return 0.
// If you choose you may supply your own FARPROC function
// address and bypass the helper's call to GetProcAddress.

break;

case dliFailLoadLib:

// LoadLibrary failed.
// If you don't want to handle this failure yourself, return 0.
// In this case the helper will raise an exception
// (ERROR_MOD_NOT_FOUND) and exit.
// If you want to handle the failure by loading an alternate
// DLL (for example), then return the HMODULE for
// the alternate DLL. The helper will continue execution with
// this alternate DLL and attempt to find the
// requested entrypoint via GetProcAddress.

break;

case dliFailGetProc:

// GetProcAddress failed.
// If you don't want to handle this failure yourself, return 0.
// In this case the helper will raise an exception
// (ERROR_PROC_NOT_FOUND) and exit.
// If you choose, you may handle the failure by returning
// an alternate FARPROC function address.

break;

case dliNoteEndProcessing:

// This notification is called after all processing is done.
// There is no opportunity for modifying the helper's behavior
// at this point except by longjmp()/throw()/RaiseException.
// No return value is processed.

break;

default :

return NULL;
}

return NULL;
}

ExternC const PfnDliHook __pfnDliNotifyHook2 = delayHook;
ExternC const PfnDliHook __pfnDliFailureHook2 = delayHook;
2 changes: 2 additions & 0 deletions gamebridge_reshade/src/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ BOOL APIENTRY DllMain( HMODULE hModule,
if (!reshade::register_addon(hModule))
return FALSE;

// Load delayed SR DLLs

reshade::register_event<reshade::addon_event::init_effect_runtime>(&on_init_effect_runtime);
reshade::register_event<reshade::addon_event::reshade_begin_effects>(&on_reshade_begin_effects);
reshade::register_event<reshade::addon_event::reshade_render_technique>(&on_render_technique);
Expand Down
42 changes: 42 additions & 0 deletions gamebridge_reshade/src/pathGetter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Created by BramTeurlings on 22-8-2024.
//

#pragma once

#include <iostream>
#include <regex>

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;
}
};

0 comments on commit 2698f16

Please sign in to comment.