首先啊,我想着就在应用层去做呗,因为驱动层我确实也没接触过,于是乎我就去一股脑去百度看了看有没有前人的案例参考参考,搜了后发现有修改注册表,组策略,还有windows自带的api(setupapi.h),我寻思注册表和组策略肯定不如api来的灵活,老板要求最好是有类似于白名单,根据策略去选择是否禁用这个u盘或者说别的存储设备,后续要是还需要别的拓展也方便一些,我就踏上了试错路。
大概初步我的设计思路就是,我只要可以获取设备插入的信息,我就直接让该设备弹出,最多就是加个白名单去判断一下。因为是踩坑经历,我这里直接上部分代码了,因为多次修改多次测,备注搞忘掉了,有兴趣的可以把代码扔到ai里让它帮你分析一下就可以啦
特意封装成类了,因为需求稍微变动,因为我这个没有界面嘛,所以要和公司内网的网页端通信,这样老板就可以躺在老板椅上打开网页随意管控咯,采用的udp通信哈,这个通信代码我就不贴了,就是单纯的简单通信,想试试的同学可以类调用Initialize方法就可以,采用的是监视WM_DEVICECHANGE消息。
然后这个只解决了弹出u盘,坑的点就来了,如果是移动硬盘,我自己测试时候成功是能成功,但是要好久才能被弹出,部分电脑还弹不出,估计等弹出来机密文件都被带走咯,然后还有个问题就是,进程被结束了怎么搞,我做成服务,服务也可被结束,于是乎我就开始研究怎么样才能不被坏小子结束我的程序,后来我采用守护线程+dll注入的形式,把我的程序直接注入到explorer.exe资源管理器进程里,然后守护线程酷酷干。

由于之前没有接触过驱动这一块,主要老听别人说驱动很难很麻烦就没接触,现在光脚不怕穿鞋,冲就完了!!!
1.首先先搭个双机调试环境,我这虚拟机win7,win10都有,在虚拟机里记得把驱动签名禁用一下,然后就只需要vs弄一下驱动环境,这个就不多说了,百度都有
2.当有了驱动环境之后呢就创建这个 
3.虚拟机里要有个DebugView和驱动的加载工具,方便你调试嘛。ok这样准备工作就完成了
在入口注册了MiniFilter后,我们主要关注点是FLT_REGISTRATION的结构体,具体可以看微软的官方文档c97K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9k6h3q4J5L8W2)9J5k6h3#2A6j5%4u0G2M7$3!0X3N6q4)9J5k6h3y4G2L8g2)9J5c8Y4A6Z5i4K6u0V1j5$3&6Q4x3V1k6%4K9h3&6V1L8%4N6K6i4K6u0V1K9r3q4J5k6s2N6S2M7X3g2Q4x3V1k6V1M7X3W2$3k6i4u0K6i4K6u0r3k6r3c8A6i4K6u0r3k6X3I4@1K9$3g2J5L8X3g2D9i4K6u0r3L8Y4y4Q4x3X3c8X3L8s2c8C8k6i4u0F1k6h3I4Q4x3X3c8Q4y4h3k6X3L8s2c8Q4y4h3k6J5k6h3N6A6M7%4c8J5j5i4c8A6L8$3^5`.
我这里用的是InstanceSetupCallback的回调,因为我想拦截移动存储设备的插入,这个回调处理是比较好的,当卷挂载时会响应这个回调。
这里回调里的思路是,首先第一步先获取卷的属性,然后去查看设备路径是否包含HarddiskVolume或者CdRom,这两个是u盘移动硬盘或者光驱等会显示的路径名,当然本地磁盘也会有这个,所以根据DeviceIoRequest去二次确认是否为移动存储设备,如果你需要根据u盘的序列号去做筛查也可以放在这个回调里去做,不过你需要提前通信得到被允许的序列号,此时就可以判断出这个挂载的移动存储设备是不是需要禁用的,你就可以进行选择附加,再去做后续的禁用读写操作,我这里是直接拒绝挂载的操作,直接删除目标卷的盘符符号,IoDeleteSymbolicLink这个函数就可以做到哈
我这里用的是ObRegisterCallbacks是个笨办法,因为我需要通信,就让应用层顺便把自身pid传上来了
剩下的就比较简单啦,就是纯体力活,就是通信既要和驱动层通信,还要和网页后端通信,调试测试也是比较麻烦,但是这个方法比刚开始的写的强很多!我这里就把最后的驱动代码作为附件上传吧,代码没有封装,写的比较乱哈,有兴趣的可以研究研究哈!
class DeviceEjector {
public:
DeviceEjector() : stopEjectThread(false), ejectThreadRunning(false), scanDurationMinutes(10) {}
void Shutdown() {
Log(L"DeviceEjector is shutting down.");
StopEjectThread(); // 停止 ejection 线程
if (hwnd) {
UnregisterDeviceNotification(hDevNotify); // 注销设备通知
DestroyWindow(hwnd); // 销毁窗口
hwnd = NULL; // 重置窗口句柄
}
// 确保在这里重置 hwnd
hwnd = NULL;
PostMessage(hwnd, WM_QUIT, 0, 0); // 退出消息循环
}
void Initialize() {
// 如果已经初始化,则返回
if (hwnd != NULL) {
Log(L"DeviceEjector is already initialized. Ignoring the request.");
return;
}
RegisterWindowClass();
CreateNotificationWindow();
RegisterDeviceNotifications();
EnumerateExistingDevices();
MessageLoop();
}
private:
std::atomic<bool> stopEjectThread;
std::atomic<bool> ejectThreadRunning;
std::mutex ejectMutex;
std::thread ejectThread;
HWND hwnd;
HDEVNOTIFY hDevNotify;
const int scanDurationMinutes;
void StartEjectThread() {
if (!ejectThreadRunning.exchange(true)) {
Log(L"Starting eject thread.");
stopEjectThread = false;
ejectThread = std::thread(&DeviceEjector::EjectRemovableDisksLoop, this);
ejectThread.detach();
}
}
void StopEjectThread() {
if (ejectThreadRunning.exchange(false)) {
Log(L"Stopping eject thread.");
stopEjectThread = true;
if (ejectThread.joinable()) {
ejectThread.join(); // 等待线程结束
}
}
}
void EnumerateExistingDevices() {
Log(L"Enumerating existing devices.");
HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
DWORD error = GetLastError();
if (hDevInfo == INVALID_HANDLE_VALUE) {
LogError(L"Failed to get device information set for disks.",error);
return;
}
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (int i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++) {
Log(L"Processing device interface " + std::to_wstring(i));
DWORD requiredSize = 0;
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &requiredSize, NULL)) {
DWORD error = GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER) {
LogError(L"Failed to get required buffer size for device interface detail.", error);
continue;
}
}
std::unique_ptr<BYTE[]> buffer(new BYTE[requiredSize]);
PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer.get();
pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, pDeviceInterfaceDetailData, requiredSize, NULL, NULL)) {
LogError(L"Failed to get device interface detail.", GetLastError());
continue;
}
std::wstring devicePath = pDeviceInterfaceDetailData->DevicePath;
WCHAR deviceInstanceId[MAX_DEVICE_ID_LEN];
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData)) {
LogError(L"Failed to enumerate device info.", GetLastError());
continue;
}
if (!SetupDiGetDeviceInstanceId(hDevInfo, &devInfoData, deviceInstanceId, MAX_DEVICE_ID_LEN, NULL)) {
LogError(L"Failed to get device instance ID.", GetLastError());
continue;
}
Log(L"Attempting to safely eject device with instance ID: " + std::wstring(deviceInstanceId));
SafeEjectDevice(deviceInstanceId, devicePath);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
void RegisterWindowClass() {
Log(L"Registering window class.");
WNDCLASS wc = { 0 };
wc.lpfnWndProc = [](HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT {
static DeviceEjector* pEjector = nullptr;
if (uMsg == WM_CREATE) {
pEjector = reinterpret_cast<DeviceEjector*>(((LPCREATESTRUCT)lParam)->lpCreateParams);
}
else if (uMsg == WM_DEVICECHANGE) {
if (pEjector) {
pEjector->HandleDeviceChange(wParam, lParam);
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
};
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = L"USBDetectorClass";
RegisterClass(&wc);
}
void CreateNotificationWindow() {
Log(L"Creating notification window.");
hwnd = CreateWindow(L"USBDetectorClass", L"USB Detector", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), this);
}
void RegisterDeviceNotifications() {
Log(L"Registering device notification.");
GUID InterfaceClassGuid = GUID_DEVINTERFACE_DISK;
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = { 0 };
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = InterfaceClassGuid;
hDevNotify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
}
void MessageLoop() {
Log(L"Entering message loop.");
MSG msg;
while (true) {
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT) {
return;
}
}
// To ensure the message loop remains responsive, add a small sleep.
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void HandleDeviceChange(WPARAM wParam, LPARAM lParam) {
if (wParam == DBT_DEVICEARRIVAL) {
DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lParam;
if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
Log(L"Device arrival detected.");
std::this_thread::sleep_for(std::chrono::seconds(1)); // Add a delay to allow the device to stabilize
if (!ejectThreadRunning.load()) {
StartEjectThread();
}
else {
Log(L"Eject thread is already running. Ignoring new device arrival until current scan completes.");
}
}
}
else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lParam;
if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
Log(L"Device removal detected.");
StopEjectThread();
}
}
}
void EjectRemovableDisksLoop() {
Log(L"Eject removable disks loop started.");
auto startTime = std::chrono::steady_clock::now();
while (!stopEjectThread.load()) {
Log(L"Scanning for removable disks to eject.");
HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
DWORD error = GetLastError();
if (hDevInfo == INVALID_HANDLE_VALUE) {
LogError(L"Failed to get device information set for disks.", error);
std::this_thread::sleep_for(std::chrono::seconds(5));
continue;
}
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (int i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++) {
Log(L"Processing device interface " + std::to_wstring(i));
DWORD requiredSize = 0;
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &requiredSize, NULL)) {
DWORD error = GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER) {
LogError(L"Failed to get required buffer size for device interface detail.", error);
continue;
}
}
std::unique_ptr<BYTE[]> buffer(new BYTE[requiredSize]);
PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer.get();
pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, pDeviceInterfaceDetailData, requiredSize, NULL, NULL)) {
LogError(L"Failed to get device interface detail.", GetLastError());
continue;
}
std::wstring devicePath = pDeviceInterfaceDetailData->DevicePath;
WCHAR deviceInstanceId[MAX_DEVICE_ID_LEN];
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData)) {
LogError(L"Failed to enumerate device info.", GetLastError());
continue;
}
if (!SetupDiGetDeviceInstanceId(hDevInfo, &devInfoData, deviceInstanceId, MAX_DEVICE_ID_LEN, NULL)) {
LogError(L"Failed to get device instance ID.", GetLastError());
continue;
}
Log(L"Attempting to safely eject device with instance ID: " + std::wstring(deviceInstanceId));
SafeEjectDevice(deviceInstanceId, devicePath);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
std::this_thread::sleep_for(std::chrono::seconds(5));
// Check if the scanning duration has exceeded the specified time limit
auto currentTime = std::chrono::steady_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::minutes>(currentTime - startTime);
if (elapsedTime.count() >= scanDurationMinutes) {
Log(L"Scan duration exceeded 10 minutes, ending eject loop.");
break;
}
}
ejectThreadRunning = false;
Log(L"Eject removable disks loop ended.");
}
void SafeEjectDevice(const std::wstring& deviceInstanceId, const std::wstring& devicePath) {
std::lock_guard<std::mutex> lock(ejectMutex);
Log(L"Ejecting device: " + deviceInstanceId);
DEVINST devInst;
CONFIGRET cr = CM_Locate_DevNode(&devInst, (DEVINSTID_W)deviceInstanceId.c_str(), CM_LOCATE_DEVNODE_NORMAL);
if (cr == CR_SUCCESS) {
cr = CM_Request_Device_Eject(devInst, NULL, NULL, 0, 0);
if (cr == CR_SUCCESS) {
Log(L"Device ejected successfully using CM_Request_Device_Eject.");
}
else {
LogError(L"Failed to eject device using CM_Request_Device_Eject.", cr);
AttemptParentEject(devInst);
}
}
else {
LogError(L"Failed to locate device node.", cr);
}
HANDLE hDevice = CreateFile(devicePath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE) {
LogError(L"Failed to open device.", GetLastError());
}
else {
DWORD bytesReturned;
if (DeviceIoControl(hDevice, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &bytesReturned, NULL)) {
Log(L"Device ejected successfully using IOCTL_STORAGE_EJECT_MEDIA.");
}
else {
LogError(L"Failed to eject device using IOCTL_STORAGE_EJECT_MEDIA.", GetLastError());
}
CloseHandle(hDevice);
}
}
void AttemptParentEject(DEVINST devInst) {
Log(L"Attempting to eject parent device.");
DEVINST parentDevInst;
CONFIGRET cr = CM_Get_Parent(&parentDevInst, devInst, 0);
if (cr == CR_SUCCESS) {
cr = CM_Request_Device_Eject(parentDevInst, NULL, NULL, 0, 0);
if (cr == CR_SUCCESS) {
Log(L"Parent device ejected successfully.");
}
else {
LogError(L"Failed to eject parent device.", cr);
}
}
else {
LogError(L"Failed to locate parent device node.", cr);
}
}
void LogToFile(const std::wstring& message, WORD type) {
// 修改路径为 C:\ProgramData\UsbEjectService.log
std::wstring logPath = L"C:\\ProgramData\\UsbEjectService111.log";
// 确保目录存在
CreateDirectoryW(L"C:\\ProgramData", NULL);
// 打开日志文件并追加写入
std::wofstream logFile(logPath, std::ios::app);
if (!logFile.is_open()) {
std::wcerr << L"Failed to open log file: " << logPath << L", Error code: " << GetLastError() << std::endl;
return;
}
auto now = std::chrono::system_clock::now();
auto now_c = std::chrono::system_clock::to_time_t(now);
logFile << L"[" << (type == EVENTLOG_INFORMATION_TYPE ? L"INFO" : L"ERROR") << L"] ["
<< std::put_time(std::localtime(&now_c), L"%Y-%m-%d %H:%M:%S") << L"]: " << message << std::endl;
logFile.close();
}
void Log(const std::wstring& message) {
LogToFile(message, EVENTLOG_INFORMATION_TYPE);
}
void LogError(const std::wstring& message, DWORD errorCode) {
std::wstring fullMessage = message;
if (errorCode != 0) {
fullMessage += L" Error code: " + std::to_wstring(errorCode);
}
LogToFile(fullMessage, EVENTLOG_ERROR_TYPE);
}
};
class DeviceEjector {
public:
DeviceEjector() : stopEjectThread(false), ejectThreadRunning(false), scanDurationMinutes(10) {}
void Shutdown() {
Log(L"DeviceEjector is shutting down.");
StopEjectThread(); // 停止 ejection 线程
if (hwnd) {
UnregisterDeviceNotification(hDevNotify); // 注销设备通知
DestroyWindow(hwnd); // 销毁窗口
hwnd = NULL; // 重置窗口句柄
}
// 确保在这里重置 hwnd
hwnd = NULL;
PostMessage(hwnd, WM_QUIT, 0, 0); // 退出消息循环
}
void Initialize() {
// 如果已经初始化,则返回
if (hwnd != NULL) {
Log(L"DeviceEjector is already initialized. Ignoring the request.");
return;
}
RegisterWindowClass();
CreateNotificationWindow();
RegisterDeviceNotifications();
EnumerateExistingDevices();
MessageLoop();
}
private:
std::atomic<bool> stopEjectThread;
std::atomic<bool> ejectThreadRunning;
std::mutex ejectMutex;
std::thread ejectThread;
HWND hwnd;
HDEVNOTIFY hDevNotify;
const int scanDurationMinutes;
void StartEjectThread() {
if (!ejectThreadRunning.exchange(true)) {
Log(L"Starting eject thread.");
stopEjectThread = false;
ejectThread = std::thread(&DeviceEjector::EjectRemovableDisksLoop, this);
ejectThread.detach();
}
}
void StopEjectThread() {
if (ejectThreadRunning.exchange(false)) {
Log(L"Stopping eject thread.");
stopEjectThread = true;
if (ejectThread.joinable()) {
ejectThread.join(); // 等待线程结束
}
}
}
void EnumerateExistingDevices() {
Log(L"Enumerating existing devices.");
HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
DWORD error = GetLastError();
if (hDevInfo == INVALID_HANDLE_VALUE) {
LogError(L"Failed to get device information set for disks.",error);
return;
}
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (int i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++) {
Log(L"Processing device interface " + std::to_wstring(i));
DWORD requiredSize = 0;
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &requiredSize, NULL)) {
DWORD error = GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER) {
LogError(L"Failed to get required buffer size for device interface detail.", error);
continue;
}
}
std::unique_ptr<BYTE[]> buffer(new BYTE[requiredSize]);
PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer.get();
pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, pDeviceInterfaceDetailData, requiredSize, NULL, NULL)) {
LogError(L"Failed to get device interface detail.", GetLastError());
continue;
}
std::wstring devicePath = pDeviceInterfaceDetailData->DevicePath;
WCHAR deviceInstanceId[MAX_DEVICE_ID_LEN];
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData)) {
LogError(L"Failed to enumerate device info.", GetLastError());
continue;
}
if (!SetupDiGetDeviceInstanceId(hDevInfo, &devInfoData, deviceInstanceId, MAX_DEVICE_ID_LEN, NULL)) {
LogError(L"Failed to get device instance ID.", GetLastError());
continue;
}
Log(L"Attempting to safely eject device with instance ID: " + std::wstring(deviceInstanceId));
SafeEjectDevice(deviceInstanceId, devicePath);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
void RegisterWindowClass() {
Log(L"Registering window class.");
WNDCLASS wc = { 0 };
wc.lpfnWndProc = [](HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT {
static DeviceEjector* pEjector = nullptr;
if (uMsg == WM_CREATE) {
pEjector = reinterpret_cast<DeviceEjector*>(((LPCREATESTRUCT)lParam)->lpCreateParams);
}
else if (uMsg == WM_DEVICECHANGE) {
if (pEjector) {
pEjector->HandleDeviceChange(wParam, lParam);
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
};
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = L"USBDetectorClass";
RegisterClass(&wc);
}
void CreateNotificationWindow() {
Log(L"Creating notification window.");
hwnd = CreateWindow(L"USBDetectorClass", L"USB Detector", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), this);
}
void RegisterDeviceNotifications() {
Log(L"Registering device notification.");
GUID InterfaceClassGuid = GUID_DEVINTERFACE_DISK;
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = { 0 };
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = InterfaceClassGuid;
hDevNotify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
}
void MessageLoop() {
Log(L"Entering message loop.");
MSG msg;
while (true) {
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT) {
return;
}
}
// To ensure the message loop remains responsive, add a small sleep.
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void HandleDeviceChange(WPARAM wParam, LPARAM lParam) {
if (wParam == DBT_DEVICEARRIVAL) {
DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lParam;
if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
Log(L"Device arrival detected.");
std::this_thread::sleep_for(std::chrono::seconds(1)); // Add a delay to allow the device to stabilize
if (!ejectThreadRunning.load()) {
StartEjectThread();
}
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!