所謂「協作安裝程式」,在ddk文件裡面稱作co-installer,有人將它翻譯成「共同安裝程式」。但是,
從ddk文件對co-installer功能的描述來看,我個人覺得翻譯成「協作安裝程式」更恰當些。
ddk文件對co-installer的描述:a co-installer is a microsoft® win32® dll that assists in
device installation. co-installers are called by setup api as "helpers" for class
installers.簡單地翻譯一下:協作安裝程式是乙個win32 dll,它輔助裝置的安裝。協作安裝程式
由setup api呼叫,作為類安裝程式的「助手」。
在本論壇搜尋了一下有關「協作安裝程式」的帖子,發現這方面的帖子很少。我想之所以這樣,是因為
大家在驅動開發過程中可能很少有需要用到協作安裝程式的地方。或者說本來有些地方可以使用,但可能
因為不太了解這方面的東西,所以沒有想到去用它。
這兒,我想介紹乙個關於協作安裝程式的應用例項。
開發過usb裝置驅動的朋友,不知有沒有碰到過下面的問題:如果你的裝置驅動程式沒有經過數字簽名,
那麼,在xp系統下,你在每個usb口上第一次插上你的usb裝置時,系統都會要求你裝一次驅動程式。
這種感覺是很不好的。我們希望能像大多數usb移動盤一樣,插上裝置就自動安裝驅動,然後就可以對
裝置進行訪問了。
如何讓我們的usb裝置插上後,系統也能自動為它安裝驅動,而不需要煩勞使用者手動安裝呢?解決此問題
的核心技術在於編寫乙個類協作安裝程式。
首先,有乙個問題大家要清楚,usb裝置第一次插到機器上的乙個usb口上時,系統要為它
裝一次驅動程式。我們以usb裝置為例,來了解一下支援熱插拔的pnp裝置的安裝過程:
(1)裝置插入系統,usb匯流排驅動向核心pnp管理器報告有新裝置接入系統;
(2)核心pnp管理器向usb匯流排驅動詢問裝置的具體資訊,比如pid和vid等;
(3)核心pnp管理器將裝置的資訊報告給使用者層的pnp管理器,並要求它為新裝置安裝驅動;
(4)使用者層pnp管理器呼叫系統的setup元件來為裝置安裝驅動;
(5)setup使用裝置vid和pid到%windir%\\inf下尋找適合它的inf檔案,並獲得乙個可用於裝置的驅動程式列表;
(6)setup在生成驅動程式列表的時候,會檢查inf檔案是否經過數字簽名,如果沒有經過數字簽名,
setup會將此inf檔案負責安裝的驅動程式設定成「不可信任的」驅動程式;
(7)setup對驅動程式列表中的各驅動程式資訊進行分析,選擇最匹配裝置的驅動程式進行安裝;
這裡,有必要提一下「不可信任的驅動程式」這個概念。這個概念在xp之後才有的,2k和98沒有。在setup
生成的驅動程式列表中,每個驅動程式的資訊結構中都有乙個rank欄位。在xp中,0x0 < rank <= 0x3fff的
驅動程式被認為是「可信任的」;0x8000 <= rank <= 0xffff的驅動被認為是「不可信任的」。如果我們的
驅動程式沒有經過數字簽名,那麼它的rank值肯定落在0x8000到0xffff之間。
再回到前面的安裝過程,如果驅動程式中有適合裝置的「可信任」驅動程式,那麼系統自動對它進行安裝;
如果驅動程式列表中的所有驅動程式都是「不可信任的」,那麼系統就會彈出「發現新硬體」嚮導,要你提
供更好的驅動程式,或者要你確認安裝「不可信任的」驅動程式。這就是為什麼在xp系統下,即便你在乙個
usb口上已經安裝了裝置的驅動程式,你再換個口插上裝置,系統又會提示你安裝驅動程式的原因。
說了半天,我想現在各位肯定都明白過來了:影響裝置驅動程式自動安裝的主要原因,是因為我們的
驅動程式被系統認為是「不可信任的」。而系統判斷乙個驅動程式是否「可信任」,是通過驅動程式資訊結
構中的rank欄位的值來判斷的。那麼,如果我們能把我們的驅動程式資訊中的rank值修改到「可信任」空間,
那麼系統是否就會信任我們的驅動程式,而自動對它進行安裝呢?答案是,有可能。我不敢說肯定可以,原因
後面會提到。但是,如何修改驅動程式資訊的rank值呢?這就要用到「協作安裝程式」。
我們知道,在裝置的安裝過程中,setup要向裝置類安裝程式、類協作安裝程式和裝置協作安裝程式傳送
「裝置安裝功能碼」(如果有這些安裝程式的話)。ddk文件中又說,類安裝程式和類協作安裝程式可以對
dif_selectbestcompatdrv請求進行處理(裝置協作安裝程式不可以)。在對dif_selectbestcompatdrv進行處理
的時候,類安裝程式和類協作安裝程式可以修改驅動程式列表中各驅動程式的資訊。答案越來越清晰了,我們
只要寫乙個類協作安裝程式,對dif_selectbestcompatdrv進行處理,修改我們想要安裝的驅動程式的rank值,
那麼就可能騙過系統,使系統相信我們的驅動程式,並完成自動安裝。關於編寫協作安裝程式的具體要求和方法,
可以參考ddk文件中的「writing a co-installer(編寫協作安裝程式)」和ddk\src\general\toaster\coinstaller。
接下來,我們來了解一下,在類協作安裝程式處理dif_selectbestcompatdrv時,應該做哪些事情。
(1)首先,呼叫setupdienumdriverinfo遍歷驅動程式列表,獲得每個驅動程式的資訊――乙個
sp_drvinfo_data結構。
(2)接著,用(1)中獲得的sp_drvinfo_data作為輸入引數,呼叫setupdigetdriverinstallparams,
獲得驅動程式安裝引數――乙個sp_drvinstall_params結構,其中我們想要修改的rank赫然在列。你可以按
照自己的需要修改rank的值,在這兒我們肯定是要把它改為0了(0表示驅動程式與裝置最匹配)。
(3)最後,把修改後的sp_drvinstall_params結構作為輸入,呼叫setupdisetdriverinstallparams將我們修改
的值設定生效。
在類協作安裝程式中只需作如此處理,便可以使setup此後信任我們的驅動程式,從而達到我們想瞞天過海的目的。
再稍微提一下類協作安裝程式的註冊。協作安裝程式做好了,如何使它參與到裝置安裝的過程中來呢?我們
必須註冊它。ddk文件對此講得非常清楚了,參看「registering a class co-installer」,我就不在這兒把它翻譯出來了。
最後,要提醒一點:必須為我們的usb裝置定義乙個新的裝置setup類,然後將我們的協作安裝程式註冊為這個
setup類的類協作安裝程式。如果我們讓裝置仍然屬於usb setup類,並將我們的類協作安裝程式註冊為usb
setup類的乙個協作安裝程式,那麼在安裝過程中,setup仍然彈出一些窗體影響我們裝置的自動安裝,似乎我們的小聰明
並沒能瞞過它。這就是前面我說修改rank值為「可信任」只是有可能瞞過系統而不是肯定能夠瞞過系統的原因。為什麼會出現
這種情況呢?從現象看,我感覺是usb setup類的類安裝程式仍然發現我們的驅動程式是不可信任的。但是,setup是以類協作
安裝程式、裝置協作安裝程式和類安裝程式的順序呼叫它們的,在setup呼叫usb setup類安裝程式之前,我們已經修改了驅動程式的
rank值。按理說,它應該不會發現驅動程式是不可信任的。這是乙個問題,具體原因我還沒有弄明白,希望有知其所以然者,能給
點提示!不管如何,通過實驗我發現,只要我們定義了新的setup類,那麼我們就可以騙過系統setup元件,使其自動為我們的裝置
安裝驅動程式。
就寫這些,有興趣的朋友可以試一下!我不想把具體的實現過程一步一步地寫出來,更不願提供具體的實現**。
因為我認為只要把原理和方法講清楚了(但願我講得還算清楚),每個人都可以在此基礎上做自己的事情。
不管各位朋友看完之後感覺如何,能誇就夸夸,該罵就罵罵,都頂一下!
asp xmlhttp應用一例
資料表 grid id,a,b,c,d,e 正在進行通訊聯接!一二 三四 五 set rs conn.execute select top 3 from grid order by id desc do while not rs.eof ondblclick changevalue this rs ...
Grails g select 標籤應用一例
iteye gsp頁面中 g select 用於建立乙個html的 selects 標籤.下面例子裡面用到的g select 屬性有 from 必需 select 的範圍 value 可選 from範圍內當前的選擇值.optionkey 可選 用於指定生成的html selects標籤中元素的 va...
select exists 的應用一例
當遇到多層exists的時候,事情就變得開始複雜了。我們來看看這個例子吧 假設有三張表 請選出選了所有課程的學生 select 姓名 from 學生表 where not exists 學生缺的學科 select from 課程表 where not exists 學生選的學科 select fro...