diff --git a/SilentPatch/ASIModuleHandle.h b/SilentPatch/ASIModuleHandle.h deleted file mode 100644 index 1a24e08..0000000 --- a/SilentPatch/ASIModuleHandle.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -template -inline HMODULE GetASIModuleHandleA( const char(&lpModuleName)[N] ) -{ - HMODULE asi = GetModuleHandleA( lpModuleName ); - if ( asi == nullptr ) - { - char nameWithSuffix[ N + 4 ]; - memcpy( nameWithSuffix, lpModuleName, sizeof(lpModuleName) - sizeof(lpModuleName[0]) ); - nameWithSuffix[N - 1] = '.'; - nameWithSuffix[N + 0] = 'a'; - nameWithSuffix[N + 1] = 's'; - nameWithSuffix[N + 2] = 'i'; - nameWithSuffix[N + 3] = '\0'; - asi = GetModuleHandleA( nameWithSuffix ); - } - return asi; -} - -template -inline HMODULE GetASIModuleHandleW( const wchar_t(&lpModuleName)[N] ) -{ - HMODULE asi = GetModuleHandleW( lpModuleName ); - if ( asi == nullptr ) - { - wchar_t nameWithSuffix[ N + 4 ]; - memcpy( nameWithSuffix, lpModuleName, sizeof(lpModuleName) - sizeof(lpModuleName[0]) ); - nameWithSuffix[N - 1] = L'.'; - nameWithSuffix[N + 0] = L'a'; - nameWithSuffix[N + 1] = L's'; - nameWithSuffix[N + 2] = L'i'; - nameWithSuffix[N + 3] = L'\0'; - asi = GetModuleHandleW( nameWithSuffix ); - } - return asi; -} - -#ifdef _UNICODE -#define GetASIModuleHandle GetASIModuleHandleW -#else -#define GetASIModuleHandle GetASIModuleHandleA -#endif \ No newline at end of file diff --git a/SilentPatch/ModuleList.hpp b/SilentPatch/ModuleList.hpp new file mode 100644 index 0000000..03f0c3d --- /dev/null +++ b/SilentPatch/ModuleList.hpp @@ -0,0 +1,114 @@ +#pragma once + +#include +#include +#include + +#define PSAPI_VERSION 1 +#include +#include + +#pragma comment(lib, "Psapi.lib") + +// Stores a list of loaded modules with their names, WITHOUT extension +class ModuleList +{ +public: + void Enumerate() + { + const HANDLE currentProcess = GetCurrentProcess(); + + constexpr size_t INITIAL_SIZE = sizeof(HMODULE) * 256; + HMODULE* modules = static_cast(malloc( INITIAL_SIZE )); + if ( modules != nullptr ) + { + DWORD cbNeeded = 0; + if ( EnumProcessModules( currentProcess, modules, INITIAL_SIZE, &cbNeeded ) != 0 ) + { + if ( cbNeeded > INITIAL_SIZE ) + { + HMODULE* newModules = static_cast(realloc( modules, cbNeeded )); + if ( newModules != nullptr ) + { + modules = newModules; + + if ( EnumProcessModules( currentProcess, modules, cbNeeded, &cbNeeded ) != 0 ) + { + EnumerateInternal( modules, cbNeeded / sizeof(HMODULE) ); + } + } + } + else + { + EnumerateInternal( modules, cbNeeded / sizeof(HMODULE) ); + } + } + free( modules ); + } + } + + void ReEnumerate() + { + Clear(); + Enumerate(); + } + + void Clear() + { + m_moduleList.clear(); + } + + HMODULE Get( const wchar_t* moduleName ) const + { + // If vector is empty then we're trying to call it without calling Enumerate first + assert( m_moduleList.size() != 0 ); + + auto it = std::find_if( m_moduleList.begin(), m_moduleList.end(), [&]( const auto& e ) { + return _wcsicmp( moduleName, e.second.c_str() ) == 0; + } ); + return it != m_moduleList.end() ? it->first : nullptr; + } + + std::vector GetAll( const wchar_t* moduleName ) const + { + // If vector is empty then we're trying to call it without calling Enumerate first + assert( m_moduleList.size() != 0 ); + + std::vector results; + for ( auto& e : m_moduleList ) + { + if ( _wcsicmp( moduleName, e.second.c_str() ) == 0 ) + { + results.push_back( e.first ); + } + } + + return results; + } + +private: + void EnumerateInternal( HMODULE* modules, size_t numModules ) + { + m_moduleList.reserve( numModules ); + for ( size_t i = 0; i < numModules; i++ ) + { + wchar_t moduleName[MAX_PATH]; + if ( GetModuleFileNameW( *modules, moduleName, MAX_PATH ) != 0 ) + { + const wchar_t* nameBegin = wcsrchr( moduleName, '\\' ) + 1; + const wchar_t* dotPos = wcsrchr( nameBegin, '.' ); + if ( dotPos != nullptr ) + { + m_moduleList.emplace_back( *modules, std::wstring( nameBegin, std::distance( nameBegin, dotPos ) ) ); + } + else + { + m_moduleList.emplace_back( *modules, nameBegin ); + } + } + modules++; + } + } + + std::vector< std::pair > m_moduleList; +}; \ No newline at end of file diff --git a/SilentPatch/TheFLAUtils.cpp b/SilentPatch/TheFLAUtils.cpp index 630f52e..e698c28 100644 --- a/SilentPatch/TheFLAUtils.cpp +++ b/SilentPatch/TheFLAUtils.cpp @@ -3,7 +3,9 @@ #define WIN32_LEAN_AND_MEAN #include -#include "ASIModuleHandle.h" +#include "ModuleList.hpp" + +extern ModuleList moduleList; int32_t (*FLAUtils::GetExtendedID8Func)(const uint8_t* ptr) = FLAUtils::GetExtendedID8_Stock; int32_t (*FLAUtils::GetExtendedID16Func)(const uint16_t* ptr) = FLAUtils::GetExtendedID16_Stock; @@ -13,7 +15,7 @@ static HMODULE flaModule = nullptr; void FLAUtils::Init() { - flaModule = GetASIModuleHandle(TEXT("$fastman92limitAdjuster")); + flaModule = moduleList.Get( L"$fastman92limitAdjuster" ); if ( flaModule != nullptr ) { const auto function8 = reinterpret_cast(GetProcAddress( flaModule, "GetExtendedIDfrom8bitBefore" )); diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 311d734..005502a 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -20,10 +20,12 @@ #include "Patterns.h" #include "DelimStringReader.h" -#include "ASIModuleHandle.h" +#include "ModuleList.hpp" #include "debugmenu_public.h" +ModuleList moduleList; + // ============= Mod compatibility stuff ============= namespace ModCompat @@ -2182,12 +2184,14 @@ BOOL InjectDelayedPatches_10() GetModuleFileNameW(hDLLModule, wcModulePath, _countof(wcModulePath) - 3); // Minus max required space for extension PathRenameExtensionW(wcModulePath, L".ini"); - const bool bHasImVehFt = GetASIModuleHandleW(L"ImVehFt") != nullptr; - const bool bSAMP = GetModuleHandleW(L"samp") != nullptr; - const bool bSARender = GetASIModuleHandleW(L"SARender") != nullptr; + moduleList.Enumerate(); - const HMODULE skygfxModule = GetASIModuleHandle( TEXT("skygfx") ); - const HMODULE modloaderModule = GetASIModuleHandle( TEXT("modloader") ); + const bool bHasImVehFt = moduleList.Get(L"ImVehFt") != nullptr; + const bool bSAMP = moduleList.Get(L"samp") != nullptr; + const bool bSARender = moduleList.Get(L"SARender") != nullptr; + + const HMODULE skygfxModule = moduleList.Get( L"skygfx" ); + const HMODULE modloaderModule = moduleList.Get( L"modloader" ); ReadRotorFixExceptions(wcModulePath); const bool bHookDoubleRwheels = ReadDoubleRearWheels(wcModulePath); @@ -2312,7 +2316,7 @@ BOOL InjectDelayedPatches_10() } // SSE conflicts - if ( GetASIModuleHandleW(L"shadows") == nullptr ) + if ( moduleList.Get(L"shadows") == nullptr ) { Patch(0x70665C, 0x52909090); InjectHook(0x706662, &CShadowCamera::Update); @@ -2346,7 +2350,7 @@ BOOL InjectDelayedPatches_10() // Adblocker #if DISABLE_FLA_DONATION_WINDOW - if ( GetASIModuleHandleW(L"$fastman92limitAdjuster") != nullptr ) + if ( moduleList.Get(L"$fastman92limitAdjuster") != nullptr ) { if ( *(DWORD*)0x748736 != 0xE8186A53 ) { @@ -2412,6 +2416,7 @@ BOOL InjectDelayedPatches_10() } FLAUtils::Init(); + moduleList.Clear(); // Race condition in CdStream fixed // Not taking effect with modloader @@ -2516,9 +2521,11 @@ BOOL InjectDelayedPatches_11() GetModuleFileNameW(hDLLModule, wcModulePath, _countof(wcModulePath) - 3); // Minus max required space for extension PathRenameExtensionW(wcModulePath, L".ini"); - bool bHasImVehFt = GetASIModuleHandleW(L"ImVehFt") != nullptr; - bool bSAMP = GetModuleHandleW(L"samp") != nullptr; - bool bSARender = GetASIModuleHandleW(L"SARender") != nullptr; + moduleList.Enumerate(); + + bool bHasImVehFt = moduleList.Get(L"ImVehFt") != nullptr; + bool bSAMP = moduleList.Get(L"samp") != nullptr; + bool bSARender = moduleList.Get(L"SARender") != nullptr; ReadRotorFixExceptions(wcModulePath); @@ -2629,7 +2636,7 @@ BOOL InjectDelayedPatches_11() } // SSE conflicts - if ( GetASIModuleHandleW(L"shadows") == nullptr ) + if ( moduleList.Get(L"shadows") == nullptr ) { Patch(0x706E8C, 0x52909090); InjectHook(0x706E92, &CShadowCamera::Update); @@ -2649,6 +2656,7 @@ BOOL InjectDelayedPatches_11() CCustomCarPlateMgr::GeneratePlateText = (decltype(CCustomCarPlateMgr::GeneratePlateText))0x6FDDE0; FLAUtils::Init(); + moduleList.Clear(); return FALSE; } @@ -2683,9 +2691,11 @@ BOOL InjectDelayedPatches_Steam() GetModuleFileNameW(hDLLModule, wcModulePath, _countof(wcModulePath) - 3); // Minus max required space for extension PathRenameExtensionW(wcModulePath, L".ini"); - bool bHasImVehFt = GetASIModuleHandleW(L"ImVehFt") != nullptr; - bool bSAMP = GetModuleHandleW(L"samp") != nullptr; - bool bSARender = GetASIModuleHandleW(L"SARender") != nullptr; + moduleList.Enumerate(); + + bool bHasImVehFt = moduleList.Get(L"ImVehFt") != nullptr; + bool bSAMP = moduleList.Get(L"samp") != nullptr; + bool bSARender = moduleList.Get(L"SARender") != nullptr; ReadRotorFixExceptions(wcModulePath); @@ -2798,7 +2808,7 @@ BOOL InjectDelayedPatches_Steam() } // SSE conflicts - if ( GetASIModuleHandleW(L"shadows") == nullptr ) + if ( moduleList.Get(L"shadows") == nullptr ) { Patch(0x74A864, 0x52909090); InjectHook(0x74A86A, &CShadowCamera::Update); @@ -2817,6 +2827,7 @@ BOOL InjectDelayedPatches_Steam() ReadCall( 0x4D3DA4, CCustomCarPlateMgr::GeneratePlateText ); FLAUtils::Init(); + moduleList.Clear(); return FALSE; } diff --git a/SilentPatchSA/SilentPatchSA.vcxproj b/SilentPatchSA/SilentPatchSA.vcxproj index 14577f5..12cc055 100644 --- a/SilentPatchSA/SilentPatchSA.vcxproj +++ b/SilentPatchSA/SilentPatchSA.vcxproj @@ -212,7 +212,6 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio - @@ -222,6 +221,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio + diff --git a/SilentPatchSA/SilentPatchSA.vcxproj.filters b/SilentPatchSA/SilentPatchSA.vcxproj.filters index 2c2d8d4..517844c 100644 --- a/SilentPatchSA/SilentPatchSA.vcxproj.filters +++ b/SilentPatchSA/SilentPatchSA.vcxproj.filters @@ -149,10 +149,10 @@ Header Files - + Header Files - + Header Files