📄 drvtype.asm
字号:
;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
include bambi.inc
include devsym.inc ; get device driver structure definitions
include dpb.inc
public IsMagicDrive
public get_drive_type
public setup_default_drive_list
;
; routines from bambinit.asm
;
extrn get_DPB :near
extrn dos_3x :word
;
; data from cmdline.asm
;
extrn drives_to_cache :byte
extrn msg_and_fail :near
extrn dosinfo :word
extrn display_message :near
extrn first_instance :byte
extrn shutupmsdosflag :byte
extrn warnmsdosmessage :byte
zseg segment public 'CODE'
assume cs:zseg
assume ds:zseg
;
; locals
;
ioctl_buffer db 64 dup(?) ;buffer for ioctl 73h
thisdrivetype dw ?
DIRSTRLEN EQU 64+3 ; Max length in bytes of directory strings
TEMPLEN EQU DIRSTRLEN*2
CURDIR_LIST STRUC
CURDIR_TEXT DB DIRSTRLEN DUP (?) ; text of assignment and curdir
CURDIR_FLAGS DW ? ; various flags
CURDIR_DEVPTR DD ? ; local pointer to DPB or net device
CURDIR_ID DW 2 dup (?) ; cluster of current dir (net ID)
CURDIR_USER_WORD DW ?
CURDIR_END DW ? ; index to ".." backup limit - see above
CURDIR_TYPE DB ? ; IFS drive (2=ifs, 4=netuse)
CURDIR_IFS_HDR DD ? ; Ptr to File System Header
CURDIR_FSDA DB 2 DUP (?) ; File System Dependent Data Area
CURDIR_LIST ENDS
curdirLen EQU Size CURDIR_list ; Needed for screwed up
; ASM87 which doesn't allow
; Size directive as a macro
; argument
CURDIR_netID EQU DWORD PTR CURDIR_ID
;** Flag values for CURDIR_FLAGS
CURDIR_isnet EQU 1000000000000000B
CURDIR_isifs EQU 1000000000000000B
CURDIR_inuse EQU 0100000000000000B
CURDIR_splice EQU 0010000000000000B
CURDIR_local EQU 0001000000000000B
SysInitVars STRUC
SYSI_DPB DD ? ; DPB chain
SYSI_SFT DD ? ; SFT chain
SYSI_CLOCK DD ? ; CLOCK device
SYSI_CON DD ? ; CON device
SYSI_MAXSEC DW ? ; maximum sector size
SYSI_BUF DD ? ; points to Hashinitvar
SYSI_CDS DD ? ; CDS list
SYSI_FCB DD ? ; FCB chain
SYSI_Keep DW ? ; keep count
SYSI_NUMIO DB ? ; Number of block devices
SYSI_NCDS DB ? ; number of CDS's
SYSI_DEV DD ? ; device list
SYSI_ATTR DW ? ; null device attribute word
SYSI_STRAT DW ? ; null device strategy entry point
SYSI_INTER DW ? ; null device interrupt entry point
SYSI_NAME DB 8 DUP(?) ; null device name
SYSI_SPLICE DB 0 ; TRUE -> splicees being done
SYSI_IBMDOS_SIZE DW ? ; DOS size in paragraphs
SYSI_IFS_DOSCALL@ DD ? ; IFS DOS service rountine entry
SYSI_IFS DD ? ; IFS header chain
SYSI_BUFFERS DW ?,0 ; BUFFERS= values (m,n)
SYSI_BOOT_DRIVE DB ? ; boot drive A=1 B=2,..
SYSI_DWMOVE DB 0 ; 1 if 386 machine
SYSI_EXT_MEM DW 0 ; Extended memory size in KB.
SysInitVars ENDS
NET_MAP EQU 1000000000000b ; Mask for net drive bits
;
; code taken from DOS 5 setup to determine if drive is a network.
; There is a bug in dos 4.0 that requires us to slime around
;
;RETURNS
NON_LOCAL_DRIVE equ 0
LOCAL_DRIVE equ 1
NOTSUPP_DRIVE equ 2
drive db 0
IsLocalDrive proc near
push es
push dx
mov drive,dl
mov AX,3000h
int 21h
cmp AL,04
je LookInCDS
mov AX,4409h ; IOCTL is redirected? function
mov BL,Drive ; BL = drive number
int 21h
jc Notsupp ; If not supported then can't be net
mov AX,LOCAL_DRIVE ; Assume it is a local drive
test DX,NET_MAP ; See if any funny bits are set
jz IsLocalExit ; No funny bits so must be local
mov ax,NON_LOCAL_DRIVE
jmp short IsLocalExit
LookInCDS:
mov AH,52h ; Get internal DOS DATA Segment
int 21h ; ES:BX --> DOS interal varibles
mov CL,Drive ; First make sure that this drive
dec CL ; is not greater than last drive
; If CL is zero it will fail the
cmp CL,ES:[BX].SYSI_NCDS ; compare by doing unsigned cmp
mov AX,LOCAL_DRIVE
jae Notsupp
les BX,ES:[BX].SYSI_CDS ; ES:BX --> First CDS entry
mov AX,SIZE CURDIR_LIST ; Find offset of the entry indexed
mul CL ; by drive in CL
add BX,AX ; ES:BX --> CDS entry for drive
test es:[bx].CURDIR_FLAGS,CURDIR_inuse
jz Notsupp
test ES:[BX].CURDIR_FLAGS,CURDIR_isnet ; Test is net bit
mov ax,NON_LOCAL_DRIVE
jnz IsLocalExit ; If true then jmp to exit
mov ax,LOCAL_DRIVE
IsLocalExit:
pop dx
pop es
ret
Notsupp:
mov ax,NOTSUPP_DRIVE
jmp short islocalexit
IsLocalDrive ENDP
;
;input dl == drive letter,zero based
;
;output NZ -> magicdrv, BX & !80h = host drive letter
; Z -> not magicdrv
IsMagicDrive proc near
push dx
push es
push di
push si
push dx
mov ax,MAGICDRV_2F ;is magicdrv installed?
mov bx,MAGICDRV_DETECT
int 2fh
pop dx
cmp bx,MD_STAMP
jne no_magic_drv_installed
mov ax,MAGICDRV_2F
mov bx,MAGICDRV_MAP
int 2fh
;;; bit 7 set means its a compressed drive
;;; dl == bl without bit 7 means its a regular drive
;;; dl != bl without bit 7 means its a swapped host drive
test bl,80h ;compressed drive?
return_magictest:
pop si
pop di
pop es
pop dx
ret
no_magic_drv_installed:
xor ax,ax ;zet zero
jmp short return_magictest
IsMagicDrive endp
;
;FUNCTION
; detect drive type
;INPUT
; dx = drive unit
;OUTPUT
; ax = drive type
; INVALID_TYPE = 0
; FLOPPY_TYPE = 1
; REMOTE_TYPE = 2
; HARDDISK_TYPE = 3
; RAMDRIVE_TYPE = 4
; CDROM_TYPE = 5
; MEMORY_TYPE = 6
; MAGIC_TYPE = 7
;
;USES
; ALL except ES,DS
;
get_drive_type proc near
call IsMagicDrive
jnz dt_magic
;;;; first check is for CDROM
inc dx ;really want drive letter
mov ax,0150bh
xor bx,bx
mov cx,dx
dec cx
int 2fh
cmp bx,0ADADh
jne notCDROM
cmp ax,0
je notCDROM
mov ax,CDROM_TYPE
jmp short dt_end
notCDROM:
;;;;
; push dx
; mov ax,440dh ;generic ioctl get_system_info
; mov cx,0873h
; mov bx,dx
; mov dx,offset ioctl_buffer
; int 21h
; pop dx
; jc not_memory_device
; mov ax,MEMORY_TYPE
; jmp dt_end
;not_memory_device:
call islocaldrive
cmp ax,LOCAL_DRIVE
je dt_local_check
cmp ax,NOTSUPP_DRIVE
je dt_not_found
mov ax, REMOTE_TYPE
jmp short dt_end
dt_local_check:
mov bl,dl
mov ax, 4408h
int 21h
; ZZZZ
; WARNING!! assuming that drive is non-removable as call 1 succeeded!
; WINDOWS FM seems to do the same!
; jc dt_not_found
jc dt_nonremovable
or ax, ax
jz dt_removable
dt_nonremovable:
;WARNING dl is UNIT now
push dx
push ds ;
push bx ;result of get_dpb in ds:bx
mov dx,bx
call get_DPB
jc dt_inv1 ; if not a local drive, bail out w/ INVALID code
cmp ds:[bx].dpb_fat_count,1 ;only one fat means RAMDRIVE
pop bx
pop ds
pop dx
je dt_ramdrive
mov ax, HARDDISK_TYPE
jmp short dt_end
dt_ramdrive:
mov ax,RAMDRIVE_TYPE
jmp short dt_end
dt_removable:
mov ax, FLOPPY_TYPE
jmp short dt_end
dt_magic:
mov ax, MAGIC_TYPE
jmp short dt_end
dt_inv1:
pop bx
pop ds ; restore stack
pop dx
dt_not_found:
xor ax, ax
dt_end:
add ax,dosinfo
ret
get_drive_type endp
;
;FUNCTION
; initialize array which determines what drives to cache
; to include all hard disks with read+write caching enabled
;
setup_default_drive_list proc near
mov cx,26
loop_units:
mov ax,MULT_BAMBI
mov bx,BAMBI_DONT_CACHE_DRIVE
int 2fh
cmp ax,BAMBI_DONT_CACHE_DRIVE
je continue_loop_units
;;;
;;;New code added for Astro to detect magic drive 7/30/92 scottq
;;;
push cx
push es
push di
push si
push dx
mov ax,MAGICDRV_2F ;is magicdrv installed?
mov bx,MAGICDRV_DETECT
push cx
int 2fh
pop cx
pop dx
cmp bx,MD_STAMP
jne no_magic_drv
dec cx
mov ax,MAGICDRV_2F
mov bx,MAGICDRV_MAP
mov dl,cl
int 2fh
;;; bit 7 set means its a compressed drive
;;; dl == bl without bit 7 means its a regular drive
;;; dl != bl without bit 7 means its a swapped host drive
test bl,80h ;compressed drive
pop si
pop di
pop es
pop cx
jz mightbehostdrv
jmp short continue_loop_units
no_magic_drv:
pop si
pop di
pop es
pop cx
jmp short continue_drivecheck
mightbehostdrv:
cmp dl,bl
jne default_cache_hd ;;bug bug scottq 7/30/92 write cache on mounted floppies
continue_drivecheck:
push cx ;check each drive
mov dx,cx ;to see if it is a hard disk
dec dx
call get_drive_type ;if so, settup global list
mov thisdrivetype,ax
pop cx
sub ax,dosinfo
cmp ax,HARDDISK_TYPE
je default_cache_hd
cmp ax,FLOPPY_TYPE
je default_cache_floppy
continue_loop_units:
loop loop_units
call detect_dont_cache_drives
cmp thisdrivetype,MEMORY_TYPE
jna baddisk
contbad:
ret
default_cache_hd:
mov bp,cx
mov drives_to_cache[bp-1],READ_CACHE or WRITE_CACHE ;read/write cache
jmp short continue_loop_units
baddisk:
cmp first_instance,1
jne contbad
mov warnmsdosmessage,1 ;cant do it yet, since command line
jmp short contbad ;has to be parsed.
default_cache_floppy:
mov bp,cx
mov drives_to_cache[bp-1],READ_CACHE ;read cache only
jmp short continue_loop_units
setup_default_drive_list endp
detect_dont_cache_drives proc near
; int 1
push ds
push es
push bp
push si
push di
mov ah,52h
int 21h
add bx,34
;;; es:bx->device header chain
push es
pop ds
assume ds:nothing
mov bp,bx
;;; ds:bp->device header chain
xor di,di ; di is index into new header table
next_chain:
les bx,es:[bx]
cmp bx,-1
je done_walking_device_chain
test word ptr es:[bx].sdevatt,8000h ;block device?
jnz next_chain
;;
;; is it a squished drive? if so, do not cache. We can detect
;; squish drive by checking to see if the devicename field is "SQUISH+"
cmp word ptr es:[bx].sdevname[1],'QS'
jne next_name
cmp word ptr es:[bx].sdevname[3],'IU'
jne next_name
cmp word ptr es:[bx].sdevname[5],'HS'
jne next_name
cmp byte ptr es:[bx].sdevname[7],'+'
jne next_name
jmp short dontcachethisdrive
next_name:
cmp word ptr es:[bx].sdevname[1],'TS'
jne next_chain
cmp word ptr es:[bx].sdevname[3],'CA'
jne next_chain
cmp word ptr es:[bx].sdevname[5],'C-'
jne next_chain
cmp byte ptr es:[bx].sdevname[7],'D'
jne next_chain
dontcachethisdrive:
push es
push bx
mov si,bx ;di:si->driver header
mov di,es
mov dx,1 ;find unit for driver
loop_dpb:
call get_DPB ;ds:bx -> dpb or unit dl
jc nodpb ;skip if error
add bx,cs:dos_3x ; adjust pointer for DOS 3.x dpb
cmp word ptr ds:[bx].dpb_driver_addr[0],si
jne do_next_dpb
cmp word ptr ds:[bx].dpb_driver_addr[2],di
jne do_next_dpb
push bp
mov bp,dx
mov drives_to_cache[bp-1],NO_CACHE
pop bp
jmp short do_next_dpb
nodpb:
pop bx
pop es
jmp next_chain
do_next_dpb:
inc dl
jmp short loop_dpb
done_walking_device_chain:
pop di
pop si
pop bp
pop es
pop ds
ret
detect_dont_cache_drives endp
zseg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -