实时获得USB磁盘(再次更新)

by czy

10分感谢sinister老大指点,程序流层:

先通过设备消息得到新加入的盘符并且排除映射盘(net use/subst).

然后通过DeviceIoControl函数发送IOCTL_STORAGE_BASE equ FILE_DEVICE_MASS_STORAGE得到盘符的总线类别,而不是通过一般的GetDirverTyte,或是网上有些人说的IOCTL_STORAGE_GET_MEDIA_TYPES.

最后通过GetDirverTyte排除USB光驱.

要注意的是调用CreateFile的时候如果文件名是//./x:形式的盘符第二三四个参数一定要为NULL
网上很多代码这儿都有问题.另外由于MASM的INC文件中没有winioctl所以有些常量得自定义:)


.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        ../include/user32.inc
includelib    ../lib/user32.lib
include        ../include/kernel32.inc
includelib    ../lib/kernel32.lib
include        ../include/windows.inc


CheckUsbDisk    proto :dword

CTL_CODE MACRO DeviceType:=<0>, Function:=<0>, Method:=<0>, Access:=<0>
        EXITM %(((DeviceType) SHL 16) OR ((Access) SHL 14) OR ((Function) SHL 2) OR (Method))
ENDM

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN    equ    1000
DLG_MAIN    equ    1000
IDC_TEXT    equ    1001

DBT_DEVICEARRIVAL equ 8000h
DBT_DEVTYP_VOLUME equ 02h

_DEV_BROADCAST_HDR struct
dbch_size       dd ?
dbch_devicetype dd ?
dbch_reserved   dd ?
_DEV_BROADCAST_HDR ends   

_DEV_BROADCAST_VOLUME struct
dbcv_size       dd ?
dbcv_devicetype dd ?
dbcv_reserved   dd ?
dbcv_unitmask   dd ?
dbcv_flags      dw ?
_DEV_BROADCAST_VOLUME ends

DBTF_MEDIA      equ 01h
DBTF_NET        equ 02h ;网络映射盘符或subst命令映射的盘符


FILE_ANY_ACCESS                        equ 0
METHOD_BUFFERED         equ 0
FILE_DEVICE_MASS_STORAGE        equ 2dh ;from ntddk.inc
IOCTL_STORAGE_BASE equ FILE_DEVICE_MASS_STORAGE ;from ntddstor.inc
IOCTL_STORAGE_QUERY_PROPERTY        equ CTL_CODE(IOCTL_STORAGE_BASE, 500h, METHOD_BUFFERED, FILE_ANY_ACCESS)

BusTypeUsb equ 7

StorageDeviceProperty equ 0
PropertyStandardQuery equ 0

STORAGE_PROPERTY_QUERY struct
PropertyId     dd ?             ; 存储设备/适配器
QueryType      dd ?             ; 查询方式
AdditionalParameters dd ?       ; 额外的数据(仅定义了象征性的1个字节)
STORAGE_PROPERTY_QUERY ends

STORAGE_DEVICE_DESCRIPTOR struct
Version             dd ?        ; 版本
theSize             dd ?        ; 结构大小
DeviceType          db ?        ; 设备类型
DeviceTypeModifier  db ?        ; SCSI-2额外的设备类型
RemovableMedia      db ?        ; 是否可移动
CommandQueueing     db ?        ; 是否支持命令队列
VendorIdOffset      dd ?        ; 厂家设定值的偏移
ProductIdOffset     dd ?        ; 产品ID的偏移
ProductRevisionOffset   dd ?    ; 产品版本的偏移
SerialNumberOffset      dd ?    ; 序列号的偏移
BusType                 dd ?    ; 总线类型
RawPropertiesLength     dd ?    ; 额外的属性数据长度
RawDeviceProperties     dd ?    ; 额外的属性数据(仅定义了象征性的1个字节)
STORAGE_DEVICE_DESCRIPTOR ends


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data
        disk3   db '//./',0
        mao     db ':',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

        .code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain    proc    uses ebx edi esi hWnd,wMsg,wParam,lParam
               
        mov    eax,wMsg
;********************************************************************
        .if    eax ==    WM_CLOSE
            invoke    EndDialog,hWnd,NULL
;********************************************************************
        .elseif    eax ==   WM_DEVICECHANGE  ;设备变化消息
            mov    eax,wParam
            .if    eax == DBT_DEVICEARRIVAL ;加入了可用的新设备
                   mov  eax,lParam
                   assume eax:ptr _DEV_BROADCAST_HDR
                   mov  eax,[eax].dbch_devicetype
                   assume eax:nothing
                   .if  eax == DBT_DEVTYP_VOLUME ;新设备添加了一个盘符
                        mov eax,lParam
                        assume eax:ptr _DEV_BROADCAST_VOLUME
                        mov edx,[eax].dbcv_unitmask
                        ;mov ecx,[eax].dbcv_flags
                        xor ebx,ebx
                        .while ebx<26
                        mov ecx,edx
                        and edx,01h
                        .if edx==1
                            mov cx,word ptr [eax].dbcv_flags
                            .if cx == 00h ;排除映射盘(subst或net use)
                            add ebx,65d ;盘符
                            invoke CheckUsbDisk,ebx
                            .endif
                            .break
                        .else
                            mov edx,ecx
                            shr edx,1
                        .endif
                        inc ebx
                        .endw
                        assume eax:nothing      
                   .endif
            .endif      
;********************************************************************
        .else
            mov    eax,FALSE
            ret
        .endif
        mov    eax,TRUE
        ret

_ProcDlgMain    endp

CheckUsbDisk        proc uses ebx esi edi disk:dword
                    LOCAL   buffer[128]:byte
                    LOCAL   hDisk:dword
                    LOCAL   notuse:dword
                    LOCAL   Query:STORAGE_PROPERTY_QUERY
                    LOCAL   DevDesc:STORAGE_DEVICE_DESCRIPTOR
               

                           invoke   lstrcpy,addr buffer,offset disk3   ;buffer=//./
                           invoke   lstrcat,addr buffer,addr   disk    ;buffer=//./X
                   invoke   lstrcat,addr buffer,offset mao     ;buffer=//./X:
                   invoke   CreateFile,addr buffer, NULL, NULL,NULL, OPEN_EXISTING, NULL,NULL
                   mov      hDisk,eax
                   .if eax !=INVALID_HANDLE_VALUE
                        mov Query.PropertyId,StorageDeviceProperty   
                        mov Query.QueryType,PropertyStandardQuery
                        invoke   DeviceIoControl,hDisk,IOCTL_STORAGE_QUERY_PROPERTY,addr Query, sizeof STORAGE_PROPERTY_QUERY,addr DevDesc,sizeof STORAGE_DEVICE_DESCRIPTOR,addr notuse, NULL
                        .if eax != NULL
                            mov eax,[ DevDesc.BusType]
                            .if eax == BusTypeUsb
                                invoke  lstrcpy,addr buffer,addr disk  ;buffer=X
                                invoke  lstrcat,addr buffer,offset mao ;buffer=X:
                                invoke        GetDriveType,addr buffer
                                .if eax != DRIVE_CDROM ;排除USB光驱
                                invoke  MessageBox,0,addr buffer,addr buffer,1
                                .endif
                            .endif      
                        .endif     
                   .endif     
                   invoke   CloseHandle,hDisk
                    ret
CheckUsbDisk        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
        invoke    GetModuleHandle,NULL
        invoke    DialogBoxParam,eax,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
        invoke    ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end    start
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值