В C / C ++, как программно обнаружить подключаемый модуль SATA SSD и отключить его в Windows?

Я пытаюсь написать программу на C / C ++ для обнаружения нового подключения SATA SSD (твердотельный накопитель) в Windows 7.

Этот SATA SSD также поставляется с кабелем SATA-USB. Я подключил конец SATA к SATA SDD, а конец USB — к моему компьютеру. Делая это, я смог обнаружить соединение и удаление SATA SDD с помощью системы сообщений Windows, чтобы обнаружить WM_DEVICECHANGE сообщение и связанный с нимDBT_DEVICEARRIVAL событие. Для этого я также использовал RegisterDeviceNotification зарегистрировать устройство (т.е. SATA SSD), чтобы окно верхнего уровня получало уведомления для типов устройств DBT_DEVTYP_DEVICEINTERFACE с одноклассником для SATA SSD.

Однако, когда я пытаюсь подключить SATA SDD к порту SATA на материнской плате моего компьютера, моя программа не работает.

В C / C ++ как определить, подключен ли SATA SSD и отключен ли в Windows?

2

Решение

В общем, подключение SSD-накопителя к порту SATA на включенном компьютере — плохая идея. Контроллер SATA должен иметь функцию горячего подключения для этого. Но вы можете отсканировать deviceclass и найти все устройства из этого класса, и он сможет вам обработать все интересные устройства. Я публикую пример кода, который может сделать это:

bool FindConnectedRemovableUsbstorDevices(std::list<std::wstring>& UsbList)
{
std::wstring ClassGuidString(L"{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}");
GUID ClassGuid;
BYTE buf[1024];
PSP_DEVICE_INTERFACE_DETAIL_DATA_W pspdidd = reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA_W>(buf);
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
DWORD size;
SP_DEVINFO_DATA dev_data;
DWORD properties;if(NOERROR != CLSIDFromString(ClassGuidString.c_str(), &ClassGuid))
return false;

HDEVINFO dev_info = INVALID_HANDLE_VALUE;
dev_info = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

if (dev_info == INVALID_HANDLE_VALUE)
return false;

DWORD index = 0;
BOOL ret = FALSE;

spdid.cbSize = sizeof(spdid);

while (true)
{
ret = SetupDiEnumDeviceInterfaces(dev_info, NULL, &ClassGuid, index, &spdid);
if (!ret)
break;

size = 0;
SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, NULL, 0, &size, NULL);
//Get required size

if (size == 0 || size >= sizeof(buf))
continue;
//prepare structs
ZeroMemory(reinterpret_cast<PVOID>(pspdidd), 1024);
pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!

ZeroMemory(reinterpret_cast<PVOID>(&spdd), sizeof(spdd));
spdd.cbSize = sizeof(spdd);

BOOL res = SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, pspdidd, size, &size, &spdd);
//Get info
if (!res)
continue;

HANDLE drive = CreateFileW(pspdidd->DevicePath, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);//open device
if (drive == INVALID_HANDLE_VALUE)
continue;

printf("\n%S\r\n", pspdidd->DevicePath);

DWORD bytes_returned = 0;
BOOL b = DeviceIoControl(drive, IOCTL_STORAGE_CHECK_VERIFY2, NULL, 0, NULL, 0, &bytes_returned, NULL);
if (!b) //check is card reader?
{
printf("IOCTL_STORAGE_CHECK_VERIFY2 error = %d\r\n", GetLastError());
goto stop_process_device;
}

bytes_returned = 0;
STORAGE_DEVICE_NUMBER sdn;
//Get Drive number
b = DeviceIoControl(drive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &bytes_returned, NULL);
if (!b)
goto stop_process_device;
RtlZeroMemory(&dev_data, sizeof(SP_DEVINFO_DATA));
dev_data.cbSize = sizeof(dev_data);
if (SetupDiEnumDeviceInfo(dev_info, sdn.DeviceNumber, &dev_data))
{
//check property
b = SetupDiGetDeviceRegistryProperty(dev_info, &dev_data, SPDRP_REMOVAL_POLICY, NULL,
reinterpret_cast<PBYTE>(&properties), sizeof(properties), NULL);
if (b && properties != CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL)
{
UsbList.push_back(pspdidd->DevicePath);
printf("REMOVAL\r\n");
}
}
stop_process_device:
CloseHandle(drive);
index++;
}
SetupDiDestroyDeviceInfoList(dev_info);
return true;
}
1

Другие решения


По вопросам рекламы [email protected]