アプリでUSBドライブ監視時にUSBの抜去ができない。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ヨシカワ

アプリでUSBドライブ監視時にUSBの抜去ができない。

#1

投稿記事 by ヨシカワ » 13年前

先日に続き恐縮ですが、質問をさせてください。

アプリ側でUSBのファイル変更の監視を行っています。
この時に、タスクトレイの「ハードウェアを安全に取り外してメディアを取り出す」からUSBの取り外しを行うと、
「このデバイスは現在使用中です。・・・・・」というエラーが発生します。

USBドライブの監視を以下のサイトを参考にしています。
方法はドライブ単位にReadDirectoryChanges()を使用したファイルアクセスのチェックです。
http://d.hatena.ne.jp/seraphy/20120506


■質問
上記のWindowsのエラーを回避してUSBの抜去をすることは可能でしょうか?
こちらで検討したところ、常時CreateFileでオープンしているため、不可能だと思っています。


■調査範囲
一応原因は把握しており、CreateFileでドライブ自体をオープンしているため、OS側がUSBドライブを使用中と判断したためだと認識しています。

現状の実装はWindowのサービス上で実装しています。
USB挿入時のイベント(SERVICE_CONTROL_DEVICEEVENT)を取得後に、監視を開始。
抜去時のイベントでリソースの開放を行っています。

物理的にUSBを抜いた場合はSERVICE_CONTROL_DEVICEEVENTは発生しますが、上記の抜き方では発生しません。






・コードの一部記載します

HANDLE m_hDir = ::CreateFile(strDirToWatch, //USBドライブのパス
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE ,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS |
FILE_FLAG_OVERLAPPED,
NULL);



-- 中略 --

BOOL b = ReadDirectoryChangesW(m_hDir, pBuf, nBufSize, TRUE, m_cOpt.dwWatchMode, 0, &m_Overlapped, 0);
if(!b) {
break;
}

-- 中略 --
ファイルアクセスがあったファイルのチェック

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: アプリでUSBドライブ監視時にUSBの抜去ができない。

#2

投稿記事 by softya(ソフト屋) » 13年前

前回のトピックが解決になっていないので解決にするか前回のトピックで続きをお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ヨシカワ

Re: アプリでUSBドライブ監視時にUSBの抜去ができない。

#3

投稿記事 by ヨシカワ » 13年前

ご指摘ありがとうございます。前質問のステータスを変更しました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: アプリでUSBドライブ監視時にUSBの抜去ができない。

#4

投稿記事 by softya(ソフト屋) » 13年前

OSの管理としては資源がアプリによって確保されている以上はUSBを切り離すことは簡単では無いと思います。
Usbstor.sysから取り外し依頼イベントをアプリに通知する仕組みがあれば良いのですが・・・。少し調べてみます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: アプリでUSBドライブ監視時にUSBの抜去ができない。

#5

投稿記事 by softya(ソフト屋) » 13年前

確実な方法は以下の様な方法みたいですね。
「USBメモリのファイル監視について - Insider.NET - @IT」
http://www.atmarkit.co.jp/bbs/phpBB/vie ... 33&forum=7
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

dig
記事: 59
登録日時: 13年前

Re: アプリでUSBドライブ監視時にUSBの抜去ができない。

#6

投稿記事 by dig » 13年前

ヨシカワ さんが書きました:先日に続き恐縮ですが、質問をさせてください。

アプリ側でUSBのファイル変更の監視を行っています。
この時に、タスクトレイの「ハードウェアを安全に取り外してメディアを取り出す」からUSBの取り外しを行うと、
「このデバイスは現在使用中です。・・・・・」というエラーが発生します。

USBドライブの監視を以下のサイトを参考にしています。
方法はドライブ単位にReadDirectoryChanges()を使用したファイルアクセスのチェックです。
http://d.hatena.ne.jp/seraphy/20120506

■質問
上記のWindowsのエラーを回避してUSBの抜去をすることは可能でしょうか?
こちらで検討したところ、常時CreateFileでオープンしているため、不可能だと思っています。

■調査範囲
一応原因は把握しており、CreateFileでドライブ自体をオープンしているため、OS側がUSBドライブを使用中と判断したためだと認識しています。

現状の実装はWindowのサービス上で実装しています。
USB挿入時のイベント(SERVICE_CONTROL_DEVICEEVENT)を取得後に、監視を開始。
抜去時のイベントでリソースの開放を行っています。

物理的にUSBを抜いた場合はSERVICE_CONTROL_DEVICEEVENTは発生しますが、上記の抜き方では発生しません。
Windowsサービスですか...サービスではやったことないのであくまで推測となります。間違ってたらすいません。

WM_DEVICECHANGEを捕捉でき、かつwparamを取得できるのであればデバイス取り外し要求メッセージであるDBT_DEVICEQUERYREMOVEを
捕捉し、デバイスの監視をそこで終了させればいけるような気がします。
もし監視終了がタイミング的に間に合わずデバイスの除去に失敗した場合は更にデバイス取り外し要求が失敗したことを表すDBT_DEVICEQUERYREMOVEFAILEDメッセージを捕捉し、アプリ側で停止、
除去してみるというのはどうでしょうか?
(ちなみにDBT_DEVICEQUERYREMOVEなどはRegisterDeviceNotification() を呼び出しておかないとメッセージが来なかったはずです。少なくともウィンドウアプリでは...
また、多機能カードリーダ(SD、XD、CFなど対応)の取り外し要求メッセージはこれで捕捉できるかどうかわかりません。)


しかしながら、どういうアプリケーションかは知りませんが、2度挿したら差分チェックするというのは意味があるのでしょうか?
ユニーク値の保存もどこまでやるのかはわかりませんが、キッチリやらないとあまり意味がないように思います。

例えば
F:にusbAデバイスを挿す→Aを抜く→usbBデバイスをF:に挿す→Bを抜く→またusbAをF:に挿す。今度はCとAを交互に...と以下ループ。

こういったことを繰り返された場合どうするのでしょうか?永遠と配列か何かでユニーク値を保存していくのでしょうか?
コンビニの店頭にある写真印刷機のような長期稼動を前提とするプログラムの場合はこれではマズイような気もします。

以上、参考になれば幸いです。

閉鎖

“C言語何でも質問掲示板” へ戻る