共用方式為


從範例程式代碼到生產驅動程式 - 範例中要變更的專案

本主題描述在根據範例程式代碼發行設備驅動器之前,必須對WDK範例驅動程序進行的重要變更。

除了這裡所述的變更之外,所有驅動程式都應該使用建立可靠內核模式驅動程式和 Surface Team Driver 開發最佳做法中所述的最佳做法 所有驅動程式也應該遵守驅動程式安全性指引中 提供的指導方針

WDK 驅動程式範例 - 唯一標識符

Windows 驅動程式套件 (WDK) 包含各種不同的範例驅動程式,可示範適用於驅動程式開發的實用技術。 您可以使用這些範例作為您自己的驅動程式的基礎,但在釋放驅動程式之前,您必須變更範例的特定裝置特定層面,超越明顯的操作程序代碼,才能唯一地套用至您自己的裝置和驅動程式。 驅動程式寫入器有時會忽略這些詳細數據。

您必須變更的確切專案會從一個範例變更為下一個範例,但一般而言,它們會識別特定的裝置、介面或驅動程式。 例如,如果範例驅動程式包含下列任一專案,您必須變更它們以套用至您的驅動程式和裝置:

  • 全域唯一識別碼 (GUID)

  • 符號連結名稱

  • 裝置物件名稱

  • 集區標籤

  • I/O 控制程式代碼 (IOCTL) 定義

  • 複製到系統資料夾的任何檔案名稱

  • 隨插即用 裝置標識碼、硬體標識碼和相容的標識碼

  • 驅動程式服務名稱

  • 裝置描述

  • 資源檔

忘記進行這些變更可能會導致安裝失敗、與系統上的其他裝置和驅動程序發生衝突,以及偵錯困難以及其他錯誤。

例如,如果您收到這類 ...\toastDrv\kmdf\toastmon\wdftoastmon.inx(18-18): error 1284: Class "Sample" is reserved for use by Microsoft. 錯誤,表示「範例」名稱必須變更為範例驅動程式的唯一名稱。

GUID

驅動程式會使用 GUID 來識別裝置設定類別、裝置介面類別、自定義 PnP 事件、自定義 Windows Management Instrumentation (WMI) 事件,以及 Windows PreProcessor (WPP) 追蹤提供者。 某些 GUID 是由Microsoft所定義,其他則由裝置和驅動程式廠商定義。

裝置設定類別 GUID、裝置介面類別 GUID 和通用裝置和 WMI 資料的 WMI GUID 定義於 WDK 或公用頭檔中供任何驅動程式使用。 您不應該變更這些 GUID。

例如,如果您要實作滑鼠,您會繼續使用 WDK Ntddmou.h 頭檔中定義的GUID_DEVINTERFACE_MOUSE作為裝置介面類別。不過,如果您定義新的裝置安裝類別,則必須產生新的裝置安裝類別 GUID 和設定類別名稱,而且可能也會產生新的裝置介面類別 GUID。 安裝類別 GUID 和裝置介面類別 GUID 必須是唯一值;它們無法共用 GUID。

對於大部分以範例為基礎的驅動程式,您應該只變更範例本機標頭或原始程式檔中定義的 GUID,因此專屬於範例。 這類 GUID 可能包含下列各項:

  • 自定義 PnP 事件

  • 自定義 WMI 事件

  • 新裝置或自定義裝置的裝置介面類別

  • WPP 追蹤提供者

如果使用已針對另一個驅動程式定義的 GUID,如果在相同的系統上載入這兩個驅動程式,可能會導致衝突。 例如,如果兩個不同的驅動程式使用相同的 GUID 來註冊裝置介面,嘗試開啟裝置介面的用戶端可能會不小心開啟錯誤的裝置。

下列摘錄來自所有烤箱驅動程式範例中包含的 Driver.h 檔案。 它會定義適用於烤箱裝置的裝置介面 GUID:

DEFINE_GUID(GUID_TOASTER_INTERFACE_STANDARD, \
            0xe0b27630, 0x5434, 0x11d3, 0xb8, 0x90, 0x0, 0xc0, \
            0x4f, 0xad, 0x51, 0x71);
// {E0B27630-5434-11d3-B890-00C04FAD5171}

如果您在自己的驅動程式中使用這個檔案,請務必將範例 GUID 取代為粗體文字,並取代為您自己的裝置的介面 GUID。 若要建立 GUID,請使用 Microsoft Visual Studio 或 Guidgen.exe 中的建立 GUID 工具,這兩者都包含在 Microsoft Windows 軟體開發工具包 (SDK) 中。 然後,您可以將 GUID 與驅動程式頭檔中的符號常數產生關聯,如範例所示。

您可能也需要為驅動程式的 WMI 事件建立新的 GUID。 烤箱驅動程式範例會定義下列 GUID,以通知烤箱裝置抵達:

DEFINE_GUID (TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT, \
             0x1cdaff1, 0xc901, 0x45b4, 0xb3, 0x59, 0xb5, 0x54, \
             0x27, 0x25, 0xe2, 0x9c);
// {01CDAFF1-C901-45b4-B359-B5542725E29C}

您應該為驅動程式中的每個 WMI 事件建立新的 GUID。

如果範例驅動程式使用 WPP 軟體追蹤,請為您根據範例的任何驅動程式產生新的追蹤提供者 GUID。 例如,%WinDDK%\Src\Kmdf\Osrusbfx2\Final 中的 Osrusbfx2 範例 Trace.h 頭文件會定義控件 GUID,如下所示:

#define WPP_CONTROL_GUIDS \
    WPP_DEFINE_CONTROL_GUID( \
           OsrUsbFxTraceGuid,(d23a0c5a,d307,4f0e,ae8e,E2A355AD5DAB), \
        WPP_DEFINE_BIT(DBG_INIT)          /* bit  0 = 0x00000001 */ \
        WPP_DEFINE_BIT(DBG_PNP)           /* bit  1 = 0x00000002 */ \
        WPP_DEFINE_BIT(DBG_POWER)         /* bit  2 = 0x00000004 */ \
        WPP_DEFINE_BIT(DBG_WMI)           /* bit  3 = 0x00000008 */ \
        WPP_DEFINE_BIT(DBG_CREATE_CLOSE)  /* bit  4 = 0x00000010 */ \
        WPP_DEFINE_BIT(DBG_IOCTL)         /* bit  5 = 0x00000020 */ \
        WPP_DEFINE_BIT(DBG_WRITE)         /* bit  6 = 0x00000040 */ \
        WPP_DEFINE_BIT(DBG_READ)          /* bit  7 = 0x00000080 */ \
       )

在您自己的驅動程式中,您會將粗體文字取代為您建立的驅動程式特定名稱和 GUID。

如果範例定義符號連結名稱,請將範例中的名稱取代為套用至您自己的驅動程序的名稱。 不過,請勿變更已知的連結名稱,例如 \DosDevices\COM1。 一般而言,如果鏈接名稱與範例名稱(例如 \DosDevices\CancelSamp)相當類似,您應該變更它。

使用與另一個驅動程式相同的符號連結,效果與使用錯誤的裝置介面 GUID 相同,因為裝置介面基本上是符號連結。

%WinDDK\Src\Kmdf\Toaster\Filter 中的 KMDF 烤箱篩選器驅動程式會建立符號連結名稱,此連結名稱會使用 Filter.h 頭文件中定義為如下的字符串:

#define SYMBOLIC_NAME_STRING     L"\\DosDevices\\ToasterFilter"

將粗體字串變更為更準確地描述您自己的驅動程式。

裝置物件名稱

如果範例為裝置物件建立名稱,您必須在調整範例程式代碼時變更名稱。

KMDF Toaster Filter 驅動程式會在 Filter.h 頭檔中命名其裝置物件,如下所示:

#define NTDEVICE_NAME_STRING      L\\Device\\ToasterFilter

如同符號連結名稱,您應該變更字串來描述驅動程式。

請記住,具名裝置物件可能代表安全性風險。 實體裝置物件 (PDO) 必須具有名稱,而且大部分這類名稱都是系統產生的,而不是由驅動程序明確指派。 只有當其他裝置物件代表控制裝置物件時,才會命名它們,這些對象用於應用程式與驅動程式之間的側帶通訊。 內核模式驅動程序架構 (KMDF) 和 Windows 驅動程式模型 (WDM) 都可讓您讓 Windows 產生名稱。 此方法可確保裝置對象的名稱是唯一的,且不具特殊許可權的用戶無法存取它。 如需詳細資訊,請參閱在 KMDF 驅動程式中控制裝置Namespace存取和控制裝置存取。

集區標籤

集區標籤是一到四個字元的常值,可識別特定的記憶體配置,並可協助偵錯。

許多範例驅動程式會在驅動程式頭檔中定義集區標籤,如下列來自 Toaster.h 這一行所示:

#define TOASTER_POOL_TAG (ULONG) 'saoT'

驅動程式會向後定義標記,因為調試程式會以反向順序顯示它。 因此,這個標記會在調試程序輸出中顯示為 Toas 。 不要使用範例所定義的標記,而是將字串變更為唯一識別您自己的程序代碼。

Pooltag.txt檔案會列出核心模式元件和 Windows 隨附驅動程式所使用的集區標籤。 Pooltag.txt會與 %winddk%\Tools\Other<i>platform\Poolmon 中的 WDK 一起安裝,其中 platform 是 amd64、i386 或 ia64。 請勿使用出現在此清單中的任何標記。

IOCTL 定義

變更任何範例定義的 I/O 控制碼,以使用適合您裝置和驅動程式的名稱、裝置類型、函式程式碼、傳輸類型和存取類型。

例如,Osrusbfx2 範例包含下列IOCTL_OSRUSBFX2_READ_SWITCHES定義:

#define IOCTL_OSRUSBFX2_READ_SWITCHES   
                    CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
                             IOCTL_INDEX + 6, \
                             METHOD_BUFFERED, \
                             FILE_READ_ACCESS)

不同裝置的範例型驅動程式需要修改此定義。

檔案名稱

在 INF 或 INX 中,變更驅動程式的名稱、廠商提供的共同安裝程式,以及安裝程式複製到系統資料夾的任何其他檔案。 這些檔名通常會出現在 INF 和 CopyFiles 專案的 [SourceDisksFiles][ClassInstall32] 區段中。

下列範例來自 KMDF 精選烤箱範例的 INX 檔案,此範例適用於 %WinDDK%\src\kmdf\Toaster\Func\Featured。 必須變更的檔案名會以粗體顯示:

[ClassInstall32]
Addreg=ToasterClassReg
CopyFiles=ToasterClassInstallerCopyFileshighlight

[ToasterClassReg]
...
HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller"
...

[ToasterClassInstallerCopyFiles]
tostrcls.dll									    
...

若要針對不同的驅動程式調整檔案的這個部分,您會將 “tostrcls.dll” 變更為類別安裝程式的檔名,並變更 “ToasterClassInstaller” 字串來描述您自己的安裝程式。 這些變更可確保安裝程式會複製正確的共同安裝程式檔案,而且登錄機碼會記錄正確的檔名。

請勿變更 WDK 或 Windows 中提供的共同安裝程式名稱,例如 KMDF、UMDF 和 WinUSB 共同安裝程式。

稍後在檔案的 [裝置安裝] 區段中需要其他變更,如下列範例所示:

[Toaster_Device.NT]
CopyFiles=Toaster_Device.NT.Copy

[Toaster_Device.NT.Copy]
wdffeatured.sys

在此範例中,您會將粗體檔名變更為所產生驅動程式檔案的名稱。

當安裝程式複製 INF 和驅動程式類別目錄檔案時,它會重新命名它們,因此您不需要在驅動程式套件中變更其名稱。 不過,通常最好確保 INF 和目錄檔名類似於驅動程式檔名。

PnP 裝置識別碼、硬體標識碼和相容的標識碼

安裝程式會使用裝置識別碼以及硬體標識碼和相容的標識碼,以選取要用於裝置安裝的 INF。

裝置標識碼是廠商定義的字串,可唯一識別特定裝置。 每個裝置都有一個裝置標識碼。 總線驅動程式會在列舉期間報告裝置標識碼,而安裝程式會使用它來比對裝置與正確的 INF 檔案。 裝置標識碼定義於 INF 的 [Manufacturer] 區段中。

下列範例顯示 OSR USB Fx2 裝置的裝置識別碼,如 Osrusbfx2.inx 檔案中所指定:

[Manufacturer]
%MfgName%=Microsoft,NT$ARCH$

; For Win2K
[Microsoft]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002
...

; For XP and later
[Microsoft.NT$ARCH$]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002

若要針對您自己的驅動程序調整此 INF 指示詞,請將以粗體顯示的裝置識別碼取代為您自己的裝置的裝置識別碼。 您也應該將製造商名稱變更為公司的名稱。

如果硬體識別碼和相容標識碼不符合裝置標識碼與 INF,安裝程式會使用的較不特定標識碼。 如果您的 INF 可以支援其他裝置,則除了裝置識別碼之外,您也應該變更這些值。 KMDF 精選烤箱驅動程式的下列範例會顯示硬體識別碼:

[Manufacturer]
%StdMfg%=Standard,NT$ARCH$

; For Win2K
[Standard]
; DisplayName                   Section           DeviceId
; -----------                   -------           --------
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

; For XP and later
[Standard.NT$ARCH$]
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

若要為您自己的驅動程序調整此 INF 指示詞,請將硬體識別碼取代為驅動程式的裝置識別碼,並將 “MsToaster” 變更為更具描述性的字串。

驅動程式服務名稱

將 INF 中 AddService 指示詞中的服務名稱更新為適合您驅動程式的值。 如果驅動程式服務名稱與系統上的另一個驅動程式發生衝突,驅動程式將不會安裝或載入。

KMDF 精選烤箱驅動程式將其服務命名如下:

[Toaster_Device.NT.Services]
AddService = wdffeatured, %SPSVCINST_ASSOCSERVICE%,
     wdffeatured_Service_Inst
      

服務名稱是 AddService 指示詞中的第一個專案。 若要調整精選烤箱的 INF,您會將粗體字串變更為更適合您驅動程式的字串。 在此範例中,wdffeatured_Service_Inst專案只會參考 INF 定義的區段,因此變更它並不重要。

裝置描述

裝置描述包含數個字串,這些字串通常定義於 INF 的 [Strings] 區段中,並用於 INF 的各個位置。 例如,KMDF 精選烤箱範例會在 WdfFeatured.inx 檔案中定義下列字串:

[Strings]
SPSVCINST_ASSOCSERVICE   = 0x00000002
MSFT                     = "Microsoft"
StdMfg                   = "(Standard system devices)"
ClassName                = "Toaster"
DiskId1                  = "Toaster Device Installation Disk #1"
ToasterDevice.DeviceDesc = "Microsoft WDF Featured Toaster"
Toaster.SVCDESC          = "Microsoft WDF Toaster Featured Device Driver"

若要修改此檔案以安裝您自己的驅動程式,您應該變更粗體字串,以反映公司、裝置和驅動程式的相關信息。

如果公司名稱也出現在 INF 的 [Manufacturer] 區段中,您也必須變更該處的名稱。

資源檔

驅動程式和其他元件,例如範例特定共同安裝程式也有資源 (.rc) 檔案,可定義驅動程式特定的字串,包括產品名稱、檔案版本和公司名稱。 將這些字串變更為驅動程式套件的適當值。

摘要 - 您應該怎麼做?

在您發行以 WDK 範例為基礎的驅動程式之前,請取代來源檔案、INF 和您用來建立自己驅動程式的任何其他資源中的任何範例特定資訊。 所需的變更會因某個範例而異,但通常包含可唯一識別範例驅動程式或其裝置的任何資訊。 以下是您必須進行的一般變更:

  • 視需要產生和使用驅動程序專屬的 GUID。

  • 更新符號連結名稱。

  • 更新裝置物件的名稱,或使用自動產生的名稱。

  • 使用集區標籤來識別您的驅動程式,且不會與任何已知的標籤衝突。

  • 定義適合您驅動程式和裝置的IOCTL程式代碼。

  • 更新複製到系統資料夾的任何檔案名稱。

  • 在 INF 中插入正確的 隨插即用 裝置識別碼、硬體識別碼和相容的識別碼。

  • 更新 INF 中驅動程式的服務名稱。

  • 變更裝置描述。

  • 修改資源檔中的任何驅動程式特定字串。

  • 遵循安全性和可靠性的最佳做法

其他資訊

書籍

使用 Windows Driver Foundation 開發驅動程式,由 Penny Orwick 和 Guy Smith

WDK 主題

定義和匯出新的 GUID

控制 KMDF 驅動程式中的裝置存取

開發、測試和部署驅動程式

建立可靠的內核模式驅動程式

Surface Team Driver 開發最佳做法

驅動程式安全性指引

撰寫您的第一個驅動程式