static int isPluginBanned(MUUID u1, DWORD dwVersion) { int i; for (i=0; i<pluginBannedListCount; i++) { if (equalUUID(pluginBannedList[i].uuid, u1)) { if (dwVersion<pluginBannedList[i].maxVersion) return 1; return 0; } } return 0; }
static int validInterfaceList(Miranda_Plugin_Interfaces ifaceProc) { MUUID *piface = ( ifaceProc ) ? ifaceProc() : NULL; int i = 0/*, j*/; if (!piface) return 0; if (equalUUID(miid_last, piface[0])) return 0; /*while (!equalUUID(miid_last, piface[i]) ) { for (j=0; j<interfaceBannedListCount; j++) { if (equalUUID(interfaceBannedList[j].uuid, piface[i])) return 0; i++; } break; }*/ return 1; }
MUUID* GetPluginInterfaces(const TCHAR* ptszFileName, bool& bIsPlugin) { bIsPlugin = false; HANDLE hFile = CreateFile( ptszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (hFile == INVALID_HANDLE_VALUE) return NULL; MUUID* pResult = NULL; BYTE* ptr = NULL; HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL ); __try { __try { if (!hMap ) __leave; DWORD dwHSize = 0, filesize = GetFileSize( hFile, &dwHSize ); if (!filesize || filesize == INVALID_FILE_SIZE || dwHSize) __leave; if ( filesize < sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) ) __leave; ptr = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); if (ptr == NULL) __leave; PIMAGE_NT_HEADERS pINTH = { 0 }; PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER)ptr; if ( pIDH->e_magic == IMAGE_DOS_SIGNATURE ) pINTH = (PIMAGE_NT_HEADERS)(ptr + pIDH->e_lfanew); else __leave; if ((PBYTE)pINTH + sizeof(IMAGE_NT_HEADERS) >= ptr + filesize ) __leave; if ( pINTH->Signature != IMAGE_NT_SIGNATURE ) __leave; int nSections = pINTH->FileHeader.NumberOfSections; if (!nSections ) __leave; INT_PTR base; PIMAGE_DATA_DIRECTORY pIDD; if ( pINTH->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 && pINTH->FileHeader.SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER32) && pINTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { pIDD = (PIMAGE_DATA_DIRECTORY)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS32, OptionalHeader.DataDirectory )); base = *(DWORD*)((PBYTE)pINTH + offsetof(IMAGE_NT_HEADERS32, OptionalHeader.ImageBase)); } else if ( pINTH->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 && pINTH->FileHeader.SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER64) && pINTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { pIDD = (PIMAGE_DATA_DIRECTORY)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory )); base = *(ULONGLONG*)((PBYTE)pINTH + offsetof(IMAGE_NT_HEADERS64, OptionalHeader.ImageBase )); } else __leave; // Export information entry DWORD expvaddr = pIDD[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; DWORD expsize = pIDD[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; if (expsize < sizeof(IMAGE_EXPORT_DIRECTORY)) __leave; BYTE* pImage = ptr + pIDH->e_lfanew + pINTH->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_NT_HEADERS) - sizeof(IMAGE_OPTIONAL_HEADER); IMAGE_SECTION_HEADER *pExp = getSectionByRVA((IMAGE_SECTION_HEADER *)pImage, nSections, pIDD); if (!pExp) __leave; BYTE *pSecStart = ptr + pExp->PointerToRawData - pExp->VirtualAddress; IMAGE_EXPORT_DIRECTORY *pED = (PIMAGE_EXPORT_DIRECTORY)&pSecStart[expvaddr]; DWORD *ptrRVA = (DWORD*)&pSecStart[pED->AddressOfNames]; WORD *ptrOrdRVA = (WORD*)&pSecStart[pED->AddressOfNameOrdinals]; DWORD *ptrFuncList = (DWORD*)&pSecStart[pED->AddressOfFunctions]; MUUID* pIds; bool bHasLoad = false, bHasUnload = false, bHasInfo = false, bHasMuuids = false; for (size_t i=0; i < pED->NumberOfNames; i++, ptrRVA++, ptrOrdRVA++) { char *szName = (char*)&pSecStart[*ptrRVA]; if (!lstrcmpA(szName, "Load")) bHasLoad = true; if (!lstrcmpA(szName, "MirandaPluginInfoEx")) bHasInfo = true; else if (!lstrcmpA(szName, "Unload")) bHasUnload = true; else if (!lstrcmpA(szName, "MirandaInterfaces")) { bHasMuuids = true; pIds = (MUUID*)&pSecStart[ ptrFuncList[*ptrOrdRVA]]; } // old plugin, skip it else if (!lstrcmpA(szName, "MirandaPluginInterfaces")) __leave; } // a plugin might have no interfaces if (bHasLoad && bHasUnload && bHasInfo) bIsPlugin = true; if (!bHasLoad || !bHasMuuids || !bHasUnload) __leave; int nLength = 1; // one for MIID_LAST for (MUUID* p = pIds; !equalUUID(*p, miid_last); p++) nLength++; pResult = (MUUID*)mir_alloc( sizeof(MUUID)*nLength); if (pResult) memcpy(pResult, pIds, sizeof(MUUID)*nLength); } __except(EXCEPTION_EXECUTE_HANDLER) {}; } __finally { if (ptr) UnmapViewOfFile(ptr); if (hMap) CloseHandle(hMap); CloseHandle(hFile); }; return pResult; }
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; }
INT_PTR CALLBACK DlgPluginOpt(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); timerID = 0; { HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); mir_subclassWindow(hwndList, PluginListWndProc); HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 4, 0); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_UNICODE); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_ANSI); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_LOADED); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_NOTLOADED); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_LOADEDGRAY); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_NOTLOADEDGRAY); ListView_SetImageList(hwndList, hIml, LVSIL_SMALL); LVCOLUMN col; col.mask = LVCF_TEXT | LVCF_WIDTH; col.pszText = _T(""); col.cx = 40; ListView_InsertColumn(hwndList, 0, &col); col.pszText = TranslateT("Plugin"); col.cx = 180; ListView_InsertColumn(hwndList, 1, &col); col.pszText = TranslateT("Name"); col.cx = 180;//max = 220; ListView_InsertColumn(hwndList, 2, &col); col.pszText = TranslateT("Version"); col.cx = 75; ListView_InsertColumn(hwndList, 3, &col); ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_SUBITEMIMAGES | LVS_EX_CHECKBOXES | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT); // scan the plugin dir for plugins, cos arPluginList.destroy(); szFilter.Empty(); enumPlugins(dialogListPlugins, (WPARAM)hwndDlg, (LPARAM)hwndList); // sort out the headers ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); // dll name int w = ListView_GetColumnWidth(hwndList, 1); if (w > 110) { ListView_SetColumnWidth(hwndList, 1, w = 110); } int max = w < 110 ? 189 + 110 - w : 189; ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); // short name w = ListView_GetColumnWidth(hwndList, 2); if (w > max) ListView_SetColumnWidth(hwndList, 2, max); ListView_SortItems(hwndList, SortPlugins, (LPARAM)hwndDlg); } return TRUE; case WM_NOTIFY: if (lParam) { NMLISTVIEW *hdr = (NMLISTVIEW *)lParam; if (hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom)) { if (hdr->uOldState != 0 && (hdr->uNewState == 0x1000 || hdr->uNewState == 0x2000)) { HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); LVITEM it; it.mask = LVIF_PARAM | LVIF_STATE; it.iItem = hdr->iItem; if (!ListView_GetItem(hwndList, &it)) break; PluginListItemData *dat = (PluginListItemData*)it.lParam; if (dat->flags & STATIC_PLUGIN) { ListView_SetItemState(hwndList, hdr->iItem, 0x3000, LVIS_STATEIMAGEMASK); return FALSE; } // find all another standard plugins by mask and disable them if ((hdr->uNewState == 0x2000) && dat->stdPlugin != 0) { for (int iRow = 0; iRow != -1; iRow = ListView_GetNextItem(hwndList, iRow, LVNI_ALL)) { if (iRow != hdr->iItem) { // skip the plugin we're standing on LVITEM dt; dt.mask = LVIF_PARAM; dt.iItem = iRow; if (ListView_GetItem(hwndList, &dt)) { PluginListItemData *dat2 = (PluginListItemData*)dt.lParam; if (dat2->stdPlugin & dat->stdPlugin) {// mask differs // the lParam is unset, so when the check is unset the clist block doesnt trigger int iSave = dat2->stdPlugin; dat2->stdPlugin = 0; ListView_SetItemState(hwndList, iRow, 0x1000, LVIS_STATEIMAGEMASK); dat2->stdPlugin = iSave; } } } } } if (bOldMode) ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), TRUE); // this here only in "ghazan mode" SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; } if (hdr->iItem != -1) { int sel = hdr->uNewState & LVIS_SELECTED; HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); LVITEM lvi = { 0 }; lvi.mask = LVIF_PARAM; lvi.iItem = hdr->iItem; if (ListView_GetItem(hwndList, &lvi)) { PluginListItemData *dat = (PluginListItemData*)lvi.lParam; TCHAR buf[1024]; ListView_GetItemText(hwndList, hdr->iItem, 2, buf, _countof(buf)); SetDlgItemText(hwndDlg, IDC_PLUGININFOFRAME, sel ? buf : _T("")); ptrT tszAuthor(latin2t(sel ? dat->author : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINAUTHOR, tszAuthor); ptrT tszEmail(latin2t(sel ? dat->authorEmail : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINEMAIL, tszEmail); ptrT p(Langpack_PcharToTchar(dat->description)); SetDlgItemText(hwndDlg, IDC_PLUGINLONGINFO, sel ? p : _T("")); ptrT tszCopyright(latin2t(sel ? dat->copyright : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINCPYR, tszCopyright); ptrT tszUrl(latin2t(sel ? dat->homepage : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINURL, tszUrl); if (!equalUUID(miid_last, dat->uuid)) { char szUID[128]; uuidToString(dat->uuid, szUID, sizeof(szUID)); SetDlgItemTextA(hwndDlg, IDC_PLUGINPID, sel ? szUID : ""); } else SetDlgItemText(hwndDlg, IDC_PLUGINPID, sel ? TranslateT("<none>") : _T("")); } } } if (hdr->hdr.code == PSN_APPLY) { bool needRestart = false; TCHAR bufRestart[1024]; int bufLen = mir_sntprintf(bufRestart, _T("%s\n"), TranslateT("Miranda NG must be restarted to apply changes for these plugins:")); HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); for (int iRow = 0; iRow != -1;) { TCHAR buf[1024]; ListView_GetItemText(hwndList, iRow, 1, buf, _countof(buf)); int iState = ListView_GetItemState(hwndList, iRow, LVIS_STATEIMAGEMASK); SetPluginOnWhiteList(buf, (iState & 0x2000) ? 1 : 0); if (!bOldMode && iState != 0x3000) { LVITEM lvi = { 0 }; lvi.mask = LVIF_IMAGE | LVIF_PARAM; lvi.stateMask = -1; lvi.iItem = iRow; lvi.iSubItem = 0; if (ListView_GetItem(hwndList, &lvi)) { lvi.mask = LVIF_IMAGE; PluginListItemData *dat = (PluginListItemData*)lvi.lParam; if (iState == 0x2000) { // enabling plugin if (lvi.iImage == 3 || lvi.iImage == 5) { if (lvi.iImage == 3 && LoadPluginDynamically(dat)) { lvi.iImage = 2; ListView_SetItem(hwndList, &lvi); } else { bufLen += mir_sntprintf(bufRestart + bufLen, _countof(bufRestart) - bufLen, _T(" - %s\n"), buf); needRestart = true; } } } else { // disabling plugin if (lvi.iImage == 2 || lvi.iImage == 4) { if (lvi.iImage == 2 && UnloadPluginDynamically(dat)) { lvi.iImage = 3; ListView_SetItem(hwndList, &lvi); } else { bufLen += mir_sntprintf(bufRestart + bufLen, _countof(bufRestart) - bufLen, _T(" - %s\n"), buf); needRestart = true; } } } } } iRow = ListView_GetNextItem(hwndList, iRow, LVNI_ALL); } LoadStdPlugins(); ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), needRestart); if (needRestart) { mir_sntprintf(bufRestart + bufLen, _countof(bufRestart) - bufLen, _T("\n%s"), TranslateT("Do you want to restart it now?")); if (MessageBox(NULL, bufRestart, _T("Miranda NG"), MB_ICONWARNING | MB_YESNO) == IDYES) CallService(MS_SYSTEM_RESTART, 1, 0); } } } break; case WM_COMMAND: if (HIWORD(wParam) == STN_CLICKED) { switch (LOWORD(wParam)) { case IDC_GETMOREPLUGINS: Utils_OpenUrl("http://miranda-ng.org/downloads/"); break; case IDC_PLUGINEMAIL: case IDC_PLUGINURL: char buf[512]; char *p = &buf[7]; mir_strcpy(buf, "mailto:"); if (GetDlgItemTextA(hwndDlg, LOWORD(wParam), p, _countof(buf) - 7)) Utils_OpenUrl(LOWORD(wParam) == IDC_PLUGINEMAIL ? buf : p); break; } } break; case WM_DESTROY: arPluginList.destroy(); RemoveAllItems(GetDlgItem(hwndDlg, IDC_PLUGLIST)); break; } return FALSE; }
INT_PTR CALLBACK DlgPluginOpt(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { HWND hwndList=GetDlgItem(hwndDlg,IDC_PLUGLIST); LVCOLUMN col; HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus()? ILC_COLOR32 : ILC_COLOR16), 4, 0); ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_UNICODE ); ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_ANSI ); ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_LOADED ); ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_NOTLOADED ); ListView_SetImageList( hwndList, hIml, LVSIL_SMALL ); TranslateDialogDefault(hwndDlg); col.mask = LVCF_TEXT | LVCF_WIDTH; col.pszText = TranslateT("Plugin"); col.cx = 70;//max = 140; ListView_InsertColumn(hwndList,0,&col); col.pszText=TranslateT("Name"); col.cx = 70;//max = 220; ListView_InsertColumn(hwndList,1,&col); col.pszText=TranslateT("Version"); col.cx=55; ListView_InsertColumn(hwndList,2,&col); col.pszText=_T(""); col.cx=20; ListView_InsertColumn(hwndList,3,&col); //ListView_InsertColumn(hwndList,4,&col); // XXX: Won't work on windows 95 without IE3+ or 4.70 ListView_SetExtendedListViewStyleEx( hwndList, 0, LVS_EX_SUBITEMIMAGES | LVS_EX_CHECKBOXES | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT ); // scan the plugin dir for plugins, cos enumPlugins( dialogListPlugins, ( WPARAM )hwndDlg, ( LPARAM )hwndList ); // sort out the headers { int w, max; ListView_SetColumnWidth( hwndList, 0, LVSCW_AUTOSIZE ); // dll name w = ListView_GetColumnWidth( hwndList, 0 ); if (w>140) { ListView_SetColumnWidth( hwndList, 0, 140 ); w = 140; } max = w<140? 220+140-w:220; ListView_SetColumnWidth( hwndList, 1, LVSCW_AUTOSIZE ); // short name w = ListView_GetColumnWidth( hwndList, 1 ); if (w>max) ListView_SetColumnWidth( hwndList, 1, max ); } return TRUE; } case WM_NOTIFY: { NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; if ( hdr && hdr->hdr.code == LVN_ITEMCHANGED && hdr->uOldState != 0 && (hdr->uNewState == 0x1000 || hdr->uNewState == 0x2000 ) && IsWindowVisible(hdr->hdr.hwndFrom) ) { HWND hwndList = GetDlgItem(hwndDlg,IDC_PLUGLIST); PluginListItemData* dat; int iRow; LVITEM it; it.mask=LVIF_PARAM | LVIF_STATE; it.iItem = hdr->iItem; if ( !ListView_GetItem( hwndList, &it )) break; dat = ( PluginListItemData* )it.lParam; if ( dat->flags == DEFMOD_DB ) { ListView_SetItemState(hwndList, hdr->iItem, 0x3000, LVIS_STATEIMAGEMASK); return FALSE; } // if enabling and replaces, find all other replaces and toggle off if ( hdr->uNewState & 0x2000 && dat->flags != 0 ) { for ( iRow=0; iRow != -1; ) { if ( iRow != hdr->iItem ) { LVITEM dt; dt.mask = LVIF_PARAM; dt.iItem = iRow; if ( ListView_GetItem( hwndList, &dt )) { PluginListItemData* dat2 = ( PluginListItemData* )dt.lParam; if ( dat2->flags == dat->flags ) { // the lParam is unset, so when the check is unset the clist block doesnt trigger int lParam = dat2->flags; dat2->flags = 0; ListView_SetItemState(hwndList, iRow, 0x1000, LVIS_STATEIMAGEMASK ); dat2->flags = lParam; } } } iRow = ListView_GetNextItem( hwndList, iRow, LVNI_ALL ); } } ShowWindow( GetDlgItem(hwndDlg, IDC_RESTART ), TRUE ); SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); break; } if ( hdr && hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != -1 ) { TCHAR buf[1024]; int sel = hdr->uNewState & LVIS_SELECTED; HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); LVITEM lvi = { 0 }; lvi.mask = LVIF_PARAM; lvi.iItem = hdr->iItem; if ( ListView_GetItem( hwndList, &lvi )) { PluginListItemData* dat = ( PluginListItemData* )lvi.lParam; ListView_GetItemText(hwndList, hdr->iItem, 1, buf, SIZEOF(buf)); SetWindowText(GetDlgItem(hwndDlg,IDC_PLUGININFOFRAME),sel ? buf : _T("")); SetWindowTextA(GetDlgItem(hwndDlg,IDC_PLUGINAUTHOR), sel ? dat->author : "" ); SetWindowTextA(GetDlgItem(hwndDlg,IDC_PLUGINEMAIL), sel ? dat->authorEmail : "" ); { TCHAR* p = LangPackPcharToTchar( dat->description ); SetWindowText(GetDlgItem(hwndDlg,IDC_PLUGINLONGINFO), sel ? p : _T("")); mir_free( p ); } SetWindowTextA(GetDlgItem(hwndDlg,IDC_PLUGINCPYR), sel ? dat->copyright : "" ); SetWindowTextA(GetDlgItem(hwndDlg,IDC_PLUGINURL), sel ? dat->homepage : "" ); if(equalUUID(miid_last, dat->uuid)) SetWindowText(GetDlgItem(hwndDlg,IDC_PLUGINPID), sel ? TranslateT("<none>") : _T("")); else { char szUID[128]; uuidToString( dat->uuid, szUID, sizeof(szUID)); SetWindowTextA(GetDlgItem(hwndDlg,IDC_PLUGINPID), sel ? szUID : "" ); } } } if ( hdr && hdr->hdr.code == PSN_APPLY ) { HWND hwndList=GetDlgItem(hwndDlg,IDC_PLUGLIST); int iRow; int iState; TCHAR buf[1024]; for (iRow=0 ; iRow != (-1) ; ) { ListView_GetItemText(hwndList, iRow, 0, buf, SIZEOF(buf)); iState=ListView_GetItemState(hwndList, iRow, LVIS_STATEIMAGEMASK); SetPluginOnWhiteList(buf, iState&0x2000 ? 1 : 0); iRow=ListView_GetNextItem(hwndList, iRow, LVNI_ALL); } } break; } case WM_COMMAND: if ( HIWORD(wParam) == STN_CLICKED ) { switch (LOWORD(wParam)) { case IDC_PLUGINEMAIL: case IDC_PLUGINURL: { char buf[512]; char * p = &buf[7]; lstrcpyA(buf,"mailto:"); if ( GetWindowTextA(GetDlgItem(hwndDlg, LOWORD(wParam)), p, SIZEOF(buf) - 7) ) { CallService(MS_UTILS_OPENURL,0,(LPARAM) (LOWORD(wParam)==IDC_PLUGINEMAIL ? buf : p) ); } break; } case IDC_GETMOREPLUGINS: { CallService(MS_UTILS_OPENURL,0,(LPARAM) "http://addons.miranda-im.org/index.php?action=display&id=1" ); break; } } } break; case WM_DESTROY: RemoveAllItems( GetDlgItem( hwndDlg, IDC_PLUGLIST )); break; } return FALSE; }
// 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; }