2012-01-12 30 views
1

ボリュームがWindows上でマウント解除されていることを検出できるようにしたいのですが(外付けUSB/FireWire/eSATAドライブ、ネットワーク共有フォルダ、ボリューム)。Windows上でマウントされていないボリュームを検出する

MSDNでRegisterDeviceNotification()機能が見つかりました。この機能は、USBドライブの接続/切断を検出するのに一般的です。この機能は、あらゆる種類のボリューム、または外部の物理デバイスでも機能できますか? もしそうでなければ、それを行うために私が何を使うことができるか(ポーリング以外)はありますか?

最後の質問、私はWindows上でC++に新しいです、とRegisterDeviceNotification() DOCは私の最初のパラメータは、私の場合はA handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter.

なければならないことを言って、私は私のプログラムのmain()機能で通知を登録したかっただろう、と通知を処理するための何らかの種類のonNotificationReceived()メソッドがあります。これを行うことができますか?そうであれば、どうしたらいいですか?別のプロセスで実行される別のウィンドウ/サービスを登録する必要がありますか?アンマウントドライブの一意のボリューム名を取得

答えて

3

WM_DEVICECHANGEは、ボリュームの到着と取り外しをアプリケーションに通知し、RegisterDeviceNotification()に電話する必要はありません。

dbch_devicetype == DBT_DEVTYP_VOLUMEを探します。

an example in the documentationがあります。

+0

これは私がやりたいように聞こえるので、これらのメッセージを受け取るには、自分のプログラムでコールバック関数を宣言するだけです。この関数の署名はどこで見つけることができますか?ありがとう! – nbarraille

+0

@nbarraille:すべてのトップレベルウィンドウに 'WM_DEVICECHANGE'メッセージを送るべきです。だからあなたのWndProcでそれらを扱うか、あなたの好きなフレームワークがウィンドウメッセージを処理するためにあなたに与えるすべての場所。 –

+1

私のプログラムは単なるコンソールプログラムであり、ウィンドウはありません。これらの通知を受け取るにはどうすれば登録できますか? – nbarraille

0

http://help.lockergnome.com/windows2/unique-volume-unmounted-drive--ftopict477553.html

FSCTL_IS_VOLUME_MOUNTEDは、指定されたボリュームがマウントされ、または指定したファイルまたはディレクトリがマウントされたボリューム上にある場合かどうかを決定します:http://msdn.microsoft.com/en-us/library/windows/desktop/aa364574(v=vs.85).aspx

どうかを検出しますそのドライブ文字にボリュームがマウントされています。

bool DiskInDrive(
    std::wstring const& inDrive) 
{ 
    std::wstring volume = std::wstring(L"\\\\.\\") + inDrive.substr(0, 2); 

    HANDLE h = CreateFileW(
    volume.c_str(), 
    GENERIC_READ, 
    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 
    NULL, 
    OPEN_EXISTING, 
    0, 
    NULL); 

    if(h == INVALID_HANDLE_VALUE) 
    { 
    DWORD lastError = GetLastError(); 
    // 2 means "no disk", anything else means by inference "disk 
    // in drive, but you do not have admin privs to do a 
    // CreateFile on that volume". 
    return lastError != 2; 
    } 

    DWORD bytesReturned; // ignored 
    BOOL devSuccess = DeviceIoControl(h, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &bytesReturned, NULL); 

    if(devSuccess == FALSE) 
    { 
    DWORD lastError = GetLastError(); 
    (void)lastError; // For debugging. 
    // Presumably, any error means "no disk in drive", or more 
    // accurately, "no volume mounted on that drive letter". 
    CloseHandle(h); 
    return false; 
    } 

    CloseHandle(h); 
    return true; 
} 
0

だけの提案がありますが、システムへの様々な変更の通知を受け取ることができますWindowsのシェル拡張を作成するに見たいと思うかもしれません。

たとえば、IShellChangeNotifyインターフェイスの実装には、SHCNE_DRIVEREMOVED, SHCNE_MEDIAREMOVED, SHCNE_NETUNSHAREなどの全範囲の通知を受信できるOnChangeメソッドが含まれています。

DLLを作成して登録する必要があります(つまり、スタンドアロンのexeファイルではありません)が、あなたが探している種類の通知が提供されると思います。

関連する問題