#include "CT2App.h" #include "GlobalFunc.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 dbPath = GetTowerDirectory() + "plugins\\Database"; BOOL errorFlag = false; CFile file; if (file.Open(dbPath, CFile::modeRead)) { CArchive archive(&file, CArchive::load); DWORD count = mList.GetCount(); archive >> count; for (unsigned int i = 0; i < count; i++) { 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 count2 = 0; POSITION p = mList.GetHeadPosition(); while (p) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p); if (CFile::GetStatus(spec->mPath, status)) { if (status.m_mtime == spec->mTime) count2++; } } if (count2 != mList.GetCount()) errorFlag = true; count2 = 0; strcpy(dirBufEnd, "*.t2p"); WIN32_FIND_DATA findData; HANDLE findHandle = FindFirstFile(dirBuf, &findData); BOOL findOK = (findHandle != INVALID_HANDLE_VALUE); while (findOK) { findOK = FindNextFile(findHandle, &findData); count2++; } FindClose(findHandle); if (count2 != mList.GetCount()) errorFlag = true; } else { errorFlag = true; } if (errorFlag) { // update the DB AfxSetResourceHandle(gT2App->m_hInstance); CDialog *dialog = new CDialog; dialog->Create(1000); gT2App->app_vfB4(); POSITION p = mList.GetHeadPosition(); while (p) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p); delete spec; } mList.RemoveAll(); strcpy(dirBufEnd, "*.t2p"); WIN32_FIND_DATA findData; HANDLE findHandle = FindFirstFile(dirBuf, &findData); BOOL findOK = (findHandle != INVALID_HANDLE_VALUE); while (findOK) { strcpy(dirBufEnd, findData.cFileName); T2PluginSpecifier *spec = new T2PluginSpecifier; spec->Initialize(NULL, dirBuf); spec->mInstance = NULL; spec->mIsLoaded = false; mList.AddTail(spec); findOK = FindNextFile(findHandle, &findData); } FindClose(findHandle); if (file.Open(dbPath, CFile::modeWrite | CFile::modeCreate)) { CArchive archive(&file, CArchive::store); DWORD count = mList.GetCount(); archive << count; p = mList.GetHeadPosition(); while (p) { T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p); 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; }