vb 脚本修改 USBSTOR 密钥后 USB_MASS_STORAGE 驱动程序崩溃
这个剧本是我自己写的。 基本上我想要的是仅针对特定设备“解锁”前置 USB 的脚本。 情况是这样的,我们有一个工作站,其注册表项 USBSTOR\Start 设置为 4(禁用),因此如果我们的 IT 部门没有进行一些额外的工作,则前端 USB 不可用 - 这样我们就可以控制谁可以访问 USB
但员工必须使用相机拍摄特定需求的照片并通过电子邮件客户端发送它们。因此我们希望自动化“锁定/解锁”阶段。
当感兴趣的设备插入时,USB 被解锁,当设备位于 USB 中时,USB 保持“解锁”状态,并且在设备拔出后,脚本再次“锁定”USB。
我决定使用 .vbs。该脚本按我的预期工作,但是在“锁定”阶段之后,USB_MASS_STORAGE 驱动程序崩溃了。我必须卸载它并重新启动 Windows,以便驱动程序再次重新加载并正常工作。之后我已经运行了几次脚本,USBSTOR\Start 中的注册表值不会影响 USB,即即使有 4 个 USB,USB 也会被解锁。如果我将值从 4 更改为 3,驱动程序就会崩溃。
我正在寻找一些建议。
这是 usbstor.vbs 脚本的代码。我使用了很多评论,其中一些解释了非常明显的事情,但我决定这样做。
' Script for access to Front Usb (a.k.a USB MASS STORAGE)
' The usb is locked by default(the value in Registry Key USBSTOR/Start is 4 - disable).It is enabled(the value in Registry Key USBSTOR/Start is 3 - enable) when the device of interest is put into front usb.
' The usb is in "enable" state ,while the device is into it. After it is removed,the Registry Key USBSTOR/Start value is set to 4(disable).
' The device is recognized by hardware id ,which is known in advance by searching USBSTOR,when the device is inserted. This script is for pc,where what we want is access to front usb only for spcecific device(a camera in our case).
' For everything else the usb should be disabled.The script is loaded in RAM and if the while loop condition isn't change to false,we must kill the process within TaskManager
' The CPU time is high > 98 while the script runs.I came to this solution for my problem,but any ideas for improvements or for different logic are highly welcomed.
Option Explicit On
Dim Shell,Start,Hwid,Enum_0,Enum_1,Count,Flag_0,Flag_1,Check_0,Check_1 'Dimension of varables we are going to use in the script.
Set Shell = CreateObject("WScript.Shell") 'Create an object to work with Windows Registry.
'Start = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start") 'Save the value of the registry key into Start variable
Hwid = "USB\Vid_0930&Pid_6545\001D92A866B8B8B1934703FE" 'hardawre id of device of interest.We get it from the registry and the script scan for this id.It is constant string
Count = 1 'Initialize the Count variable with value of 1.We use it as a condition in endless while() loop.It makes script run in real-time,so it can scan uninterupted for changes in the registry
QueryEnum0 ' The subroutines QueryEnum0 and QueryEnum1.The id is either in USBSTOR\Enum\0 or in USBSTOR\Enum\1 .That is for sure.
QueryEnum1 ' Declaration before definition - not exactly explanation.
'The purpose of these two subroutines is: create an object everytime the sub is called ,thus read the value in Enum\0 or in Enum\1 constantly as "scanning"
'Probably not so elegant solution to somebody,but actually it works.
Sub QueryEnum0 ' Enter the sub
Dim Flag_Enum_0,Shell ' Declare local variables.They will be created each time the sub is invoked.
Set Shell = CreateObject("WScript.Shell") 'Create an object to work wirh registry any time the sub is called
On Error Resume Next 'Error handling
Flag_Enum_0 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\0") 'Try to read reg value into Flag_Enum_0. The purpose
On Error GoTo 0
Flag_0 = Flag_Enum_0 'Assign the value to variable Flag_0,outside of sub.The memory for Flag_0 is set once and lasts while the script runs.
End Sub
' Same as QueryEnum0
Sub QueryEnum1
Dim Flag_Enum_1,Shell
Set Shell = CreateObject("WScript.Shell")
On Error Resume Next
Flag_Enum_1 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\1")
On Error GoTo 0
Flag_1 = Flag_Enum_1
End Sub
Do While Count = 1 'Real-time loop,the code within while is running while count is equal to 1. The script is loaded in memory constanlty.
On Error Resume Next
Enum_0 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\0") ' Try to read hardware id if it is in Enum\0
On Error GoTo 0 '
On Error Resume Next
Enum_1 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\1") 'Try to read hardware id if it is in Enum\1
On Error GoTo 0
If StrComp(Hwid,Enum_0) <> 0 And StrComp(Hwid,Enum_1) <> 0 Then 'Check if both reg keys are empty
MsgBox "There is no device in the front usb.Please put the device or see the connection"
ElseIf StrComp(Hwid,Enum_0) = 0 Then 'If the hardware id is in Enum\0,thus assigned to Enum_0
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",3 'Enable the usb by "unlock" it
On Error Resume Next
QueryEnum0 'Invoke sub QueryEnum0.If the id we looking for is in Enum\0,we know that it is assigned to Flag_0 also
Check_0 = Flag_0 'Use another variable to copy value from Flag_0.
On Error GoTo 0
If StrComp(Hwid,Check_0) = 0 Then 'Compare the constant Hwid with the value in Check_0,test for id
Msgbox "Check_0 still holds the hardware id" 'Some messages to inform us whats happening
else
MsgBox "Check_0 does not contain the hardware id anymore"
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",4 'Disable the front usb
Count = 2 'End the while loop,count is 2,so the condition is false .The loop breaks.
End If
ElseIf StrComp(Hwid,Enum_1) = 0 Then 'If the hardware is in Enum\1....same as above mentioned
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",3
On Error Resume Next
QueryEnum1
Check_1 = Flag_1
On Error GoTo 0
If StrComp(Hwid,Check_1) = 0 Then
MsgBox "Check_1 still holds the hardware id"
MsgBox Check_1
else
MsgBox "Check_0 does not contain the hardware id anymore"
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",4
Count = 2
End If
End If
Loop
' Useful information for me
'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR -> value name -> Start ,value data = 3(enable) = 4(disable)
'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum -> value name -> 1 or 0 ,value data we look for is -> USB\Vid_04da&Pid_2372\5&2f621ee5&0&8
' USB\Vid_04da&Pid_2372\5&2f621ee5&0&8 - camera id in our case
' fantom value - USB\Vid_03f0&Pid_032a\000000000Q912WFBSI1c - name: 0 ,type: REG_SZ,in the key Enum.This is another hardware id,which is strange somehow,because I do not have any device
' inserted in my usb.However,I take this value into account,thus use both keys 0 and 1 within Enum to scan for the id I need.
I have this script written by myself.
Basically what I wanted was script that "unlock" the front usb only for specific device.
The situation is such that we have a workstation with registry key USBSTOR\Start set to 4(disable) so the front usb is not available without some additional work of our IT department - this way we control who can access the usb
But the employees must use a camera to take pictures for specific needs and to send them through email clients.So we want to automate the "lock/unlock" phase.
The usb is unlocked when the device of interest is inserted,it stays "unlocked" while the device is in usb and after the device is plugged out,the script "lock" the usb again.
I have decided to use .vbs.The script works as I expected,but after the "lock" phase,the USB_MASS_STORAGE driver get crashed.I must uninstall it and restart the Windows for the driver to be reloaded again and to work properly.After I have run the script several times,the registry value in USBSTOR\Start does not affect the usb,i.e the usb is unlocked even if there is 4.If I change the value from 4 to 3 the driver crashes.
I am looking for some advices.
Here is the code for usbstor.vbs script. I have used a lot of comments,some of them explain a pretty obvious things,but I have decide so.
' Script for access to Front Usb (a.k.a USB MASS STORAGE)
' The usb is locked by default(the value in Registry Key USBSTOR/Start is 4 - disable).It is enabled(the value in Registry Key USBSTOR/Start is 3 - enable) when the device of interest is put into front usb.
' The usb is in "enable" state ,while the device is into it. After it is removed,the Registry Key USBSTOR/Start value is set to 4(disable).
' The device is recognized by hardware id ,which is known in advance by searching USBSTOR,when the device is inserted. This script is for pc,where what we want is access to front usb only for spcecific device(a camera in our case).
' For everything else the usb should be disabled.The script is loaded in RAM and if the while loop condition isn't change to false,we must kill the process within TaskManager
' The CPU time is high > 98 while the script runs.I came to this solution for my problem,but any ideas for improvements or for different logic are highly welcomed.
Option Explicit On
Dim Shell,Start,Hwid,Enum_0,Enum_1,Count,Flag_0,Flag_1,Check_0,Check_1 'Dimension of varables we are going to use in the script.
Set Shell = CreateObject("WScript.Shell") 'Create an object to work with Windows Registry.
'Start = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start") 'Save the value of the registry key into Start variable
Hwid = "USB\Vid_0930&Pid_6545\001D92A866B8B8B1934703FE" 'hardawre id of device of interest.We get it from the registry and the script scan for this id.It is constant string
Count = 1 'Initialize the Count variable with value of 1.We use it as a condition in endless while() loop.It makes script run in real-time,so it can scan uninterupted for changes in the registry
QueryEnum0 ' The subroutines QueryEnum0 and QueryEnum1.The id is either in USBSTOR\Enum\0 or in USBSTOR\Enum\1 .That is for sure.
QueryEnum1 ' Declaration before definition - not exactly explanation.
'The purpose of these two subroutines is: create an object everytime the sub is called ,thus read the value in Enum\0 or in Enum\1 constantly as "scanning"
'Probably not so elegant solution to somebody,but actually it works.
Sub QueryEnum0 ' Enter the sub
Dim Flag_Enum_0,Shell ' Declare local variables.They will be created each time the sub is invoked.
Set Shell = CreateObject("WScript.Shell") 'Create an object to work wirh registry any time the sub is called
On Error Resume Next 'Error handling
Flag_Enum_0 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\0") 'Try to read reg value into Flag_Enum_0. The purpose
On Error GoTo 0
Flag_0 = Flag_Enum_0 'Assign the value to variable Flag_0,outside of sub.The memory for Flag_0 is set once and lasts while the script runs.
End Sub
' Same as QueryEnum0
Sub QueryEnum1
Dim Flag_Enum_1,Shell
Set Shell = CreateObject("WScript.Shell")
On Error Resume Next
Flag_Enum_1 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\1")
On Error GoTo 0
Flag_1 = Flag_Enum_1
End Sub
Do While Count = 1 'Real-time loop,the code within while is running while count is equal to 1. The script is loaded in memory constanlty.
On Error Resume Next
Enum_0 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\0") ' Try to read hardware id if it is in Enum\0
On Error GoTo 0 '
On Error Resume Next
Enum_1 = Shell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum\1") 'Try to read hardware id if it is in Enum\1
On Error GoTo 0
If StrComp(Hwid,Enum_0) <> 0 And StrComp(Hwid,Enum_1) <> 0 Then 'Check if both reg keys are empty
MsgBox "There is no device in the front usb.Please put the device or see the connection"
ElseIf StrComp(Hwid,Enum_0) = 0 Then 'If the hardware id is in Enum\0,thus assigned to Enum_0
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",3 'Enable the usb by "unlock" it
On Error Resume Next
QueryEnum0 'Invoke sub QueryEnum0.If the id we looking for is in Enum\0,we know that it is assigned to Flag_0 also
Check_0 = Flag_0 'Use another variable to copy value from Flag_0.
On Error GoTo 0
If StrComp(Hwid,Check_0) = 0 Then 'Compare the constant Hwid with the value in Check_0,test for id
Msgbox "Check_0 still holds the hardware id" 'Some messages to inform us whats happening
else
MsgBox "Check_0 does not contain the hardware id anymore"
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",4 'Disable the front usb
Count = 2 'End the while loop,count is 2,so the condition is false .The loop breaks.
End If
ElseIf StrComp(Hwid,Enum_1) = 0 Then 'If the hardware is in Enum\1....same as above mentioned
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",3
On Error Resume Next
QueryEnum1
Check_1 = Flag_1
On Error GoTo 0
If StrComp(Hwid,Check_1) = 0 Then
MsgBox "Check_1 still holds the hardware id"
MsgBox Check_1
else
MsgBox "Check_0 does not contain the hardware id anymore"
Shell.RegWrite "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Start",4
Count = 2
End If
End If
Loop
' Useful information for me
'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR -> value name -> Start ,value data = 3(enable) = 4(disable)
'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum -> value name -> 1 or 0 ,value data we look for is -> USB\Vid_04da&Pid_2372\5&2f621ee5&0&8
' USB\Vid_04da&Pid_2372\5&2f621ee5&0&8 - camera id in our case
' fantom value - USB\Vid_03f0&Pid_032a\000000000Q912WFBSI1c - name: 0 ,type: REG_SZ,in the key Enum.This is another hardware id,which is strange somehow,because I do not have any device
' inserted in my usb.However,I take this value into account,thus use both keys 0 and 1 within Enum to scan for the id I need.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据 Microsoft 文档,CurrentControlSet 注册表树中的数据在启动和驱动程序初始化期间使用。
此外,在 Windows 7 及更高版本中,对 HKEY_LOCAL_MACHINE 的任何更改都必须由以管理员身份运行的实用程序进行。否则,将对 HKEY_LOCAL_MACHINE 的用户克隆进行更改,并且更改将仅影响运行该实用程序的帐户的用户。
请参阅 HKLM\SYSTEM\CurrentControlSet\服务注册树其中指出
我发现的所有关于通过设置此值来提高 USB 存储设备安全性的内容都表明,作为预防措施,只需执行一次。因此,您概述的方法似乎并不可行解决方案
还可能存在初始状态问题,因为在插入 USB 大容量存储设备之前,设备驱动程序尚未完全初始化,因此该数据可能尚未被访问,这也表明它将取决于。 设备之前是否已成功插入,是否创建了必要的注册表数据和驱动程序初始化,
我认为可以肯定地说,以这种方式动态更改注册表值并不是 Windows USB 驱动程序的设计意图。
无论 还有 Microsoft 知识库文章 103000,CurrentControlSet\Services 子项条目的此页面,了解有关数据的详细信息在此注册表项中。本文介绍了有关
Start
关键字值的以下内容。另请参阅以下 stackoverflow 帖子。
C# 禁用/启用 USB 端口
启用和禁用 USB 端口
Win32 API 函数以编程方式启用/禁用设备
According to the Microsoft documentation the data in the CurrentControlSet Registry tree is used during start up and driver initialization.
Also with Windows 7 and later any changes to HKEY_LOCAL_MACHINE must be made by a utility running as an Administrator. Otherwise the changes will be made to a user clone of HKEY_LOCAL_MACHINE and changes will affect only the user under whose account the utility was run.
See HKLM\SYSTEM\CurrentControlSet\Services Registry Tree which states
Everything that I have found thus far concerning additional security for USB storage devices by setting this value indicates that it is done once as a preventive measure. So it would appear that the approach you outlined is not a feasible solution.
There may also be an initial state issue in that the until a USB mass storage device is plugged in, the device driver is not fully initialized hence this data may not have yet been accessed. Readings also seem to imply that it will depend on whether the device has been previously plugged in successfully, creating the necessary Registry data and driver initialization or not.
I think it is pretty safe to say that changing the Registry value on the fly in this way was not design intent for Windows USB drivers.
See also this page of Microsoft Knowledge Base article 103000, CurrentControlSet\Services Subkey Entries for details about the data in this Registry entry. This article says the following about the
Start
keyword values.See also the following stackoverflow posts.
C# Disable/Enable USB ports
Enable and Disable USB port
Win32 API function to programmatically enable/disable device