├── .clang-format ├── .clang-tidy ├── CMakeLists.txt ├── README.md ├── include └── source-engine-interfaces-book │ └── SourceEngineInterfacesBook.hpp └── src ├── SourceEngineInterfacesBook.cpp ├── interfaces.hpp └── utils ├── CMakeLists.txt ├── include └── utils │ └── source-engine-interfaces-utils.hpp └── src ├── unix └── source-engine-interfaces-utils.cpp └── windows └── source-engine-interfaces-utils.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: LLVM 3 | AccessModifierOffset: -4 4 | AlignAfterOpenBracket: DontAlign 5 | AlignConsecutiveAssignments: AcrossEmptyLinesAndComments 6 | AlignConsecutiveDeclarations: AcrossEmptyLinesAndComments 7 | AlignEscapedNewlines: DontAlign 8 | AlignOperands: true 9 | AlignTrailingComments: true 10 | AllowAllParametersOfDeclarationOnNextLine: true 11 | AllowShortBlocksOnASingleLine: Empty 12 | AllowShortCaseLabelsOnASingleLine: false 13 | AllowShortFunctionsOnASingleLine: Inline 14 | AllowShortIfStatementsOnASingleLine: false 15 | AllowShortLoopsOnASingleLine: false 16 | AlwaysBreakAfterDefinitionReturnType: None 17 | AlwaysBreakAfterReturnType: None 18 | AlwaysBreakBeforeMultilineStrings: false 19 | AlwaysBreakTemplateDeclarations: Yes 20 | BinPackArguments: false 21 | BinPackParameters: false 22 | BraceWrapping: 23 | AfterClass: true 24 | AfterControlStatement: false 25 | AfterEnum: false 26 | AfterFunction: true 27 | AfterNamespace: false 28 | AfterObjCDeclaration: false 29 | AfterStruct: true 30 | AfterUnion: false 31 | AfterExternBlock: false 32 | BeforeCatch: false 33 | BeforeElse: false 34 | IndentBraces: false 35 | SplitEmptyFunction: false 36 | SplitEmptyRecord: false 37 | SplitEmptyNamespace: false 38 | BreakAfterJavaFieldAnnotations: false 39 | BreakBeforeBinaryOperators: All 40 | BreakBeforeBraces: Custom 41 | BreakBeforeTernaryOperators: true 42 | BreakInheritanceList: BeforeColon 43 | BreakStringLiterals: true 44 | CommentPragmas: '^ IWYU pragma:' 45 | CompactNamespaces: false 46 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 47 | ConstructorInitializerIndentWidth: 4 48 | ContinuationIndentWidth: 4 49 | Cpp11BracedListStyle: true 50 | DerivePointerAlignment: false 51 | DisableFormat: false 52 | ExperimentalAutoDetectBinPacking: false 53 | FixNamespaceComments: true 54 | IncludeBlocks: Regroup 55 | IncludeCategories: 56 | # Headers in <> without extension. 57 | - Regex: '<([-A-Za-z0-9\Q/-_\E])+>' 58 | Priority: 4 59 | # Headers in <> from specific external libraries. 60 | - Regex: '<(gtest|gmock)\/' 61 | Priority: 3 62 | # Headers in <> with extension. 63 | - Regex: '<([-A-Za-z0-9.\Q/-_\E])+>' 64 | Priority: 2 65 | # Headers in "" with extension. 66 | - Regex: '"([-A-Za-z0-9.\Q/-_\E])+"' 67 | Priority: 1 68 | IncludeIsMainRegex: '(Test)?$' 69 | IndentCaseLabels: false 70 | IndentPPDirectives: None 71 | IndentWidth: 4 72 | IndentWrappedFunctionNames: false 73 | JavaScriptQuotes: Leave 74 | JavaScriptWrapImports: true 75 | KeepEmptyLinesAtTheStartOfBlocks: false 76 | Language: Cpp 77 | ColumnLimit: 120 78 | MacroBlockBegin: '' 79 | MacroBlockEnd: '' 80 | MaxEmptyLinesToKeep: 1 81 | NamespaceIndentation: None 82 | ObjCBinPackProtocolList: Auto 83 | ObjCBlockIndentWidth: 4 84 | ObjCSpaceAfterProperty: false 85 | ObjCSpaceBeforeProtocolList: true 86 | PenaltyBreakAssignment: 150 87 | PenaltyBreakBeforeFirstCallParameter: 300 88 | PenaltyBreakComment: 500 89 | PenaltyBreakFirstLessLess: 400 90 | PenaltyBreakString: 600 91 | PenaltyBreakTemplateDeclaration: 10 92 | PenaltyExcessCharacter: 50 93 | PenaltyReturnTypeOnItsOwnLine: 300 94 | PointerAlignment: Left 95 | ReflowComments: false 96 | SortIncludes: CaseInsensitive 97 | SortUsingDeclarations: true 98 | SpaceAfterCStyleCast: true 99 | SpaceAfterTemplateKeyword: false 100 | SpaceBeforeAssignmentOperators: true 101 | SpaceBeforeCpp11BracedList: false 102 | SpaceBeforeCtorInitializerColon: true 103 | SpaceBeforeInheritanceColon: false 104 | SpaceBeforeParens: ControlStatements 105 | SpaceBeforeRangeBasedForLoopColon: true 106 | SpaceInEmptyParentheses: false 107 | SpacesBeforeTrailingComments: 1 108 | SpacesInAngles: false 109 | SpacesInCStyleCastParentheses: false 110 | SpacesInContainerLiterals: false 111 | SpacesInParentheses: false 112 | SpacesInSquareBrackets: false 113 | Standard: c++20 114 | TabWidth: 4 115 | UseTab: Never -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*, 2 | bugprone-*, 3 | cppcoreguidelines-*, 4 | google-*, 5 | misc-*, 6 | modernize-*, 7 | performance-*, 8 | readability-*, 9 | cert-err52-cpp, 10 | cert-err60-cpp, 11 | cert-err34-c, 12 | cert-str34-c, 13 | cert-dcl21-cpp, 14 | cert-msc50-cpp, 15 | cert-msc51-cpp, 16 | cert-dcl58-cpp, 17 | cert-flp30-c, 18 | hicpp-multiway-paths-covered, 19 | hicpp-ignored-remove-result, 20 | hicpp-exception-baseclass' -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.18) 2 | project(SourceEngineInterfacesBook LANGUAGES CXX) 3 | 4 | set(CMAKE_CXX_STANDARD 20) 5 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 6 | set(CMAKE_CONFIGURATION_TYPES Release Debug) 7 | 8 | 9 | 10 | add_subdirectory(src/utils) 11 | 12 | set(SOURCES 13 | src/SourceEngineInterfacesBook.cpp 14 | ) 15 | 16 | add_library(SourceEngineInterfacesBook STATIC ${SOURCES}) 17 | 18 | set_target_properties(SourceEngineInterfacesBook PROPERTIES PUBLIC_HEADER 19 | include/source-engine-interfaces-book/SourceEngineInterfacesBook.hpp 20 | ) 21 | 22 | target_include_directories(SourceEngineInterfacesBook PUBLIC include) 23 | target_link_libraries(SourceEngineInterfacesBook PRIVATE source-engine-interfaces-utils) 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # source-engine-interfaces-book 2 | Tiny tool for making accessing Source Engine's interfaces simpler 3 | 4 | You no longer need to guess about which shared library contains target interface and care about its version. 5 | 6 | # Usage 7 | 8 | The only thing you need to do is to use function `sourceEngineInterfaces::book::getInterface`: 9 | 10 | ```cpp 11 | auto* ICvarInterface = static_cast(sourceEngineInterfaces::book::getInterface("ICvar")); 12 | 13 | // NOTE: there are some interfaces that have two different versions on client and server side at the same runtime 14 | // EXAMPLE: 15 | 16 | auto* stringTablesClient { static_cast(sourceEngineInterfaces::book::getInterface("INetworkStringTableContainer","VEngineClientStringTable001")) }; 17 | 18 | auto* stringTablesServer { static_cast(sourceEngineInterfaces::book::getInterface("INetworkStringTableContainer","VEngineServerStringTable001")) }; 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /include/source-engine-interfaces-book/SourceEngineInterfacesBook.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace sourceEngineInterfaces::book 4 | { 5 | auto getInterface(std::string_view interfaceType, std::string_view interfaceVersion = "") -> void*; 6 | } -------------------------------------------------------------------------------- /src/SourceEngineInterfacesBook.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "interfaces.hpp" 6 | #include "source-engine-interfaces-book/SourceEngineInterfacesBook.hpp" 7 | 8 | namespace 9 | { 10 | using InterfaceCreator = std::function; 11 | using CreateInterfaceSig = void*(*)(const char*, int*); 12 | 13 | auto buildCreateInterfaceFunctionsList() -> std::list 14 | { 15 | auto functionsList{std::list{}}; 16 | 17 | const auto loadedLibrariesList {sourceEngineInterfaces::utils::getLoadedSharedLibsNames()}; 18 | 19 | for (const auto& libraryName : loadedLibrariesList) { 20 | const auto* createInterfaceFnAddress { 21 | sourceEngineInterfaces::utils::getSymbolFromDynamicLib(libraryName, sourceEngineInterfaces::utils::CREATE_INTERFACE_SYMBOL) 22 | }; 23 | 24 | if (not createInterfaceFnAddress) { 25 | continue; 26 | } 27 | 28 | auto* createInterfaceFnPtr {reinterpret_cast(createInterfaceFnAddress)}; 29 | 30 | functionsList.emplace_back(createInterfaceFnPtr); 31 | } 32 | 33 | return functionsList; 34 | } 35 | } 36 | 37 | namespace sourceEngineInterfaces::book 38 | { 39 | auto getInterface(std::string_view interfaceType, std::string_view interfaceVersion) -> void* 40 | { 41 | static const auto createInterfaceFunctionsList {buildCreateInterfaceFunctionsList()}; 42 | 43 | for(const auto& createInterfaceFunction : createInterfaceFunctionsList) { 44 | auto interfaceTypeStr {std::string{interfaceType}}; 45 | 46 | std::ranges::transform(interfaceTypeStr, interfaceTypeStr.begin(), [](unsigned char letter) -> int { 47 | return std::tolower(letter); 48 | }); 49 | 50 | auto* foundInterface {static_cast(nullptr)}; 51 | const auto& interfaceVersions {interfacesMap.at(interfaceTypeStr)}; 52 | 53 | foundInterface = std::find(interfaceVersions.begin(), interfaceVersions.end(), interfaceVersion) != interfaceVersions.end() 54 | ? createInterfaceFunction(interfaceVersion.data(), nullptr) 55 | : nullptr; 56 | 57 | if (foundInterface) { 58 | return foundInterface; 59 | } 60 | 61 | if (!interfaceVersion.empty()) { 62 | continue; 63 | } 64 | 65 | for (const auto& version : interfaceVersions) { 66 | foundInterface = createInterfaceFunction(version.data(), nullptr); 67 | if (foundInterface) { 68 | return foundInterface; 69 | } 70 | } 71 | } 72 | 73 | return nullptr; 74 | } 75 | } -------------------------------------------------------------------------------- /src/interfaces.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace 7 | { 8 | static inline constexpr const auto INTERFACE_VERSIONS_MAX_COUNT {5U}; 9 | } 10 | using interfaceType = std::string; 11 | using interfaceVersions = std::array; 12 | 13 | static inline const std::unordered_map interfacesMap 14 | { 15 | {"ivphysicsdebugoverlay", { "VPhysicsDebugOverlay001"} }, 16 | {"ibasefilesystem", { "VBaseFileSystem011"} }, 17 | {"ishadowmgr", { "VEngineShadowMgr002"} }, 18 | {"idatacache", { "VDataCache003"} }, 19 | {"ivengineserver", { "VEngineServer023"} }, 20 | {"itoolframeworkinternal", { "VTOOLFRAMEWORKVERSION002"} }, 21 | {"ivmodelrender", { "VEngineModel016"} }, 22 | {"ivdebugoverlay", { "VDebugOverlay003"} }, 23 | {"ivprofexport", { "VProfExport001"} }, 24 | {"imdlcache", { "MDLCache004"} }, 25 | {"istudiodatacache", { "VStudioDataCache005"} }, 26 | {"ivrenderview", { "VEngineRenderView014"} }, 27 | {"ivengineclient", { "VEngineClient014"} }, 28 | {"ivgui", { "VGUI_ivgui008"} }, 29 | {"ivengineclient013", { "VEngineClient013"} }, 30 | {"icvarquery", { "VCvarQuery001"} }, 31 | {"iserverpluginhelpers", { "ISERVERPLUGINHELPERS001"} }, 32 | {"idownloadsystem", { "DownloadSystem001"} }, 33 | {"ienginesound", { "IEngineSoundClient003","IEngineSoundServer003"} }, 34 | {"isourcevirtualreality", { "SourceVirtualReality001"} }, 35 | {"inetworkstringtablecontainer", { "VEngineClientStringTable001","VEngineServerStringTable001"} }, 36 | {"iscenefilecache", { "SceneFileCache002"} }, 37 | {"ienginetool", { "VENGINETOOL003"} }, 38 | {"ctooldictionary", { "VTOOLDICTIONARY002"} }, 39 | {"imatchmaking", { "VENGINE_MATCHMAKING_VERSION001"} }, 40 | {"iplayerinfomanager", { "PlayerInfoManager002"} }, 41 | {"ienginetoolframework", { "VENGINETOOLFRAMEWORK003"} }, 42 | {"ienginetrace", { "EngineTraceServer003","EngineTraceClient003"} }, 43 | {"ienginereplay", { "EngineReplay001"} }, 44 | {"iqueuedloader", { "QueuedLoaderVersion001","QueuedLoaderVersion004"} }, 45 | {"iengineclientreplay", { "EngineClientReplay001"} }, 46 | {"igameeventmanager2", { "GAMEEVENTSMANAGER002"} }, 47 | {"iservergamedll008", { "ServerGameDLL008"} }, 48 | {"igameeventmanager", { "GAMEEVENTSMANAGER001"} }, 49 | {"ivmodelinfo003", { "VModelInfoServer003"} }, 50 | {"ivmodelinfo", { "VModelInfoServer004"} }, 51 | {"iserverchoreotools", { "VSERVERCHOREOTOOLS001"} }, 52 | {"ivmodelinfoclient", { "VModelInfoClient006"} }, 53 | {"iclientrendertargets", { "ClientRenderTargets001"} }, 54 | {"iuniformrandomstream", { "VEngineRandom001"} }, 55 | {"ireplaydemoplayer", { "ReplayDemoPlayer001"} }, 56 | {"ispatialpartition", { "SpatialPartition001"} }, 57 | {"istaticpropmgrclient", { "StaticPropMgrClient004"} }, 58 | {"imaterialsystem", { "VMaterialSystem080","VMaterialSystem081"} }, 59 | {"istaticpropmgrserver", { "StaticPropMgrServer002"} }, 60 | {"igameserverdata", { "GameServerData001"} }, 61 | {"iclienttools", { "VCLIENTTOOLS001"} }, 62 | {"ireplaysystem", { "ReplaySystem001"} }, 63 | {"ibaseclientdll", { "VClient017"} }, 64 | {"iuploadgamestats", { "ServerUploadGameStats001"} }, 65 | {"ieffects", { "IEffects001"} }, 66 | {"iengineapi", { "VENGINE_LAUNCHER_API_VERSION004"} }, 67 | {"ivengineserver021", { "VEngineServer021"} }, 68 | {"ivengineserver022", { "VEngineServer022"} }, 69 | {"ienginevgui", { "VEngineVGui001"} }, 70 | {"icliententitylist", { "VClientEntityList003"} }, 71 | {"ixboxsystem", { "XboxSystemInterface001"} }, 72 | {"ip4", { "VP4002"} }, 73 | {"icvar", { "VEngineCvar007","VEngineCvar004"} }, 74 | {"ifilesystem", { "VFileSystem017","VFileSystem022"} }, 75 | {"iservertools", { "VSERVERTOOLS003"} }, 76 | {"iclientleafsystem", { "ClientLeafSystem002"} }, 77 | {"ihltvdirector", { "HLTVDirector001"} }, 78 | {"iclientvirtualreality", { "ClientVirtualReality001"} }, 79 | {"iprediction", { "VClientPrediction001"} }, 80 | {"isoundemittersystembase", { "VSoundEmitter003","VSoundEmitter002"} }, 81 | {"ireplayfactory", { "IReplayFactory001"} }, 82 | {"iclientreplay", { "ClientReplay001"} }, 83 | {"icenterprint", { "VCENTERPRINT002"} }, 84 | {"iservertools001", { "VSERVERTOOLS001"} }, 85 | {"iservertools002", { "VSERVERTOOLS002"} }, 86 | {"imaterialsystemstub", { "VMaterialSystemStub001"} }, 87 | {"iserverreplay", { "ServerReplay001"} }, 88 | {"iservergamedll", { "ServerGameDLL010"} }, 89 | {"iserverplugincallbacks", { "ISERVERPLUGINCALLBACKS003"} }, 90 | {"iservergameclients003", { "ServerGameClients003"} }, 91 | {"isurface", { "VGUI_Surface031","VGUI_Surface030"} }, 92 | {"iservergameclients", { "ServerGameClients004"} }, 93 | {"iplayerinfomanager_v1", {"PlayerInfoManager001" } }, 94 | {"ibotmanager", { "BotManager001"} }, 95 | {"ipluginhelperscheck", { "PluginHelpersCheck001"} }, 96 | {"igamemovement", { "GameMovement001"} }, 97 | {"iparticlesystemquery", { "VParticleSystemQuery001"} }, 98 | {"igameconsole", { "GameConsole004"} }, 99 | {"igameui", { "GameUI011"} }, 100 | {"ivguimoduleloader", { "VGuiModuleLoader003"} }, 101 | {"igamecoordinator", { "GAMECOORDINATOR003"} }, 102 | {"imdllib", { "VMDLLIB001"} }, 103 | {"ihammer", { "Hammer001"} }, 104 | {"iinputsystem", { "InputSystemVersion001"} }, 105 | {"icolorcorrectionsystem", { "COLORCORRECTION_VERSION_1"} }, 106 | {"materialsystem_config_t", { "VMaterialSystemConfig002"} }, 107 | {"ivballoctracker", { "VBAllocTracker001"} }, 108 | {"imaterialsystemhardwareconfig", { "MaterialSystemHardwareConfig013","MaterialSystemHardwareConfig012"} }, 109 | {"ishaderapi", { "ShaderApi030"} }, 110 | {"idebugtextureinfo", { "DebugTextureInfo001"} }, 111 | {"ishaderdevice", { "ShaderDevice001"} }, 112 | {"ishaderdevicemgr", { "ShaderDeviceMgr001"} }, 113 | {"ishadershadow", { "ShaderShadow010"} }, 114 | {"ishadersystem", { "ShaderSystem002"} }, 115 | {"inetworksystem", { "NetworkSystemVersion001"} }, 116 | {"iserverbrowser", { "ServerBrowser005"} }, 117 | {"ivguimodule", {"VGuiModuleServerBrowser001" } }, 118 | {"isoundsystem", { "SoundSystem001"} }, 119 | {"istudiorender", { "VStudioRender026","VStudioRender025"} }, 120 | {"itooldictionary", { "VTOOLDICTIONARY002"} }, 121 | {"iadminserver", { "AdminServer002"} }, 122 | {"ishaderutil", { "VShaderUtil001"} }, 123 | {"isqlwrapperfactory", { "ISQLWRAPPER001"} }, 124 | {"ivraddll", { "vraddll_1"} }, 125 | {"ilaunchabledll", { "launchable_dll_1"} }, 126 | {"ivtex", { "VTEX_003"} }, 127 | {"iinput", { "VGUI_Input005"} }, 128 | {"iinputinternal", { "VGUI_InputInternal001"} }, 129 | {"ischememanager", { "VGUI_Scheme010"} }, 130 | {"isystem", { "VGUI_System010"} }, 131 | {"ivideosubsystem", { "IVideoSubSystem002"} }, 132 | {"ivideoservices", { "IVideoServices002"} }, 133 | {"iphysics", { "VPhysics031"} }, 134 | {"iphysicscollision", { "VPhysicsCollision007"} }, 135 | {"iphysicssurfaceprops", { "VPhysicsSurfaceProps001"} }, 136 | {"iprocessutils", { "VProcessUtils002","VProcessUtils001"} } 137 | }; 138 | -------------------------------------------------------------------------------- /src/utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(WIN32) 2 | set(UTILS_SOURCE_FILE src/windows/source-engine-interfaces-utils.cpp) 3 | else() 4 | set(UTILS_SOURCE_FILE src/unix/source-engine-interfaces-utils.cpp) 5 | endif() 6 | 7 | add_library(source-engine-interfaces-utils STATIC ${UTILS_SOURCE_FILE}) 8 | target_include_directories(source-engine-interfaces-utils PUBLIC include) 9 | set_target_properties(source-engine-interfaces-utils PROPERTIES PUBLIC_HEADER include/utils/source-engine-interfaces-utils.hpp) -------------------------------------------------------------------------------- /src/utils/include/utils/source-engine-interfaces-utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace sourceEngineInterfaces::utils 8 | { 9 | using DynamicLibsList = std::list; 10 | 11 | static inline constexpr const auto* CREATE_INTERFACE_SYMBOL {"CreateInterface"}; 12 | 13 | auto getLoadedSharedLibsNames() -> DynamicLibsList; 14 | auto getSymbolFromDynamicLib(std::string_view dynamicLibName, std::string_view symbolName) -> void*; 15 | } -------------------------------------------------------------------------------- /src/utils/src/unix/source-engine-interfaces-utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils/source-engine-interfaces-utils.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using SharedLib = struct dl_phdr_info; 9 | using ModuleHandle = void* ; 10 | 11 | namespace { 12 | auto trimSharedLibName(const SharedLib *lib) -> std::string 13 | { 14 | const std::string_view bufferView{lib->dlpi_name}; 15 | const auto subFrom{bufferView.find_last_of("/\\")}; 16 | 17 | if (std::string_view::npos == subFrom){ 18 | return ""; 19 | } 20 | 21 | return std::string{bufferView.substr(subFrom + 1)}; 22 | } 23 | 24 | auto addLibName(SharedLib *lib, std::size_t /*size*/, void *data) -> int 25 | { 26 | const auto trimmedSharedLibraryName {trimSharedLibName(lib)}; 27 | if (not trimmedSharedLibraryName.empty()){ 28 | static_cast(data)->emplace_back(trimmedSharedLibraryName); 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | auto getModuleHandle(std::string_view moduleName) -> void* 35 | { 36 | ModuleHandle dynLibHandle{dlopen(moduleName.data(), RTLD_NOLOAD | RTLD_NOW)}; 37 | 38 | if (not dynLibHandle) { 39 | return nullptr; 40 | } 41 | 42 | return static_cast(dynLibHandle); 43 | } 44 | } //namespace 45 | 46 | namespace sourceEngineInterfaces::utils 47 | { 48 | auto getSymbolFromDynamicLib(std::string_view dynamicLibName, std::string_view symbolName) -> void* 49 | { 50 | const auto dynLibHandle { static_cast(getModuleHandle(dynamicLibName)) }; 51 | 52 | if (not dynLibHandle) { 53 | return nullptr; 54 | } 55 | 56 | return dlsym(dynLibHandle, symbolName.data()); 57 | } 58 | 59 | auto getLoadedSharedLibsNames() -> DynamicLibsList 60 | { 61 | DynamicLibsList result {}; 62 | 63 | dl_iterate_phdr(addLibName, static_cast(&result)); 64 | 65 | return result; 66 | } 67 | } -------------------------------------------------------------------------------- /src/utils/src/windows/source-engine-interfaces-utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define WIN32_LEAN_AND_MEAN 3 | 4 | #include "utils/source-engine-interfaces-utils.hpp" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | using SharedLib = HMODULE; 13 | using ModuleHandle = HMODULE; 14 | 15 | static inline constexpr const auto SHARED_LIB_NAME_BUFFER_SIZE {1024U}; 16 | static inline constexpr const auto SHARED_LIBS_COUNT_BUFFER_SIZE {512U}; 17 | 18 | namespace { 19 | auto trimSharedLibName(const SharedLib *lib) -> std::string 20 | { 21 | std::array buffer{'\0'}; 22 | buffer.fill('\0'); 23 | GetModuleFileNameA(*lib, buffer.data(), buffer.size()); 24 | 25 | const std::string_view bufferView{buffer.data()}; 26 | const auto subFrom{bufferView.find_last_of("/\\")}; 27 | 28 | if (subFrom == std::string_view::npos){ 29 | return ""; 30 | } 31 | 32 | return std::string{bufferView.substr(subFrom + 1)}; 33 | } 34 | 35 | auto iterateThroughLoadedLibs(sourceEngineInterfaces::utils::DynamicLibsList& libsNamesList) -> void 36 | { 37 | DWORD modulesCount{0}; 38 | HANDLE curProcess{GetCurrentProcess()}; 39 | std::array modules{nullptr}; 40 | 41 | modules.fill(nullptr); 42 | 43 | EnumProcessModules(curProcess, modules.data(), sizeof(modules), &modulesCount); 44 | 45 | for (const auto& module : modules) { 46 | const auto trimmedSharedLibraryName {trimSharedLibName(&module)}; 47 | if (not trimmedSharedLibraryName.empty()){ 48 | libsNamesList.emplace_back(trimmedSharedLibraryName); 49 | } 50 | } 51 | } 52 | 53 | auto GetModHandle(std::string_view moduleName) -> ModuleHandle 54 | { 55 | ModuleHandle moduleHandle{GetModuleHandleA(moduleName.data())}; 56 | 57 | if (not moduleHandle){ 58 | return nullptr; 59 | } 60 | 61 | return static_cast(moduleHandle); 62 | } 63 | } // namespace 64 | 65 | namespace sourceEngineInterfaces::utils 66 | { 67 | auto getSymbolFromDynamicLib(std::string_view dynamicLibName, std::string_view symbolName) -> void* 68 | { 69 | const auto dynLibHandle {static_cast(GetModHandle(dynamicLibName))}; 70 | 71 | if (not dynLibHandle) { 72 | return nullptr; 73 | } 74 | 75 | auto* procedureAdress {static_cast(GetProcAddress(dynLibHandle, symbolName.data()))}; 76 | return procedureAdress; 77 | } 78 | 79 | auto getLoadedSharedLibsNames() -> DynamicLibsList 80 | { 81 | DynamicLibsList result{}; 82 | 83 | iterateThroughLoadedLibs(result); 84 | 85 | return result; 86 | } 87 | } --------------------------------------------------------------------------------