我在尝试使用windows RegisterDeviceNotification函数为TrueCrypt驱动器注册通知时遇到问题。我的代码是一个windows服务,注册部分如下:
TCHAR volumePath[MAX_PATH];
_stprintf( volumePath, _T("\\.\%c:"), (*lpcDrive));
//Create File and add notification
HANDLE hDevice = CreateFile( volumePath,
GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL );
if (hDevice == INVALID_HANDLE_VALUE)
{
bResult=FALSE;
goto end;
}
DEV_BROADCAST_HANDLE filter = {0};
filter.dbch_size = sizeof(filter);
filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
filter.dbch_handle = hDevice;
filter.dbch_hdevnotify = RegisterDeviceNotification(m_hStatus, &filter, DEVICE_NOTIFY_SERVICE_HANDLE);
truecrypt驱动器的卷路径为:"\\.\m:"m_hStatus句柄是使用RegisterServiceCtrlHandlerEx注册控制处理程序时获得的句柄。并且它是一个有效的句柄。
文件句柄也是有效的,但是当调用RegisterDeviceNotification时,它返回NULL。现在我不知道为什么它没有正确注册,因为所有其他磁盘/设备都注册成功了。我一直在网上寻找解决方案,但什么也找不到。我不确定问题是否与设备类型有关,但我浏览了TrueCrypt的代码,似乎他们将安装的设备注册为DBT_DEVTYP_VOLUME。
所有必要的设备类型都在服务开始时使用以下代码进行注册:
HANDLE hDevNotify = new HDEVNOTIFY[sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID)];
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
for(int i=0; i<sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID); i++)
{
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
hDevNotify[i] = RegisterDeviceNotification(h,&NotificationFilter, DEVICE_NOTIFY_SERVICE_HANDLE);
}
GUID_DEVINTERFACE_LIST包含一组设备GUID,包括USB、磁盘/卷、HID和LAN。顺便说一句,它们都很好用。
问题是,从Window应用程序中,我可以通过WM_DEVICECHANGE获得通知。但由于我的应用程序是一项服务,我无法收到该消息。
因此,如果有人以前遇到过这个问题,或者有办法在windows服务中获得TrueCrypt设备通知,我会洗耳恭听。
最有可能的原因是truecrypt只向自己的会话发送通知,而您的服务在不同的会话中工作。在我们的虚拟存储产品中,我们实现了一个助手DLL,它由Explorer在每个用户会话中加载。它与挂载代码通信,并在加载的每个会话中进一步发送广播。很可能你需要做一些类似的事情。