摘要:本文從驅(qū)動(dòng)級(jí)過(guò)濾多輸入的數(shù)據(jù),提供了一種方法用來(lái)支持一臺(tái)計(jì)算機(jī)的多輸入設(shè)備的實(shí)時(shí)運(yùn)行,如多鼠標(biāo)、多鍵盤運(yùn)行,將此方法實(shí)現(xiàn)為多設(shè)備輸入接口,并使用此接口制作了計(jì)算機(jī)的多鼠標(biāo)實(shí)時(shí)操控過(guò)濾驅(qū)動(dòng),命名為MouFi。
關(guān)鍵詞:計(jì)算機(jī);多輸入設(shè)備;原理
中圖分類號(hào):TP391.1 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1007-9599 (2012) 10-0000-02
隨著團(tuán)隊(duì)協(xié)作工作和人機(jī)交互的進(jìn)一步發(fā)展,支持多人同時(shí)操作同一計(jì)算機(jī)顯得十分有意義,使用多個(gè)同類輸入設(shè)備(如多個(gè)鼠標(biāo))對(duì)同一主機(jī)進(jìn)行實(shí)時(shí)操控,獨(dú)立完成各項(xiàng)操作互不影響,可使多人同時(shí)共享一臺(tái)電腦的各項(xiàng)資源,特別在電腦緊缺或不方便聯(lián)網(wǎng)的情況,提高電腦的利用率,并在單機(jī)多人游戲領(lǐng)域顯示其優(yōu)勢(shì)。本文從驅(qū)動(dòng)級(jí)過(guò)濾多輸入的數(shù)據(jù),提供了一種方法用來(lái)支持一臺(tái)計(jì)算機(jī)的多輸入設(shè)備的實(shí)時(shí)運(yùn)行,如多鼠標(biāo)、多鍵盤運(yùn)行,將此方法實(shí)現(xiàn)為多設(shè)備輸入接口,并使用此接口制作了計(jì)算機(jī)的多鼠標(biāo)實(shí)時(shí)操控過(guò)濾驅(qū)動(dòng),命名為MouFi。
主要貢獻(xiàn)有以下幾個(gè)方面:1.本文所提供的內(nèi)核級(jí)信號(hào)過(guò)濾方法普適于所有人機(jī)交互輸入設(shè)備(human interface devices input)。2.本方法主要用于提供內(nèi)核級(jí)信號(hào)過(guò)濾接口,在此基礎(chǔ)上,可編寫多種應(yīng)用程序?qū)崿F(xiàn)多輸入的用戶級(jí)應(yīng)用。3.本文所提供的方法實(shí)現(xiàn)接口后,內(nèi)核運(yùn)行在系統(tǒng)進(jìn)程,屬于驅(qū)動(dòng)程序級(jí)別,更貼近底層,過(guò)濾效率高,系統(tǒng)資源占用較少。4.本文所實(shí)現(xiàn)的范例系統(tǒng)可以支持2到6部甚至更多鼠標(biāo)獨(dú)立工作。
相關(guān)工作:目前國(guó)內(nèi)外已有不少支持多輸入的軟件,但大都存在不足有待改進(jìn)。TeamPlayer軟件支持同一電腦多鼠標(biāo)、多鍵盤的操作。但降低了輸入設(shè)備的靈活性,并不適用于一些高速游戲。且鼠標(biāo)操作中會(huì)有沖突,僅能實(shí)現(xiàn)鼠標(biāo)的分時(shí)控制。MultiPointer以軟件形式,通過(guò)切換當(dāng)前的操作鼠標(biāo)為默認(rèn)指針的方式,支持同一電腦的最多5個(gè)鼠標(biāo)的同時(shí)操作。但不同鼠標(biāo)的同時(shí)操作會(huì)產(chǎn)生閃爍,并無(wú)法支持同時(shí)點(diǎn)擊,鼠標(biāo)拖曳操作也會(huì)受到其他移動(dòng)中鼠標(biāo)的影響。而此類多個(gè)輸入設(shè)備同時(shí)控制不同對(duì)象的問(wèn)題則可以通過(guò)本文提供的接口編程解決。
系統(tǒng)設(shè)計(jì):
相關(guān)定義:
IRP(I/O request packets):I/O請(qǐng)求包,內(nèi)核模式的結(jié)構(gòu)體,Windows驅(qū)動(dòng)模型和Windows NT設(shè)備驅(qū)動(dòng)間通過(guò)傳遞此結(jié)構(gòu)體與操作系統(tǒng)進(jìn)行信息交流。
MOUSE_INPUT_DATA:IRP包中的一個(gè)結(jié)構(gòu)體,包含了鼠標(biāo)輸入數(shù)據(jù)。當(dāng)鼠標(biāo)器產(chǎn)生一個(gè)中斷時(shí),此數(shù)據(jù)結(jié)構(gòu)中的各參數(shù)值將被設(shè)置,并包含在IRP中傳回操作系統(tǒng),操作系統(tǒng)根據(jù)其數(shù)值產(chǎn)生相應(yīng)消息,插入消息隊(duì)列等待執(zhí)行。
相關(guān)原理:
鼠標(biāo)工作原理:鼠標(biāo)設(shè)備接入計(jì)算機(jī)后,操作系統(tǒng)為了獲取一次鼠標(biāo)操作,首先會(huì)產(chǎn)生一個(gè)鼠標(biāo)相關(guān)的I/O請(qǐng)求包(IRP_MJ_READ(MouClass)),分層級(jí)發(fā)送到鼠標(biāo)物理驅(qū)動(dòng)的設(shè)備棧,驅(qū)動(dòng)收到此IRP后會(huì)一直保持為等待(pending)狀態(tài)。當(dāng)鼠標(biāo)器有動(dòng)作引發(fā)中斷時(shí),鼠標(biāo)物理驅(qū)動(dòng)就會(huì)將鼠標(biāo)事件的相關(guān)數(shù)據(jù)以系統(tǒng)定義的MOUSE_INPUT_DATA數(shù)據(jù)結(jié)構(gòu)形式填入IRP中,并完成這個(gè)IRP,由驅(qū)動(dòng)設(shè)備自底向上傳送。操作系統(tǒng)獲取該鼠標(biāo)操作,產(chǎn)生Windows消息插入消息隊(duì)列中,之后立即產(chǎn)生下一個(gè)鼠標(biāo)相關(guān)I/O請(qǐng)求包,進(jìn)入下一輪等待。
鼠標(biāo)工作驅(qū)動(dòng)設(shè)置:Windows操作系統(tǒng)利用mouclass驅(qū)動(dòng)將不同類型(如PS2、USB或觸板等)鼠標(biāo)進(jìn)行抽象,在系統(tǒng)進(jìn)程讀取鼠標(biāo)數(shù)據(jù)的時(shí)候,并不對(duì)具體端口進(jìn)行區(qū)分。在驅(qū)動(dòng)結(jié)構(gòu)中,每個(gè)mouclass驅(qū)動(dòng)中都有若干PointerClass設(shè)備,其數(shù)量由系統(tǒng)鼠標(biāo)總數(shù)決定,每個(gè)PointerClass設(shè)備都依附于其獨(dú)有的鼠標(biāo)接口設(shè)備PointerPort。
鼠標(biāo)數(shù)據(jù)過(guò)濾方法:指在操作系統(tǒng)獲取鼠標(biāo)操作、產(chǎn)生消息并插入消息隊(duì)列、供用戶程序處理的全過(guò)程中,通過(guò)特定過(guò)濾方法,使得流過(guò)的數(shù)據(jù)經(jīng)指定處理后傳遞給上一層。過(guò)濾方法主要分為內(nèi)核級(jí)過(guò)濾和用戶級(jí)過(guò)濾。內(nèi)核級(jí)過(guò)濾是指在分層驅(qū)動(dòng)模型中允許某一驅(qū)動(dòng)構(gòu)造一個(gè)匿名的設(shè)備對(duì)象,在相應(yīng)層級(jí)接受分層傳遞的IRP,使得該IRP經(jīng)該對(duì)象的過(guò)濾設(shè)備驅(qū)動(dòng)程序處理后再繼續(xù)向上傳遞。用戶級(jí)過(guò)濾方法主要有消息鉤子(Message Hook)等,利用應(yīng)用程序接口(API)以消息為單位進(jìn)行過(guò)濾,在用戶程序處理之前對(duì)該消息進(jìn)行指定處理。比較實(shí)現(xiàn)方式原理可知,內(nèi)核級(jí)過(guò)濾方法更高效并具有更強(qiáng)的可靠性。
實(shí)現(xiàn)方法:
為了高效的支持多輸入設(shè)備的運(yùn)行并簡(jiǎn)化用戶級(jí)程序的操作,本方法采取內(nèi)核級(jí)過(guò)濾方式對(duì)設(shè)備的輸入數(shù)據(jù)進(jìn)行過(guò)濾修改繼續(xù)上傳,并根據(jù)過(guò)濾獲得的鼠標(biāo)事件真實(shí)數(shù)據(jù)進(jìn)行模擬操作,創(chuàng)建了WDM式過(guò)濾驅(qū)動(dòng)MouFi。
過(guò)濾驅(qū)動(dòng)的初始化
計(jì)算機(jī)啟動(dòng)后,操作系統(tǒng)載入系統(tǒng)驅(qū)動(dòng)時(shí)由DriverEntry入口進(jìn)入該過(guò)濾驅(qū)動(dòng)程序,將其載入系統(tǒng),設(shè)置在接口驅(qū)動(dòng)及鼠標(biāo)類驅(qū)動(dòng)之間,過(guò)濾驅(qū)動(dòng)MouFi創(chuàng)建主設(shè)備(MainDevice)及其符號(hào)鏈接,并初始化各種狀態(tài)變量。在計(jì)算機(jī)運(yùn)行過(guò)程中,若有新的鼠標(biāo)器設(shè)備接入主機(jī),過(guò)濾驅(qū)動(dòng)MouFi使用AddDevice在該鼠標(biāo)類設(shè)備PointerClass及其對(duì)應(yīng)端口類設(shè)備PointerPort之間創(chuàng)建過(guò)濾設(shè)備,邏輯上插入了二者之間,接受和發(fā)送IRP,此后過(guò)濾驅(qū)動(dòng)MouFi主要進(jìn)行以下兩方面的操作。
數(shù)據(jù)過(guò)濾
1.各鼠標(biāo)器設(shè)備下層對(duì)應(yīng)設(shè)置的過(guò)濾設(shè)備接收下級(jí)端口驅(qū)動(dòng)設(shè)備對(duì)象上傳的IRP,將IRP鼠標(biāo)數(shù)據(jù)傳遞到主設(shè)備,將包中MOUSE_INPUT_DATA數(shù)據(jù)放入主設(shè)備緩沖區(qū)等待用戶程序調(diào)用,并根據(jù)IRP中的MOUSE_INPUT_DATA數(shù)據(jù)結(jié)構(gòu)的硬件編號(hào)將原IRP包中MOUSE_INPUT_DATA的對(duì)應(yīng)鼠標(biāo)實(shí)例的位置信息、操作信息等全部項(xiàng)清零。
2.將清零后的IRP包向上傳遞到鼠標(biāo)器驅(qū)動(dòng)設(shè)備對(duì)象PointerClass進(jìn)行進(jìn)一步處理。操作系統(tǒng)接收返回的IRP,分析清零后的MOUSE_INPUT_DATA產(chǎn)生無(wú)效果的Windows消息,隨即產(chǎn)生下次IRP操作。
事件模擬
用戶程序從主設(shè)備緩存獲取真實(shí)MOUSE_INPUT_DATA數(shù)據(jù)結(jié)構(gòu),對(duì)數(shù)據(jù)結(jié)構(gòu)參數(shù)值(硬件編號(hào)、X軸Y軸位移量、按鍵等數(shù)據(jù))進(jìn)行提取。依據(jù)所提取參數(shù)值使用Win32 API mouse_event來(lái)模擬響應(yīng)的動(dòng)作。對(duì)于涉及鼠標(biāo)移動(dòng)的動(dòng)作,得到動(dòng)作響應(yīng)后確定當(dāng)前系統(tǒng)默認(rèn)鼠標(biāo)的指針圖標(biāo)HCURSOR,并利用BitBlt等API函數(shù)將指針畫在該鼠標(biāo)實(shí)例的指針層窗體上。
在過(guò)濾驅(qū)動(dòng)運(yùn)行過(guò)程中,操作系統(tǒng)始終無(wú)法獲得有效的鼠標(biāo)操作數(shù)據(jù),因而鼠標(biāo)指針不受操作系統(tǒng)支配。只有某個(gè)用戶級(jí)的應(yīng)用程序通過(guò)讀取過(guò)濾驅(qū)動(dòng)的主設(shè)備,才可獲得真實(shí)的鼠標(biāo)操作數(shù)據(jù),進(jìn)而根據(jù)硬件編號(hào)進(jìn)行區(qū)分,根據(jù)偏移和按鍵進(jìn)行實(shí)踐模擬,依次產(chǎn)生相應(yīng)響應(yīng)動(dòng)作。用戶體驗(yàn)近似多鼠標(biāo)控制計(jì)算機(jī),模擬支持多輸入設(shè)備工作。
系統(tǒng)演示:對(duì)本文提供的接口經(jīng)上述過(guò)程編程完成了多鼠標(biāo)過(guò)濾驅(qū)動(dòng)MouFi的實(shí)現(xiàn),點(diǎn)擊安裝后重啟計(jì)算機(jī),即完成了過(guò)濾驅(qū)動(dòng)的初始化,插入多個(gè)鼠標(biāo)設(shè)備后,計(jì)算機(jī)顯示器上則會(huì)顯示多個(gè)鼠標(biāo)器指針,可同時(shí)獨(dú)立完成多項(xiàng)操作。
討論:本文所提供的接口程序在理論上可用以支持無(wú)限多個(gè)人機(jī)交互設(shè)備同時(shí)運(yùn)行,但在實(shí)際運(yùn)行中會(huì)存在硬件資源限制、計(jì)算機(jī)處理時(shí)間遲延等約束,使得所支持的輸入設(shè)備存在上限。以鼠標(biāo)器為例,Windows操作系統(tǒng)采樣兩次鼠標(biāo)器中斷的最短時(shí)間間隔T為15.625ms,而系統(tǒng)處理一次鼠標(biāo)器操作的時(shí)間為Min{cpu處理一個(gè)中斷的時(shí)間t1,算法模擬一次鼠標(biāo)器操作時(shí)間t2}。鼠標(biāo)器個(gè)數(shù)最大值為n = T / t
總結(jié):本文提供了一種基于內(nèi)核級(jí)數(shù)據(jù)過(guò)濾的多設(shè)備輸入支持方法,并基于此方法實(shí)現(xiàn)了多設(shè)備輸入的接口,可用于實(shí)現(xiàn)多個(gè)設(shè)備對(duì)同一計(jì)算機(jī)的獨(dú)立操作,開發(fā)用戶可在此基礎(chǔ)上編寫程序,實(shí)現(xiàn)多個(gè)輸入設(shè)備同時(shí)獨(dú)立控制多個(gè)對(duì)象。為了進(jìn)一步展示此接口的用途,本文利用此接口實(shí)現(xiàn)了多鼠標(biāo)輸入的系統(tǒng),可以同時(shí)支持2到6部甚至更多鼠標(biāo)器設(shè)備在同一計(jì)算機(jī)上運(yùn)行。
參考文獻(xiàn):
[1]王淼,沈超.輸入消息截獲方法對(duì)鼠標(biāo)動(dòng)力學(xué)識(shí)別的影響[D].西安交通大學(xué)博士生論文,2011
[2]譚文,楊瀟,邵堅(jiān)磊.Windows內(nèi)核安全編程[M].北京:電子工業(yè)出版社,2009:17-83
[3]SARGENT,M,SHOEMAKER, R.L.The personal computer from the inside out (3rd ed.).New York, Addison-Wesley.1995
[4]SEGALOWITZ,S.,GRAVES,R. .Suitability of the IBM XT, AT, and PS/2 keyboard, mouse, and game port as response devices in reaction time paradigms.Behavior Research Methods, Instruments, Computers,1990: 283–289