#include #include //#include #include #include #include "plugin.h" #include "service.h" using namespace std; list plugins; list services; bool shutdown_called = false; int LoadModules(); INT_PTR CallService(const char *name, WPARAM w, LPARAM l); HANDLE CreateServiceFunction(const char *name, SERVICE pService); DWORD WINAPI OnModulesLoadedThread( LPVOID lpParam ); int ServiceExists(const char *name); SERVICE Test(WPARAM, LPARAM); SERVICE Shutdown(WPARAM, LPARAM); PLUGINLINK link = {&CreateServiceFunction, &CallService, &ServiceExists}; int main(int argc, char *argv[]) { if(LoadModules()) return 1; //something wrong CreateServiceFunction("Core/Test", (SERVICE)Test); CreateServiceFunction("Core/Shutdown", (SERVICE)Shutdown); for(list::iterator p = plugins.begin(); p != plugins.end(); p++) //initializing plugins { (*p)->getFuncs().load(&link); } for(list::iterator p = plugins.begin(); p != plugins.end(); p++) { if((*p)->getFuncs().loaded) { CreateThread(NULL, 0, OnModulesLoadedThread, (LPVOID)(*p)->getFuncs().loaded, 0, 0); } } for(;;) { if(shutdown_called) { plugin *db; for(list::iterator p = plugins.begin(); p != plugins.end(); p++) { if((*p)->getPluginInfo()->flags == F_DB_PLUGIN) db = (*p); else delete (*p); //is it right? , at least do not crasing... } delete db; plugins.clear(); break; } Sleep(1000); } return 0; } int LoadModules() { WIN32_FIND_DATAA findFileData; HANDLE hFile = 0; if(!(hFile = FindFirstFileA(".\\modules\\*", &findFileData))) return 1; //failed to find any plugins in directory HMODULE hPlugin = 0; char tmp[MAX_PATH] = {0}; plugin::exported_funcs_s funcs; while(hFile != INVALID_HANDLE_VALUE && GetLastError() != ERROR_NO_MORE_FILES) { strcpy(tmp, ".\\modules\\"); strcat(tmp, findFileData.cFileName); hPlugin = LoadLibraryA(tmp); funcs.info = (SetPluginInfo)GetProcAddress(hPlugin, "SetPluginInfo"); funcs.load = (Load)GetProcAddress(hPlugin, "Load"); funcs.loaded = (OnModulesLoaded)GetProcAddress(hPlugin, "OnModulesLoaded"); funcs.unload = (Unload)GetProcAddress(hPlugin, "Unload"); if(funcs.info && funcs.load) { PLUGININFO *pi = funcs.info(); plugins.push_back(new plugin(hPlugin, funcs, pi)); } else FreeLibrary(hPlugin); FindNextFileA(hFile, &findFileData); } return 0; } const HMODULE plugin::getHmodule() { return hModule; } int plugin::setHandle(const HMODULE &hMod) { if(!hMod) return 1; hModule = hMod; return 0; } const plugin::exported_funcs_s plugin::getFuncs() { return funcs; } PLUGININFO *plugin::getPluginInfo() { return pluginInfo; } plugin::plugin(const HMODULE hMod, const exported_funcs_s fnct, PLUGININFO *info) { hModule = hMod; funcs = fnct; pluginInfo = info; } plugin::~plugin() { if(funcs.unload) funcs.unload(); FreeLibrary(hModule); } service::service(const char *name, SERVICE service) { szName = new char [strlen(name)+1]; strcpy(szName, name); pService = service; } const char *service::getName() { return szName; } const SERVICE service::getService() { return pService; } INT_PTR CallService(const char *name, WPARAM w, LPARAM l) { for(list::iterator p = services.begin(); p != services.end(); p++) { if(!strcmp((*p)->getName(), name)) { SERVICE s = *(*p)->getService(); return s(w, l); } } return 0; } HANDLE CreateServiceFunction(const char *name, SERVICE pService) { if(!ServiceExists(name)) services.push_back(new service(name, pService)); } int ServiceExists(const char *name) { for(list::iterator p = services.begin(); p != services.end(); p++) if(!strcmp((*p)->getName(), name)) return 1; return 0; } SERVICE Test(WPARAM, LPARAM) { MessageBoxA(0, "Test service working", "INFO", MB_OK); return 0; } SERVICE Shutdown(WPARAM, LPARAM) { shutdown_called = true; } DWORD WINAPI OnModulesLoadedThread( LPVOID lpParam ) { OnModulesLoaded &l = (OnModulesLoaded&)lpParam; l(); return 0; }