Miranda插件分析
发布时间:2020-12-14 17:01:14 所属栏目:大数据 来源:网络整理
导读:? 1. ?? 概述 Miranda 提供了一套非常灵活的插件机制,使得用户可以很方便的通过增减插件来添加或去除一些扩展功能. 源码里有一个testplug project,演示了实现一个Miranda插件的基本方法,下面就通过对testplug project的分析,来学习Miranda的插件技术. 2. ??
?
1.?? 概述
Miranda 提供了一套非常灵活的插件机制,使得用户可以很方便的通过增减插件来添加或去除一些扩展功能. 源码里有一个testplug project,演示了实现一个Miranda插件的基本方法,下面就通过对testplug project的分析,来学习Miranda的插件技术.
2.?? Miranda插件分类
?基本插件: srmm.dll,clist_modern.dll,dbx_3x.dll
?协议插件: jabber,msn,qq等
?辅助插件: png2dib等
3.?? 一个插件需要实现的基本接口与变量
3.1.基本变量
?这个通过分析testplug project可以很清楚的看到,一个插件有三个基本全局变量:
?HINSTANCE hInst;
??????? //记录该插件的模块句柄
?PLUGINLINK *pluginLink; //用来登记通用的操作插件的函数指针
?PLUGININFO pluginInfo;?//该插件的描述信息
3.2.基本接口
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
?????? hInst=hinstDLL;
?????? return TRUE;
}
?
//这是一个菜单命令的响应函数
static int PluginMenuCommand(WPARAM wParam,LPARAM lParam)
{
?????? MessageBox(NULL,"Just groovy,baby!","Plugin-o-rama",MB_OK);
?????? return 0;
}
?
__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
{
?????? return &pluginInfo;
}
?
int __declspec(dllexport) Load(PLUGINLINK *link)
{
???
pluginLink=link;
???
//下面这段代码在主菜单里插入菜单项 "&Test Plugin..."
//当单击该菜单项时PluginMenuCommand将被调用
?????? CLISTMENUITEM mi;
?????? CreateServiceFunction("TestPlug/MenuCommand",PluginMenuCommand);
?????? ZeroMemory(&mi,sizeof(mi));
?????? mi.cbSize=sizeof(mi);
?????? mi.position=-0x7FFFFFFF;
?????? mi.flags=0;
?????? mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
?????? mi.pszName="&Test Plugin...";
?????? mi.pszService="TestPlug/MenuCommand";
?????? CallService(MS_CLIST_ADDMAINMENUITEM,(LPARAM)&mi);
?
?????? return 0;
}
?
int __declspec(dllexport) Unload(void)
{
?????? return 0;
}
?
3.3.插件如何添加并响应自己的菜单命令
参考3.2 基本接口 中Load函数中加载菜单项?"&Test Plugin..."的方法.
?
4.?? 主要数据结构:
4.1.PLUGINLINK
typedef struct {
?????? HANDLE (*CreateHookableEvent)(const char *);
?????? int (*DestroyHookableEvent)(HANDLE);
?????? int (*NotifyEventHooks)(HANDLE,WPARAM,LPARAM);
?????? HANDLE (*HookEvent)(const char *,MIRANDAHOOK);
?????? HANDLE (*HookEventMessage)(const char *,HWND,UINT);
?????? int (*UnhookEvent)(HANDLE);
?????? HANDLE (*CreateServiceFunction)(const char *,MIRANDASERVICE);
?????? HANDLE (*CreateTransientServiceFunction)(const char *,MIRANDASERVICE);
?????? int (*DestroyServiceFunction)(HANDLE);
?????? int (*CallService)(const char *,LPARAM);
?????? int (*ServiceExists)(const char *);????????????? ?//v0.1.0.1+
?????? int (*CallServiceSync)(const char *,LPARAM);??????? //v0.3.3+
?????? int (*CallFunctionAsync) (void (__stdcall *)(void *),void *);??? //v0.3.4+
?????? int (*SetHookDefaultForHookableEvent) (HANDLE,MIRANDAHOOK); // v0.3.4 (2004/09/15)
} PLUGINLINK;
?
?
extern PLUGINLINK *pluginLink;
#define CreateHookableEvent(a)
?????????????? pluginLink->CreateHookableEvent(a)
#define DestroyHookableEvent(a)
?? ???????????pluginLink->DestroyHookableEvent(a)
#define NotifyEventHooks(a,b,c)
????????????? pluginLink->NotifyEventHooks(a,c)
#define HookEventMessage(a,c)
????????????? pluginLink->HookEventMessage(a,c)
#define HookEvent(a,b)
?????????????????????? pluginLink->HookEvent(a,b)
#define UnhookEvent(a)
?????????????????????? pluginLink->UnhookEvent(a)
#define CreateServiceFunction(a,b)
?????????? pluginLink->CreateServiceFunction(a,b)
#define CreateTransientServiceFunction(a,b)?pluginLink->CreateTransientServiceFunction(a,b)
#define DestroyServiceFunction(a)
??????????? pluginLink->DestroyServiceFunction(a)
#define CallService(a,c)
?????????????????? pluginLink->CallService(a,c)
#define ServiceExists(a)
???????????????????? pluginLink->ServiceExists(a)
#define CallServiceSync(a,c)
?????????????? pluginLink->CallServiceSync(a,c)
#define CallFunctionAsync(a,b)
???????????????????????? pluginLink->CallFunctionAsync(a,b)
#define SetHookDefaultForHookableEvent(a,b)?pluginLink->SetHookDefaultForHookableEvent(a,b)
?
?
4.2.pluginEntry
typedef struct pluginEntry {
?????? char pluginname[64]; //插件的名称
?????? unsigned int pclass; // PCLASS_*
?????? BASIC_PLUGIN_INFO bpi;
?????? struct pluginEntry * nextclass;
} pluginEntry;
?
4.3.PLUGININFO
typedef struct {
?????? int cbSize;
?????? char *shortName;
?????? DWORD version;
?????? char *description;
?????? char *author;
?????? char *authorEmail;
?????? char *copyright;
?????? char *homepage;
?????? BYTE isTransient;??? //leave this as 0 for now
?????? int replacesDefaultModule;?????????? ?? //one of the DEFMOD_ constants in m_plugins.h or zero
?????? ???????? //if non-zero,this will supress the loading of the specified built-in module
???????????????????? ?//with the implication that this plugin provides back-end-compatible features
} PLUGININFO;
?
4.4.BASIC_PLUGIN_INFO
typedef struct { // can all be NULL
?????? HINSTANCE hInst;????????????????????
?????? Miranda_Plugin_Load Load;
?????? Miranda_Plugin_Unload Unload;
?????? Miranda_Plugin_Info Info;
?????? Database_Plugin_Info DbInfo;
?????? CList_Initialise clistlink;
?????? PLUGININFO * pluginInfo;?// must be freed if hInst==NULL then its a copy
?????? DATABASELINK * dblink;?????????? // only valid during module being in memory?????
} BASIC_PLUGIN_INFO;
?
5.?? 主要全局变量:
SortedList pluginList = { 0 },
pluginListAddr = { 0 };
PLUGINLINK pluginCoreLink;
char
?? mirandabootini[MAX_PATH];
static DWORD mirandaVersion;
static pluginEntry * pluginListDb;
static pluginEntry * pluginListUI;
static pluginEntry * pluginList_png2dib = NULL;
static HANDLE hPluginListHeap = NULL;//插件用到的堆
static pluginEntry * pluginDefModList[DEFMOD_HIGHEST+1]; // do not free this memory
static int askAboutIgnoredPlugins;
?
6.?? 辅助函数:
3.1 HINSTANCE GetInstByAddress( void* codePtr )
??? 根据一个函数的地址返回函数所在的模块的句柄
???
3.2 enumPlugins(scanPluginsDir,0);
??? 枚举所有的插件
???
3.3 checkAPI
??? 动态加载一个插件,并检查该插件的API函数
??? Load,Unload,MirandaPluginInfo 三个基本的API函数
?
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |