MCPcopy Create free account
hub / github.com/crosire/reshade / register_module

Method register_module

source/hook_manager.cpp:517–593  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

515}
516
517void reshade::hooks::register_module(const std::filesystem::path &target_path)
518{
519#ifndef RESHADE_TEST_APPLICATION
520 if (s_dll_notification_cookie == nullptr)
521 {
522 const auto ntdll_module = GetModuleHandleW(L"ntdll.dll");
523 assert(ntdll_module != nullptr);
524
525 const auto LdrRegisterDllNotification = reinterpret_cast<LONG (NTAPI *)(ULONG Flags, FARPROC NotificationFunction, PVOID Context, PVOID *Cookie)>(GetProcAddress(ntdll_module, "LdrRegisterDllNotification"));
526 if (LdrRegisterDllNotification == nullptr ||
527 // The Steam overlay is using 'LoadLibrary' hooks, so always use them too if it is used, to ensure that ReShade installs hooks after the Steam overlay already did so
528 // Detect whether the Steam overlay is used by checking for a 'SteamOverlayGameId' environment variable that Steam sets, instead of looking for 'GameOverlayRenderer[64].dll', since ReShade may be injected before the Steam overlay DLL
529 GetEnvironmentVariableW(L"SteamOverlayGameId", nullptr, 0) ||
530 LdrRegisterDllNotification(0, reinterpret_cast<FARPROC>(&DllNotificationCallback), nullptr, &s_dll_notification_cookie) != 0 /* STATUS_SUCCESS */)
531 {
532#if RESHADE_VERBOSE_LOG
533 log::message(log::level::debug, "Using LoadLibrary hooks.");
534#endif
535
536 // Fall back 'LoadLibrary' hooks if DLL notification registration failed or the Steam overlay is used
537 // Skip this in the test application to make RenderDoc work (which hooks these too)
538 install("LoadLibraryA", reinterpret_cast<hook::address>(&LoadLibraryA), reinterpret_cast<hook::address>(&HookLoadLibraryA), true);
539 install("LoadLibraryExA", reinterpret_cast<hook::address>(&LoadLibraryExA), reinterpret_cast<hook::address>(&HookLoadLibraryExA), true);
540 install("LoadLibraryW", reinterpret_cast<hook::address>(&LoadLibraryW), reinterpret_cast<hook::address>(&HookLoadLibraryW), true);
541 install("LoadLibraryExW", reinterpret_cast<hook::address>(&LoadLibraryExW), reinterpret_cast<hook::address>(&HookLoadLibraryExW), true);
542
543 // Install all 'LoadLibrary' hooks in one go immediately
544 if (hook::apply_queued_actions())
545 s_dll_notification_cookie = reinterpret_cast<PVOID>(-1); // Set cookie to something so that these hooks are only installed once
546 else
547 log::message(log::level::error, "Failed to install LoadLibrary hooks!");
548 }
549 }
550#endif
551
552 log::message(log::level::info, "Registering hooks for '%s' ...", target_path.u8string().c_str());
553
554 // Compare module names and delay export hooks for later installation since we cannot call 'LoadLibrary' from this function (it is called from 'DLLMain', which does not allow this)
555 // Do a case insensitive comparison here to catch cases like "OPENGL32" refering to the same module as "opengl32.dll"
556 assert(target_path.extension() == L".dll");
557 const std::filesystem::path target_name = target_path.filename();
558 const std::filesystem::path replacement_name = g_reshade_dll_path.filename();
559 if (_wcsicmp(target_name.c_str(), replacement_name.c_str()) == 0)
560 {
561 assert(target_path != g_reshade_dll_path && target_path.is_absolute());
562
563 if (!s_export_module_path.empty())
564 {
565 log::message(log::level::info, "> Skipped.");
566 }
567 else
568 {
569 log::message(log::level::info, "> Delayed until first call to an exported function.");
570
571 register_export_module(target_path);
572
573 // Register for function hooking as well, in case a third party (like NVIDIA Streamline) explicitly loads the system library between now and the first call to an exported function
574 s_delayed_hook_paths.push_back(target_path);

Callers

nothing calls this directly

Calls 2

messageFunction · 0.85
install_internalFunction · 0.85

Tested by

no test coverage detected