Windows 7 Sensor Driverを作ろう - その2

さて、Sensor Driver第二弾です。

早速、SensorSkeltonの中を覗いてみましょう。
先ずは、Driver.h/cppです。
その1で説明したとおり、Sensor Driverは、UMDFのドライバーです。
このファイルには、UMDFとして認識される為のCMyDriverクラスが定義されています。デバイスがWinUSBやHUDのようにPlug & Play(以下PnPと書きます)に対応している場合、デバイスをPCに装着したときに、OnDeviceAddが、デバイスをPCから外した時に、OnDeinitializeがコールされます。
また、このDriverがシステムにロードされたとき、OnInitializeがコールされます。
PnPのセンサーデバイスで、使い始める為にセンサーの初期化等が必要であれば、OnDeviceAddで処理を行います。そして、サンプルにあるように、CMyDeviceクラスのインスタンスを作成します。

CMyDeviceクラスは、Device.h/cppで定義されています。OnDeviceAddがコールされたとき、引数としてIWDFDriverとIWDFDeviceInitializeのインスタンスが渡されてくるので、それを使ってCMyDeviceインスタンスを作成します。CMyDeviceインスタンスは一つしか必要ないので、CreateInstanceというFactoryメソッドが用意されていて、Singletonパターンが使われています。
そしてこのメソッドの中で、渡されたIWDFDriverインスタンスのCreateDeviceメソッドをコールし、システム側にデバイスの生成を通知します。
その後、システムが各種処理を行い、準備が完了すると、OnPrepareHardwareメソッドがコールされます。
ここで、CSensorDDIインスタンスを生成し、引数IWDFDeviceを渡してInitializeメソッドを呼び、CSensorDDIインスタンスを初期化します。そして、システムがSensor Driver向けにSensor Driverとして振舞うのに必要な諸機能を提供するSensorClassExtention COMインスタンスを取り出し、このCOMインスタンスを初期化します。
ここまでで、Sensor Frameworkに対する準備が整い、CSensorDDIインスタンスへのメソッドコールが始まります。

CSensorDDIクラスは、SensorDdi.h/cppファイルで定義されています。ヘッダーファイルを覗いてみると、このクラスがISensorDriverインターフェイスを実装するクラスであることが判ります。システム側は、このISensorDriverとして、このインスタンスにアクセスする事になります。
このCSensorDDIのメソッドをざっと見渡すと、Onが頭についたSTDMETHODCALLTYPEを戻り値型とするメソッド群がありますね。これらのメソッドは、先頭のOnを取ると、アプリケーション側で使うISensorクラスに定義されているメソッド群に一対一対応しています。アプリケーション側でISensorの各メソッドをコールすると、そのメソッド名の先頭にOnを付けた名前のCSensorDDIクラスのメソッドがシステムからコールされるようになっています。

何のセンサーか、そして何のプロパティをサポートするかは、SensorDdi.cppの先頭の方で、定数として定義され、各メソッドで利用されています。プロパティの管理は、Vistaで導入されたWindows Portable Deviceフレームワークを利用しているので、プロパティキーや値の設定の仕方は、・・・を参照してくださいね。
で、OnGetPropertiesやOnGetDataFieldsがコールされた際に、デバイスからデータを取得し、システム側に返してやれば良いわけです。
デバイスからデータを取得する為の仕掛けは、前に説明した、初期化時にシステムから渡される、IWDFDeviceインスタンスから取り出すことができます。この辺は、かなり難しいので、このブログでは割愛しますが、興味のある方は、Sensor Development Kitで公開されているDriverソースコードのReadWriteRequest.cppを見るとよいでしょう。

後はおまけ。
Visual Studio 2010のモデリング機能で、Sensor ドライバーの階層、SensorSkeltonのクラス図、処理の流れのシーケンス図を書いて以下のページで公開しましたぁ。
https://blogs.msdn.com/hirosho/pages/sensor-driver-sample-model.aspx
一応、参考まで

以上でその2は終わりです。次回はアプリケーションに非同期にデータを送る為の仕組みを解説します。