;运行效果

;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