diff -r 7602d7fb60d9 -r 026da5437111 loader/loader.cpp --- a/loader/loader.cpp Fri Jul 11 06:51:21 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,318 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include -#include -#include - -#if defined _MSC_VER - #define DLL_EXPORT extern "C" __declspec(dllexport) - #define openlib(lib) LoadLibrary(lib) - #define closelib(lib) FreeLibrary(lib) - #define findsym(lib, sym) GetProcAddress(lib, sym) - #define PLATFORM_EXT ".dll" - #define vsnprintf _vsnprintf - #define PATH_SEP_CHAR "\\" - inline bool IsPathSepChar(char c) - { - return (c == '/' || c == '\\'); - } - #include -#else - #define DLL_EXPORT extern "C" __attribute__((visibility("default"))) - #define openlib(lib) dlopen(lib, RTLD_NOW) - #define closelib(lib) dlclose(lib) - #define findsym(lib, sym) dlsym(lib, sym) - #define PLATFORM_EXT ".so" - typedef void * HINSTANCE; - #define PATH_SEP_CHAR "/" - inline bool IsPathSepChar(char c) - { - return (c == '/'); - } - #include -#endif - -#define METAMOD_API_MAJOR 2 -#define FILENAME_1_4_EP1 "sourcemod.1.ep1" PLATFORM_EXT -#define FILENAME_1_6_EP2 "sourcemod.2.ep2" PLATFORM_EXT -#define FILENAME_1_6_EP1 "sourcemod.2.ep1" PLATFORM_EXT - -HINSTANCE g_hCore = NULL; -bool load_attempted = false; - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); - -class FailPlugin : public SourceMM::ISmmFailPlugin -{ -public: - int GetApiVersion() - { - return fail_version; - } - - bool Load(SourceMM::PluginId id, SourceMM::ISmmAPI *ismm, char *error, size_t maxlength, bool late) - { - if (error != NULL && maxlength != 0) - { - UTIL_Format(error, maxlength, "%s", error_buffer); - } - return false; - } - - int fail_version; - char error_buffer[512]; -} s_FailPlugin; - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - size_t len = vsnprintf(buffer, maxlength, fmt, ap); - va_end(ap); - - if (len >= maxlength) - { - len = maxlength - 1; - buffer[len] = '\0'; - } - - return len; -} - -METAMOD_PLUGIN *_GetPluginPtr(const char *path, int fail_api) -{ - METAMOD_FN_ORIG_LOAD fn; - METAMOD_PLUGIN *pl; - int ret; - - if (!(g_hCore=openlib(path))) - { -#if defined __linux__ - UTIL_Format(s_FailPlugin.error_buffer, - sizeof(s_FailPlugin.error_buffer), - "%s", - dlerror()); -#else - DWORD err = GetLastError(); - - if (FormatMessageA( - FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - s_FailPlugin.error_buffer, - sizeof(s_FailPlugin.error_buffer), - NULL) - == 0) - { - UTIL_Format(s_FailPlugin.error_buffer, - sizeof(s_FailPlugin.error_buffer), - "unknown error %x", - err); - } -#endif - - s_FailPlugin.fail_version = fail_api; - - return (METAMOD_PLUGIN *)&s_FailPlugin; - } - - if (!(fn=(METAMOD_FN_ORIG_LOAD)findsym(g_hCore, "CreateInterface"))) - { - goto error; - } - - pl = (METAMOD_PLUGIN *)fn(METAMOD_PLAPI_NAME, &ret); - if (!pl) - { - goto error; - } - - return pl; -error: - closelib(g_hCore); - g_hCore = NULL; - return NULL; -} - -bool GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength) -{ -#if defined _MSC_VER - MEMORY_BASIC_INFORMATION mem; - if (!VirtualQuery(pAddr, &mem, sizeof(mem))) - return false; - if (mem.AllocationBase == NULL) - return false; - HMODULE dll = (HMODULE)mem.AllocationBase; - GetModuleFileName(dll, (LPTSTR)buffer, maxlength); -#else - Dl_info info; - if (!dladdr(pAddr, &info)) - return false; - if (!info.dli_fbase || !info.dli_fname) - return false; - const char *dllpath = info.dli_fname; - snprintf(buffer, maxlength, "%s", dllpath); -#endif - return true; -} - -DLL_EXPORT METAMOD_PLUGIN *CreateInterface_MMS(const MetamodVersionInfo *mvi, const MetamodLoaderInfo *mli) -{ - char *filename; - - load_attempted = true; - - if (mvi->api_major > METAMOD_API_MAJOR) - { - return NULL; - } - - switch (mvi->source_engine) - { - case SOURCE_ENGINE_ORANGEBOX: - { - filename = FILENAME_1_6_EP2; - break; - } - case SOURCE_ENGINE_EPISODEONE: - case SOURCE_ENGINE_ORIGINAL: - { - filename = FILENAME_1_6_EP1; - break; - } - default: - { - return NULL; - } - } - - char abspath[256]; - UTIL_Format(abspath, sizeof(abspath), "%s" PATH_SEP_CHAR "%s", mli->pl_path, filename); - - return _GetPluginPtr(abspath, METAMOD_FAIL_API_V2); -} - -DLL_EXPORT void UnloadInterface_MMS() -{ - if (g_hCore) - { - closelib(g_hCore); - g_hCore = NULL; - } -} - -DLL_EXPORT void *CreateInterface(const char *iface, int *ret) -{ - /** - * If a load has already been attempted, bail out immediately. - */ - if (load_attempted) - { - return NULL; - } - - if (strcmp(iface, METAMOD_PLAPI_NAME) == 0) - { - char thisfile[256]; - char targetfile[256]; - - if (!GetFileOfAddress((void *)CreateInterface_MMS, thisfile, sizeof(thisfile))) - { - return NULL; - } - - size_t len = strlen(thisfile); - for (size_t iter=len-1; iter>=0 && iter