windows-nt/Source/XPSP1/NT/base/ntsetup/mpk/iolib/diskio.asm
2020-09-26 16:20:57 +08:00

518 lines
10 KiB
NASM

DOSSEG
.MODEL LARGE
include disk.inc
.DATA?
public DiskList
DiskList dd ?
.CODE
ASSUME ds:NOTHING
extrn InitializeInt13DiskList:far
extrn OpenInt13Disk:far
extrn CloseInt13Disk:far
extrn Int13DiskIo:far
extrn GetInt13DiskInfo:far
.386
;++
;
; UINT
; _far
; InitializeDiskList(
; VOID
; );
;
; Routine Description:
;
; This routine initializes internal data structures necessary so that
; other disk-related routines in this module can be called.
;
; A data structure for each disk (currently int13 units only) is built
; and saved away. The structure contains various info such as
; drive geometry.
;
; This routine may be called multiple times. Subsequent calls after
; the first simply return the disk count.
;
; Arguments:
;
; None.
;
; Return Value:
;
; Total count of all hard drives that we can deal with.
; 0 if an error occurs.
;
;--
public _InitializeDiskList
_InitializeDiskList proc far
push ds
push si
;
; See if we're initialized yet by counting items in the DiskList
; linked list. If 0, then assume not initialized yet.
;
mov ax,DGROUP
mov ds,ax
mov si,OFFSET DGROUP:DiskList
mov ax,0
idl1:
.errnz DiskInfoNextl
mov cx,[si].DiskInfoNextl
or cx,[si].DiskInfoNexth
jz idl2
inc ax
lds si,[si].DiskInfoNext
jmp short idl1
idl2:
cmp ax,0
jne idl3
;
; Currently we deal with int13 disks only.
;
push ax ; disk ids start at 0
call InitializeInt13DiskList
add sp,2
idl3:
pop si
pop ds
retf
_InitializeDiskList endp
;++
;
; HDISK
; _far
; OpenDisk(
; IN UINT DiskId
; );
;
; Routine Description:
;
; This routine "opens" a disk so that i/o can be performed to it.
; Housekeeping such as locking, etc, is performed.
; A disk can be opened only once at a time.
;
; Arguments:
;
; DiskId - supplies an ordinal value for the disk to be opened.
; Range is 0 - n-1, where n is the value returned by
; InitializeDiskList().
;
; Return Value:
;
; Handle, or 0 if an error occurs.
;
;--
DiskId equ word ptr [bp+6]
public _OpenDisk
_OpenDisk proc far
push bp
mov bp,sp
push ds
push si
;
; Locate the disk record corresponding to this disk id.
;
mov ax,DiskId
call far ptr pLocateDiskRecord
mov cx,si
or cx,dx
mov ax,0
jz od_done ; dx:ax already 0 for error return
od_gotrec:
;
; Make sure disk is not already open
;
cmp [si].DiskInfoDiskOpen,al
jz @f
mov dx,ax ; dx:ax = 0
jnz od_done ; disk already open, error.
@@:
;
; Int13 disks only for now.
;
push ds
push si
call OpenInt13Disk
pop si
pop ds
cmp ax,0
jnz @f
mov dx,ax
jz od_done ; error, dx:ax set for return
@@: inc [si].DiskInfoDiskOpen
mov dx,ds
mov ax,si ; dx:ax = handle for return
od_done:
pop si
pop ds
leave
retf
_OpenDisk endp
;++
;
; VOID
; _far
; CloseDisk(
; IN HDISK DiskHandle
; );
;
; Routine Description:
;
; This routine "closes" a disk previously opened by OpenDisk().
; Housekeeping such as unlocking, etc, is performed.
;
; Arguments:
;
; DiskHandle - supplies the handle of the disk to be closed,
; as previously opened by OpenDisk().
;
; Return Value:
;
; None.
;
;--
DiskHandle equ dword ptr [bp+6]
public _CloseDisk
_CloseDisk proc far
push bp
mov bp,sp
push ds
push si
lds si,DiskHandle
cmp [si].DiskInfoDiskOpen,0
jz cd_done ; not open, nothing to do
;
; Int13 disks only for now
;
push ds
push si
call CloseInt13Disk
pop si
pop ds ; ds:si -> disk record
dec [si].DiskInfoDiskOpen
cd_done:
pop si
pop ds
leave
retf
_CloseDisk endp
;++
;
; BOOL
; _far
; GetDiskInfoByHandle(
; IN HDISK DiskHandle,
; OUT FPBYTE Int13UnitNumber,
; OUT FPBYTE SectorsPerTrack,
; OUT FPUSHORT Heads,
; OUT FPUSHORT Cylinders,
; OUT FPULONG ExtendedSectorCount,
; OUT FPUINT DiskId
; );
;
; BOOL
; _far
; GetDiskInfoById(
; IN UINT DiskId,
; IN UINT Reserved,
; OUT FPBYTE Int13UnitNumber,
; OUT FPBYTE SectorsPerTrack,
; OUT FPUSHORT Heads,
; OUT FPUSHORT Cylinders,
; OUT FPULONG ExtendedSectorCount
; );
;
; Routine Description:
;
; These routines fetch information about a disk.
;
; Arguments:
;
; Return Value:
;
; non-0 - success
; 0 - failure
;
;--
DiskHandle equ dword ptr [bp+6]
DiskId equ word ptr [bp+6]
Int13UnitNumber equ dword ptr [bp+10]
SectorsPerTrack equ dword ptr [bp+14]
Heads equ dword ptr [bp+18]
Cylinders equ dword ptr [bp+22]
ExtendedSecCnt equ dword ptr [bp+26]
pDiskId equ dword ptr [bp+30]
public _GetDiskInfoById
_GetDiskInfoById proc far
push bp
mov bp,sp
push ds
push si
;
; Locate the disk record.
;
mov ax,DiskId
call far ptr pLocateDiskRecord
cmp dx,0
jnz gdi_do_it
cmp si,0
jnz gdi_do_it
mov ax,dx
jz gdi_done
gdi_do_it:
;
; Int13 disks are the only ones supported now so we can
; just call the int13-specific disk info routine.
;
push ExtendedSecCnt
push Cylinders
push Heads
push SectorsPerTrack
push Int13UnitNumber
push ds
push si
call GetInt13DiskInfo
add sp,24
mov ax,1
gdi_done:
pop si
pop ds
leave
retf
_GetDiskInfoById endp
public _GetDiskInfoByHandle
_GetDiskInfoByHandle proc far
push bp
mov bp,sp
push ds
push si
;
; Make sure the disk is open.
;
lds si,DiskHandle
cmp [si].DiskInfoDiskOpen,0
jz @f
;
; Set disk id in caller's variable
;
mov ax,[si].DiskInfoDiskId
lds si,pDiskId
mov [si],ax
lds si,DiskHandle
jmp short gdi_do_it
@@: mov ax,0
jz gdi_done
_GetDiskInfoByHandle endp
;++
;
; BOOL
; _far
; ReadDisk(
; IN HDISK DiskHandle,
; IN ULONG StartSector,
; IN BYTE SectorCount,
; OUT PVOID Buffer
; );
;
; BOOL
; _far
; WriteDisk(
; IN HDISK DiskHandle,
; IN ULONG StartSector,
; IN BYTE SectorCount,
; IN PVOID Buffer
; );
;
; Routine Description:
;
; These routines perform i/o to a disk previously opened with
; OpenDisk().
;
; Arguments:
;
; DiskHandle - supplies the handle of the disk to be read/written,
; as previously opened by OpenDisk().
;
; StartSector - supplies the physical start sector where the read/write
; is to begin.
;
; SectorCount - supplies the number of sectors to be read/written.
;
; Buffer - supplies a buffer for the transfer.
;
; Return Value:
;
; non-0 - success
; 0 - failure
;
;--
DiskHandle equ dword ptr [bp+6]
StartSector equ dword ptr [bp+10]
SectorCount equ word ptr [bp+14]
Buffer equ dword ptr [bp+16]
public _WriteDisk
_WriteDisk label far
mov ax,1
jmp short DiskIo
public _ReadDisk
_ReadDisk label far
mov ax,0
DiskIo proc far
push bp
mov bp,sp
push ds
push si
lds si,DiskHandle
cmp [si].DiskInfoDiskOpen,0
jnz @f
mov ax,0 ; not open, error out
jz rd_done
;
; Int13 disks only for now
;
@@: push ax
push Buffer
push SectorCount
push StartSector ; only care about low byte
push ds
push si
call Int13DiskIo
add sp,16
rd_done:
pop si
pop ds
leave
retf
DiskIo endp
;++
;
; PVOID
; _far
; pLocateDiskRecord(
; IN UINT DiskId
; );
;
; Routine Description:
;
; Internal routine.
;
; This routine locates a disk record in the linked list
; of all disk records as prepared by InitializeDiskList().
;
; Arguments:
;
; DiskId - supplies an ordinal value identifying the disk.
; Valid range is 0 - n-1, where n is the number returned
; from InitializeDiskList().
;
; This parameter is passed in ax, not on the stack.
;
; Return Value:
;
; NULL if record not located.
; Otherwise fills ds:si and dx:si with a far pointer to the
; disk record.
;
;--
pLocateDiskRecord proc far
mov dx,DGROUP
mov ds,dx
mov si,offset DGROUP:[DiskList] ; ds:si = &DiskList
;
; Note that this code depends on the link field in the
; disk record structure being first!
;
.errnz DiskInfoNext
ldr_loop:
lds si,[si].DiskInfoNext
mov dx,ds
cmp dx,0
jz ldr_done ; end of list, we're done
cmp [si].DiskInfoDiskId,ax
jz ldr_done
jmp short ldr_loop
ldr_done:
retf
pLocateDiskRecord endp
end