分析mirand事件

 

最近換了工作, 新的工作任務是維護一個IM系統,由於一些原因還沒有拿到IM的源碼,所以這段時間就研究一下開源的IM客戶端miranda,初步瞭解一下,就感覺miranda是一個很優秀的系統,靈活的插件結構,使的miranda系統非常的靈活,也方便世界各地的程序員實現各種不同的功能,以後我會陸續把自己分析的筆記貼出來,同時也歡迎分析過這個系統的朋友一起來參與討論,指出我理解的不正確的地方.

0 概述
miranda系統中預定義了一些事件,例如:
ME_SYSTEM_SHUTDOWN,
ME_SYSTEM_PRESHUTDOWN,
ME_SYSTEM_MODULESLOADED,
ME_SYSTEM_OKTOEXIT
全局靜態變量*hook中維護了這些事件的數組,數組中每一項都對應一個事件,
每種事件不同的功能模塊可能要做不同的處理,所以一個事件可能有多個處理函數,
因此用*subscriber來保存這些處理函數的指針和參數,在需要的情況下用NotifyEventHooks
觸發一個事件,就會依次調用該事件所有的處理函數,這些操作實際上還是同步調用的,而且是
開發人員主動調用的,所以這裏的Event與window裏的事件含義是不同的.

SERVICE也不是windows service或web service的概念.廣義上的意思是一樣的,都是提供了一些服務供用戶調用,
miranda裏的service按照這個思想實現了自己的一套機制,這個套路和HOOK的套路是一樣的,都是維護一個一維數組,將所有的功能都登記在冊,每一項服務都有一個名字和一個hash code,然後掛接一個函數指針,及函數參數,通過CallService可以調用一個服務,與HOOK不同的是每一項服務只對應一個函數

1 主要數據結構及變量
1.1 HOOK
typedef struct {
 MIRANDAHOOK pfnHook;//回調函數指針
 HINSTANCE hOwner;   //回調函數所在模塊的句柄
 HWND hwnd;
 UINT message;
} THookSubscriber;

typedef struct {
 char name[MAXMODULELABELLENGTH];//一個hook的名稱,最大64個字符
 DWORD hookHash;                 //該hook的hash碼
 int subscriberCount;            //記錄有多少個處理函數
 THookSubscriber *subscriber;    //一個事件可以掛接有多個方法,比如ME_SYSTEM_SHUTDOWN的時候,
                                 //不同的模塊需要做不同的處理,就可以通過掛接自己的方法上去即可
 MIRANDAHOOK pfnHook;            //這個好像沒有用到,估計是最初設計的時候考慮一個事件對應一個處理函數,
                                 //實際開發的時候發現一個事件需要有多個處理函數,這些函數的參數又都不同,
                                 //所以僅僅靠這一個函數指針保存不了這麼多信息,所以催生出了THookSubscriber *subscriber
                                 //這些僅僅是猜測
} THookList;

typedef struct {
 int hookId;
 HANDLE hDoneEvent;
 WPARAM wParam;
 LPARAM lParam;
 int result;
} THookToMainThreadItem;

static THookList *hook;
static CRITICAL_SECTION csHooks;
static int hookCount;

1.2 SERVICE
typedef struct {
 char name[MAXMODULELABELLENGTH];//服務的名字
 DWORD nameHash;                 //服務的hash碼
 HINSTANCE hOwner;               //模塊句柄
 MIRANDASERVICE pfnService;      //回調函數指針
} TServiceList;

typedef struct {
 HANDLE hDoneEvent;
 WPARAM wParam;
 LPARAM lParam;
 int result;
 const char *name;
} TServiceToMainThreadItem;

static TServiceList *service;
static int serviceCount;
static CRITICAL_SECTION csServices;

2 主要函數說明

2.1 NameHashFunction(name);
根據名字計算出hash碼

2.2 CreateHookableEvent(ME_SYSTEM_SHUTDOWN);
在THookList *hook裏登記一項,並返回一個handle,實際是該項在hook數組裏的位置
NotifyEventHooks將通過這個句柄來調用這個函數

2.3 HookEvent(ME_SYSTEM_SHUTDOWN,SystemShutdownProc);
將一個hook與一個回調函數指針綁定在一起

2.4 NotifyEventHooks(hModulesLoadedEvent,0,0);
觸發一個事件,hModulesLoadedEvent實際是該事件在hook裏的位置,該函數調用CallHookSubscribers

2.5 CallHookSubscribers(hEvent,wParam,lParam)
調用一個hook函數,hEvent實際是該事件在hook裏的位置,
該函數根據hook[hookId].subscriberCount循環調用每一個掛接的函數

2.6 CreateServiceFunction(MS_SYSTEM_FORK_THREAD,ForkThreadService);
在static TServiceList *service裏動態加入一項,並與指定 的毀掉函數指針綁定

2.7 int CallService(const char *name,WPARAM wParam,LPARAM lParam);
根據名字調用TServiceList *service裏的一個方法 

發佈了68 篇原創文章 · 獲贊 0 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章