VB 卸载USB设备/解锁文件

这次索性贴完整源码,希望能对大家有所帮助.

frmMain.frm

VERSION 5.00
Begin VB.Form frmMain
   BorderStyle     =   1  'Fixed Single
   Caption         =   "Usb卸载程序"
   ClientHeight    =   2445
   ClientLeft      =   45
   ClientTop       =   435
   ClientWidth     =   4425
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   MinButton       =   0   'False
   ScaleHeight     =   2445
   ScaleWidth      =   4425
   StartUpPosition =   2  '屏幕中心
   Begin VB.CommandButton cmdAbout
      Caption         =   "关于(&A)"
      Height          =   375
      Left            =   1050
      TabIndex        =   4
      Top             =   1590
      Width           =   1005
   End
   Begin VB.CommandButton cmdExit
      Cancel          =   -1  'True
      Caption         =   "退出(&C)"
      Height          =   375
      Left            =   3150
      TabIndex        =   3
      Top             =   1590
      Width           =   1005
   End
   Begin VB.CommandButton cmdUnLoad
      Caption         =   "卸载(&U)"
      Default         =   -1  'True
      Height          =   375
      Left            =   2100
      TabIndex        =   2
      Top             =   1590
      Width           =   1005
   End
   Begin VB.TextBox txtUsbDrive
      Height          =   285
      Left            =   1530
      TabIndex        =   0
      Top             =   750
      Width           =   2625
   End
   Begin VB.Label lblMsg
      AutoSize        =   -1  'True
      Caption         =   "输入USB盘符:"
      Height          =   180
      Left            =   240
      TabIndex        =   1
      Top             =   810
      Width           =   1080
   End
End
Attribute VB_Name = "frmMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub cmdAbout_Click()
    Shell "explorer /s , http://blog.csdn.net/chenhui530/"
    MsgBox "欢迎大家使用我编写的卸载USB程序,如果您在使用中发现有什么BUG或者是好的建" & vbNewLine & "议可以到我的博客上留言反映情况。地址是: http://blog.csdn.net/chenhui530/", vbInformation, "关于"
End Sub

Private Sub cmdExit_Click()
    Unload Me
End Sub

Private Sub cmdUnLoad_Click()
    Dim lngLenPath As Long, blnIsUsb As Boolean, strPath As String
    lngLenPath = Len(txtUsbDrive.Text)
    If lngLenPath <= 3 And Dir(txtUsbDrive.Text, 1 Or 2 Or 4 Or vbDirectory) <> "" Then
        If lngLenPath = 2 Then
            If GetDriveBusType(txtUsbDrive.Text) <> "Usb" Then
                MsgBox "只能解锁USB设备分区!!", vbCritical, "错误"
                txtUsbDrive.SetFocus
                Exit Sub
            End If
            strPath = txtUsbDrive.Text & "/"
        ElseIf lngLenPath = 1 Then
            If GetDriveBusType(txtUsbDrive.Text & ":") <> "Usb" Then
                MsgBox "只能解锁USB设备分区!!", vbCritical, "错误"
                txtUsbDrive.SetFocus
                Exit Sub
            End If
            strPath = txtUsbDrive.Text & ":/"
        Else
            If GetDriveBusType(Left(txtUsbDrive.Text, 2)) <> "Usb" Then
                MsgBox "只能解锁USB设备分区!!", vbCritical, "错误"
                txtUsbDrive.SetFocus
                Exit Sub
            End If
            strPath = txtUsbDrive.Text
        End If
        blnIsUsb = True
    Else
        MsgBox "您输入的USB盘符不要求!!", vbCritical, "错误"
        txtUsbDrive.SetFocus
        Exit Sub
    End If
    Me.cmdUnLoad.Enabled = False
    Me.cmdExit.Enabled = False
    '这里只检测本进程因为在获取驱动器类型的时候会打开一个句柄但是WINDOWS没有自己关闭所以用这个来
    '解除锁定,当然你也可以使用CloseLoackFiles函数来检测所有进程
    If CloseLockFileHandle(Left(strPath, 2), GetCurrentProcessId) Then
        If blnIsUsb Then
            If RemoveUsbDrive("//./" & Left(strPath, 2), True) Then
                MsgBox "卸载UBS设备成功!!", , "提示"
            Else
                MsgBox "但卸载UBS设备失败!!", vbCritical, "提示"
            End If
        End If
    Else
        MsgBox "发现有锁定文件还没解锁!!", vbCritical, "提示"
    End If
    Me.cmdUnLoad.Enabled = True
    Me.cmdExit.Enabled = True
End Sub

modGetDriveType.bas

Attribute VB_Name = "modGetDriveType"
Option Explicit
'****************************************************************************************************************
'此模块来自于网络
'****************************************************************************************************************
'判断驱动器的类型

Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long

Private Const DRIVE_UNKNOWN = 0        '驱动器类型无法确定
Private Const DRIVE_NO_ROOT_DIR = 1    '驱动器根目录不存在
Private Const DRIVE_REMOVABLE = 2      '软盘驱动器或可移动盘
Private Const DRIVE_FIXED = 3          '硬盘驱动器
Private Const DRIVE_REMOTE = 4         'Network 驱动器
Private Const DRIVE_CDROM = 5          '光盘驱动器
Private Const DRIVE_RAMDISK = 6        'RAM 存储器

'****************************************************************************************************************

' CreateFile获取设备句柄

'参数
'lpFileName                       文件名
'dwDesiredAccess                  访问方式
'dwShareMode                      共享方式
'ATTRIBUTES lpSecurityAttributes  安全描述符指针
'dwCreationDisposition            创建方式
'dwFlagsAndAttributes             文件属性及标志
' hTemplateFile                   模板文件的句柄

'CreateFile这个函数用处很多,这里我们用它「打开」设备驱动程序,得到设备的句柄。
'操作完成後用CloseHandle关闭设备句柄。
'与普通文件名有所不同,设备驱动的「文件名」形式固定为「//./DeviceName」(注意在C程序中该字符串写法为「.//DeviceName」)
'DeviceName必须与设备驱动程序内规定的设备名称一致。
'一般地,调用CreateFile获得设备句柄时,访问方式参数设置为0或GENERIC_READ|GENERIC_WRITE
'共享方式参数设置为FILE_SHARE_READ|FILE_SHARE_WRITE,创建方式参数设置为OPEN_EXISTING,其它参数设置为0或NULL。

Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Const GENERIC_READ = &H80000000   '允许对设备进行读访问
Private Const FILE_SHARE_READ = &H1       '允许读取共享
Private Const OPEN_EXISTING = 3           '文件必须已经存在。由设备提出要求
Private Const FILE_SHARE_WRITE = &H2      '允许对文件进行共享访问

'****************************************************************************************************************

'DeviceIoControl说明

'用途              实现对设备的访问—获取信息,发送命令,交换数据等。

'参数
'hDevice           设备句柄
'dwIoControlCode   控制码
'lpInBuffer        输入数据缓冲区指针
'nInBufferSize     输入数据缓冲区长度
'lpOutBuffer       输出数据缓冲区指针
'nOutBufferSize    输出数据缓冲区长度
'lpBytesReturned   输出数据实际长度单元长度
'lpOverlapped      重叠操作结构指针
Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As Any, ByVal nOutBufferSize As Long, lpBytesReturned As Long, lpOverlapped As OVERLAPPED) As Long

Private Type SECURITY_ATTRIBUTES
    nLength As Long                    '结构体的大小
    lpSecurityDescriptor As Long       '安全描述符(一个C-Style的字符串)。
    bInheritHandle As Long             '所创建出来的东西是可以被其他的子进程使用的
End Type

'查询存储设备还是适配器属性
Private Enum STORAGE_PROPERTY_ID
    StorageDeviceProperty = 0          '查询设备属性
    StorageAdapterProperty             '查询适配器属性
End Enum

'查询存储设备属性的类型
Private Enum STORAGE_QUERY_TYPE
    PropertyStandardQuery = 0          '读取描述
    PropertyExistsQuery                '测试是否支持
    PropertyMaskQuery                  '读取指定的描述
    PropertyQueryMaxDefined            '验证数据
End Enum

'查询属性输入的数据结构
Private Type STORAGE_PROPERTY_QUERY
    PropertyId As STORAGE_PROPERTY_ID  '设备/适配器
    QueryType As STORAGE_QUERY_TYPE    '查询类型
    AdditionalParameters(0) As Byte    '额外的数据(仅定义了象徵性的1个字节)
End Type

Private Type OVERLAPPED
    Internal As Long                  '保留给操作系统使用。用于保存系统状态,当GetOverLappedRseult的返回值中没有设置ERROR_IO_PENDING时,本域为有效。
    InternalHigh As Long              '成员保留给操作系统使用。用于保存异步传输数据的长度。当GetOverLappedRseult返回TRUE时,本域为有效。
    offset As Long                    '指定开始进行异步传输的文件的一个位置。该位置是距离文件开头处的偏移值。在调用ReadFile或WriteFile之前,必须设置此分量。
    OffsetHigh As Long                '指定开始异步传输处的字节偏移的高位字部分。
    hEvent As Long                    '指向一个事件的句柄,当传输完后将其设置为信号状态。
End Type

'存储设备的总线类型
Private Enum STORAGE_BUS_TYPE
    BusTypeUnknown = 0
    BusTypeScsi
    BusTypeAtapi
    BusTypeAta
    BusType1394
    BusTypeSsa
    BusTypeFibre
    BusTypeUsb
    BusTypeRAID
    BusTypeMaxReserved = &H7F
End Enum

'查询属性输出的数据结构
Private Type STORAGE_DEVICE_DESCRIPTOR
    Version As Long                 '版本
    Size As Long                    '结构大小
    DeviceType As Byte              '设备类型
    DeviceTypeModifier As Byte      'SCSI-2额外的设备类型
    RemovableMedia As Byte          '是否可移动
    CommandQueueing As Byte         '是否支持命令队列
    VendorIdOffset As Long          '厂家设定值的偏移
    ProductIdOffset As Long         '产品ID的偏移
    ProductRevisionOffset As Long   '产品版本的偏移
    SerialNumberOffset As Long      '序列号的偏移
    BusType As STORAGE_BUS_TYPE     '总线类型
    RawPropertiesLength As Long     '额外的属性数据长度
    RawDeviceProperties(0) As Byte  '额外的属性数据(仅定义了象徵性的1个字节)
End Type

'计算控制码   IOCTL_STORAGE_QUERY_PROPERTY
Private Const IOCTL_STORAGE_BASE As Long = &H2D
Private Const METHOD_BUFFERED = 0
Private Const FILE_ANY_ACCESS = 0

'获取磁盘属性
Private Function GetDisksProperty(ByVal hDevice As Long, utDevDesc As STORAGE_DEVICE_DESCRIPTOR) As Boolean
    Dim ut As OVERLAPPED
    Dim utQuery As STORAGE_PROPERTY_QUERY
    Dim lOutBytes As Long
    With utQuery
        .PropertyId = StorageDeviceProperty
        .QueryType = PropertyStandardQuery
    End With
    GetDisksProperty = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, utQuery, LenB(utQuery), utDevDesc, LenB(utDevDesc), lOutBytes, ut)
End Function

Private Function CTL_CODE(ByVal lDeviceType As Long, ByVal lFunction As Long, ByVal lMethod As Long, ByVal lAccess As Long) As Long
    CTL_CODE = (lDeviceType * 2 ^ 16&) Or (lAccess * 2 ^ 14&) Or (lFunction * 2 ^ 2) Or (lMethod)
End Function

'获取设备属性信息,希望得到系统中所安装的各种固定

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值