;运行效果
;win32汇编环境,怎么得到磁盘的盘符
;以下代码主要为了展示一下原理,应用GetLogicalDrives、GetLogicalDriveStrings函数、屏蔽某些二进制位、按双字节复制内容等。以下代码最多查8个盘,即返回值中的1个字节的信息
;直接抄进RadAsm可编译运行。重点部分加备注。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
; 自定义函数声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD ;对话框窗口函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
DlgName db "MyDialog",0
szFormat01 db 13,10
db "通过GetLogicalDrives函数判断",13,10
db "总计是 %d 个逻辑分区",13,10,0
szFormat02 db 13,10
db 13,10
db "通过GetLogicalDriveStrings函数判断",13,10
db "总计是 %d 个逻辑分区",0
szCaption db "提示",0
sz db "分别是",0
szA db "A: ",0
szB db "B: ",0
szC db "C: ",0
szD db "D: ",0
szE db "E: ",0
szF db "F: ",0
szG db "G: ",0
szH db "H: ",0
.data?
hInstance HINSTANCE ?
.const
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000 ;图标
ID_EDIT01 equ 11 ;编辑框控件标识符
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam, hInstance, ADDR DlgName,NULL, addr DlgProc, NULL
invoke ExitProcess,eax
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL @szBuffer[128]:byte
LOCAL @szBuffer1[256]:byte
LOCAL @szBuffer2[1024]:byte
LOCAL @hDriver:byte
LOCAL @Apen:byte
LOCAL @Bpen:byte
LOCAL @Cpen:byte
LOCAL @Dpen:byte
LOCAL @Epen:byte
LOCAL @Fpen:byte
LOCAL @Gpen:byte
LOCAL @Hpen:byte
LOCAL @hDriverCount ;逻辑盘数量,默认的变量是DWORD型的,即四字节,32位的
LOCAL @hEdit
.if uMsg == WM_INITDIALOG
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
invoke RtlZeroMemory,addr @szBuffer,sizeof @szBuffer
invoke RtlZeroMemory,addr @szBuffer1,sizeof @szBuffer1
invoke RtlZeroMemory,addr @szBuffer2,sizeof @szBuffer2
;以下通过GetLogicalDrives函数也可以判断有多少个盘符
mov @Apen,00000001B ;B的意思是二进制值
mov @Bpen,00000010B
mov @Cpen,00000100B
mov @Dpen,00001000B
mov @Epen,00010000B
mov @Fpen,00100000B
mov @Gpen,01000000B
mov @Hpen,10000000B
invoke GetLogicalDrives ;GetLogicalDrives函数检索一个表示当前可用磁盘驱动器的位掩码,就是其返回值转换成二进制时,哪位是1,则对应的某个盘。比如第0位是1,则说明A盘有效,第1位是1,则说明B盘有效,为0则无效。以此类推
mov @hDriver,al ;只取返回值中的低位字节,也就是最多查询8个盘符
mov @hDriverCount,0
invoke lstrcat,addr @szBuffer,addr sz
mov al,@hDriver
and @Apen,al ;让al与00000001B相与,即把第0位原值留下,其它7位全部置0的意思,要知道,第一位是0位开始的
.if @Apen == 00000001B ;如果第0位是1,说明A盘存在。
inc @hDriverCount ;盘数自增1
invoke lstrcat,addr @szBuffer,addr szA
.endif
mov al,@hDriver ;让al与00000010B相与,即把第1位原值留下,其它7位全部置0的意思.
and @Bpen,al
.if @Bpen == 00000010B ;如果第1位是1,说明B盘存在。后面的以此类推
inc @hDriverCount
invoke lstrcat,addr @szBuffer,addr szB
.endif
mov al,@hDriver
and @Cpen,al
.if @Cpen == 00000100B
inc @hDriverCount
invoke lstrcat,addr @szBuffer,addr szC
.endif
mov al,@hDriver
and @Dpen,al
.if @Dpen == 00001000B
inc @hDriverCount
invoke lstrcat,addr @szBuffer,addr szD
.endif
mov al,@hDriver
and @Epen,al
.if @Epen == 00010000B
inc @hDriverCount
invoke lstrcat,addr @szBuffer,addr szE
.endif
mov al,@hDriver
and @Fpen,al
.if @Fpen == 00100000B
inc @hDriverCount
invoke lstrcat,addr @szBuffer,addr szF
.endif
mov al,@hDriver
and @Gpen,al
.if @Gpen == 01000000B
inc @hDriverCount
invoke lstrcat,addr @szBuffer,addr szG
.endif
mov al,@hDriver
and @Hpen,al
.if @Hpen == 10000000B
inc @hDriverCount
invoke lstrcat,addr @szBuffer,addr szH
.endif
invoke wsprintf,addr @szBuffer1,addr szFormat01,@hDriverCount
invoke lstrcat,addr @szBuffer2,addr @szBuffer1
invoke lstrcat,addr @szBuffer2,addr @szBuffer
;以下通过GetLogicalDriveStrings函数也可以判断有多少个盘符
invoke RtlZeroMemory,addr @szBuffer,sizeof @szBuffer
invoke RtlZeroMemory,addr @szBuffer1,sizeof @szBuffer1
invoke GetLogicalDriveStrings,sizeof @szBuffer,addr @szBuffer
;GetLogicalDriveStrings函数的返回值是字节数,每个盘占4个字节,依次排列,比如有12个字节,则说明有3个盘。但是每4个字节之中,第4个字节是0,即结束符,所以遍历字符串时不能以结束符为判断结束的条件
mov ebx,4 ;4是每个盘的信息占4个字节,通过除以4,就知道总共多少个盘符
div ebx
mov @hDriverCount,eax
invoke wsprintf,addr @szBuffer1,addr szFormat02,@hDriverCount
invoke lstrcat,addr @szBuffer2,addr @szBuffer1
mov ebx,0
.while TRUE
.break .if ebx == @hDriverCount
invoke lstrlen,addr @szBuffer2 ;得到要显示到编辑框里的文本长度,因为后面直接把盘符加上去
mov edx,eax
mov ax,word ptr [@szBuffer+ebx*4] ;因为盘符占用4个字节中开头2个字节,比如C:,所以直接按双字word复制内容
mov word ptr [@szBuffer2+edx],ax
inc ebx
.endw
invoke GetDlgItem,hWnd,ID_EDIT01
mov @hEdit,eax
invoke SendMessage,@hEdit,WM_SETTEXT,0,addr @szBuffer2
.elseif uMsg == WM_CLOSE
invoke EndDialog, hWnd,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end start