static pluginEntry* getCListModule(TCHAR * exe, TCHAR * slice, int useWhiteList) { pluginEntry * p = pluginListUI; BASIC_PLUGIN_INFO bpi; while ( p != NULL ) { mir_sntprintf(slice, &exe[MAX_PATH] - slice, _T("\\Plugins\\%s"), p->pluginname); CharLower(p->pluginname); if ( useWhiteList ? isPluginOnWhiteList(p->pluginname) : 1 ) { if ( checkAPI(exe, &bpi, mirandaVersion, CHECKAPI_CLIST, NULL) ) { p->bpi = bpi; p->pclass |= PCLASS_LAST | PCLASS_OK | PCLASS_BASICAPI; pluginListAddr.insert( p ); if ( bpi.clistlink(&pluginCoreLink) == 0 ) { p->bpi = bpi; p->pclass |= PCLASS_LOADED; return p; } else Plugin_Uninit( p ); } //if } //if p = p->nextclass; } return NULL; }
static BOOL dialogListPlugins(WIN32_FIND_DATA * fd, TCHAR * path, WPARAM, LPARAM lParam) { LVITEM it; int iRow; HWND hwndList=(HWND)lParam; BASIC_PLUGIN_INFO pi; int exports=0; TCHAR buf[MAX_PATH]; int isdb = 0; HINSTANCE gModule; PluginListItemData* dat; mir_sntprintf(buf, SIZEOF(buf), _T("%s\\Plugins\\%s"), path, fd->cFileName); CharLower(fd->cFileName); gModule = GetModuleHandle(buf); if ( checkAPI(buf, &pi, mirandaVersion, CHECKAPI_NONE, &exports) == 0 ) { // failed to load anything, but if exports were good, show some info. return TRUE; } isdb = pi.pluginInfo->replacesDefaultModule == DEFMOD_DB; ZeroMemory(&it, sizeof(it)); it.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; it.pszText = fd->cFileName; it.iImage = ( pi.pluginInfo->flags & 1 ) ? 0 : 1; it.lParam = (LPARAM)( dat = (PluginListItemData*)mir_alloc( sizeof( PluginListItemData ))); iRow=SendMessage( hwndList, LVM_INSERTITEM, 0, (LPARAM)&it ); if ( isPluginOnWhiteList(fd->cFileName) ) ListView_SetItemState(hwndList, iRow, !isdb ? 0x2000 : 0x3000, LVIS_STATEIMAGEMASK); if ( iRow != -1 ) { dat->flags = pi.pluginInfo->replacesDefaultModule; dat->author = mir_strdup( pi.pluginInfo->author ); dat->authorEmail = mir_strdup( pi.pluginInfo->authorEmail ); dat->copyright = mir_strdup( pi.pluginInfo->copyright ); dat->description = mir_strdup( pi.pluginInfo->description ); dat->homepage = mir_strdup( pi.pluginInfo->homepage ); if ( pi.pluginInfo->cbSize == sizeof( PLUGININFOEX )) dat->uuid = pi.pluginInfo->uuid; else memset( &dat->uuid, 0, sizeof(dat->uuid)); TCHAR *shortNameT = mir_a2t(pi.pluginInfo->shortName); ListView_SetItemText(hwndList, iRow, 1, shortNameT); mir_free(shortNameT); mir_sntprintf(buf, SIZEOF(buf), _T("%d.%d.%d.%d"), HIBYTE(HIWORD(pi.pluginInfo->version)), LOBYTE(HIWORD(pi.pluginInfo->version)), HIBYTE(LOWORD(pi.pluginInfo->version)), LOBYTE(LOWORD(pi.pluginInfo->version))); ListView_SetItemText(hwndList, iRow, 2, buf); it.mask = LVIF_IMAGE; it.iItem = iRow; it.iSubItem = 3; it.iImage = ( gModule != NULL ) ? 2 : 3; ListView_SetItem( hwndList, &it ); } else mir_free( dat ); FreeLibrary(pi.hInst); return TRUE; }
static BOOL dialogListPlugins(WIN32_FIND_DATA *fd, TCHAR *path, WPARAM, LPARAM lParam) { TCHAR buf[MAX_PATH]; mir_sntprintf(buf, _T("%s\\Plugins\\%s"), path, fd->cFileName); HINSTANCE hInst = GetModuleHandle(buf); BASIC_PLUGIN_INFO pi; if (checkAPI(buf, &pi, MIRANDA_VERSION_CORE, CHECKAPI_NONE) == 0) return TRUE; PluginListItemData *dat = (PluginListItemData*)mir_alloc(sizeof(PluginListItemData)); dat->hInst = hInst; dat->flags = pi.pluginInfo->flags; dat->stdPlugin = 0; if (pi.Interfaces) { MUUID *piface = pi.Interfaces; for (int i = 0; !equalUUID(miid_last, piface[i]); i++) { int idx = getDefaultPluginIdx(piface[i]); if (idx != -1) { dat->stdPlugin |= (1 << idx); break; } } } CharLower(fd->cFileName); _tcsncpy_s(dat->fileName, fd->cFileName, _TRUNCATE); HWND hwndList = (HWND)lParam; LVITEM it = { 0 }; // column 1: Checkbox + Enable/disabled icons it.mask = LVIF_PARAM | LVIF_IMAGE; it.iImage = (hInst != NULL) ? 2 : 3; bool bNoCheckbox = (dat->flags & STATIC_PLUGIN) != 0; if (bNoCheckbox || hasMuuid(pi, miid_clist) || hasMuuid(pi, miid_protocol)) it.iImage += 2; it.lParam = (LPARAM)dat; int iRow = ListView_InsertItem(hwndList, &it); if (isPluginOnWhiteList(fd->cFileName)) ListView_SetItemState(hwndList, iRow, bNoCheckbox ? 0x3000 : 0x2000, LVIS_STATEIMAGEMASK); if (iRow != -1) { // column 2: Unicode/ANSI icon + filename it.mask = LVIF_IMAGE | LVIF_TEXT; it.iItem = iRow; it.iSubItem = 1; it.iImage = (dat->flags & UNICODE_AWARE) ? 0 : 1; it.pszText = fd->cFileName; ListView_SetItem(hwndList, &it); dat->author = mir_strdup(pi.pluginInfo->author); dat->authorEmail = mir_strdup(pi.pluginInfo->authorEmail); dat->copyright = mir_strdup(pi.pluginInfo->copyright); dat->description = mir_strdup(pi.pluginInfo->description); dat->homepage = mir_strdup(pi.pluginInfo->homepage); if (pi.pluginInfo->cbSize == sizeof(PLUGININFOEX)) dat->uuid = pi.pluginInfo->uuid; else memset(&dat->uuid, 0, sizeof(dat->uuid)); TCHAR *shortNameT = mir_a2t(pi.pluginInfo->shortName); // column 3: plugin short name if (shortNameT) { ListView_SetItemText(hwndList, iRow, 2, shortNameT); mir_free(shortNameT); } // column4: version number DWORD unused, verInfoSize = GetFileVersionInfoSize(buf, &unused); if (verInfoSize != 0) { UINT blockSize; VS_FIXEDFILEINFO *fi; void *pVerInfo = mir_alloc(verInfoSize); GetFileVersionInfo(buf, 0, verInfoSize, pVerInfo); VerQueryValue(pVerInfo, _T("\\"), (LPVOID*)&fi, &blockSize); mir_sntprintf(buf, _T("%d.%d.%d.%d"), HIWORD(fi->dwProductVersionMS), LOWORD(fi->dwProductVersionMS), HIWORD(fi->dwProductVersionLS), LOWORD(fi->dwProductVersionLS)); mir_free(pVerInfo); } else mir_sntprintf(buf, _T("%d.%d.%d.%d"), HIBYTE(HIWORD(pi.pluginInfo->version)), LOBYTE(HIWORD(pi.pluginInfo->version)), HIBYTE(LOWORD(pi.pluginInfo->version)), LOBYTE(LOWORD(pi.pluginInfo->version))); ListView_SetItemText(hwndList, iRow, 3, buf); arPluginList.insert(dat); } else mir_free(dat); FreeLibrary(pi.hInst); return TRUE; }
// called in the first pass to create pluginEntry* structures and validate database plugins static BOOL scanPluginsDir (WIN32_FIND_DATA * fd, TCHAR * path, WPARAM, LPARAM) { int isdb = validguess_db_name(fd->cFileName); BASIC_PLUGIN_INFO bpi; pluginEntry* p = (pluginEntry*)HeapAlloc(hPluginListHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, sizeof(pluginEntry)); _tcsncpy(p->pluginname, fd->cFileName, SIZEOF(p->pluginname)); // plugin name suggests its a db module, load it right now if ( isdb ) { TCHAR buf[MAX_PATH]; mir_sntprintf(buf, SIZEOF(buf), _T("%s\\Plugins\\%s"), path, fd->cFileName); if (checkAPI(buf, &bpi, mirandaVersion, CHECKAPI_DB, NULL)) { // db plugin is valid p->pclass |= (PCLASS_DB | PCLASS_BASICAPI); // copy the dblink stuff p->bpi=bpi; // keep a faster list. if ( pluginListDb != NULL ) p->nextclass = pluginListDb; pluginListDb=p; } else // didn't have basic APIs or DB exports - failed. p->pclass |= PCLASS_FAILED; } else if (validguess_clist_name(fd->cFileName)) { // keep a note of this plugin for later if ( pluginListUI != NULL ) p->nextclass=pluginListUI; pluginListUI=p; p->pclass |= PCLASS_CLIST; } else if (validguess_servicemode_name(fd->cFileName)) { TCHAR buf[MAX_PATH]; mir_sntprintf(buf, SIZEOF(buf), _T("%s\\Plugins\\%s"), path, fd->cFileName); if (checkAPI(buf, &bpi, mirandaVersion, CHECKAPI_NONE, NULL)) { p->pclass |= (PCLASS_OK | PCLASS_BASICAPI); p->bpi = bpi; if (bpi.Interfaces) { int i = 0; MUUID *piface = bpi.Interfaces(); while (!equalUUID(miid_last, piface[i])) { if (!equalUUID(miid_servicemode, piface[i++])) continue; p->pclass |= (PCLASS_SERVICE); if ( pluginListSM != NULL ) p->nextclass = pluginListSM; pluginListSM=p; if (pluginList_crshdmp == NULL && lstrcmpi(fd->cFileName, _T("svc_crshdmp.dll")) == 0) { pluginList_crshdmp = p; p->pclass |= PCLASS_LAST; } break; } } } else // didn't have basic APIs or DB exports - failed. p->pclass |= PCLASS_FAILED; } else if (pluginList_freeimg == NULL && lstrcmpi(fd->cFileName, _T("advaimg.dll")) == 0) pluginList_freeimg = p; // add it to the list pluginList.insert( p ); return TRUE; }
int LoadNewPluginsModule(void) { TCHAR exe[MAX_PATH]; TCHAR* slice; pluginEntry* p; pluginEntry* clist = NULL; int useWhiteList, i; bool msgModule = false; // make full path to the plugin GetModuleFileName(NULL, exe, SIZEOF(exe)); slice = _tcsrchr(exe, '\\'); if (slice) *slice = 0; // remember some useful options askAboutIgnoredPlugins=(UINT) GetPrivateProfileInt( _T("PluginLoader"), _T("AskAboutIgnoredPlugins"), 0, mirandabootini); // if Crash Dumper is present, load it to provide Crash Reports if (pluginList_crshdmp != NULL && isPluginOnWhiteList(pluginList_crshdmp->pluginname)) { if ( pluginList_crshdmp->bpi.Load(&pluginCoreLink) == 0 ) pluginList_crshdmp->pclass |= PCLASS_LOADED | PCLASS_LAST; else Plugin_Uninit( pluginList_crshdmp ); } // if freeimage is present, load it to provide the basic core functions if ( pluginList_freeimg != NULL ) { BASIC_PLUGIN_INFO bpi; mir_sntprintf(slice, &exe[SIZEOF(exe)] - slice, _T("\\Plugins\\%s"), pluginList_freeimg->pluginname); if ( checkAPI(exe, &bpi, mirandaVersion, CHECKAPI_NONE, NULL) ) { pluginList_freeimg->bpi = bpi; pluginList_freeimg->pclass |= PCLASS_OK | PCLASS_BASICAPI; if ( bpi.Load(&pluginCoreLink) == 0 ) pluginList_freeimg->pclass |= PCLASS_LOADED; else Plugin_Uninit( pluginList_freeimg ); } } // first load the clist cos alot of plugins need that to be present at Load() for ( useWhiteList = 1; useWhiteList >= 0 && clist == NULL; useWhiteList-- ) clist=getCListModule(exe, slice, useWhiteList); /* the loop above will try and get one clist DLL to work, if all fail then just bail now */ if ( clist == NULL ) { // result = 0, no clist_* can be found if ( pluginListUI ) MessageBox(NULL, TranslateT("Unable to start any of the installed contact list plugins, I even ignored your preferences for which contact list couldn't load any."), _T("Miranda IM"), MB_OK | MB_ICONINFORMATION); else MessageBox(NULL, TranslateT("Can't find a contact list plugin! you need clist_classic or any other clist plugin.") , _T("Miranda IM"), MB_OK | MB_ICONINFORMATION); return 1; } /* enable and disable as needed */ p = pluginListUI; while ( p != NULL ) { SetPluginOnWhiteList(p->pluginname, clist != p ? 0 : 1 ); p = p->nextclass; } /* now loop thru and load all the other plugins, do this in one pass */ for ( i=0; i < pluginList.getCount(); i++ ) { p = pluginList[i]; CharLower(p->pluginname); if (!(p->pclass & (PCLASS_LOADED | PCLASS_DB | PCLASS_CLIST))) { if (isPluginOnWhiteList(p->pluginname)) { BASIC_PLUGIN_INFO bpi; mir_sntprintf(slice, &exe[SIZEOF(exe)] - slice, _T("\\Plugins\\%s"), p->pluginname); if ( checkAPI(exe, &bpi, mirandaVersion, CHECKAPI_NONE, NULL) ) { int rm = bpi.pluginInfo->replacesDefaultModule; p->bpi = bpi; p->pclass |= PCLASS_OK | PCLASS_BASICAPI; if ( pluginDefModList[rm] == NULL ) { pluginListAddr.insert( p ); if ( bpi.Load(&pluginCoreLink) == 0 ) { p->pclass |= PCLASS_LOADED; msgModule |= (bpi.pluginInfo->replacesDefaultModule == DEFMOD_SRMESSAGE); } else { Plugin_Uninit( p ); i--; } if ( rm ) pluginDefModList[rm]=p; } //if else { SetPluginOnWhiteList( p->pluginname, 0 ); Plugin_Uninit( p ); i--; } } else p->pclass |= PCLASS_FAILED; } else { Plugin_Uninit( p ); i--; } } else if ( p->bpi.hInst != NULL ) { pluginListAddr.insert( p ); p->pclass |= PCLASS_LOADED; } } if (!msgModule) MessageBox(NULL, TranslateT("No messaging plugins loaded. Please install/enable one of the messaging plugins, for instance, \"srmm.dll\""), _T("Miranda IM"), MB_OK | MB_ICONINFORMATION); HookEvent(ME_OPT_INITIALISE, PluginOptionsInit); return 0; }