Posted on 2009-10-25 17:00
S.l.e!ep.¢% 閱讀(658)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
Windows WDM
怎樣控制驅(qū)動(dòng)程序的加載順序?
2009-10-13 18:05
設(shè)計(jì) Windows NT 時(shí)所采用的概念是:第一個(gè)提出占有某設(shè)備的驅(qū)動(dòng)程序獲得該設(shè)備的所有權(quán)。這個(gè)所有權(quán)可以共享,也可以獨(dú)占,這由提出占有要求的設(shè)備驅(qū)動(dòng)程序決定。如果設(shè)備驅(qū)動(dòng)程序?qū)υO(shè)備提出了獨(dú)占占有要求,則由以后加載的設(shè)備驅(qū)動(dòng)程序?qū)υ撛O(shè)備嘗試提出的任何占有要求都將失敗。因此,設(shè)備驅(qū)動(dòng)程序的加載順序必須可以由設(shè)備驅(qū)動(dòng)程序的作者進(jìn)行修改。本文介紹可用于控制設(shè)備驅(qū)動(dòng)程序加載順序的兩種方法。
更多信息有兩種方法可以用于控制設(shè)備驅(qū)動(dòng)程序的加載順序。這兩種方法都利用了位于 \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\...有兩種方法可以用于控制設(shè)備驅(qū)動(dòng)程序的加載順序。這兩種方法都利用了位于 \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control 的注冊(cè)表項(xiàng)。第一種方法是修改 ServiceGroupOrder。第二種方法是根據(jù) GroupOrderList 分配用于決定驅(qū)動(dòng)程序加載順序的 Tag 值。Tag 值、起始值、類型值和組名稱都位于 HKLM\SYSTEM\CurrentControlSet\Services\<drivername> 項(xiàng)中,必須先添加此項(xiàng),然后這些值才能在組名稱列表中列出。
這兩種方法僅對(duì)起始值為 0 (SERVICE_BOOT_START) 或 1 (SERVICE_SYSTEM_START) 的設(shè)備驅(qū)動(dòng)程序有效。在所有情況中,起始值為 0 的設(shè)備驅(qū)動(dòng)程序都將在起始值為 1 的所有設(shè)備驅(qū)動(dòng)程序嘗試加載之前先加載。
方法 1:ServiceGroupOrder ServiceGroupOrder 包含按加載順序排列的組名稱列表。下面原樣列出 ServiceGroupOrder 的內(nèi)容:
SCSI miniport port Primary disk SCSI class SCSI CDROM class filter boot file system Base Pointer Port Keyboard Port Pointer Class Keyboard Class Video Init Video Video Save file system Event log Streams Drivers NDIS TDI NetBIOSGroup SpoolerGroup 根據(jù) ServiceGroupOrder,“SCSI class”組中的設(shè)備驅(qū)動(dòng)程序?qū)⒃凇癙rimary disk”組中的所有設(shè)備驅(qū)動(dòng)程序之后,及“SCSI CDROM class”組中的設(shè)備驅(qū)動(dòng)程序之前加載。設(shè)備驅(qū)動(dòng)程序所在的組在列表中的位置越高,越先加載它。ServiceGroupOrder 列表將被掃描兩次。首先加載所有起始值為 0 的設(shè)備驅(qū)動(dòng)程序,然后加載所有起始值為 1 的設(shè)備驅(qū)動(dòng)程序。因此,無(wú)論起始值為 0 的設(shè)備驅(qū)動(dòng)程序在 ServiceGroupOrder 列表中處于什么位置,它都會(huì)在所有起始值為 1 的設(shè)備驅(qū)動(dòng)程序之前加載。
設(shè)備驅(qū)動(dòng)程序的作者可以編輯 ServiceGroupOrder。這樣就可以在列表中的任意位置創(chuàng)建新組。名為“SAMPLDRV”的 SCSI class 設(shè)備驅(qū)動(dòng)程序就是個(gè)很好的示例,因?yàn)椤癝CSIDISK”正在提出占有 SAMPLDRV 需要提出占有的設(shè)備,所以 SAMPLDRV 需要在 SCSIDISK 之前加載。下面是 SCSIDISK 的注冊(cè)表項(xiàng):
\registry\machine\system\currentcontrolset\services\scsidisk Type = REG_DWORD 0x00000001 Start = REG_DWORD 0x00000000 Group = SCSI class ErrorControl = REG_DWORD 0x00000000 DependOnGroup = REG_MULTI_SZ "SCSI miniport"
可以將名為“Load Me First”的新組添加到 ServiceGroupOrder 中,并將 SAMPLDRV 設(shè)置為 Load Me First 組的成員。下面是經(jīng)過修改的 ServiceGroupOrder:
SCSI miniport port Primary disk Load Me First SCSI class SCSI CDROM class filter boot file system . . . 下面是 SAMPLDRV 的注冊(cè)表項(xiàng):
\registry\machine\system\currentcontrolset\services\sampldrv Type = REG_DWORD 0x00000001 Start = REG_DWORD 0x00000000 Group = Load Me First ErrorControl = REG_DWORD 0x00000000 DependOnGroup = REG_MULTI_SZ "SCSI miniport"
根據(jù)該配置,SAMPLDRV 將在 SCSIDISK 之前加載。
方法 2:GroupOrderList 和 Tag 值 稱為 Tag 的可選項(xiàng)可以包括在設(shè)備驅(qū)動(dòng)程序的注冊(cè)表中。Tag 的值可以幫助決定某個(gè)組內(nèi)設(shè)備驅(qū)動(dòng)程序的加載順序。加載順序不必按數(shù)字順序排列,相反,可以按照由 GroupOrderList 定義的順序排列。GroupOrderList 中每個(gè)組的第一項(xiàng)都是 Tag 值的數(shù)值。接下來(lái)是要加載的 Tag 值的數(shù)字順序。組中的設(shè)備驅(qū)動(dòng)程序首先按照其由 GroupOrderList 所定義的 Tag 值進(jìn)行加載。如果設(shè)備驅(qū)動(dòng)程序沒有 Tag 值,或者 Tag 值不在 GroupOrderList 中,則這些設(shè)備驅(qū)動(dòng)程序?qū)⒃诩虞d具有有效 Tag 值的設(shè)備驅(qū)動(dòng)程序之后進(jìn)行加載。對(duì)于這些設(shè)備驅(qū)動(dòng)程序,無(wú)法保證加載順序,只能保證組中的所有設(shè)備驅(qū)動(dòng)程序都在下一組加載之前進(jìn)行加載。
下面是 GroupOrderList 的部分輸出:
\registry\machine\system\currentcontrolset\control\grouporderlist Base = REG_BINARY 0d 00 00 00 01 00... Extended base = REG_BINARY 04 00 00 00 01 00... Filter = REG_BINARY 05 00 00 00 01 00... Keyboard Class = REG_BINARY 01 00 00 00 01 00... Keyboard Port = REG_BINARY 01 00 00 00 01 00... Ndis = REG_BINARY 09 00 00 00 01 00... Pointer Class = REG_BINARY 01 00 00 00 01 00... Pointer Port = REG_BINARY 03 00 00 00 01 00... . . .
注意:沒有為 SCSI class 定義值。并非每個(gè)組都出現(xiàn)在 GroupOrderList 中。如果 GroupOrderList 中沒有某個(gè)組,則無(wú)法保證組內(nèi)設(shè)備驅(qū)動(dòng)程序的加載順序。
與 ServiceGroupOrder 一樣,GroupOrderList 也可以修改。以上示例可以添加 SCSI class 的 Tag 項(xiàng):
\registry\machine\system\currentcontrolset\control\grouporderlist SCSI class = REG_BINARY 02 00 00 00 02 00 00 00 01 00 00 00 Base = REG_BINARY 0d 00 00 00 01 00... Extended base = REG_BINARY 04 00 00 00 01 00... . . .
在這個(gè)示例中,SCSI class 組識(shí)別出兩個(gè) Tag 值:00000001 和 00000002。Tag 值的加載順序是先加載 00000002,其次是 00000001。如果 SAMPLDRV 在 SCSI class 組中(與 SCSIDISK 相同),則任一 Tag 值都可以保證 SAMPLDRV 在 SCSIDISK 之前加載,因?yàn)?SCSIDISK 沒有 Tag 值,而沒有作標(biāo)記的驅(qū)動(dòng)程序?qū)⒃诮M中最后一個(gè)加載。
如果由于某種原因,SCSIDISK 分配的 Tag 值是 0x00000001,則當(dāng) SAMPLDRV 分配的 Tag 值是 00000002 時(shí),SAMPLDRV 在 SCSIDISK 之前加載:
\registry\machine\system\currentcontrolset\services\sampldrv Type = REG_DWORD 0x00000001 Start = REG_DWORD 0x00000000 Group = SCSI class ErrorControl = REG_DWORD 0x00000000 DependOnGroup = REG_MULTI_SZ "SCSI miniport" Tag = REG_DWORD 0x00000002
|