无法注册TrueCrypt设备事件

时间:2011-06-06 07:46:36

标签: visual-c++ windows-services truecrypt

我在尝试使用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设备通知。

1 个答案:

答案 0 :(得分:0)

最有可能的原因是,truecrypt仅将通知发送给它自己的会话,并且您的服务在不同的会话中工作。在我们的Virtual Storage产品中,我们实现了一个帮助器DLL,在每个用户会话中由Explorer加载。它与安装代码进行通信,并在每个加载的会话中进一步发送广播。很可能你需要做类似的事情。