2012-01-04 15 views
5

リムーバブルデバイスの挿入を検出し、NTサービスを使用してそのデバイスのドライブ文字を取得しようとしています。私はデバイスの挿入と取り外しを検出するのに成功しましたが、ドライブ文字、GUIDなどをボリュームから取得できるように、構造体をDEV_BROADCAST_VOLUMEに設定できませんでした。C++でWindowsサービスを使用してリムーバブルデバイスのデータを取得できない

case SERVICE_CONTROL_DEVICEEVENT:{ 
      switch(evtype){ 
      case DBT_DEVICEARRIVAL:{ 
        DEV_BROADCAST_VOLUME *hdr = (DEV_BROADCAST_VOLUME*) evdata; 
        ofstream log ("C:\\log.txt", ios::app); 
        log << hdr->dbcv_devicetype; 
        log.close(); 
       } 
       break; 

上記のコードはコンパイルされ、正常に動作が、私はフラッシュドライブを挿入すると、(USBドライブが何であるかである)55555DBT_DEVTYP_VOLUMEの値としてhdr->dbcv_devicetypeログは2hdr->dbcv_devicetypeが等しくなければならないように定義されます私はフラッシュドライブを挿入したのでDBT_DEVTYP_VOLUME)。なんらかの理由でDBT_DEVTYP_VOLUMEが正しく初期化されていないか、または私がやっている何かが間違っています。私はVisual Studio 2011 C + +でWindows 7を使用しています。

+3

から引き出さ? 「外部USBハードドライブ」と「内部USBハードドライブ」の違いは任意です。技術的には、 "ディスク"と "ボリューム"とドライブの定義は違います... LOCAL_SYSTEMはC:\がC:\ – Dan

+0

と見なす必要はありません理想的には、ドライブ文字のマッピングはユーザー単位で管理されるため、ユーザーのコンテキストで行う必要があります。もしあなたがそれを行うことができれば、エクスプローラは既に大変な作業をしているので、作業を大幅に簡素化できます。 SHChangeNotifyRegister()への簡単な呼び出しを使用して通知を取得できます。 – Luke

+0

@ルークそのアイデアはいいですが、まだマウントされていないドライブを検出しますか?たとえば、WindowsはLinuxファイルシステムをマウントしません。ユーザーにフォーマットを通知するだけです。 'SHChangeNotifyRegister()'は、 'E:\\'のようなドライブ文字にマウントされていなくても挿入を選ぶでしょうか? – user99545

答えて

1

これを試してみてください:

PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)evdata; 
    if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME) 
    { 
    PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb; 

    if (lpdbv -> dbcv_flags & DBTF_MEDIA) 
    { 
     StringCchPrintf(szMsg, sizeof(szMsg)/sizeof(szMsg[0]), 
         TEXT("Drive %c: Media has arrived.\n"), 
         FirstDriveFromMask(lpdbv ->dbcv_unitmask)); 

     MessageBox(hwnd, szMsg, TEXT("WM_DEVICECHANGE"), MB_OK); 
    } 
    } 

    /*------------------------------------------------------------------ 
     FirstDriveFromMask(unitmask) 

     Description 
     Finds the first valid drive letter from a mask of drive letters. 
     The mask must be in the format bit 0 = A, bit 1 = B, bit 2 = C, 
     and so on. A valid drive letter is defined when the 
     corresponding bit is set to 1. 

     Returns the first drive letter that was found. 
    --------------------------------------------------------------------*/ 

    char FirstDriveFromMask(ULONG unitmask) 
    { 
    char i; 

    for (i = 0; i < 26; ++i) 
     { 
     if (unitmask & 0x1) 
     break; 
     unitmask = unitmask >> 1; 
     } 

    return(i + 'A'); 
    } 

コードを使用すると、ドライブやドライバが嘘と考えたDetecting Media Insertion or Removal

+0

デバイスの取り外しを検出するコードがリンクに含まれています。 –

+0

サービスをクラッシュさせたいくつかのエラーが発生したため、コードを少し修正しなければなりませんでした。私は変更をここに掲載しました。(http://pastebin.com/3Fyb3b1p)問題は、ドライブを挿入するたびに、ドライブ文字が「A」(引用符なし)と表示されます。私も多くのデバイスを試しました。これがなぜ起きているのか分かりません。おそらく 'FirstDriveFromMask()'関数でしょうか?私はwin32コンソールアプリケーションでそのコードを使用しようとしましたが、完全に動作するように管理されているため、ここでは完全に混乱しています。これは、Windowsサービス固有のものでなければなりません。 – user99545

+0

彼らはメッセージを得るためにトップのウィンドウメッセージループを使いました。しかし、私は適応するのが難しいとは思わない。 ドライブ文字 'A'のみが表示される問題については、break文を削除して、設定されたビット数を確認してください。 お使いのコンピュータでドライブAビットが常に設定され、このアルゴリズムが最初のドライブ文字で停止する可能性があります。 –

関連する問題