2009年01月29日

filedisk を MinGW でビルド (wk002)

FileDiskという 仮想ディスクドライバーを MinGW でビルドしようと思い立ち ... 一応動作するところまでこぎつけた。

とりあえず 今の版を filedisk-wk002.zipとして置いておく。

これはあくまで、移植のサンプル。実用として使うなら、オリジナルもしくは、上位版の CrossCrypt を使うことをお勧めする。
ただ、FileDisk を使うなら、中にある fdsetup.exe を使うと、MSYS で使えるようになる。MSYS を常用しているなら fdsetup.exe は便利かも知れない。

移植のまとめ

Windows Device Driver Programming Part 1Part 2 という解説ページが非常に参考になった。

デバッグに便利だったツールは、

  • ServiWin --- ドライバーを開始したり停止したりできる。状態を見るためにも必須。
  • DebugView --- DbgPrint だけが、MinGW でのデバッグ手段。メッセージをキャプチャーして表示するプログラムで必須。
  • DIP.zip (↑ 解説ページより) --- ドライバーを Install したり Uninstall したりできるツール。reboot しなくて良いので便利。
    (オリジナル DIP (Driver Install Program) は、Install するとサービスを自動でスタートするようになってきてテストには不向きなので、手動になるように手を入れたものを filedisk-wk002.zip に添付)


ソースコードの修正ポイント (コンパイルまで)

  • MinGW では、/mingw/include/ddk に DDK 関連のインクルードファイルが集まっている。だいたいは揃っている。足りない define は、ググるなり、オリジナルの DDK のヘッダを見るなりして補う。
  • カーネルから call される関数は DDKAPI の アトリビュートが必要。warning が出るので、対処する。
  • define されていることが期待されているものがいくつかある模様。_NTDDK_ もたぶんその一つ。コンパイルオプションで明示的に define する。


リンク


  • 成功したリンクオプションは以下のもの

    -static
    -Wl,--subsystem,native -Wl,--image-base,0x10000 \
    -Wl,--entry,_DriverEntry@8
    -nostartfiles -nostdlib -lntoskrnl

  • ただし、足りないものがある。仕方がないので、オリジナルの DDK の ntoskrnl.lib から取り出す。
    方法は、足りないものを call する stub0.o を作り、

    ld -r -o stub.o stub0.o ntoskrnl.lib

    ちなみに Windows Server 2003 DDK は、無償で ダウンロードできる。これをいったんインストールすれば、ntoskrnl.lib を取り出すことができる。


これをベースに何をしたいか

実をいうと、オリジナルの FILEDISK もかなり便利。ファイルを 仮想ディスクとして見せるだけでなく、-cd オプションをつけることにより、iso ファイルの マウントもできる。さらに、CrossCrypt になると暗号化もサポートしている。

それはそれで良いのだが、qemu 用の仮想ディスクフォーマットである qcow2 を 仮想ディスクに見せるものを(実験的にでも)作ってみたい。理由は copy-on-write の機能があるので、ランダムな Write を 再配置して性能を上げられるかも知れないから。暗号化もできるし、スナップショットも作れるので、便利で高速なものになるかも知れない。

というわけで、filedisk を qcow2 とくっつけてみようと思う。



メモ: filedisk の構造

DDKAPI をつけた関数は全部で 6個それらについて簡単に

DriveEntry() -- ドライバの初期化関数 (以下の関数を登録)

FileDiskCreateClose()  -- Create/Close 共通関数
( 実はなにもしない )
FileDiskReadWrite() -- Read/Write 共通関数
(I/O スレッドに投げる)
FileDiskDeviceControl() -- ioctl (これも I/O スレッドに投げる)
FileDiskUnload() -- 終了関数

FileDiskThread() -- I/O スレッド
(キューイングされたリクエストを順番に処理)
IRP_MJ_READ:
buffer をアロケート( ExAllocatePool(PagedPool,))
ZwReadFile (同期 read )
buffer をコピー
      buffer を 開放 (ExFreePool)
IRP_MJ_WRITE:
ZwWriteFile
IRP_MJ_DEVICE_CONTROL:
OCTL_FILE_DISK_OPEN_FILE:
ZwCreateFile()
IOCTL_FILE_DISK_CLOSE_FILE:
ZwClose()


FileDiskThread がほぼすべての処理をする。処理をする際は、キューから取り出して、同期 Read/Write を行う。

非同期の要素がなく、非常に簡単な構造。せめて、Write のバッファリングぐらいしたいもの。IRP_MJ_FLUSH_BUFFERS というのがあるから、それで バッファリングしたデータを書くようにすれば良いのだろう。
posted by すz at 00:17| Comment(0) | TrackBack(0) | プログラミング
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス: [必須入力]

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/30760568
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック