Index: modules/App Framework/Plugin.cpp =================================================================== diff -u -N --- modules/App Framework/Plugin.cpp (revision 7d997aef1e72f049ed1bc199e1b765d737d9963a) +++ modules/App Framework/Plugin.cpp (revision 0) @@ -1,282 +0,0 @@ -/************************************************************************ - Copy Handler 1.x - program for copying data in Microsoft Windows - systems. - Copyright (C) 2001-2003 Ixen Gerthannes (ixen@interia.pl) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*************************************************************************/ -#include "stdafx.h" -#include "plugin.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -CPlugin::CPlugin(bool bInternal) -{ - m_hModule=NULL; - m_bInternal=bInternal; - m_byLoadState=PLGS_NOTLOADED; - m_lLockCount=0; - m_pszFilename=NULL; - m_bNeedChange=false; - - // cache - m_ppdData=NULL; - - // exports addresses - m_pfnInit=NULL; - m_pfnUninit=NULL; - m_pfnGetInfo=NULL; -} - -CPlugin::~CPlugin() -{ - // free all - Unload(true); // unload if loaded - - // free filename - delete [] m_pszFilename; - m_pszFilename=NULL; -} - -void CPlugin::Load(PCTSTR pszName, PFNEXTINFOPROC pfn) -{ - if (pszName && m_byLoadState != PLGS_NOTLOADED) - { - // trying to load a plugin to already initialized class - if (m_bInternal) - THROW_PLUGINEXCEPTIONEX(_T("Trying to load a plugin to already initialized class (internal plugin)."), NULL, PLERR_LOAD, 0); - else - THROW_PLUGINEXCEPTIONEX(_T("Trying to load a plugin to already initialized class (external plugin)."), pszName, PLERR_LOAD, 0); - } - - // check if loading is needed - if (!pszName) - { - if (m_byLoadState == PLGS_LOADED) - return; - else if (m_byLoadState == PLGS_NOTLOADED) - THROW_PLUGINEXCEPTIONEX(_T("Cannot re-load plugin (with NULL path) when it wasn't loaded before."), NULL, PLERR_LOAD, 0); // not loaded and pszName==NULL - this shouldn't happen - } - - // load - copy data to internal members - if (m_bInternal) - { - // copy only if there is anything to copy - if (pszName) - { - m_hModule=(HMODULE)pszName; // should be HMODULE of current app - m_pszFilename=(TCHAR*)pszName; - } - else - m_hModule=(HMODULE)m_pszFilename; - m_byLoadState=PLGS_LOADED; - } - else - { - // remember the name of this plugin (path) - if (pszName) - { - delete [] m_pszFilename; - m_pszFilename=new TCHAR[_tcslen(pszName)+1]; - _tcscpy(m_pszFilename, pszName); - } - - // try to open - m_hModule=LoadLibrary(m_pszFilename); - if (!m_hModule || !LoadExports()) - { - m_byLoadState=PLGS_NOTLOADED; - if (m_bInternal) - THROW_PLUGINEXCEPTIONEX(_T("Cannot load an internal plugin - probably LoadExports failed."), NULL, PLERR_LOAD, GetLastError()); - else - THROW_PLUGINEXCEPTIONEX(_T("Cannot load an external plugin - either LoadLibrary failed or LoadExports failed."), pszName, PLERR_LOAD, GetLastError()); - } - else - m_byLoadState=PLGS_LOADED; - } - - // now initialize the plugin - Init(pfn); -} - -void CPlugin::Unload(bool bCompletely) -{ - if (m_byLoadState == PLGS_NOTLOADED) - return; - - // uninit if loaded - if (m_byLoadState == PLGS_LOADED) - Uninit(); - - // release the loaded library (if partial - doesn't need to) - if (!m_bInternal && m_byLoadState == PLGS_LOADED) - { - if (!FreeLibrary(m_hModule)) - THROW_PLUGINEXCEPTIONEX(_T("Cannot release loaded plugin (FreeLibrary failed)."), m_pszFilename, PLERR_UNLOAD, GetLastError()); - } - m_hModule=NULL; - - // release the rest of data if completely - if (bCompletely) - { - // filename - if (!m_bInternal) - delete [] m_pszFilename; - m_pszFilename=NULL; - - // cached data - delete m_ppdData; - m_ppdData=NULL; - - // free other data - FreePluginData(); - } - - // determine load state - m_byLoadState=(BYTE)(bCompletely ? PLGS_NOTLOADED : PLGS_PARTIAL); -} - -bool CPlugin::LoadExports() -{ - _ASSERT(m_hModule); - - m_pfnInit=(PFNINIT)GetProcAddress(m_hModule, "Init"); - if (!m_pfnInit) - { - TRACE("Last Error: %lu\n!!!", GetLastError()); - return false; - } - m_pfnUninit=(PFNUNINIT)GetProcAddress(m_hModule, "Uninit"); - if (!m_pfnUninit) - return false; - m_pfnGetInfo=(PFNGETINFO)GetProcAddress(m_hModule, "GetInfo"); - if (!m_pfnUninit) - return false; - - return true; -} - -void CPlugin::Init(PFNEXTINFOPROC pfn) -{ - _ASSERT(m_hModule); - if (!m_bInternal) - { - // store pfn for future use - if (pfn) - m_pfnCallback=pfn; - - // call Init - TRACE("External CPlugin::Init()\n"); - if (!(*m_pfnInit)(m_pfnCallback)) - THROW_PLUGINEXCEPTIONEX(_T("External plugin initialization failed."), m_pszFilename, PLERR_INIT, 0); - } - else - TRACE("Internal CPlugin::Init() - does nothing\n"); -} - -void CPlugin::Uninit() -{ - if (!m_hModule) - return; - - if (!m_bInternal) - { - TRACE("External CPlugin::Uninit()\n"); - if (!(*m_pfnUninit)()) - THROW_PLUGINEXCEPTIONEX(_T("External plugin deinitialization failed."), m_pszFilename, PLERR_UNINIT, 0); - } - else - TRACE("Internal CPlugin::Uninit() - does nothing\n"); -} - -bool CPlugin::GetInfo(_PLUGININFO* pInfo) -{ - // alloc new _PLUGININFO - if (m_ppdData) - { - *pInfo=*m_ppdData; // get data from cache - return true; - } - else - { - if (!m_bInternal) - { - BeginUsage(); - // call - bool bRes=(*m_pfnGetInfo)(pInfo); - if (bRes) - { - // fill cache - m_ppdData=new _PLUGININFO; - *m_ppdData=*pInfo; - } - EndUsage(); - return bRes; - } - else - return false; // must override in internal plugin - } -} - -void CPlugin::BeginUsage() -{ - // only means something for partial plugin state - m_cs.Lock(); - if (m_byLoadState == PLGS_PARTIAL) - { - try - { - m_lLockCount++; - Load(NULL, m_pfnCallback); - m_bNeedChange=true; - } - catch (CPluginException*) - { - m_cs.Unlock(); - throw; - } - } - else if (m_bNeedChange) - m_lLockCount++; - - m_cs.Unlock(); -} - -void CPlugin::EndUsage() -{ - m_cs.Lock(); - try - { - if (m_bNeedChange) - { - if (m_lLockCount > 0) - m_lLockCount--; - if (m_lLockCount == 0) - { - Unload(false); - m_bNeedChange=false; - } - } - } - catch (CPluginException*) - { - m_cs.Unlock(); - throw; - } - - m_cs.Unlock(); -}