在C/ c++中如何以编程方式检测Windows下SATA SSD的插拔
In C/C++ how to programmatically detect SATA SSD plug in and unplug in Windows?
我正在尝试写一个C/c++程序来检测Windows 7中新的SATA SSD(固态硬盘)连接。
这款SATA SSD还配有SATA- usb电缆。我已经将SATA端连接到SATA SDD, USB端连接到我的电脑。这样做,我已经能够通过使用windows消息系统检测WM_DEVICECHANGE
消息和相关的DBT_DEVICEARRIVAL
事件来检测SATA SDD连接和移除。为此,我还使用RegisterDeviceNotification
来注册设备(即SATA SSD),以便顶层窗口接收设备类型DBT_DEVTYP_DEVICEINTERFACE
的通知,并带有SATA SSD的classguid。
但是,当我尝试将SATA SDD连接到计算机主板上的SATA端口时,我的程序无法工作。
在C/c++中,我如何检测SATA SSD在Windows中插入和拔出?
一般来说,将SSD驱动器连接到已通电的计算机上的SATA端口是一个坏主意。SATA控制器必须具有热插拔功能才能做到这一点。但你可以扫描devicecclass并从这个类中找到所有设备它能处理所有有趣的设备。我的邮政编码示例可以这样做:
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%Srn", 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 = %drn", 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("REMOVALrn");
}
}
stop_process_device:
CloseHandle(drive);
index++;
}
SetupDiDestroyDeviceInfoList(dev_info);
return true;
}
相关文章:
- 编译的C可执行文件被Windows defender检测为病毒
- GetVersionEx Windows 10 被检测为 Windows 8
- 如何在 Windows API 中检测带有虚拟代码的非字母?
- C++ - 我需要一个宏或环境变量来检测我何时在 Windows 上运行 bazel
- 如何使用Visual Studio检测和获取Windows服务的代码覆盖率?
- 如何检测第一次Windows启动
- 如何使用选择正确检测我是在Windows还是Linux中构建C 代码
- 有没有办法在C++中检测或更改从 Windows 到 Linux 的 EOL 格式
- 视觉C++如何检测 Windows 更新正在运行
- 通用 Windows 平台上的内存泄漏检测
- Windows Gflags应用程序堆检测堆
- 如何检测Windows服务中的睡眠模式唤醒
- 应用程序如何检测缩放和监视Windows 10上的布局更改
- 如何在 Windows 10 上检测辅助监视器的本机屏幕分辨率或缩放因子
- c++Windows自动检测代理设置
- 如何在Windows C ++上检测滚轮向下
- Windows资源监视器使用哪些Win32函数来检测已终止进程的磁盘和网络活动
- 如何检测端口是否已在服务器端使用(在windows上的C++中)
- 如何检测我的Windows应用程序是否已经结束
- 无法在Windows中初始化Kinect(检测到0个传感器)