Проблемы с чтением дисков при подключении

Тема в разделе "WASM.WIN32", создана пользователем drem1lin, 7 фев 2020.

Метки:
  1. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Всем здравствуйте, я столкнулся с проблемой чтения содержимого диска вставленного в cd-rom. Я подписался на сообщения от cdrom через RegisterDeviceNotification и получаю сообщения DBT_CUSTOMEVENT, DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE.
    Код (Text):
    1. DWORD OpenDevNotify(SCANNING_DRIVE* pDesc, HANDLE hReceiver, bool isService)
    2. {
    3.     if (pDesc->hDevice == nullptr || pDesc->hDevice == INVALID_HANDLE_VALUE)
    4.         return ERROR_INVALID_PARAMETER;
    5.     DEV_BROADCAST_HANDLE NotificationFilter;
    6.     RtlZeroMemory(&NotificationFilter, sizeof(DEV_BROADCAST_HANDLE));
    7.     NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
    8.     NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
    9.     NotificationFilter.dbch_handle = pDesc->hDevice;
    10.     DWORD Flag = isService ? DEVICE_NOTIFY_SERVICE_HANDLE : DEVICE_NOTIFY_WINDOW_HANDLE;
    11.     pDesc->hDevNotify = RegisterDeviceNotification(hReceiver, &NotificationFilter, Flag);
    12.     if (pDesc->hDevNotify == nullptr)
    13.         return GetLastError();
    14.     return 0;
    15. }
    16.  
    17. DWORD OpenDeviceHandle(SCANNING_DRIVE* pDesc, const wchar_t* RootFolder)
    18. {
    19.     std::wstring RootFolderPattern(L"\\\\.\\");
    20.     RootFolderPattern.append(RootFolder);
    21.     pDesc->hDevice = CreateFile(RootFolderPattern.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
    22.         nullptr, OPEN_EXISTING, 0, nullptr);
    23.     if (pDesc->hDevice == INVALID_HANDLE_VALUE)
    24.         return GetLastError();
    25.     return 0;
    26. }
    27.  
    28. SCANNING_DRIVE RegisterForDeviceNotifications(const wchar_t* RootFolder, HANDLE hReceiver, bool isService)
    29. {
    30.     SCANNING_DRIVE dsc;
    31.     RtlZeroMemory(&dsc, sizeof(SCANNING_DRIVE));
    32.  
    33.     DWORD res = OpenDeviceHandle(&dsc, RootFolder);
    34.     if (res != 0)
    35.         return dsc;
    36.  
    37.     res = OpenDevNotify(&dsc, hReceiver, isService);
    38.     if (res != 0)
    39.         return dsc;
    40.  
    41.     SetRootDir(&dsc, RootFolder);
    42.     CreateStopEvent(&dsc);
    43.  
    44.     return dsc;
    45. }
    46.  
    47. bool OnDeviceArrival(HANDLE hReceiver, WPARAM wParam, LPARAM lparam, BOOL isService)
    48. {
    49.     PDEV_BROADCAST_HDR pdbhdr = nullptr;
    50.     PDEV_BROADCAST_HANDLE pdbh = nullptr;
    51.     PDEV_BROADCAST_VOLUME pdbv = nullptr;
    52.     size_t i = SIZE_MAX;
    53.  
    54.     switch (wParam)
    55.     {
    56.     case DBT_DEVICEARRIVAL:
    57.         {
    58.         pdbhdr = reinterpret_cast<PDEV_BROADCAST_HDR>(lparam);
    59.         if (pdbhdr == nullptr || pdbhdr->dbch_devicetype != DBT_DEVTYP_VOLUME)
    60.             break;
    61.         pdbv = reinterpret_cast<PDEV_BROADCAST_VOLUME>(lparam);
    62.         auto vol = VolumeLetterFromUnitMask(pdbv->dbcv_unitmask);
    63.         i = GetDeviceIndexFromListByVolumeLetter(vol);
    64.         if (i == SIZE_MAX || g_ConnectedDeviceVector.size() < i)
    65.             break;
    66.         if (g_ConnectedDeviceVector[i].hProcessingThread == INVALID_HANDLE_VALUE || g_ConnectedDeviceVector[i].hProcessingThread == nullptr)
    67.         {
    68.             g_ConnectedDeviceVector[i].hProcessingThread = CreateAndStartScanningThread(&g_ConnectedDeviceVector[i], ProcessDeviceThread);
    69.             //auto a = ResumeThread(g_ConnectedDeviceVector[i].hProcessingThread);
    70.             auto d = GetLastError();
    71.         }
    72.         break;
    73.         }
    74.     case DBT_CUSTOMEVENT:
    75.         {
    76. /*      pdbhdr = reinterpret_cast<PDEV_BROADCAST_HDR>(lparam);
    77.         if (pdbhdr->dbch_devicetype != DBT_DEVTYP_HANDLE)
    78.             break;
    79.         pdbh = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lparam);
    80.         i = GetDeviceIndexFromListByHandle(pdbh->dbch_handle);
    81.         if (i == SIZE_MAX || g_ConnectedDeviceVector.size() < i)
    82.             break;
    83.         if (IsEqualGUID(pdbh->dbch_eventguid, GUID_IO_MEDIA_ARRIVALGUID_IO_MEDIA_ARRIVAL))
    84.         {
    85.             auto cmcc = reinterpret_cast<CLASS_MEDIA_CHANGE_CONTEXT*>(pdbh->dbch_data);
    86.             if (cmcc->NewState == 1) // 1 - Media Present
    87.                 g_ConnectedDeviceVector[i].hProcessingThread = CreateScanningThread(&g_ConnectedDeviceVector[i], ProcessDeviceThread);
    88.         }
    89.  
    90.         if (IsEqualGUID(pdbh->dbch_eventguid, GUID_IO_MEDIA_EJECT_REQUEST) ||
    91.             IsEqualGUID(pdbh->dbch_eventguid, GUID_IO_MEDIA_REMOVAL))
    92.         {
    93.             StopScanningThread(&g_ConnectedDeviceVector[i]);
    94.         }*/
    95.         break;
    96.         }
    97.     case DBT_DEVICEREMOVECOMPLETE:
    98.         {
    99.         pdbhdr = reinterpret_cast<PDEV_BROADCAST_HDR>(lparam);
    100.         if (pdbhdr->dbch_devicetype != DBT_DEVTYP_HANDLE)
    101.             break;
    102.         pdbh = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lparam);
    103.         i = GetDeviceIndexFromListByHandle(pdbh->dbch_handle);
    104.         if (i == SIZE_MAX || g_ConnectedDeviceVector.size() < i)
    105.             break;
    106.         //StopScanningThread(&g_ConnectedDeviceVector[i]);
    107.         }
    108.         break;
    109.  
    110.     default:
    111.         break;
    112.     }
    113.     return true;
    114. }
    Когда моя программа работает, то подключенный диск выглядит вот так

    [​IMG]
    Но стоит только остановить отладчик и диск начинает отображаться вот так
    [​IMG]
    Т.е. моя программа как то мешает системе работать, но я совсем не могу понять как.
    Может кто сталкивался или кто-то поделится идеями, что можно капнуть?
     
  2. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.954
    Единственное что на ум приходит:
    То есть ты мешаешь не системе, а експлореру, слишком долго ждет своей очереди.
     
  3. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Проверил, время тут не причем. Убрав обработчик эффект тот же, но закрыв хэндл диска, используемого при регистрации все стало определяться нормально
     
  4. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.074
    попробуй другой дивидюк == можь твой малёхо коцанный иль с дравами у него трабла.