首先啊,我想着就在应用层去做呗,因为驱动层我确实也没接触过,于是乎我就去一股脑去百度看了看有没有前人的案例参考参考,搜了后发现有修改注册表,组策略,还有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的结构体,具体可以看微软的官方文档https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/fltkernel/ns-fltkernel-_flt_registration
我这里用的是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();
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课