我有一个特定的应用程序,每次有新的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();
我的问题是位锁驱动器。警报会触发,但是我需要等到用户确实输入正确的密码。我主要关心的是如何处理这种等待。
有人可以帮助我微调wql查询,使其仅针对未加密的卷发出警报吗? 这个想法是,在用户引入了bitlocker密码之后,观察者(带有经过微调的查询)应立即触发。因此基本上,对于我的程序,位锁变得透明了。
答案 0 :(得分: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();
}