リムーバブルメディアの取り外し をWin32APIで実行する方法 [プログラミング]
久々に開発ネタ。やり方はしってはいたのだが、URL忘れるので貼っておく。
SetupDi を使用してハードウェア機器を列挙する方法
http://support.microsoft.com/kb/259695/ja
http://support.microsoft.com/kb/165721/ja
Windowsではリムーバブルメディア(USB-HDD)に大して遅延書き込みをする場合、遅延書き込みデータをフラッシュするために「安全な取り外し」を推奨している。これをやらないとメモリにデータが残っていてデータロスや、ファイルシステムの破損につながる。
一方でSATAにはeSATAという取り外し可能な規格があるが、自分が使っているSATAのホストアダプタはWindowsに取り外し可能であると通知しないため、取り外しアイコンが出てこない。
そこでHotSwap!とかのフリーウェアを使っているのだが、それの実装はこの処理をやっている。
キーワードはSetupDi/CM_あたり。ここらへんはデバイスマネージャーの機能をプログラムでできるようになっている。
プログラム組むのが面倒な場合は、devcon.exeというのもある。前にエントリ書いた気がするが。
余談だが、\\.\Xで開いたときはボリュームだが、\\.\PhysicalDeviceXで開けるのはディスクドライバだったりする。
ボリューム -> ファイルシステムドライバ -> PartMgr -> ディスクドライバ
IOCTLを出すと自分が担当じゃない場合は次に投げる処理が入っている・・・わけでもなかったりするので、ディスク全体の情報を有機的に調べる方法が意外に難しい。
USB-HDDなどをOSが認識した場合
・ホストアダプタがOSへ新しいドライブができたことを通知する
・ディスクドライバが物理デバイスオブジェクトに貼りつく(これがいわゆるFDO)
・ディスクドライバのUpperFilterであるPartMgrがMBRを読み込み、パーティション管理を行う
・Windowsの誰かからIOCTL_DISK/IOCTL_STORAGEでその情報を取得しにくる
・パーティションがNTFSだとNTFSドライバが動き出す(フィルタドライバがあればそれも動き出す)
というような流れになっている。ことから以下のことがおこる
・\\.\PhysicalDeviceXでNTFSでフォーマットされたディスクを直接書き換えると確実に破損するし、キャッシュとの不整合がおきる
・同様にMBRを物理的に書き換えても、上位のPartMgrやNTFSが知るすべが無いのでOSは知らんぷり。再接続したときだけわかる。
・NTFSはパーティションのことしか知らないので、そのパーティションが物理デバイスのどこにあるかはIOCTL_DISK/STORAGE_なんちゃらを出さないといけない。
・FSCTL_はNTFSへ、IOCTL_DISK/STORAGEはディスクへ出す物と考えていいはずだが、実際はキャッシュされているし、OSからのシーケンスでしか動かないので制約が多い
例えば上記のように知るすべがないから自分がIOCTLを出して変更を促そうと思っても覚えているのが別の何かでそいつがリクエストを出してこないといけないので意味が無い。Windowsだとこういう制限が多すぎて開発する気力が亡くなる人も多いのではないだろうか。
ここらへんのことをまともに書いた本が無いのがまた困る・・・
NTFSについては以下の本が素晴らしいのだが、古いからセキュリティに付いての記述がない上に絶版。しかも真面目につくろうとするとアンドキュメンテッドな事象に遭遇しまくる。
SetupDi を使用してハードウェア機器を列挙する方法
http://support.microsoft.com/kb/259695/ja
http://support.microsoft.com/kb/165721/ja
Createfile を GENERIC_READ|GENERIC_WRITE、FILE_SHARE_READ|FILE_SHARE_WRITE、し OPEN_EXISTING を使用します。LpFileName\\.\X パラメーターに指定する必要があります: (X は、実際のドライブ文字)。他のすべてのパラメーターは 0 になります。 FSCTL_LOCK_VOLUME IOCTL を使用して発行することによって、ボリュームをロックします。DeviceIoControl。その他のアプリケーションまたはシステムを使用している場合は、ボリューム、この IOCTL は失敗します。この関数を正常に戻ると、アプリケーション ボリューム以外が使用されていないことが保証されています。このシステムでは。 FSCTL_DISMOUNT_VOLUME IOCTL を発行することによって、ボリュームをマウント解除します。これボリュームのすべての情報を削除するのには、ファイル システムをがボリュームが関係を維持する内部情報を破棄します。 実行して、メディアを削除できるかどうかを確認、IOCTL_STORAGE_MEDIA_REMOVAL IOCTL。PreventMediaRemoval のメンバーを設定します。PREVENT_MEDIA_REMOVAL 構造体を FALSE この IOCTL を呼び出す前にします。これは、デバイスからメディアの削除を防ぐを停止します。 IOCTL_STORAGE_EJECT_MEDIA IOCTL とメディアを取り出します。場合は、デバイスIOCTL_STORAGE_EJECT_MEDIA することができますし、自動排出をすることはできません。スキップし、ユーザーがメディアを削除するように指定できます。 閉じる、ボリューム ハンドルを取得、最初のステップの問題で、FSCTL_UNLOCK_VOLUME IOCTL。これは、ドライブを使用することができます。他のプロセス。
Windowsではリムーバブルメディア(USB-HDD)に大して遅延書き込みをする場合、遅延書き込みデータをフラッシュするために「安全な取り外し」を推奨している。これをやらないとメモリにデータが残っていてデータロスや、ファイルシステムの破損につながる。
一方でSATAにはeSATAという取り外し可能な規格があるが、自分が使っているSATAのホストアダプタはWindowsに取り外し可能であると通知しないため、取り外しアイコンが出てこない。
そこでHotSwap!とかのフリーウェアを使っているのだが、それの実装はこの処理をやっている。
キーワードはSetupDi/CM_あたり。ここらへんはデバイスマネージャーの機能をプログラムでできるようになっている。
プログラム組むのが面倒な場合は、devcon.exeというのもある。前にエントリ書いた気がするが。
余談だが、\\.\Xで開いたときはボリュームだが、\\.\PhysicalDeviceXで開けるのはディスクドライバだったりする。
ボリューム -> ファイルシステムドライバ -> PartMgr -> ディスクドライバ
IOCTLを出すと自分が担当じゃない場合は次に投げる処理が入っている・・・わけでもなかったりするので、ディスク全体の情報を有機的に調べる方法が意外に難しい。
USB-HDDなどをOSが認識した場合
・ホストアダプタがOSへ新しいドライブができたことを通知する
・ディスクドライバが物理デバイスオブジェクトに貼りつく(これがいわゆるFDO)
・ディスクドライバのUpperFilterであるPartMgrがMBRを読み込み、パーティション管理を行う
・Windowsの誰かからIOCTL_DISK/IOCTL_STORAGEでその情報を取得しにくる
・パーティションがNTFSだとNTFSドライバが動き出す(フィルタドライバがあればそれも動き出す)
というような流れになっている。ことから以下のことがおこる
・\\.\PhysicalDeviceXでNTFSでフォーマットされたディスクを直接書き換えると確実に破損するし、キャッシュとの不整合がおきる
・同様にMBRを物理的に書き換えても、上位のPartMgrやNTFSが知るすべが無いのでOSは知らんぷり。再接続したときだけわかる。
・NTFSはパーティションのことしか知らないので、そのパーティションが物理デバイスのどこにあるかはIOCTL_DISK/STORAGE_なんちゃらを出さないといけない。
・FSCTL_はNTFSへ、IOCTL_DISK/STORAGEはディスクへ出す物と考えていいはずだが、実際はキャッシュされているし、OSからのシーケンスでしか動かないので制約が多い
例えば上記のように知るすべがないから自分がIOCTLを出して変更を促そうと思っても覚えているのが別の何かでそいつがリクエストを出してこないといけないので意味が無い。Windowsだとこういう制限が多すぎて開発する気力が亡くなる人も多いのではないだろうか。
ここらへんのことをまともに書いた本が無いのがまた困る・・・
NTFSについては以下の本が素晴らしいのだが、古いからセキュリティに付いての記述がない上に絶版。しかも真面目につくろうとするとアンドキュメンテッドな事象に遭遇しまくる。
Windows NT ファイルシステム詳説―A Developer’s Guide
- 作者: ラジーブ ナガール
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 1999/01
- メディア: 単行本
コメント 0