dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
{
	int i;
	HMODULE lib;

	lib = LoadLibrary(name);
	if (!lib)
		return NULL;

	if (funcs)
	{
		for (i = 0; funcs[i].name; i++)
		{
			*funcs[i].funcptr = GetProcAddress(lib, funcs[i].name);
			if (!*funcs[i].funcptr)
				break;
		}
		if (funcs[i].name)
		{
			Sys_CloseLibrary((dllhandle_t*)lib);
			lib = NULL;
		}
	}

	return (dllhandle_t*)lib;
}
Exemple #2
0
/*
 * @brief Opens and loads the specified shared library. The function identified by
 * entry_point is resolved and invoked with the specified parameters, its
 * return value returned by this function.
 */
void *Sys_LoadLibrary(const char *name, void **handle, const char *entry_point, void *params) {
	typedef void *EntryPointFunc(void *);
	EntryPointFunc *EntryPoint;

	if (*handle) {
		Com_Warn("%s: handle already open\n", name);
		Sys_CloseLibrary(handle);
	}

	Sys_OpenLibrary(name, handle);

	EntryPoint = (EntryPointFunc *) dlsym(*handle, entry_point);

	if (!EntryPoint) {
		Sys_CloseLibrary(handle);
		Com_Error(ERR_DROP, "%s: Failed to resolve %s\n", name, entry_point);
	}

	return EntryPoint(params);
}
void PbSvUnload()
{
    pbsv.field_4 = 0;
    pbsv.sa = 0;
    pbsv.sb = 0;
    pbsv.ConnectStringTrap = 0;
    pbsv.AuthClient = 0;
    pbsv.CaptureConsole = 0;
    if ( pbsv.hLibModule )
    {
        Sys_CloseLibrary(pbsv.hLibModule);
    }
    pbsv.hLibModule = 0;
}
void PHandler_Unload(int id) // Unload a plugin, safe for use.
{
    static qboolean unloading = qfalse;
    void *lib_handle;
    int i;
    
    if(unloading){
	Com_PrintError("PHandler_Unload: tried to unload plugin #%d from it's destructor!\n",id);
	return;
    }
    
    
    if(pluginFunctions.plugins[id].loaded){
        if(pluginFunctions.plugins[id].exports != 0){ // Library-plugins cannot be unloaded, see plugins/readme.txt
            Com_PrintError("PHandler_Unload: Cannot unload a library plugin!\n");
            return;
        }
        if(pluginFunctions.plugins[id].scriptfunctions != 0 || pluginFunctions.plugins[id].scriptmethods != 0){
            // Script-library plugins cannot be unloaded, see plugins/readme.txt
            Com_PrintError("PHandler_Unload: Cannot unload a script-library plugin!\n");
            return;
        }
        unloading = qtrue; // Preventing endless recursion...
        if(pluginFunctions.plugins[id].OnUnload != NULL){
            pluginFunctions.hasControl = id;
            (*pluginFunctions.plugins[id].OnUnload)();
            pluginFunctions.hasControl = PLUGIN_UNKNOWN;
        }
        unloading = qfalse;
        // Remove all server commands of the plugin
        for(i=0;i<pluginFunctions.plugins[id].cmds;i++){
            if(pluginFunctions.plugins[id].cmd[i].xcommand!=NULL){
                Com_DPrintf("Removing command \"%s\"...\n",pluginFunctions.plugins[id].cmd[i].name);
                Cmd_RemoveCommand(pluginFunctions.plugins[id].cmd[i].name);
            }

        }
        lib_handle = pluginFunctions.plugins[id].lib_handle;                // Save the lib handle
        Com_Memset(&(pluginFunctions.plugins[id]), 0x00, sizeof(plugin_t));     // Wipe out all the data
        Sys_CloseLibrary(lib_handle);                                                // Close the dll as there are no more references to it
        --pluginFunctions.loadedPlugins;
    }else{
        Com_Printf("Tried unloading a not loaded plugin!\nPlugin ID: %d.",id);
    }
}
void PHandler_Load(char* name) // Load a plugin, safe for use
{
    int i,j;
    char* realpath;
    char filepathbuf[MAX_OSPATH];
    char hash[128];
    long unsigned sizeofhash;
    void *lib_handle;

    pluginInfo_t info;

    if(!pluginFunctions.enabled){
        Com_Printf("Plugin handler is not initialized!\n");
        return;

    }
    if(pluginFunctions.loadedPlugins>=MAX_PLUGINS-1){
        Com_Printf("Too many plugins loaded.");
        return;
    }
    /* +18 for "plugins/%s.dynlib" */
    if(strlen(name) + 18 >= sizeof(pluginFunctions.plugins[0].name)){
        Com_Printf("Pluginname is too long.");
        return;
    }
    Com_DPrintf("Checking if the plugin is not already loaded...\n");
    //    Check if the plugin is not already loaded...
    for(i=0;i<MAX_PLUGINS;i++){
        if(Q_stricmp(name, pluginFunctions.plugins[i].name) == qfalse){
            Com_Printf("This plugin is already loaded!\n");
            return;
        }
    }
    Com_DPrintf("Checking if the plugin file exists and is of correct format...\n");

    //Additional test if a file is there
    realpath = (char*)PHandler_OpenTempFile(name, filepathbuf, sizeof(filepathbuf)); // Load a plugin, safe for use
    if(realpath == NULL)
    {
        return;
    }

    Com_DPrintf("Loading the plugin .so...\n");


    if(com_securemode)
    {
	hash[0] = '\0';
	sizeofhash = sizeof(hash);

	Sec_HashFile(SEC_HASH_TIGER, realpath, hash, &sizeofhash, qfalse);

	if(Q_stricmp(hash ,PLUGINGAMERANGER_HASH) && Q_stricmp(hash ,PLUGINCENSOR_HASH) && Q_stricmp(hash ,PLUGINANTISPAM_HASH))
	{
		Com_Printf("Tiger = %s\n", hash);
		Com_PrintError("%s checksum missmatch! This plugin will not be loaded in securemode.\n", realpath);
		return;
	}

    }

    lib_handle = Sys_LoadLibrary(realpath);
    if (!lib_handle)
	{
        Com_PrintError("Failed to load the plugin %s!\n", realpath);
        PHandler_CloseTempFile( realpath );
        return;
    }
    PHandler_CloseTempFile( realpath );
    Com_DPrintf("Plugin OK! Loading...\n");
    // find first free plugin slot
    for(i=0;i<MAX_PLUGINS;i++){
        if(!(pluginFunctions.plugins[i].loaded))
            break;
    }
    pluginFunctions.plugins[i].OnInit = Sys_GetProcedure("OnInit");
    for(j=0;j<PLUGINS_ITEMCOUNT;++j){
        pluginFunctions.plugins[i].OnEvent[j] = Sys_GetProcedure(PHandler_Events[j]);

    }
    pluginFunctions.plugins[i].OnInfoRequest = pluginFunctions.plugins[i].OnEvent[PLUGINS_ONINFOREQUEST];
    pluginFunctions.plugins[i].OnUnload = Sys_GetProcedure("OnUnload");
    pluginFunctions.plugins[i].loaded = qtrue;
    pluginFunctions.plugins[i].enabled = qtrue;
    Q_strncpyz(pluginFunctions.plugins[i].name, name, sizeof(pluginFunctions.plugins[i].name));
    pluginFunctions.initializing_plugin = qtrue;

    if(pluginFunctions.plugins[i].OnInit==NULL){
        Com_Printf("Error loading plugin's OnInit function.\nPlugin load failed.\n");
        pluginFunctions.initializing_plugin = qfalse;
        memset(pluginFunctions.plugins + i,0x00,sizeof(plugin_t));    // We need to remove all references so we can dlclose.
        Sys_CloseLibrary(lib_handle);
        return;
    }

    pluginFunctions.hasControl = PLUGIN_UNKNOWN;
    Com_Printf("Plugin's OnInit executed successfully!\n");
    //    Save info about the loaded plugin
    pluginFunctions.initializing_plugin = qfalse;
    pluginFunctions.loadedPlugins++;
    pluginFunctions.plugins[i].lib_handle = lib_handle;

    if(pluginFunctions.plugins[i].OnInfoRequest){
        Com_DPrintf("Fetching plugin information...\n");
        pluginFunctions.hasControl = i;
        (*pluginFunctions.plugins[i].OnInfoRequest)(&info);
        pluginFunctions.hasControl = PLUGIN_UNKNOWN;
			
        if(info.handlerVersion.major != PLUGIN_HANDLER_VERSION_MAJOR || (info.handlerVersion.minor - info.handlerVersion.minor %100) != (PLUGIN_HANDLER_VERSION_MINOR - PLUGIN_HANDLER_VERSION_MINOR %100))
	{
            Com_PrintError("This plugin might not be compatible with this server version! Requested plugin handler version: %d.%d, server's plugin handler version: %d.%d. Unloading the plugin...\n",info.handlerVersion.major,info.handlerVersion.minor, PLUGIN_HANDLER_VERSION_MAJOR,PLUGIN_HANDLER_VERSION_MINOR);
            PHandler_Unload(i);
            return;
        }

    }else{

        Com_PrintError("function OnInfoRequest not found in the plugin file. Unloading...\n");
        PHandler_Unload(i);
        return;

    }

    Com_DPrintf("Executing plugin's OnInit...\n");

    pluginFunctions.hasControl = i;
    if((*pluginFunctions.plugins[i].OnInit)()<0)
    {
        pluginFunctions.hasControl = PLUGIN_UNKNOWN;
        Com_Printf("Error in plugin's OnInit function!\nPlugin load failed.\n");
        pluginFunctions.initializing_plugin = qfalse;
        memset(pluginFunctions.plugins + i,0x00,sizeof(plugin_t));    // We need to remove all references so we can dlclose.
        Sys_CloseLibrary(lib_handle);
        return;
    }

    Com_Printf("Plugin %s loaded successfully. Server is currently running %d plugins.\n",pluginFunctions.plugins[i].name,pluginFunctions.loadedPlugins);
    return;

}