サンプル コードから運用ドライバへ: サンプルにおいて変更すべき点

最終更新日: 2008年5月13日

Windows Driver Kit (WDK) には、ドライバ開発に有用な技法を示す、さまざまなサンプル ドライバが含まれています。独自ドライバの基礎として、これらのサンプルを使用できます。ただし、独自デバイスとドライバに適用するには、ドライバをリリースする前に、運用コード以外にも、サンプルにおいて、デバイス固有の特定の側面を変更する必要があります。ドライバ作成者は時として、これらの詳細を見落とす場合があります。

変更しなければならない正確な項目はサンプルごとに異なりますが、一般的に、これらの項目は、特定のデバイス、インターフェイス、またはドライバを識別します。たとえば、サンプル ドライバに下記の項目のいずれかが含まれている場合、それらを変更してドライバとデバイスに適用する必要があります。

グローバル一意識別子 (GUID)

シンボリック リンク名

デバイス オブジェクト名

プール タグ

I/O 制御コード (IOCTL) の定義

ユーザー モード ドライバ フレームワーク (UMDF) のドライバ オブジェクト クラス ID

システム フォルダにコピーされるすべてのファイルの名前

プラグ アンド プレイ デバイス ID、ハードウェア ID、および互換性 ID

ドライバのサービス名

デバイスの説明

リソース ファイル

これらの変更を行わないと、インストールの失敗、システム上での他のデバイスおよびドライバとの競合、デバッグでの障害、およびその他のエラーにつながる場合があります。

GUID。ドライバは、GUID を使用して、デバイス セットアップ クラス、デバイス インターフェイス クラス、カスタム PnP イベント、カスタム Windows Management Instrumentation (WMI) イベント、および Windows PreProcessor (WPP) トレース プロバイダを識別します。一部の GUID は Microsoft によって定義され、その他の GUID はデバイスとドライバのメーカーによって定義されます。

一般的なデバイスおよび WMI データの、デバイス セットアップ クラス GUID、デバイス インターフェイス クラス GUID、および WMI GUID は、すべてのドライバが使用できるよう、WDK またはパブリック ヘッダー ファイル内で定義されます。これらの GUID は変更しないでください。たとえば、マウスを実装する場合、WDK Ntddmou.h ヘッダー ファイルで定義された GUID_DEVINTERFACE_MOUSE を、デバイス インターフェイス クラスとして引き続き使用します。

ただし、新しいデバイス セットアップ クラスを定義する場合、新しいデバイス セットアップ クラスの GUID とセットアップ クラスの名前、場合によっては、新しいデバイス インターフェイス クラスの GUID も生成する必要があります。セットアップ クラスの GUID およびデバイス インターフェイス クラスの GUID は、一意な値である必要があり、GUID を共有できません。

サンプル ベースの大半のドライバの場合、サンプルのローカル ヘッダーまたはソース ファイルで定義された、サンプルに固有の GUID のみを変更する必要があります。そのような GUID には、下記のものが含まれている場合があります。

カスタム PnP イベント

カスタム WMI イベント

新規またはカスタム デバイスのデバイス インターフェイス クラス

WPP トレース プロバイダ

両方のドライバが同じシステムに読み込まれている場合、別のドライバ用に定義された GUID を使用すると、競合が生じる可能性があります。たとえば、2 つの異なるドライバが同じ 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 の Create GUID ツールを使用するか、Uuidgen.exe または Guidgen.exe を使用します。いずれも、Microsoft Windows Software Development Kit (SDK) に含まれています。これにより、例で示すように、GUID をドライバ ヘッダー ファイル内のシンボリック定数と関連付けることができます。

また、ドライバの WMI イベント用に、新しい GUID を作成しなければならない場合もあります。Toaster ドライバ サンプルは、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 ドライバは、Filter.h ヘッダー ファイルで下記のように定義された文字列を使用する、シンボリック リンク名を作成します。


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

太字の文字列を変更して、独自ドライバをより正確に記述してください。

デバイス オブジェクト名。サンプルがデバイス オブジェクトの名前を作成する場合、サンプル コードを応用する際に、名前を変更する必要があります。

KMDF Toaster Filter ドライバは、下記のように Filter.h ヘッダー ファイル内のデバイス オブジェクトに名前を付けます。


#define NTDEVICE_NAME_STRING      L\\Device\\ToasterFilter

シンボリック リンク名の場合と同様に、文字列を変更してドライバを説明する必要があります。

名前付きデバイス オブジェクトがセキュリティ リスクとなりうる点に注意してください。物理デバイス オブジェクト (PDO) には名前がありますが、そのような名前の大半は、ドライバによって明示的に割り当てられたのではなく、システムが生成したものです。他のデバイス オブジェクトは、制御デバイス オブジェクトを表す場合にのみ、名前を付ける必要があります。それらの名前は、アプリケーションとドライバとの側波帯通信で使用されます。カーネル モード ドライバ フレームワーク (KMDF) と Windows Driver Model (WDM) の両方を用いて、Windows に名前を生成させることができます。このアプローチにより、デバイス オブジェクトの名前は一意になり、特権のないユーザーはそれにアクセスできなくなります。詳細については、WDK を参照してください。

プール タグ。プール タグは、1 文字から 4 文字のリテラルで、特定のメモリ割り当てを識別し、デバッグの際に役に立ちます。

サンプル ドライバの多くは、Toaster h の下記の行のように、ドライバ ヘッダー ファイルでプール タグを定義します。


#define TOASTER_POOL_TAG (ULONG) 'saoT'
      

ドライバは、後から前へタグを定義します。これは、デバッガがタグを逆順で表示するからです。そのため、このタグは、デバッガ出力で「Toas」と表示されます。サンプルが定義するタグを使用する代わりに、独自のコードが一意に識別されるよう、文字列を変更してください。

Pooltag.txt ファイルは、Windows で提供されるカーネル モード コンポーネントとドライバが使用するプール タグを一覧で示します。Pooltag.txt は、WDK と共に、%winddk%\Tools\Other\platform\Poolmon にインストールされます (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)
      

異なるデバイス用のサンプル ベースのドライバでは、この定義に対する変更が必要となります。

UMDF ドライバ オブジェクト クラス ID。UMDF サンプルを使用する場合、ドライバ オブジェクトのクラス ID を変更する必要があります。この値は通常、Internal.h ヘッダー ファイルで MYDRIVER_CLASS_ID として定義されます。ただし、一部のサンプルは、別のヘッダー ファイルでこれを定義します。

下記の例は、Skeleton ドライバの Internal.h ヘッダー ファイルの一部です。このファイルは、%WinDDK\Src\Umdf\Skeleton にあります。


#define MYDRIVER_CLASS_ID   { 0xd4112073, 0xd09b, 0x458f, \
        { 0xa5, 0xaa, 0x35, 0xef, 0x21, 0xee, 0xf5, 0xde } }
      

ドライバが Skeleton サンプルに基づく場合、上記の太字の定義を、ドライバ オブジェクトの一意なクラス ID に変更してください。

ファイル名。INF または INX で、ドライバ、メーカー提供の co-installer、およびインストール手順によってシステム フォルダにコピーされるその他のファイルの名前を変更してください。これらのファイル名は通常、INF の [SourceDisksFiles] セクションと [ClassInstall32] セクション、および CopyFiles エントリに表示されます。

下記の例は、KMDF Featured 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" 文字列を、独自のインストーラを記述するよう変更してください。これらの変更により、インストール手順で適切な co-installer ファイルがコピーされ、レジストリ キーに適切なファイル名が記録されます。

KMDF、UMDF、WinUSB の co-installer など、WDK または Windows で提供される co-installers の名前は変更しないでください。

下記の例で示すように、後で追加の変更が、ファイルの Device Install セクションで必要となります。


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

[Toaster_Device.NT.Copy]
wdffeatured.sys

この例では、太字のファイル名を、生成したドライバ ファイルの名前に変更してください。

セットアップは、INF とドライバ カタログ ファイルをコピーする際、それらの名前を変更します。したがって、ドライバ パッケージでそれらの名前を変更する必要は厳密にはありません。ただし、そうすれば、INF とカタログ ファイルの名前をドライバ ファイルの名前と同様なものにするのに、通常効果的です。

PnP デバイス ID、ハードウェア ID、および互換性 ID。セットアップは、ハードウェア ID および互換性 ID と共にデバイス ID を使用して、デバイスのインストールに使用する INF を選択します。

デバイス ID は、特定のデバイスを一意に識別する、メーカーが定義した文字列です。すべてのデバイスには、1 つだけデバイス ID があります。バス ドライバは列挙中にデバイス ID を報告し、セットアップはそれを使用して、デバイスを適切な INF ファイルに一致させます。デバイス ID は、INF の [Manufacturer] セクションで定義されます。

下記の例は、Osrusbfx2 で指定されているように、OSR USB Fx2 デバイスのデバイス ID を示したものです。


[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 ディレクティブを独自ドライバに適用するには、太字のデバイス ID を、独自デバイスのデバイス ID で置き換えます。また、メーカー名を自社の名称に変更する必要があります。

ハードウェア ID と互換性 ID は、デバイス ID ほど固有の ID ではなく、セットアップがそれらを使用するのは、デバイス ID を INF に一致させることができない場合です。INF が他のデバイスをサポートできる場合、デバイス ID だけでなく、これらの値を変更する必要があります。KMDF Featured Toaster ドライバでの下記の例は、ハードウェア ID を示したものです。


[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 ディレクティブを独自ドライバに適用するには、ハードウェア ID をドライバのデバイス ID で置き換え、"MsToaster" をより説明的な文字列に変更してください。

ドライバのサービス名。INF の AddService ディレクティブ内のサービス名を、ドライバに適切な値に更新してください。ドライバのサービス名が、システム上の別のドライバのサービス名と競合した場合、ドライバはインストールされない、または、読み込まれません。

KMDF Featured Toaster ドライバは、次のようにそのサービスの名前を付けます。


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

サービス名は、AddService ディレクティブ内の最初のエントリです。Featured Toaster の INF を適用するには、太字の文字列を、独自ドライバにより適した文字列に変更してください。この例で、wdffeatured_Service_Inst エントリは、INF で定義されたセクションを参照するのみです。したがって、このエントリの変更は重要ではありません。

デバイスの説明。デバイスの説明は、INF の [Strings] セクションで通常定義され INF のさまざまな場所で使用される、複数の文字列から成ります。たとえば、KMDF Featured 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] セクションにも存在する場合、その名称も変更する必要があります。

リソース ファイル。ドライバやサンプル固有の co-installer といった他のコンポーネントには、リソース (.rc) ファイルもあります。このファイルは、製品名、ファイル バージョン、企業名など、ドライバ固有の文字列を定義します。これらの文字列を、ドライバ パッケージに適切な値に変更してください。

どうすればよいでしょうか。

WDK サンプルに基づくドライバをリリースする前に、独自ドライバ作成に使用した、ソース ファイル、INF、および他のリソース内のサンプル固有の情報をすべて置き換えてください。必要な変更は、サンプルによって異なりますが、一般に、サンプル ドライバまたはそのデバイスを一意に識別するすべての情報が対象となります。通常、行う必要のある変更点は、次のとおりです。

適切な場合、ドライバに固有の GUID を生成して使用します。

シンボリック リンク名を更新します。

デバイス オブジェクトの名前を更新するか、自動生成された名前を使用します。

ドライバを識別し既知のタグと競合しないプール タグを使用します。

ドライバとデバイスに適切な IOCTL コードを定義します。

UMDF ドライバ オブジェクト用に一意なクラス ID を使用します。

システム フォルダにコピーされるすべてのファイルの名前を更新します。

適切なプラグ アンド プレイ デバイス ID、ハードウェア ID、および互換性 ID を INF に挿入します。

INF 内のドライバのサービス名を更新します。

デバイスの説明を変更します。

リソース ファイル内のドライバ固有の文字列をすべて変更します。

詳細情報:

書籍
Developing Drivers with the Windows Driver Foundation、Penny Orwick、Guy Smith 共著

WHDC Web サイト上のドライバに関するヒント
Who's Using the Pool?

WDK ドキュメント
Defining and Exporting New GUIDs
Controlling Device Access in Framework-Based Drivers
IoCreateDeviceSecure

Windows SDK
Microsoft Windows Software Development Kit (SDK)


ページのトップへページのトップへ