0

我有一个特定的应用程序必须在每次将新的 USB 卷连接到系统或从系统断开连接时做出反应(在设备上搜索特定文件)。

对于普通的未加密设备,我只为新 USB 创建了一个观察程序,使用

  ManagementEventWatcher watcher = new ManagementEventWatcher();
  WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2 or EventType = 3");
  watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
  watcher.Query = query;
  watcher.Start();

我的问题是 bitlocker 驱动器。警报触发,但我需要等到用户确实输入了正确的密码。如何处理这种等待是我主要关心的问题。

有人可以帮我微调 wql 查询,以便它只对未加密的卷发出警报吗?这个想法是,在用户输入 bitlocker 密码之后,观察者(带有微调查询)应该触发。所以基本上对于我的程序,bitlocker 变得透明。

4

2 回答 2

0

在寻找解决方案几个小时后,我发现了一个远非理想的工作解决方案。

首先,我找到了 Win32_EncryptableVolume 类 https://docs.microsoft.com/en-us/windows/win32/secprov/win32-encryptablevolume ,我使用了非常有用的工具 WMI Code Creator 来识别属性并获取一些工作示例 C# 代码 https ://www.microsoft.com/en-us/download/details.aspx?id=8572

据我所知,没有与该 EncryptableVolume 类相关的事件类。所以我首先从前面的 Win32_VolumeChangeEvent 中获取驱动器号,然后运行第二个 WMI 查询(使用 Win32_EncryptableVolume)和该驱动器号来检查属性 ProtectionStatus 的值。从测试中我发现,在用户输入有效密码之前,该值为 2。一旦解锁,该值变为 1。所以基本上我启动了一个线程并等待操作系统更改此属性。

对于等待部分,这是我最不喜欢的部分,我让线程在一个活动循环中运行,而不是能够在某个特定事件到达时“消耗”它。

此解决方案的另一个副作用是,要访问 root\cimv2\Security\MicrosoftVolumeEncryption,您需要管理员权限,因此从现在开始,我将开发使用管理员权限 (runas) 执行的 Visual Studio。:/

ManagementObjectSearcher searcher2 = new ManagementObjectSearcher("root\\cimv2\\Security\\MicrosoftVolumeEncryption", "SELECT * FROM Win32_EncryptableVolume WHERE driveletter ='" + s_drive_letter + "'");
try
{
   ManagementObjectCollection queryCollection = searcher2.Get();
   ManagementObject mo = queryCollection.OfType<ManagementObject>().FirstOrDefault();

   if (mo["ProtectionStatus"].ToString() == "2")
   {
       new Thread(() =>
       {
           while (mo["ProtectionStatus"].ToString() == "2")
           {
               Thread.Sleep(2000);
               queryCollection = searcher2.Get();
               mo = queryCollection.OfType<ManagementObject>().FirstOrDefault();
               if (mo == null)
                  Thread.CurrentThread.Abort();  
           }
           // Here the code we want to execute once the device gets unlocked.
       }).Start();
   }
于 2020-03-13T15:59:30.943 回答
0

我知道这对你来说已经很晚了,但也许将来可以帮助某人,我有同样的问题(或多或少)我想知道设备何时被 Bitlocker 解锁,放置一个 FileSystemWatcher,我有一个想法因为不使用 continuos do while。插入设备后,使用 `WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");

        insertWatcher = new ManagementEventWatcher(insertQuery);
        insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent);
        insertWatcher.Start();`

但是不容易知道设备何时解锁,但我看到当你解锁设备时,触发所有关于 CIM_DataFile 和 CIM_Directory 的事件 WMI,然后你可以像这样使用:` WqlEventQuery waitForBitlockerQuery = new WqlEventQuery("SELECT * From __InstanceCreationEvent WITHIN 5 where TargetInstance ISA "CIM_Directory" And TargetInstance.Drive="" + driveUnit.Name.Replace("\", "") + "" And TargetInstance.Path = ''"); //Creamos un eventto que cuando el dispotivo pueda, disparara el eventto con el direcotrio raiz, y por tanto indicando que el file system ya tiene acceso al dispositivo (isReady = true)

        ManagementEventWatcher copyWatcher = new ManagementEventWatcher(waitForBitlockerQuery);
        copyWatcher.EventArrived += new EventArrivedEventHandler(DeviceStatusChanged);
        copyWatcher.Start();`

并使用功能 DeviceStatusChanged 在设备解锁后进行任何您想要的操作

于 2022-02-11T11:11:14.567 回答