Почему CDROM не полностью прочитал CDROM, когда моя программа работает? - PullRequest
0 голосов
/ 04 февраля 2020

Я пишу программу, которая должна читать файлы из cdrom и находит определенные c файлы. Я подписался на WM_DEVICECHANGE для устройства CdRom и получаю DBT_CUSTOMEVENT, DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE сообщения.

DWORD OpenDevNotify(SCANNING_DRIVE* pDesc, HANDLE hReceiver, bool isService)
{
    if (pDesc->hDevice == nullptr || pDesc->hDevice == INVALID_HANDLE_VALUE)
        return ERROR_INVALID_PARAMETER;
    DEV_BROADCAST_HANDLE NotificationFilter;
    RtlZeroMemory(&NotificationFilter, sizeof(DEV_BROADCAST_HANDLE));
    NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
    NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
    NotificationFilter.dbch_handle = pDesc->hDevice;
    DWORD Flag = isService ? DEVICE_NOTIFY_SERVICE_HANDLE : DEVICE_NOTIFY_WINDOW_HANDLE;
    pDesc->hDevNotify = RegisterDeviceNotification(hReceiver, &NotificationFilter, Flag);
    if (pDesc->hDevNotify == nullptr)
        return GetLastError();
    return 0;
}

DWORD OpenDeviceHandle(SCANNING_DRIVE* pDesc, const wchar_t* RootFolder)
{
    std::wstring RootFolderPattern(L"\\\\.\\");
    RootFolderPattern.append(RootFolder);
    pDesc->hDevice = CreateFile(RootFolderPattern.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        nullptr, OPEN_EXISTING, 0, nullptr);
    if (pDesc->hDevice == INVALID_HANDLE_VALUE)
        return GetLastError();
    return 0;
}

SCANNING_DRIVE RegisterForDeviceNotifications(const wchar_t* RootFolder, HANDLE hReceiver, bool isService)
{
    SCANNING_DRIVE dsc;
    RtlZeroMemory(&dsc, sizeof(SCANNING_DRIVE));

    DWORD res = OpenDeviceHandle(&dsc, RootFolder);
    if (res != 0)
        return dsc;

    res = OpenDevNotify(&dsc, hReceiver, isService);
    if (res != 0)
        return dsc;

    SetRootDir(&dsc, RootFolder);
    CreateStopEvent(&dsc);

    return dsc;
}

bool OnDeviceArrival(HANDLE hReceiver, WPARAM wParam, LPARAM lparam, BOOL isService)
{
    PDEV_BROADCAST_HDR pdbhdr = nullptr;
    PDEV_BROADCAST_HANDLE pdbh = nullptr;
    PDEV_BROADCAST_VOLUME pdbv = nullptr;
    size_t i = SIZE_MAX;

    switch (wParam)
    {
    case DBT_DEVICEARRIVAL:
        {
        pdbhdr = reinterpret_cast<PDEV_BROADCAST_HDR>(lparam);
        if (pdbhdr == nullptr || pdbhdr->dbch_devicetype != DBT_DEVTYP_VOLUME)
            break;
        pdbv = reinterpret_cast<PDEV_BROADCAST_VOLUME>(lparam);
        auto vol = VolumeLetterFromUnitMask(pdbv->dbcv_unitmask);
        i = GetDeviceIndexFromListByVolumeLetter(vol);
        if (i == SIZE_MAX || g_ConnectedDeviceVector.size() < i)
            break;
        if (g_ConnectedDeviceVector[i].hProcessingThread == INVALID_HANDLE_VALUE || g_ConnectedDeviceVector[i].hProcessingThread == nullptr)
        {
            g_ConnectedDeviceVector[i].hProcessingThread = CreateAndStartScanningThread(&g_ConnectedDeviceVector[i], ProcessDeviceThread);
            //auto a = ResumeThread(g_ConnectedDeviceVector[i].hProcessingThread);
            auto d = GetLastError();
        }
        break;
        }
    case DBT_CUSTOMEVENT:
        {
/*      pdbhdr = reinterpret_cast<PDEV_BROADCAST_HDR>(lparam);
        if (pdbhdr->dbch_devicetype != DBT_DEVTYP_HANDLE)
            break;
        pdbh = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lparam);
        i = GetDeviceIndexFromListByHandle(pdbh->dbch_handle);
        if (i == SIZE_MAX || g_ConnectedDeviceVector.size() < i)
            break;
        if (IsEqualGUID(pdbh->dbch_eventguid, GUID_IO_MEDIA_ARRIVALGUID_IO_MEDIA_ARRIVAL))
        {
            auto cmcc = reinterpret_cast<CLASS_MEDIA_CHANGE_CONTEXT*>(pdbh->dbch_data);
            if (cmcc->NewState == 1) // 1 - Media Present
                g_ConnectedDeviceVector[i].hProcessingThread = CreateScanningThread(&g_ConnectedDeviceVector[i], ProcessDeviceThread);
        }

        if (IsEqualGUID(pdbh->dbch_eventguid, GUID_IO_MEDIA_EJECT_REQUEST) ||
            IsEqualGUID(pdbh->dbch_eventguid, GUID_IO_MEDIA_REMOVAL))
        {
            StopScanningThread(&g_ConnectedDeviceVector[i]);
        }*/
        break;
        }
    case DBT_DEVICEREMOVECOMPLETE:
        {
        pdbhdr = reinterpret_cast<PDEV_BROADCAST_HDR>(lparam);
        if (pdbhdr->dbch_devicetype != DBT_DEVTYP_HANDLE)
            break;
        pdbh = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lparam);
        i = GetDeviceIndexFromListByHandle(pdbh->dbch_handle);
        if (i == SIZE_MAX || g_ConnectedDeviceVector.size() < i)
            break;
        //StopScanningThread(&g_ConnectedDeviceVector[i]);
        }
        break;

    default:
        break;
    }
    return true;
}

Но когда я запускаю свою программу и вставляю cdrom, я не вижу содержимого диска, я вижу что-то вот так Programm working и это неправильно, когда я прекращаю отладку, содержимое cdrom меняется на enter image description here И я не знаю, почему это происходит, когда я отлаживал свою программу, я заметил тот факт, что после того, как я вставил диск, я получил сообщение DBT_DEVICEREMOVECOMPLETE. Я думаю, что моя проблема в функции обработки сообщений или открытом дескрипторе, который не позволяет системе правильно читать содержимое диска. Спасибо за помощь.

...