#ifndef _LOADPLUGIN_H_ #define _LOADPLUGIN_H_ #include<map> //#include<helpers_s.h> #ifdef _UNICODE #define _tstring wstring #else #define _tstring string #endif typedef HRESULT (STDAPICALLTYPE *PDLLGETCLASSOBJECT)(const CLSID& clsid, const IID& iid, void** ppv); class cLoadPlugin { public: cLoadPlugin() { m_plugins.clear(); InitializeCriticalSection( &m_cs ); } ~cLoadPlugin(); bool LoadPlugin( const TCHAR* szDllPath , IID IInterface , void** pInterface ); private: HMODULE GetModule( const TCHAR* szDllPath ); _tstring& toLower( _tstring& sin ); HMODULE isInList( _tstring& path ); map<_tstring , HMODULE> m_plugins; CRITICAL_SECTION m_cs; void ecs() { EnterCriticalSection( &m_cs ); } void lcs() { LeaveCriticalSection( &m_cs ); } }; cLoadPlugin::~cLoadPlugin() { map<_tstring , HMODULE>::iterator it; DeleteCriticalSection( &m_cs ); for ( it=m_plugins.begin() ; it != m_plugins.end(); it++ ) { FreeLibrary( (HMODULE)it->second ); } } _tstring& cLoadPlugin::toLower( _tstring& sin ) { TCHAR cStart = L'A', cEnd=L'Z'; for( unsigned int i=0; i < sin.length(); i++ ) { if( sin[i] >= cStart && sin[i] <= cEnd ) { sin[i] = sin[i]+32; } } return( sin ); } HMODULE cLoadPlugin::isInList( _tstring& path ) { map<_tstring , HMODULE>::iterator it; it = m_plugins.find( path ); if( it == m_plugins.end() ) return( NULL ); return( it->second ); } bool cLoadPlugin::LoadPlugin( const TCHAR* szDllPath , IID IInterface , void** pInterface ) { ecs(); HRESULT hr; HMODULE hMod = NULL; PDLLGETCLASSOBJECT proc = NULL; IClassFactory* pFactory = NULL; //Get the module from list or load it hMod = GetModule( szDllPath ); if( !hMod ) { lcs(); return( false ); } //Get Proc address proc = (PDLLGETCLASSOBJECT) GetProcAddress( hMod , "DllGetClassObject" ); if( !proc ) { lcs(); return( false ); } hr = proc( IInterface , IID_IClassFactory , (void**)&pFactory ); if( hr || !pFactory ) { lcs(); return( false ); } hr = pFactory->CreateInstance( NULL, IInterface , pInterface ); if( hr || !pInterface ) { lcs(); return( false ); } pFactory->Release(); lcs(); return( true ); } HMODULE cLoadPlugin::GetModule( const TCHAR* szDllPath ) { _tstring spath; _tstring mname; const TCHAR *pName = NULL, c = L'\\'; HMODULE hMod = NULL; PDLLGETCLASSOBJECT proc = NULL; if( !szDllPath ) return( NULL ); //convet path to lowercase and check if file exist //If not a file spath = szDllPath; toLower( spath ); //if( !IsFile( toLower( spath ).c_str() ) ) // return( false ); //Is alread on list pName = _tcsrchr( spath.c_str() , c ); if( !pName ) pName = spath.c_str(); else pName++; mname = pName; //Check if module already loaded hMod = isInList( mname ); //if not on list load module and store it to list if( !hMod ) { if( ( hMod = LoadLibrary( spath.c_str() ) ) == NULL ) return( NULL ); proc = (PDLLGETCLASSOBJECT) GetProcAddress( hMod , "DllGetClassObject" ); if( !proc ) { FreeLibrary( hMod ); return( NULL ); } //insert plugin m_plugins[mname] = hMod; } return( hMod ); } #endif //_LOADPLUGIN_H_