لماذا تظهر رسالة WM_DEVICECHANGE واحدة فقط عند إزالة جهاز USB متعدد وحدات التخزين؟

StackOverflow https://stackoverflow.com/questions/1608915

  •  05-07-2019
  •  | 
  •  

سؤال

أنا أكتب تطبيقًا يكتشف متى يتم توصيل جهاز تخزين USB كبير السعة ومتى يتم فصله - من خلال الاستماع إلى رسائل WM_DEVICECHANGE.

لقد قمت أيضًا بتسجيل طلبي للاستماع إليه WM_DEVICECHANGE رسائل ل DBT_DEVTYP_DEVICEINTERFACE (باستخدام تسجيل جهاز الإخطار استدعاء API) وأحصل على كل من DBT_DEVICEARRIVAL و DBT_DEVICEREMOVECOMPLETE رسائل عند توصيل جهاز تخزين USB كبير السعة أو فصله.

الآن، المشكلة يحدث عندما يكون جهاز USB ذلك لديه مجلدات متعددة يتم توصيله، ومن ثم فصله.

أحصل على الرسائل التالية عند توصيل الجهاز:

  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL من النوع DBT_DEVTYP_DEVICEINTERFACE)
  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL من النوع DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL من النوع DBT_DEVTYP_VOLUME)

والرسائل التالية عند توصيله:

  • WM_DEVICECHANGE (DBT_DEVICEREMOVECOMPLETE من النوع DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE (DBT_DEVICEREMOVECOMPLETE من النوع DBT_DEVTYP_DEVICEINTERFACE)

لذا، رسالة إزالة واحدة فقط على الرغم من وجود مجلدين.لماذا؟؟

لدي سؤالان:

  • كيف يمكنني الارتباط DBT_DEVTYP_DEVICEINTERFACE رسائل مع DBT_DEVTYP_VOLUME الرسائل (بشكل أساسي، كيف أعرف أي منها مقدار رسالة يتوافق مع الذي واجهة الجهاز رسالة - منذ أن حصلت على كل منهما للجهاز)؟
  • هل هناك طريقة لجعل Windows يخطرني بكلتا عمليات إزالة وحدات التخزين؟
هل كانت مفيدة؟

المحلول

حسنًا ، لقد تمكنت من الإجابة على أحد أسئلتي الخاصة: هل هناك طريقة لجعل Windows يخطرني بكلتا عمليات إزالة وحدات التخزين؟

نعم - على الرغم من أن النوافذ ترسل واحدة فقط DBT_DEVTYP_VOLUME WM_DEVICECHANGE رسالة، يتم إخطارك بالفعل بكلتا عمليات إزالة المجلدات - ولكن، كما هو الحال دائما، الجواب يكمن في أعماق MSDN:

على الرغم من أن العضو dbcv_unitmask قد يحدد أكثر من وحدة تخزين واحدة في أي رسالة، إلا أن هذا لا يضمن إنشاء رسالة واحدة فقط لحدث محدد.قد تقوم مكونات النظام المتعددة بإنشاء رسائل بشكل مستقل لوحدات التخزين المنطقية في نفس الوقت.

لذلك، كل ما كان علي فعله هو تجاهل وظيفة المثال التي تقدمها مايكروسوفت في إحدى عيناتها،

char FirstDriveFromMask (ULONG unitmask)
{
   char i;

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

   return (i + 'A');
}

واستبدلها بوظيفة تفسر القناع عنها الجميع محركات الأقراص المتضررة.لذا فإن الرسالة الوحيدة التي كنت أتلقاها كانت بالفعل لكلا المجلدين، وكان كلا حرفي محرك الأقراص متاحًا في القناع.

// [IN] ULONG unitmask
// [IN/OUT] char* outDriveLetters  - an array of characters to be passed in
//                                   that is filled out with the drive letters
//                                   in the mask (this must be 26 bytes to be safe)
// RETURNS the number of drive letters in the mask
int MaskToDriveLetters (ULONG unitmask, char* outDriveLetters)
{
   int cnt = 0;
   for (i = 0; i < 26; ++i)
   {
      if (unitmask & 0x1)
      {
         outDriveLetters[cnt++] = 'A' + i;
         cnt++;
      }
      unitmask = unitmask >> 1;
   }

   outDriveLetters[cnt] = 0; // set the last character to \0 (optional)
   return cnt;  // the number of drives that were set in the mask
}

لا يزال لدي سؤال آخر يجب الإجابة عليه - كيف يمكن للرسالتين (DBT_DEVTYP_DEVICEINTERFACE و DBT_DEVTYP_VOLUME) تكون مرتبطة؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top