Я пишу программу, которая должна читать файлы из 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, я не вижу содержимого диска, я вижу что-то вот так и это неправильно, когда я прекращаю отладку, содержимое cdrom меняется на И я не знаю, почему это происходит, когда я отлаживал свою программу, я заметил тот факт, что после того, как я вставил диск, я получил сообщение DBT_DEVICEREMOVECOMPLETE. Я думаю, что моя проблема в функции обработки сообщений или открытом дескрипторе, который не позволяет системе правильно читать содержимое диска. Спасибо за помощь.