From f7e482e4333df76b198b16c7685c2304007fbe79 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 16 Jul 2012 18:28:49 +0000 Subject: dynamic dll checker git-svn-id: http://svn.miranda-ng.org/main/trunk@989 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/core/stdauth/main.cpp | 7 +- src/core/stdautoaway/main.cpp | 7 +- src/core/stdaway/main.cpp | 7 +- src/core/stdemail/main.cpp | 7 +- src/core/stdfile/main.cpp | 7 +- src/core/stdhelp/main.cpp | 7 +- src/core/stdidle/main.cpp | 7 +- src/core/stduihist/main.cpp | 7 +- src/core/stdurl/main.cpp | 7 +- src/core/stduserinfo/main.cpp | 7 +- src/core/stduseronline/main.cpp | 7 +- src/miranda32_10.vcxproj | 3 + src/miranda32_10.vcxproj.filters | 3 + src/modules/plugins/dll_sniffer.cpp | 150 +++++++++++++++++++++++++++++++++++ src/modules/plugins/newplugins.cpp | 151 ++++++++++++++++-------------------- src/modules/plugins/pluginopts.cpp | 2 +- src/modules/plugins/plugins.h | 7 +- 17 files changed, 237 insertions(+), 156 deletions(-) create mode 100644 src/modules/plugins/dll_sniffer.cpp (limited to 'src') diff --git a/src/core/stdauth/main.cpp b/src/core/stdauth/main.cpp index ae1c5de1d0..a0d800ccae 100644 --- a/src/core/stdauth/main.cpp +++ b/src/core/stdauth/main.cpp @@ -40,8 +40,6 @@ PLUGININFOEX pluginInfo = { { 0x8d0a046d, 0x8ea9, 0x4c55, {0xb5, 0x68, 0x38, 0xda, 0x52, 0x05, 0x64, 0xfd}} }; -static const MUUID interfaces[] = { MIID_SRAUTH, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -53,10 +51,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SRAUTH, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stdautoaway/main.cpp b/src/core/stdautoaway/main.cpp index ed5cea618c..b4bf3a5fd6 100644 --- a/src/core/stdautoaway/main.cpp +++ b/src/core/stdautoaway/main.cpp @@ -40,8 +40,6 @@ PLUGININFOEX pluginInfo = { { 0x9f5ca736, 0x1108, 0x4872, {0xbe, 0xc3, 0x19, 0xc8, 0x4b, 0xc2, 0x14, 0x3b}} }; -static const MUUID interfaces[] = { MIID_AUTOAWAY, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -53,10 +51,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_AUTOAWAY, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stdaway/main.cpp b/src/core/stdaway/main.cpp index 7b9b12772d..ec8ed4b101 100644 --- a/src/core/stdaway/main.cpp +++ b/src/core/stdaway/main.cpp @@ -41,8 +41,6 @@ PLUGININFOEX pluginInfo = { { 0xe58558e3, 0x83e7, 0x44ef, {0x8e, 0x39, 0xd9, 0xe0, 0x54, 0x19, 0x56, 0xdf}} }; -static const MUUID interfaces[] = { MIID_SRAWAY, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -54,10 +52,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SRAWAY, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stdemail/main.cpp b/src/core/stdemail/main.cpp index 62deebb5b7..211bf4f4f5 100644 --- a/src/core/stdemail/main.cpp +++ b/src/core/stdemail/main.cpp @@ -40,8 +40,6 @@ PLUGININFOEX pluginInfo = { {0xb774d10a, 0xc761, 0x11e1, {0x84, 0x05, 0x27, 0xe7, 0x61, 0x88, 0x70, 0x9b }} }; -static const MUUID interfaces[] = { MIID_SREMAIL, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -53,10 +51,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SREMAIL, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stdfile/main.cpp b/src/core/stdfile/main.cpp index 9a7330b7db..84d93121c1 100644 --- a/src/core/stdfile/main.cpp +++ b/src/core/stdfile/main.cpp @@ -45,8 +45,6 @@ PLUGININFOEX pluginInfo = { { 0x39698dce, 0x7ed4, 0x4334, {0xac, 0x4c, 0xba, 0x8b, 0x37, 0xa8, 0x6f, 0x13}} }; -static const MUUID interfaces[] = { MIID_SRFILE, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -58,10 +56,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SRFILE, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stdhelp/main.cpp b/src/core/stdhelp/main.cpp index 9760bac441..d3c4c96ab6 100644 --- a/src/core/stdhelp/main.cpp +++ b/src/core/stdhelp/main.cpp @@ -42,8 +42,6 @@ PLUGININFOEX pluginInfo = { { 0x1e64fd80, 0x299e, 0x48a0, {0x94, 0x41, 0xde, 0x28, 0x68, 0x56, 0x3b, 0x6f}} }; -static const MUUID interfaces[] = { MIID_UIHELP, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -55,10 +53,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_UIHELP, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stdidle/main.cpp b/src/core/stdidle/main.cpp index 6845f61813..2db8f102d1 100644 --- a/src/core/stdidle/main.cpp +++ b/src/core/stdidle/main.cpp @@ -48,8 +48,6 @@ PLUGININFOEX pluginInfo = { { 0x53ac190b, 0xe223, 0x4341, {0x82, 0x5f, 0x70, 0x9d, 0x85, 0x20, 0x21, 0x5b}} }; -static const MUUID interfaces[] = { MIID_IDLE, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -61,10 +59,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_IDLE, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stduihist/main.cpp b/src/core/stduihist/main.cpp index 1bb467ada7..8c68f49529 100644 --- a/src/core/stduihist/main.cpp +++ b/src/core/stduihist/main.cpp @@ -42,8 +42,6 @@ PLUGININFOEX pluginInfo = { { 0x5eedf3c5, 0x3071, 0x4234, {0xa6, 0x27, 0xef, 0xd0, 0x62, 0xa4, 0xd6, 0x94}} }; -static const MUUID interfaces[] = { MIID_UIHISTORY, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -55,10 +53,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_UIHISTORY, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stdurl/main.cpp b/src/core/stdurl/main.cpp index 183ba8f3ff..fa2cbb0474 100644 --- a/src/core/stdurl/main.cpp +++ b/src/core/stdurl/main.cpp @@ -42,8 +42,6 @@ PLUGININFOEX pluginInfo = { { 0x0ca63eee, 0xeb2c, 0x4aed, {0xb3, 0xd0, 0xbc, 0x8e, 0x6e, 0xb3, 0xbf, 0xb8}} }; -static const MUUID interfaces[] = { MIID_SRURL, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -55,10 +53,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SRURL, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stduserinfo/main.cpp b/src/core/stduserinfo/main.cpp index 0dc541834a..0d24ab924d 100644 --- a/src/core/stduserinfo/main.cpp +++ b/src/core/stduserinfo/main.cpp @@ -45,8 +45,6 @@ PLUGININFOEX pluginInfo = { {0x8198dc94, 0xbc4, 0x448a, {0x84, 0x95, 0x8f, 0xe8, 0x32, 0xc1, 0xd3, 0x33 }} }; -static const MUUID interfaces[] = {MIID_UIUSERINFO, MIID_LAST}; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -58,10 +56,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_UIUSERINFO, MIID_LAST}; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/core/stduseronline/main.cpp b/src/core/stduseronline/main.cpp index a69942c6c0..783a0c7d65 100644 --- a/src/core/stduseronline/main.cpp +++ b/src/core/stduseronline/main.cpp @@ -41,8 +41,6 @@ PLUGININFOEX pluginInfo = { { 0x251c78d7, 0xf6e0, 0x4083, {0x92, 0xdc, 0x25, 0x2d, 0xcb, 0x3b, 0xe7, 0x24}} }; -static const MUUID interfaces[] = { MIID_USERONLINE, MIID_LAST }; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst = hinstDLL; @@ -54,10 +52,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_USERONLINE, MIID_LAST }; extern "C" int __declspec(dllexport) Load(void) { diff --git a/src/miranda32_10.vcxproj b/src/miranda32_10.vcxproj index 12ee6ef476..5b817e1d8e 100644 --- a/src/miranda32_10.vcxproj +++ b/src/miranda32_10.vcxproj @@ -407,6 +407,9 @@ ..\..\core\commonheaders.h + + ..\..\core\commonheaders.h + ..\..\core\commonheaders.h diff --git a/src/miranda32_10.vcxproj.filters b/src/miranda32_10.vcxproj.filters index a8de3311a0..90c60ffac7 100644 --- a/src/miranda32_10.vcxproj.filters +++ b/src/miranda32_10.vcxproj.filters @@ -560,6 +560,9 @@ Modules\utils + + Modules\plugins + diff --git a/src/modules/plugins/dll_sniffer.cpp b/src/modules/plugins/dll_sniffer.cpp new file mode 100644 index 0000000000..469cebf931 --- /dev/null +++ b/src/modules/plugins/dll_sniffer.cpp @@ -0,0 +1,150 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2010 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "..\..\core\commonheaders.h" +#include "plugins.h" + +static IMAGE_SECTION_HEADER *getSectionByRVA(IMAGE_SECTION_HEADER *pISH, int nSections, IMAGE_DATA_DIRECTORY *pIDD) +{ + for (int i=0; i < nSections; i++, pISH++) + if (pIDD->VirtualAddress >= pISH->VirtualAddress && pIDD->VirtualAddress + pIDD->Size <= pISH->VirtualAddress + pISH->SizeOfRawData ) + return pISH; + + return NULL; +} + +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_WRITECOPY, 0, 0, NULL ); + + __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; + 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]]; + } + } + + // 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); + } + __finally + { + UnmapViewOfFile(ptr); + CloseHandle(hFile); + }; + + return pResult; +} diff --git a/src/modules/plugins/newplugins.cpp b/src/modules/plugins/newplugins.cpp index 9712f01d07..3c27b63f22 100644 --- a/src/modules/plugins/newplugins.cpp +++ b/src/modules/plugins/newplugins.cpp @@ -91,14 +91,24 @@ int equalUUID(const MUUID& u1, const MUUID& u2) return memcmp(&u1, &u2, sizeof(MUUID))?0:1; } +bool hasMuuid(const MUUID* p, const MUUID& uuid) +{ + if (p == NULL) + return false; + + for (int i=0; !equalUUID(miid_last, p[i]); i++) + if ( equalUUID(uuid, p[i])) + return true; + + return false; +} + + bool hasMuuid(const BASIC_PLUGIN_INFO& bpi, const MUUID& uuid) { - if (bpi.Interfaces) { - MUUID *piface = bpi.Interfaces(); - for (int i=0; !equalUUID(miid_last, piface[i]); i++) - if ( equalUUID(uuid, piface[i])) - return true; - } + if (bpi.Interfaces) + return hasMuuid(bpi.Interfaces, uuid); + return false; } @@ -162,13 +172,8 @@ MUUID miid_clist = MIID_CLIST; MUUID miid_database = MIID_DATABASE; MUUID miid_servicemode = MIID_SERVICEMODE; -static bool validInterfaceList(Miranda_Plugin_Interfaces ifaceProc) +static bool validInterfaceList(MUUID *piface) { - // we don't need'em anymore in the common case - if (ifaceProc == NULL) - return true; - - MUUID *piface = ifaceProc(); if (piface == NULL) return false; @@ -256,7 +261,7 @@ int checkAPI(TCHAR* plugin, BASIC_PLUGIN_INFO* bpi, DWORD mirandaVersion, int ch bpi->Load = (Miranda_Plugin_Load) GetProcAddress(h, "Load"); bpi->Unload = (Miranda_Plugin_Unload) GetProcAddress(h, "Unload"); bpi->InfoEx = (Miranda_Plugin_InfoEx) GetProcAddress(h, "MirandaPluginInfoEx"); - bpi->Interfaces = (Miranda_Plugin_Interfaces) GetProcAddress(h, "MirandaPluginInterfaces"); + bpi->Interfaces = (MUUID*) GetProcAddress(h, "MirandaInterfaces"); // if they were present if ( !bpi->Load || !bpi->Unload || !bpi->InfoEx) { @@ -367,42 +372,6 @@ static int valid_library_name(TCHAR *name) return 0; } -// returns true if the given file matches dbx_*.dll, which is used to LoadLibrary() -static int validguess_db_name(TCHAR *name) -{ - int rc = 0; - // this is ONLY SAFE because name -> ffd.cFileName == MAX_PATH - TCHAR x = name[4]; - name[4] = 0; - rc = lstrcmpi(name, _T("dbx_")) == 0 || lstrcmpi(name, _T("dbrw")) == 0; - name[4] = x; - return rc; -} - -// returns true if the given file matches clist_*.dll -static int validguess_clist_name(TCHAR *name) -{ - int rc = 0; - // argh evil - TCHAR x = name[6]; - name[6] = 0; - rc = lstrcmpi(name, _T("clist_")) == 0; - name[6] = x; - return rc; -} - -// returns true if the given file matches svc_*.dll -static int validguess_servicemode_name(TCHAR *name) -{ - int rc = 0; - // argh evil - TCHAR x = name[4]; - name[4] = 0; - rc = lstrcmpi(name, _T("svc_")) == 0; - name[4] = x; - return rc; -} - void enumPlugins(SCAN_PLUGINS_CALLBACK cb, WPARAM wParam, LPARAM lParam) { // get miranda's exe path @@ -456,16 +425,27 @@ static INT_PTR PluginsEnum(WPARAM, LPARAM lParam) pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path) { - BASIC_PLUGIN_INFO bpi; pluginEntry* p = (pluginEntry*)HeapAlloc(hPluginListHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, sizeof(pluginEntry)); _tcsncpy(p->pluginname, tszFileName, SIZEOF(p->pluginname)); - TCHAR buf[MAX_PATH]; - mir_sntprintf(buf, SIZEOF(buf), _T("%s\\%s\\%s"), path, dir, tszFileName); + // add it to the list anyway + pluginList.insert(p); + + TCHAR tszFullPath[MAX_PATH]; + mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\%s\\%s"), path, dir, tszFileName); + + // map dll into the memory and check its exports + bool bIsPlugin = false; + mir_ptr pIds( GetPluginInterfaces(tszFullPath, bIsPlugin)); + if ( !bIsPlugin) { + p->pclass |= PCLASS_FAILED; // piece of shit + return p; + } - // plugin name suggests its a db module, load it right now - if ( validguess_db_name(tszFileName)) { - if (checkAPI(buf, &bpi, mirandaVersion, CHECKAPI_DB)) { + // plugin declared that it's a database. load it asap! + if ( hasMuuid(pIds, miid_database)) { + BASIC_PLUGIN_INFO bpi; + if (checkAPI(tszFullPath, &bpi, mirandaVersion, CHECKAPI_DB)) { // db plugin is valid p->pclass |= (PCLASS_DB | PCLASS_BASICAPI); // copy the dblink stuff @@ -478,14 +458,18 @@ pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path) // didn't have basic APIs or DB exports - failed. p->pclass |= PCLASS_FAILED; } - else if ( validguess_clist_name(tszFileName)) { + // plugin declared that it's a contact list. mark it for the future load + else if ( hasMuuid(pIds, miid_clist)) { // 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(tszFileName)) { - if (checkAPI(buf, &bpi, mirandaVersion, CHECKAPI_NONE)) { + // plugin declared that it's a service mode plugin. + // load it for a profile manager's window + else if ( hasMuuid(pIds, miid_servicemode)) { + BASIC_PLUGIN_INFO bpi; + if (checkAPI(tszFullPath, &bpi, mirandaVersion, CHECKAPI_NONE)) { p->pclass |= (PCLASS_OK | PCLASS_BASICAPI); p->bpi = bpi; if ( hasMuuid(bpi, miid_servicemode)) { @@ -499,28 +483,9 @@ pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path) // didn't have basic APIs or DB exports - failed. p->pclass |= PCLASS_FAILED; } - - // add it to the list - pluginList.insert(p); return p; } -// called in the first pass to create pluginEntry* structures and validate database plugins -static BOOL scanPluginsDir(WIN32_FIND_DATA *fd, TCHAR *path, WPARAM, LPARAM) -{ - pluginEntry* p = OpenPlugin(fd->cFileName, _T("Plugins"), path); - if ( !(p->pclass & PCLASS_FAILED)) { - if (pluginList_freeimg == NULL && lstrcmpi(fd->cFileName, _T("advaimg.dll")) == 0) - pluginList_freeimg = p; - - if (pluginList_crshdmp == NULL && lstrcmpi(fd->cFileName, _T("svc_crshdmp.dll")) == 0) { - pluginList_crshdmp = p; - p->pclass |= PCLASS_LAST; - } - } - - return TRUE; -} void SetPluginOnWhiteList(const TCHAR* pluginname, int allow) { @@ -572,7 +537,7 @@ bool TryLoadPlugin(pluginEntry *p, bool bDynamic) p->pclass |= PCLASS_OK | PCLASS_BASICAPI; if (p->bpi.Interfaces) { - MUUID *piface = bpi.Interfaces(); + MUUID *piface = bpi.Interfaces; for (int i=0; !equalUUID(miid_last, piface[i]); i++) { int idx = getDefaultPluginIdx( piface[i] ); if (idx != -1 && pluginDefault[idx].pImpl) { @@ -591,7 +556,7 @@ bool TryLoadPlugin(pluginEntry *p, bool bDynamic) p->pclass |= PCLASS_LOADED; if (p->bpi.Interfaces) { - MUUID *piface = bpi.Interfaces(); + MUUID *piface = bpi.Interfaces; for (int i=0; !equalUUID(miid_last, piface[i]); i++) { int idx = getDefaultPluginIdx( piface[i] ); if (idx != -1) @@ -744,7 +709,6 @@ void UnloadNewPlugins(void) } } ///////////////////////////////////////////////////////////////////////////////////////// -// // Loads all plugins int LoadNewPluginsModule(void) @@ -827,6 +791,22 @@ int LoadNewPluginsModule(void) // Plugins module initialization // called before anything real is loaded, incl. database +static BOOL scanPluginsDir(WIN32_FIND_DATA *fd, TCHAR *path, WPARAM, LPARAM) +{ + pluginEntry* p = OpenPlugin(fd->cFileName, _T("Plugins"), path); + if ( !(p->pclass & PCLASS_FAILED)) { + if (pluginList_freeimg == NULL && lstrcmpi(fd->cFileName, _T("advaimg.dll")) == 0) + pluginList_freeimg = p; + + if (pluginList_crshdmp == NULL && lstrcmpi(fd->cFileName, _T("svc_crshdmp.dll")) == 0) { + pluginList_crshdmp = p; + p->pclass |= PCLASS_LAST; + } + } + + return TRUE; +} + int LoadNewPluginsModuleInfos(void) { bModuleInitialized = TRUE; @@ -855,14 +835,13 @@ int LoadNewPluginsModuleInfos(void) void UnloadNewPluginsModule(void) { - int i; - - if ( !bModuleInitialized) return; + if ( !bModuleInitialized) + return; UnloadPluginOptions(); // unload everything but the DB - for (i = pluginList.getCount()-1; i >= 0; i--) { + for (int i = pluginList.getCount()-1; i >= 0; i--) { pluginEntry* p = pluginList[i]; if ( !(p->pclass & PCLASS_DB) && p != pluginList_crshdmp) Plugin_Uninit(p); @@ -872,8 +851,8 @@ void UnloadNewPluginsModule(void) Plugin_Uninit(pluginList_crshdmp); // unload the DB - for (i = pluginList.getCount()-1; i >= 0; i--) { - pluginEntry* p = pluginList[i]; + for (int k = pluginList.getCount()-1; k >= 0; k--) { + pluginEntry* p = pluginList[k]; Plugin_Uninit(p); } diff --git a/src/modules/plugins/pluginopts.cpp b/src/modules/plugins/pluginopts.cpp index 45d8080d98..0b0f8ab821 100644 --- a/src/modules/plugins/pluginopts.cpp +++ b/src/modules/plugins/pluginopts.cpp @@ -89,7 +89,7 @@ static BOOL dialogListPlugins(WIN32_FIND_DATA* fd, TCHAR* path, WPARAM, LPARAM l dat->flags = 0; if (pi.Interfaces) { - MUUID *piface = pi.Interfaces(); + MUUID *piface = pi.Interfaces; for (int i=0; !equalUUID(miid_last, piface[i]); i++) { int idx = getDefaultPluginIdx( piface[i] ); if (idx != -1 ) { diff --git a/src/modules/plugins/plugins.h b/src/modules/plugins/plugins.h index 6cfa8595c7..64118a45ed 100644 --- a/src/modules/plugins/plugins.h +++ b/src/modules/plugins/plugins.h @@ -17,8 +17,6 @@ typedef PLUGININFOEX * (__cdecl * Miranda_Plugin_InfoEx) (DWORD mirandaVersion); typedef DATABASELINK * (__cdecl * Database_Plugin_Info) (void * reserved); // prototype for clists typedef int (__cdecl * CList_Initialise) (void); -// Interface support -typedef MUUID * (__cdecl * Miranda_Plugin_Interfaces) (void); // can all be NULL struct BASIC_PLUGIN_INFO @@ -27,10 +25,10 @@ struct BASIC_PLUGIN_INFO Miranda_Plugin_Load Load; Miranda_Plugin_Unload Unload; Miranda_Plugin_InfoEx InfoEx; - Miranda_Plugin_Interfaces Interfaces; Database_Plugin_Info DbInfo; CList_Initialise clistlink; PLUGININFOEX * pluginInfo; // must be freed if hInst = = NULL then its a copy + MUUID *Interfaces; // array of supported interfaces DATABASELINK * dblink; // only valid during module being in memory }; @@ -66,6 +64,7 @@ void SetPluginOnWhiteList(const TCHAR* pluginname, int allow); int getDefaultPluginIdx(const MUUID& muuid); bool hasMuuid(const BASIC_PLUGIN_INFO&, const MUUID&); +bool hasMuuid(const MUUID* pFirst, const MUUID&); int equalUUID(const MUUID& u1, const MUUID& u2); int checkAPI(TCHAR* plugin, BASIC_PLUGIN_INFO* bpi, DWORD mirandaVersion, int checkTypeAPI); @@ -88,3 +87,5 @@ struct MuuidReplacement extern MuuidReplacement pluginDefault[]; bool LoadCorePlugin( MuuidReplacement& ); + +MUUID* GetPluginInterfaces(const TCHAR* ptszFileName, bool& bIsPlugin); \ No newline at end of file -- cgit v1.2.3