共用方式為


從範例程式碼到生產驅動程式 - 範例中要變更的內容

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

除了這裡所述的變更之外,所有驅動程式都應該使用建立 可靠Kernel-Mode驅動程式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 所定義,而其他則由裝置和驅動程式廠商定義。

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

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

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

  • 自訂 PnP 事件

  • 自訂 WMI 事件

  • 新裝置或自訂裝置的裝置介面類別別

  • WPP 追蹤提供者

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

下列摘錄來自所有 Toaster 驅動程式範例中包含的 Driver.h 檔案。 它會定義適用于 Toaster 裝置的裝置介面 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 中的建立 GUID 工具或Guidgen.exe,這兩者都包含在 Microsoft Windows 軟體發展工具組 (SDK) 中。 然後,您可以將 GUID 與驅動程式標頭檔中的符號常數產生關聯,如範例所示。

您可能也需要為驅動程式的 WMI 事件建立新的 GUID。 Toaster 驅動程式範例會定義下列 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 Toaster 篩選驅動程式會建立符號連結名稱,其使用 Filter.h 標頭檔中定義如下的字串:

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

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

Device 物件名稱

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

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

#define NTDEVICE_NAME_STRING      L\\Device\\ToasterFilter

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

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

集區標籤

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

許多範例驅動程式都會在驅動程式標頭檔中定義集區標籤,如下列來自 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 精選的 Toaster 範例的 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 精選 Toaster 驅動程式的範例會顯示硬體識別碼:


[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 驅動程式會命名其服務,如下所示:


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

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

裝置描述

裝置描述包含數個字串,這些字串通常定義于 INF 的 [Strings] 區段中,並用於整個 INF 的各種位置。 例如,KMDF 精選 Toaster 範例會在 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 開發驅動程式,作者:Peny Orwick 和 Guy Smith

WDK 主題

定義和匯出新的 GUID

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

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

建立可靠的Kernel-Mode驅動程式

Surface Team Driver 開發最佳做法

驅動程式安全性指引

撰寫您的第一個驅動程式