INFファイルの構文チェック ~ chkinf の使い方 ~

皆さん、こんにちは。A寿です。

 

突然ですが、皆さんは、大使館に行ったことはありますか?・・・このお話にご興味のある方は本文の最後の【閑話休題】までどうぞ。

 

さて、今回は INF ファイルの構文チェックを行う、 chkinf というツールをご紹介しようと思います。以前、「ドライバ インストール時のトラブルシューティングの第一歩」という記事を書きました。ここに書いた以外のトラブルシューティング初期の切り分け方法として、 chkinf ツールで INF ファイルの構文チェックを行い、出力結果のエラーや警告をもとに正しい構文になるよう修正し、問題が解決するかどうか確認する、という方法もあります。今回は、 chkinf の使い方だけではなく、実際に、WDK サンプルの INF ファイルを変更しながら、どのようなエラーや警告が出るかをお見せしていこうと思います。この情報により、皆さんのトラブルシューティングの一助となれば幸いです。

 

まず、chkinf ツールは、以下のフォルダにあります。

 

  \WinDDK\{バージョン}\tools\Chkinf

 

このフォルダ内の chkinf.bat というバッチファイルで Perl のスクリプトを実行しています。このフォルダ内には、 chkinf.pm を初めとして、多くの .pm ファイルがあります。これらが INF ファイルの構文チェックをする実体です。 chkinf.bat は、これら .pm ファイルを実行する役割を持ちます。このフォルダの詳細については、下記ドキュメントをご参照ください。

 

  ChkINF Components

  https://msdn.microsoft.com/en-us/library/ff543464(VS.85).aspx

 

続いて、手順の概要は以下の通りです。

 

1. コマンドプロンプトを起動します。

   管理者権限は必要ありません。

2. 構文チェックをしたいINFファイルがあるディレクトリに、cd コマンドで移動します。

3. デフォルトでは、上記のChkinfフォルダへのパスが通っていませんので、ご自身でパスを設定していただくか、そうしない場合には、以下のようにフルパスを指定して実行します。

> \WinDDK\{バージョン}\tools\Chkinf\chkinf.bat <INFファイル名>.inf

   なお、WDFで使用する.inxファイルは、そのままではchkinfで使用できません。一度ビルドして.infファイルにする必要があります。

4. カレントディレクトリに、htmフォルダが生成されます。

   htmフォルダには、以下の2つのhtmファイルが生成されます。

   - summary.htm: エラーと警告の個数が表示されるファイルです。

   - <INFファイル名>.htm: 結果の詳細が表示されるファイルです。<INFファイル名> の部分は、上記 <INFファイル名>.inf の「<INFファイル名>」に指定した内容から自動的に生成されます。

 

ちなみに、上記は、 chkinf.bat の引数に INFファイルのみを指定した場合ですが、他のオプションもあるので、ご興味のある方は下記ドキュメントをご参照ください。

 

  ChkINF Command Syntax

  https://msdn.microsoft.com/en-us/library/ff543462(VS.85).aspx

 

それでは、実際に chkinf を使ってみましょう。今回は、対象の INF ファイルとして、WDK 7.1.0 の toasterのバスドライバ用のINFファイルを使います。具体的には、以下のフォルダにあるbus.infを使います。

 

  \WinDDK\7600.16385.1\src\general\toaster\wdm\inf\i386

 

それでは、上記手順に沿って chkinf.bat を実行してみましょう。例えば、 \blog\chkinf\bus\ のフォルダを作成し、 bus.inf をそのフォルダ以下にコピーしたとしますと、手順 2. で、以下のコマンドを実行して、そのフォルダに移動します。

> cd \blog\chkinf\bus\

手順 3. で、以下のコマンドを実行して、 INF ファイルの構文チェックを行います。

\WinDDK\7600.16385.1\tools\Chkinf\chkinf.bat bus.inf

その結果、手順 4. で、 \blog\chkinf\bus\フォルダに、 htm フォルダが生成されます。その中に、 summary.htm と @+__bus.htm の 2 つのファイルが作成されます。

 

C:\blog\chkinf\bus\htm>dir

ドライブ C のボリューム ラベルがありません。

ボリューム シリアル番号は 0836-2E4B です

 

C:\blog\chkinf\bus\htm のディレクトリ

 

2011/09/14 13:31 <DIR> .

2011/09/14 13:31 <DIR> ..

2011/09/14 13:31 4,472 @+__bus.htm

2011/09/14 13:31 602 summary.htm

               2 個のファイル 5,074 バイト

               2 個のディレクトリ 11,508,051,968 バイトの空き領域

 

summary.htm を開くと、以下の図のように、bus.inf ファイルに エラーが 1 個あり、警告はないことがわかります。

 

clip_image001[4]

 

この図で下線のある 「.\bus.inf:」 をクリックすると、以下の図のように、 @+__bus.htm の内容が表示されます。

 

clip_image002[4]

 

chkinf ツールの便利なところは、解析した結果を、上部に一覧表示してくれるだけでなく、エラーや警告に該当する行にも、その内容を挿入し、色を変えて強調表示してくれるところです。そのため、今回の Provider のエラーも非常に見つけやすくなっています。

 

今回のエラーの内容は、17行目にある [Version] セクションの Provider ディレクティブが「マイクロソフト」を指定しているため、「実際にその INF ファイルを記述した組織」を指定する必要がある、というものです。 17行目の Provider に指定されている %MSFT% の文字列は、74行目の [Strings] セクション内に以下の通り記述されています。(以降、INF ファイルの内容の抜粋には、各行の左端に行番号をつけます。行番号は、本記事のわかりやすさのために追記しているもので、実際のファイルには記述されません。)

 

74 MSFT = "Microsoft"

 

bus.inf のサンプルを使用してドライバを開発する方は、自分が属する組織名(例えば、社名)が Provider に指定されるように変更する必要がある、ということが以上からわかります。

 

ここまでは、 bus.inf を例にそのまま chkinf を実行してどうなるかを見てきました。ここからは、 bus.inf に間違った変更を加えた結果、どのように chkinf がそのことを指摘してくれるのかについて、 4 つ例を挙げてご紹介していきたいと思います。

 

 

■例1: [Version]セクションの DriverVer ディレクティブがない場合

 

以下のように、 bus.inf の 18 行目の DriverVer ディレクティブをコメントアウトして、 chkinf を実行してみます。

 

13 [Version]

14 Signature="$WINDOWS NT$"

15 Class=System

16 ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}

17 Provider=%MSFT%

18 ; DriverVer=09/21/2006,6.0.5736.1

19 CatalogFile=toaster.cat

 

結果は、以下のエラーメッセージが表示されます。

 

Line 13: (E22.1.1080) Directive: DriverVer required (and must not be blank) in section [Version]

 

ここでは、13行目に問題があると記載されています。 DriverVer ディレクティブを [Version] セクションに記載していないために、「[Version] セクションに問題がある」というエラーとなっています。

 

 

■例2: [Models] セクションのハードウェア ID がない場合

 

[Models] セクションとは、[Manufacturer] セクションの構文を以下のように展開していった時の、 models-section-name の名前を持つセクションのことです。

 

まず、[Manufacturer] セクションの構文は以下です。

 

[Manufacturer]

 

manufacturer-identifier

[manufacturer-identifier]

[manufacturer-identifier]

...

 

この manufacturer-identifier は以下の構文を持ちます。

 

manufacturer-name |

%strkey%=models-section-name |

%strkey%=models-section-name [,TargetOSVersion] [,TargetOSVersion] ... (Windows XP and later versions of Windows)

 

これらの構文の詳細については、以下のドキュメントをご参照ください。

 

  INF Manufacturer Section

  https://msdn.microsoft.com/en-us/library/ff547454(VS.85).aspx

 

続いて、 [Models] セクションは、以下の構文を持ちます。

 

[models-section-name] |

[models-section-name.TargetOSVersion] (Windows XP and later versions of Windows)

 

device-description=install-section-name[,hw-id][,compatible-id...]

[device-description=install-section-name[,hw-id][,compatible-id]...] ...

 

[Models] セクションのハードウェア ID とは、上記の [,hw-id] の部分を指します。

 

これらの構文の詳細については、以下のドキュメントをご参照ください。

 

  INF Models Section

  https://msdn.microsoft.com/en-us/library/ff547456(VS.85).aspx

 

以上を理解したうえで、 bus.inf を見ます。

以下に抜粋した bus.inf の 34 ~ 35 行目では、 "Standard" という名前が、[Models] セクションのセクション名として使用されます。

 

34 [Manufacturer]

35 %StdMfg%=Standard

 

そこで、 37 行目以降の [Standard] セクションを見ると、以下の "root\busenum" がハードウェア ID に相当します。

 

37 [Standard]

38 ;

39 ; These are the toaster bus pnp ids

40 ;

41

42 %ToasterBus.DeviceDesc%=ToasterBus_Device, root\busenum

 

以下のように、 bus.inf の 42 行目の "root\busenum" をコメントアウトして、 chkinf を実行してみます。

 

37 [Standard]

38 ;

39 ; These are the toaster bus pnp ids

40 ;

41

42 %ToasterBus.DeviceDesc%=ToasterBus_Device;, root\busenum

 

結果は、以下のエラーメッセージが表示されます。

 

Line 42: (E22.1.1025) No value for hw-id.

 

42 行目のハードウェア ID がないことを正しく検出できました。

 

 

■例3: CopyFiles ディレクティブで INF ファイルをコピーしようとした場合

 

CopyFiles ディレクティブは、インストールメディアからドライバのファイルをコピーするのに使用されます。これは、上記 [Models] セクションの中で、 install-section-name の名前を持つセクションの中に記載されます。このセクションは、MSDN ドキュメントでは、以下のドキュメントに該当します。

 

  INF DDInstall Section

  https://msdn.microsoft.com/en-us/library/ff547344(VS.85).aspx

 

bus.inf では、 "ToasterBus_Device" の名前を持ち、かつ、 ".NT" の拡張子を持つ、 44 行目の [ToasterBus_Device.NT] セクションに該当します。上記ドキュメントの、 CopyFiles の項目からリンクされている下記ドキュメントに記載されていますが、 CopyFiles ディレクティブを使って、INF ファイルをコピーしてはいけません

 

  INF CopyFiles Directive

  https://msdn.microsoft.com/en-us/library/ff546346(VS.85).aspx

 

      Do not use CopyFiles directives to copy INF files. For more information, see Copying INF Files

 

余談になりますが、 INF ファイルをコピーしたい場合は、 SetupCopyOEMInf API を使用するか、 CopyINF ディレクティブを使用します。このことについては、下記ドキュメントをご参照ください。

 

  Copying INF Files

  https://msdn.microsoft.com/en-us/library/ff540117(VS.85).aspx

 

さて、以下のように、 bus.inf の 45 行目の CopyFiles ディレクティブが参照している "Drivers_Dir" というセクションは、 54 行目にあり、その下にコピー対象の busenum.sys というドライバファイルが記載されています。

 

44 [ToasterBus_Device.NT]

45 CopyFiles=Drivers_Dir

 

(略)

 

54 [Drivers_Dir]

55 busenum.sys

 

ここに、以下のように、 bus.inf を並べて記載して、 chkinf を実行してみます。

 

54 [Drivers_Dir]

55 busenum.sys

56 bus.inf

 

結果は、以下の警告メッセージが表示されます。

 

Warnings:

Line 56: (W22.1.2028) "CopyFiles" directive should not copy files of type .inf.

Line 56: (W22.1.2112) File "bus.inf" is not listed in the [SourceDisksFiles].

 

1 つ目の警告は、本例の意図通り、 CopyFiles ディレクティブに INF ファイルを指定してはいけない、ということを表しています。2 つ目の警告は、 [SourceDisksFiles] セクションに bus.inf を指定しなかったので、 [SourceDisksFiles] セクションにないものを CopyFiles ディレクティブに指定したことを警告しています。今回は bus.inf を CopyFiles に指定すべきではないので、この警告は無視できます。

 

chkinf の警告は、2 つ目のように無視しても問題ない場合もありますが、無視することで、自分の意図通りのインストールが行えないような場合は、修正が必要な場合もあります。そのような場合が、次の例です。

 

 

■例4: サービス インストール セクションで、インストール セクション名を間違えた場合

 

サービス インストール セクションは、インストールセクション名 (上述の install-section-name ) に .Services がついたセクションです。主に、 AddService ディレクティブによって、この INF ファイルのインストール対象ドライバを、レジストリのHKEY_LOCAL_MACHINE\System\CurrentControlSet\Services の下にサービスとして登録する、というようなことができるセクションです。MSDN ドキュメントでは、以下のドキュメントに該当します。

 

  INF DDInstall.Services Section

  https://msdn.microsoft.com/en-us/library/ff547349(VS.85).aspx

 

bus.inf では、以下のように 58 ~ 60 行目が該当します。

 

58 ;-------------- Service installation

59 [ToasterBus_Device.NT.Services]

60 AddService = busenum,%SPSVCINST_ASSOCSERVICE%, busenum_Service_Inst

 

この 59 行目の ToasterBus_Device がインストール セクション名です。bus.inf では、 42 行目で定義され、 44, 47, 50 行目などで使われています。もし、 59 行目の ToasterBus_Device を他の名前に書き間違ってしまうと、サービス インストール セクションは、インストールセクションと何ら関連がなくなってしまい、サービスのインストールが正しく行われません。サービスのインストールが行われないと、ドライバが正しく起動できません。

 

そこで、これを、以下のように ToasterBus_Inst に変更し、 chkinf を実行してみます。

 

58 ;-------------- Service installation

59 [ToasterBus_Inst.NT.Services]

60 AddService = busenum,%SPSVCINST_ASSOCSERVICE%, busenum_Service_Inst

 

結果は、以下の警告メッセージが表示されます。

 

Line 59: (W22.1.2083) Section [TOASTERBUS_INST.NT.SERVICES] not referenced

Line 63: (W22.1.2083) Section [BUSENUM_SERVICE_INST] not referenced

 

1 つ目の警告は、 [ToasterBus_Inst.NT.Services] セクションがどのセクション、エントリ、ディレクティブからも参照されないことを表します。2 つ目の警告は、 [ToasterBus_Inst.NT.Services] セクションがどこからも参照されないことにより、 60 行目の busenum_Service_Inst の名前を持つ、63 行目の [busenum_Service_Inst] セクションが参照されなくなってしまったことを表します。

 

それでは、このような INF ファイルで実際に busenum.sys をインストールしてみましょう。

このbus.infを使って、管理者権限のコマンドプロンプト上から、

> devcon install bus.inf "root\busenum"

を実行すると、"devcon failed." というメッセージが出ます。

デバイスマネージャでは、以下の図のように、「不明なデバイス」として表示されます。

 

clip_image004[4]

 

このように、サービスのインストールが行われないと、ドライバが正しく起動できません。また、chkinf の出力結果が、エラーではなく警告だからと言って、必ずしも無視することはできないことがおわかりいただけたかと思います。

 

以上のように、 chkinf を使えば、 INF ファイルのだいたいの問題のありそうなところを指摘してくれるので、便利です。INF ファイルを作成したら、まずは chkinf を実行していただき、ドライバのインストールの問題を未然に防ぐ、といったような、お役に立てば幸いです。

 

――――――――――――――――

【閑話休題】突然ですが、皆さんは、大使館に行ったことはありますか?

 

・・・いいえ、亡命ではありません。1年くらい前に、「大使館で大使とお茶を楽しむ」という趣旨のカルチャーセンターの講座があり、以前から大使館に興味があったのと、「大使とお茶ができる機会があるなんて珍しい」と思い、東京都内某所にある、某国の大使館に行ってきました。その講座の内容は、具体的には、大使が、数十名の受講者を前に、1時間くらい英語で観光PRをし(もちろん日本語の通訳つき)、その後1時間くらいで、その国のブッフェを楽しむというものでした。私個人は、その国自体にはあまり興味がありませんでしたが、観光PRの内容が非常に魅力的だったので、一度行ってみたいと思えるようになりました。ただ、数週間後にはその国で政治的な混乱が起き、現在でさえ、外務省の渡航情報でも「渡航の是非を検討してください。」や、「渡航の延期をお勧めします。」といった表示がされる状況のままとなっており、いまだに訪問できてはいません。私個人のためだけでなく、その国の方々のためにも、早く状況が落ち着くよう祈ります。さて、観光PRの後、受講者たちはブッフェに移動し、大使と記念写真を撮りました。そして、いよいよ大使とお茶ができるのか、と思いきや、観光PRの予定時間がおしてしまったために、大使は一口もお茶やブッフェを一緒に楽しむことなく、次の予定へと出かけて行ってしまい、がっかりしました・・・。しかし、再度カルチャーセンターのパンフレットを見直すと、「大使館で、駐日大使からその国の魅力を伺い、ティータイムを楽しむ」と書かれているだけで、決して「駐日大使とティータイムを楽しむ」とは書かれていないのでした・・・。皆様も、勝手な思い込みで過度な期待をしないよう、ご注意ください。