/* * Function * GfModFreeInfoList * * Description * Free a modules info list without unloading the modules * * Parameters * modlist (in/out) list of info to free * * Return * 0 Ok * -1 Error * * Remarks * */ int GfModFreeInfoList(tModList **modlist) { tModList *curMod; tModList *nextMod; curMod = *modlist; if (curMod == 0) return 0; do { nextMod = curMod->next; GfModInfoFreeNC(curMod->modInfo, curMod->modInfoSize); free(curMod->sopath); free(curMod); curMod = nextMod; } while (curMod != *modlist); *modlist = 0; return 0; }
/* * Function * linuxModUnloadList * * Description * Unload the modules of a list * * Parameters * modlist (in/out) list of modules to unload * * Return * 0 Ok * -1 Error * * Remarks * */ static int linuxModUnloadList(tModList **modlist) { tModList *curMod; tModList *nextMod; int termSts; int unloadSts = 0; curMod = *modlist; if (curMod == 0) return 0; do { nextMod = curMod->next; /* Terminate the module */ termSts = GfModTerminate(curMod->handle, curMod->sopath); if (termSts) unloadSts = termSts; // Comment out for valgrind runs, be aware that the driving with the keyboard does // just work to first time this way. dlclose(curMod->handle); GfLogInfo("Unloaded module %s\n", curMod->sopath); GfModInfoFreeNC(curMod->modInfo, curMod->modInfoSize); free(curMod->sopath); free(curMod); curMod = nextMod; } while (curMod != *modlist); *modlist = (tModList *)NULL; return unloadSts; }
/* * Function * GfModInitialize * * Description * Initialize the module with given handle and library file path * * Parameters * soHandle (in) handle of the loaded shared library * soPath (in) path of the loaded shared library * gfid (in) id of the gaming framework that the module MUST implement to be initialized * (Not taken into account if == GfIdAny) * mod (in) address of module entry to allocate and initialize * (0 if any error occured or modules not retained for bad GFId) * * Return * 0 if initialization succeeded (even if the module was rejected for bad GFId) * -1 if any error occured * * Remarks * */ int GfModInitialize(tSOHandle soHandle, const char *soPath, unsigned int gfid, tModList **mod) { tfModInfoWelcome fModInfoWelcome; /* function to exchange information with the module at welcome time */ tfModInfoInitialize fModInfoInit = 0; /* init function of the module */ int initSts = 0; /* returned status */ int retained = 1; char soName[256]; char soDir[1024]; char* lastSlash; /* Allocate module entry in list */ if (!(*mod = (tModList*)calloc(1, sizeof(tModList)))) { GfLogError("GfModInitialize: Failed to allocate tModList for module %s\n", soPath); return -1; } /* Determine the shared library / DLL name and load dir */ strcpy(soDir, soPath); lastSlash = strrchr(soDir, '/'); if (lastSlash) { strcpy(soName, lastSlash+1); *lastSlash = 0; } else { strcpy(soName, soPath); *soDir = 0; } soName[strlen(soName) - SOFileExtLen] = 0; /* cut so file extension */ /* Welcome the module : exchange informations with it : 1) Call the dedicated module function if present */ if ((fModInfoWelcome = (tfModInfoWelcome)dlsym(SOHandle(soHandle), GfModInfoWelcomeFuncName)) != 0) { /* Prepare information to give to the module */ tModWelcomeIn welcomeIn; welcomeIn.itfVerMajor = 1; welcomeIn.itfVerMinor = 0; welcomeIn.name = soName; /* Prepare a place for the module-given information */ tModWelcomeOut welcomeOut; /* Call the welcome function */ if ((initSts = fModInfoWelcome(&welcomeIn, &welcomeOut)) != 0) { GfLogError("GfModInitialize: Module welcome function failed %s\n", soPath); } else { /* Save information given by the module */ (*mod)->modInfoSize = welcomeOut.maxNbItf; } } /* 2) If not present, default number of interfaces (backward compatibility) */ else { (*mod)->modInfoSize = GfModInfoDefaultMaxItf; } /* Get module initialization function if welcome succeeded : 1) Try the new sheme (fixed name) */ if (initSts == 0) { fModInfoInit = (tfModInfoInitialize)dlsym(SOHandle(soHandle), GfModInfoInitializeFuncName); //GfLogDebug("GfModInitialize: fModInfoInit(%s) @ %p\n", // GfModInfoInitializeFuncName, fModInfoInit); } /* 2) Backward compatibility (dll name) */ if (initSts == 0 && !fModInfoInit) { fModInfoInit = (tfModInfoInitialize)dlsym(SOHandle(soHandle), soName); //GfLogDebug("GfModInitialize: fModInfoInit(%s) @ %p\n", soName, fModInfoInit); } /* Call module initialization function if welcome succeeded and init function found */ if (initSts == 0 && fModInfoInit) { /* Allocate module interfaces info array according to the size we got */ tModInfo* constModInfo; if ((constModInfo = GfModInfoAllocate((*mod)->modInfoSize)) != 0) { /* Library loaded, init function exists, call it... */ if ((initSts = fModInfoInit(constModInfo)) == 0) { /* Duplicate strings in each interface, in case the module gave us static data ! */ if (((*mod)->modInfo = GfModInfoDuplicate(constModInfo, (*mod)->modInfoSize)) != 0) { /* Reject module if not of requested gaming framework Id */ if (gfid != GfIdAny && (*mod)->modInfo[0].gfId != gfid) { GfLogTrace("GfModInitialize: Module not retained %s\n", soPath); GfModInfoFreeNC((*mod)->modInfo, (*mod)->modInfoSize); retained = 0; } /* Free the module info data returned by the module (we have a copy) */ GfModInfoFree(constModInfo); } else { initSts = -1; } } else { GfLogError("GfModInitialize: Module init function failed %s\n", soPath); } } else { initSts = -1; } } /* If init function not found, we have a problem ... */ else { GfLogError("GfModInitialize: Module init function %s not found ... %s\n", soPath, dlerror()); initSts = -1; } /* Store other module information */ if (initSts == 0 && retained) { GfOut("Initialized module %s (maxItf=%d)\n", soPath, (*mod)->modInfoSize); (*mod)->handle = (tSOHandle)soHandle; (*mod)->sopath = strdup(soPath); } else { free(*mod); *mod = 0; } return initSts; }