#include "StdAfx.h" #include "GlobalFunc.h" #include "../T2.h" #include "T2DLL.h" #include "T2PluginLoader.h" #include "T2PluginSpecifier.h" T2PluginLoader::T2PluginLoader() { } T2PluginLoader::~T2PluginLoader() { POSITION p = mList.GetHeadPosition(); while (p) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p); if (spec->mIsLoaded) UnloadPlugin(spec); delete spec; } } void T2PluginLoader::InitFileList() { char *dirBuf = (char *) malloc(1000); GetTowerDirectory(dirBuf); strcat(dirBuf, "Plugins\\"); char *dirBufEnd = &dirBuf[strlen(dirBuf)]; CString databasePath = GetTowerDirectory() + "plugins\\Database"; BOOL fail = false; CFile file; if (file.Open(databasePath, CFile::modeRead)) { CArchive archive(&file, CArchive::load); DWORD countDatabase = mList.GetCount(); archive >> countDatabase; for (unsigned int index = 0; index < countDatabase; index++) { T2PluginSpecifier *spec = new T2PluginSpecifier; spec->Read(archive); mList.AddTail(spec); } archive.Close(); file.Close(); // check that the database is up-to-date CFileStatus status; int numSpec = 0; POSITION pos = mList.GetHeadPosition(); while (pos) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(pos); if (CFile::GetStatus(spec->mPath, status)) { if (status.m_mtime == spec->mTime) numSpec++; } } if (numSpec != mList.GetCount()) fail = true; numSpec = 0; strcpy(dirBufEnd, "*.t2p"); WIN32_FIND_DATA findInfo; HANDLE handle = FindFirstFile(dirBuf, &findInfo); BOOL find = (handle != INVALID_HANDLE_VALUE); while (find) { find = FindNextFile(handle, &findInfo); numSpec++; } FindClose(handle); if (numSpec != mList.GetCount()) fail = true; } else { fail = true; } if (fail) { // update the DB AfxSetResourceHandle(gT2App->m_hInstance); CDialog *dialog = new CDialog; dialog->Create(1000); gT2App->app_vfB4(); POSITION pos = mList.GetHeadPosition(); while (pos) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(pos); delete spec; } mList.RemoveAll(); strcpy(dirBufEnd, "*.t2p"); WIN32_FIND_DATA findInfo; HANDLE handle = FindFirstFile(dirBuf, &findInfo); BOOL find = (handle != INVALID_HANDLE_VALUE); while (find) { strcpy(dirBufEnd, findInfo.cFileName); T2PluginSpecifier *spec = new T2PluginSpecifier; spec->Initialize(NULL, dirBuf); spec->mInstance = NULL; spec->mIsLoaded = false; mList.AddTail(spec); find = FindNextFile(handle, &findInfo); } FindClose(handle); if (file.Open(databasePath, CFile::modeWrite | CFile::modeCreate)) { CArchive archive(&file, CArchive::store); DWORD count = mList.GetCount(); archive << count; pos = mList.GetHeadPosition(); while (pos) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(pos); spec->Write(archive); } archive.Close(); file.Close(); } dialog->DestroyWindow(); } free(dirBuf); } typedef void *(MSVC_STDCALL* ConstructProgramPluginType) (T2PluginSpecifier *); typedef void (MSVC_STDCALL* DestructProgramPluginType) (void); /*static*/ void* T2PluginLoader::LoadPlugin(T2PluginSpecifier* spec) { if (!spec->mIsLoaded) { HMODULE module = LoadLibrary(spec->mPath); spec->mInstance = (HINSTANCE) module; } ConstructProgramPluginType func = (ConstructProgramPluginType) GetProcAddress((HMODULE) spec->mInstance, "ConstructProgramPlugin"); #line 142 _ASSERT(func); spec->mIsLoaded = true; return func(spec); } /*static*/ void T2PluginLoader::UnloadPlugin(T2PluginSpecifier* spec) { if (spec->mIsSubPlugin) { spec->mIsLoaded = false; return; } #line 154 _ASSERT(spec->mIsLoaded); DestructProgramPluginType func = (DestructProgramPluginType) GetProcAddress((HMODULE) spec->mInstance, "DestructProgramPlugin"); #line 156 _ASSERT(func); spec->mIsLoaded = false; func(); FreeLibrary((HMODULE) spec->mInstance); } void T2PluginLoader::SetTypeFilter(POSITION& p, DWORD type) { p = mList.GetHeadPosition(); if (type) mTypeFilter = type; else mTypeFilter = 0; } T2PluginSpecifier* T2PluginLoader::GetNext(POSITION& p) { while (p) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p); if ( (mTypeFilter == 0 || spec->mType == mTypeFilter) && (spec->m28 == -1 || spec->m28 == 1) // 1 might be a version constant here ) return spec; } return NULL; } T2PluginSpecifier* T2PluginLoader::FindPlugin(DWORD id, DWORD type) { POSITION p; T2PluginSpecifier *spec; SetTypeFilter(p, type); while ((spec = GetNext(p))) { if (spec->mID == id) return spec; } return NULL; } T2PluginSpecifier* T2PluginLoader::FindPlugin(const char* name, DWORD type) { POSITION p; T2PluginSpecifier *spec; SetTypeFilter(p, type); while ((spec = GetNext(p))) { if (spec->mPluginName == name) return spec; } return NULL; }