vb脚本修改USBSTOR键后,USB_MASS_STORAGE驱动程序崩溃

时间:2011-03-31 11:52:56

标签: vbscript

我自己编写了这个脚本。 基本上我想要的是脚本,只为特定设备“解锁”前面的USB。 这种情况是我们有一个工作站,注册表项USBSTOR \ Start设置为4(禁用),所以如果没有我们IT部门的一些额外工作,前面的usb不可用 - 这样我们就可以控制谁可以访问usb

但员工必须使用相机拍照以满足特定需求并通过电子邮件客户端发送。因此我们希望自动化“锁定/解锁”阶段。

当插入感兴趣的设备时,usb会解锁,当设备处于USB状态时,它会保持“解锁”状态,并且在设备拔出后,脚本会再次“锁定”USB。

我已决定使用.vbs。该脚本按预期工作,但在“锁定”阶段后,USB_MASS_STORAGE驱动程序崩溃。我必须卸载它并重新启动Windows以便重新加载驱动程序并运行在我多次运行脚本之后,USBSTOR \ Start中的注册表值不会影响usb,即即使有4,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.

1 个答案:

答案 0 :(得分:0)

根据Microsoft文档,在启动和驱动程序初始化期间使用CurrentControlSet注册表树中的数据。

对于Windows 7及更高版本,对HKEY_LOCAL_MACHINE的任何更改都必须由以管理员身份运行的实用程序进行。否则,将对HKEY_LOCAL_MACHINE的用户克隆进行更改,更改将仅影响运行该实用程序的用户。

请参阅HKLM\SYSTEM\CurrentControlSet\Services Registry Tree说明哪些

  

&#34;驱动程序可以在其密钥下存储全局驱动程序定义的数据   服务树。可以使用此密钥下存储的信息   在初始化期间给驱动程序。&#34;

到目前为止,通过设置此值,我发现的有关USB存储设备的额外安全性的所有内容都表明它已作为预防措施完成一次。因此,您所概述的方法似乎不是一个可行的解决方案。

可能还存在初始状态问题,因为在插入USB大容量存储设备之前,设备驱动程序未完全初始化,因此可能尚未访问此数据。读数似乎也暗示它将取决于设备之前是否已成功插入,是否创建了必要的注册表数据和驱动程序初始化。

我认为以这种方式动态更改注册表值并不是Windows USB驱动程序的设计意图是非常安全的。

有关此注册表项中的数据的详细信息,另请参阅Microsoft Knowledge Base article 103000, CurrentControlSet\Services Subkey Entries的此页面。本文介绍了有关Start关键字值的以下内容。

  

0x3(按需加载)可用,无论类型如何,但在用户启动之前不会启动(例如,使用“控制面板”中的“设备”图标)。

     

0x4(禁用)不能在任何条件下启动。

另请参阅以下stackoverflow帖子。

C# Disable/Enable USB ports

Enable and Disable USB port

Win32 API function to programmatically enable/disable device