📄 ide.asm
字号:
DEBUG equ 0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Programmed by 罗云彬, bigluo@telekbird.com.cn
; Website: http://asm.yeah.net
; LuoYunBin's Win32 ASM page (罗云彬的编程乐园)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 读取硬盘序列号
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none ; case sensitive
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 硬盘返回的信息数据定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDEINFO struct
wGenConfig dw ?
wNumCyls dw ?
wReserved dw ?
wNumHeads dw ?
wBytesPerTrack dw ?
wBytesPerSector dw ?
wSectorsPerTrack dw ?
wVendorUnique dw 3 dup (?)
sSerialNumber db 20 dup (?)
wBufferType dw ?
wBufferSize dw ? ;n * 512
wECCSize dw ?
sFirmwareRev db 8 dup (?)
sModelNumber db 40 dup (?)
wMoreVendorUnique dw ?
wDoubleWordIO dw ?
wCapabilities dw ?
wReserved1 dw ?
wPIOTiming dw ?
wDMATiming dw ?
wBS dw ?
wNumCurrentCyls dw ?
wNumCurrentHeads dw ?
wNumCurrentSectorsPerTrack dw ?
dwCurrentSectorCapacity dd ?
wMultSectorStuff dw ?
dwTotalAddressableSectors dd ?
wSingleWordDMA dw ?
wMultiWordDMA dw ?
bReserved db 128 dup (?)
IDEINFO ends
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
szBuffer db 1024 dup (?)
szModelNumber db 41 dup (?)
szSerialNumber db 21 dup (?)
szFirmwareRev db 9 dup (?)
stIDEINFO IDEINFO <?>
.data
szTitle db 'IDE 硬盘信息',0
szErrNT db '本程序无法在 Windows NT 下运行',0
szErrInfo db '无法读取硬盘信息',0
szIDEInfo db '柱面数 : %d',0dh,0ah
db '磁头数 : %d',0dh,0ah
db '每道扇区数 : %d',0dh,0ah
db '缓冲大小 : %d 扇区',0dh,0ah
db '硬盘型号 : %40s',0dh,0ah
db '序列号 : %20s',0dh,0ah
db '版本号 : %8s',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
if DEBUG
include Debug.asm
endif
include Ring0.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 向硬盘发送命令读取序列号等信息
; 输入参数:IDEINFO 结构的地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_IDEInfo proc _lpstIDEINFO
pushad
mov ebx,_lpstIDEINFO
assume ebx:ptr IDEINFO
;********************************************************************
; 等待硬盘就绪
;********************************************************************
mov ecx,10000h
mov dx,01f7h
@@:
in al,dx
cmp al,50h
jnz @F
loop @B
jmp _II_TimeOut
@@:
;********************************************************************
; 发送命令
; 如果向主控制发送命令,则端口为 1f0h-1f7h
; 如果向副控制发送命令,则端口为 170h-177h
; 1f6h 如果要检测的设备为该IDE接口的主(MASTER)设备,
; 那么发送 a0,如果为从那么发送 b0
; 1f7h 如果要检测的设备为 ATA 设备那么发送 ec
; 如果为 ATAPI 设备那么发送 a1
;********************************************************************
mov al,0a0h
mov dx,01f6h
out dx,al
mov al,0ech
inc dx
out dx,al
;********************************************************************
; 等待硬盘就绪
;********************************************************************
mov ecx,10000h
@@:
in al,dx
cmp al,58h
jz @F
loop @B
jmp _II_TimeOut
@@:
;********************************************************************
; 将返回信息读回
; 注意一定要读满 100h 个字长
;********************************************************************
cld
mov edx,01f0h
mov edi,ebx
mov ecx,0100h
rep insw
;********************************************************************
; 返回的信息中,型号、序列号、版本号为字形式
; 需要整理到字符串的形式
;********************************************************************
lea esi,[ebx].sSerialNumber
mov edi,esi
mov ecx,10
@@:
lodsw
xchg ah,al
stosw
loop @B
lea esi,[ebx].sFirmwareRev
mov edi,esi
mov ecx,24
@@:
lodsw
xchg ah,al
stosw
loop @B
_II_TimeOut:
popad
assume ebx:nothing
ret
_IDEInfo endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 程序开始
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _CheckNT
.if eax
mov eax,offset szErrNT
.else
invoke _Ring0Call,offset _IDEInfo,addr stIDEINFO
.if stIDEINFO.wNumCyls
lea esi,stIDEINFO.sModelNumber
mov edi,offset szModelNumber
mov ecx,sizeof stIDEINFO.sModelNumber
rep movsb
lea esi,stIDEINFO.sSerialNumber
mov edi,offset szSerialNumber
mov ecx,sizeof stIDEINFO.sSerialNumber
rep movsb
lea esi,stIDEINFO.sFirmwareRev
mov edi,offset szFirmwareRev
mov ecx,sizeof stIDEINFO.sFirmwareRev
rep movsb
movzx eax,stIDEINFO.wNumCyls
movzx ebx,stIDEINFO.wNumHeads
movzx ecx,stIDEINFO.wSectorsPerTrack
movzx edx,stIDEINFO.wBufferSize
invoke wsprintf,addr szBuffer,addr szIDEInfo,\
eax,ebx,ecx,edx,\
addr szModelNumber,\
addr szSerialNumber,\
addr szFirmwareRev
mov eax,offset szBuffer
.else
mov eax,offset szErrInfo
.endif
.endif
invoke MessageBox,NULL,eax,addr szTitle,MB_ICONINFORMATION or MB_OK
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -