;運行效果
;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?
?