はじめに
PCIデバイス制御方法
内部構造
DLL部分
NT用ドライバー
95/98用ドライバー

 

ドライバコントロールシーケンスの統一

95/98のデバイスドライバーを制御する方法はINT 2Fを利用したものや、I/OトラップによるものDeviceIoControlによるものなどです。このうちDeviceIoControlを使う方法はNTの場合と同じ形式です。DLLの部分を統一できるためこれを使用することにします。

ドライバーのロード方法

アプリケーションが開始されるとまずpcidebug.dllはOSの種類を判定し、それに応じてデバイスドライバーをロードします。

OSの種類によりドライバーのロード方法は少々異なります。95/98の場合はVxDの名前に\\.\を付けてCreateFile()を呼び出すことでドライバーのロードができます。CreateFile()が返したハンドルがDeviceIoControl()で使用するハンドルになります。これを保存しておきます。

NTの場合はデバイスドライバーのロード開始とCreateFile()によるオープンは別々に行います。

ダイナミックなデバイスドライバーのロード

通常NTのデバイスドライバーはアドミニストレータ−の権限でインストールを行い、ブート時に開始されます。この方法ではpcidebug.dllを使用する時にデバイスドライバーのインストール、再起動、実行の手順をふまなければなりません。デバックソフトは定常的に使用するものではないので、システムの設定を変えたりせずできればファイルコピー程度で安易に実行できたほうが良いでしょう。またハードウエアを任意にアクセスできるドライバーをシステムにインストールして常時動作させておくのも少々気が引けます。そこで、DLLが動作を開始したときにダイナミックにデバイスドライバーをロード開始さ、DLL終了時に解放することとします。

デバイスドライバーを開始するにはまずOpenSCManager() でサービスコントロールマネージャーを開いた後、CreateService()でドライバーを登録し、StartService()で開始します。(driverload.c

開始後、デバイス名に\\.\を付けたものをファイル名としてCreateFile()を呼び出しハンドルを取得します。このハンドルは95/98の場合と同様にDeviceIoControlで使えます。サービスコントロールマネージャを使うにはアドミニストレータの権限が必要なのでpcidebug.dllを使ったアプリケーションを実行するにはアドミニストレータまたはアドミニストレータの権限を持っている必要があります。

割り込み処理の方法

Windowsでは割り込みが発生すると、デバイスドライバー内部の処理ルーチンが呼び出されます。つまり割り込み処理を行うにはデバイスドライバーのを作成しなけれなりません。そこで、Pcidebug.dllでは、割り込みが発生すると指定したユーザーモードの関数が呼び出される仕組みを用意し、デバイスドライバーの作成なしに割り込みを受け取ることを可能にしました。

割り込み処理の開始を宣言する関数_hookIRQ()を提供します。この関数に割り込みの番号と割り込み処理関数へのポインターを渡します。すると割り込みを監視するスレッドが開始されます。この割り込み監視スレットは割り込みが発生するまで停止し、割り込みが発生すると再開しアプリケーションの割り込み処理関数を呼び出します。

この仕組みにより割り込み処理をユーザーモードのプログラムで実現できるわけです。

wpe9.jpg (42098 バイト)

割り込み処理の方法

割り込み処理関数の制限事項

 

割り込み処理関数はスレットから呼び出されるため、マルチスレットのプログラムを作成する時の注意事項がそのまま当てはまります。特にMFCを使用している場合は注意が必要です。

MFCを使用したアプリケーションの場合、CWinThread オブジェクトを使わずにスレッドを作成したマルチスレッド アプリケーションでは、作成したスレッドから MFC オブジェクトにアクセスできません。

また、Window ハンドルは作成したスレットからしかアクセスできません。つまりMFCを使って割り込み処理関数からWindowに表示することは容易にはできません。

割り込み処理関数ではメモリー操作やデバイスへのアクセスにとどめ、なにか表示する場合はPostMessage()使ってメインスレットへメッセージを伝え、メインスレットで表示させるのが良いでしょう。

VC以外の言語から使用するために

 

VC以外の言語から容易に呼び出すことのできるようにDLL外部にエクスポートする関数は

関数の呼び出し規約は _stdcall 型にする。
DEFファイルを作成し装飾されていない名前をエクスポートする。

このような形式にすることにより、DelphiやVisual Basicから呼び出しが可能になります。

戻る 上へ 進む