Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

217 lines
5.7 KiB

;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1988 - 1991
; * All Rights Reserved.
; */
; Check for existence of a VDisk header. Check the beginning of the segment
; addressed by the INT 19 vector, and, if XMS is available to give us
; A20 toggling, check at the 1Mb boundary. We don't do the latter check
; if we can't do the A20 switch.
;
; Return the size of the VDisk if found.
;
; Checking for a VDISK header at 1Mb is currently disabled. This is because
; the XMS calls used to access the HMA will cause INT 15 memory to
; be claimed if there are currently no Himem or XMS users, and the MEM
; command shouldn't disturb the memory environment in that way.
; We rely on VDisk allocators to use the INT 19 approach to signal
; their memory usage. According to Ray Duncan, this may not be
; entirely reliable, but this is probably better than adding the
; code necessary to do lots of INT 15 block moves to interrogate
; the extended memory arena.
CHECKXMS equ 0 ; set to non-zero to enable checking
; of the HMA for VDisk headers.
.MODEL SMALL
.CODE
extrn _XMM_Installed :Near
extrn _XMM_QueryA20 :Near
extrn _XMM_EnableA20 :Near
extrn _XMM_DisableA20 :Near
;----------------------------------------------------------------------------
;
; following piece of code will be moved into a para boundary. And the para
; address posted in seg of int 19h vector. Offset of int 19h will point to
; VDint19. This is to protect HMA from apps which use VDISK header method
; to determine free extended memory.
;
; For more details read "power programming" column by Ray Duncan in the
; May 30 1989 issue of PC Magazine (pp 377-388) [USING EXTENDED MEMORY,PART 1]
;
;----------------------------------------------------------------------------
;
StartVDHead label byte
;
;-------------- what follows is a dummy device driver header (not used by DOS)
;
dd 0 ; link to next device driver
dw 8000h ; device attribute
dw 0 ; strategy routine offset
dw 0 ; interrupt routine offset
db 1 ; number of units
db 7 dup(0) ; reserved area
VDiskSig1 db 'VDISK'
VLEN1 equ ($-offset VDiskSig1)
db ' V3.3' ; vdisk label
db 15 dup (0) ; pad
VDiskEnd1 dw 0 ; bits 0-15 of free HMA
db 11h ; bits 16-23 of free HMA (1M + 64K)
VDInt19:
db 0eah ; jmp to old vector
OldVDInt19 dd ? ; Saved int 19 vector
EndVDHead label byte
;
;
VDiskHMAHead db 0,0,0 ; non-bootable disk
VDiskSig2 db 'VDISK'
VLEN2 equ ($-offset VDiskSig2)
db '3.3' ; OEM - signature
dw 128 ; number of bytes/sector
db 1 ; sectors/cluster
dw 1 ; reserved sectors
db 1 ; number of FAT copies
dw 64 ; number of root dir entries
dw 512 ; number of sectors
db 0feh ; media descriptor
dw 6 ; number of sectors/FAT
dw 8 ; sectors per track
dw 1 ; number of heads
dw 0 ; number of hodden sectors
VDiskEnd2 dw 440h ; Start of free HMA in K (1M+64K)
EndVDiskHMAHead label byte
;
;
;----------------------------------------------------------------------------
;
; procedure : IsVDiskInstalled
;
; Checks for the presence of VDISK header at 1MB boundary
; & INT 19 vector. Returns number of Kb used as Vdisk
;
; Inputs : none
; Outputs : AX = size of VDisk in Kb, 0 if none found
; Uses : AX, CX
;
;----------------------------------------------------------------------------
;
public _CheckVDisk
_CheckVDisk proc near
push bp
push si ; Save regs
push di
push es
push ds
mov ax,3519h ; Get Int Vector 19h
int 21h
; set registers for CMPS
mov di, offset VDiskSig1 - offset StartVDHead
mov cx, VLEN1
push cs
pop ds
mov si, offset VDiskSig1
rep cmpsb
IF NOT CHECKXMS
jnz cvd_NoDisk
ELSE
jnz cvd_checkXMS ; jump if we didn't find it
ENDIF
;
; Get the first free address in Kb, and determine the number of Kb used
; above 1Mb. First free address in a 24-bit address, so divide by 1024
; to get number of Kb
;
mov di,offset VDiskEnd1 - offset StartVDHead
mov ax,es:[di]+1 ; load top 16 bits of end address
shr ax,1
shr ax,1 ; fast divide of 24 bits by 1024
test es:[di],03FFh ; check for rounding
jz @F
inc ax ; round up if needed
@@:
IF NOT CHECKXMS
jmp short cvd_End
ELSE
pop ds ; clear top of stack
jmp short cvd_End ; AX now has size in Kb
;
; Ensure that A20 is on before we check above 1Mb. If XMS is not
; installed, we punt, and assume no VDisk
;
cvd_checkXMS:
pop ds ; get DS again
call _XMM_Installed
or ax,ax
jz cvd_NoDisk ; No XMS, assume no VDisk
;
; Get and save current A20 state, get A20 on
;
call _XMM_QueryA20
push ax ; save current state
or ax,ax ; already on?
jnz cvd_A20On ; yes, don't turn it on
call _XMM_EnableA20 ; turn it on
cvd_A20On:
push ds ; save DS again
mov ax, 0ffffh
mov ds, ax
mov si, 10h+(offset VDiskSig2 - offset VDiskHMAHead)
mov ax,cs
mov es,ax
mov di, offset VDiskSig2
mov cx, VLEN2
rep cmpsb
jne @F ; if no header, turn off A20 now
; get first free address in Kb
mov si,offset VDiskEnd2 - offset VDiskHMAHead
mov ax,[si]
@@:
pop ds ; get original DS again
pop ax ; get original A20 state
pushf ; save result of header check
or ax,ax ; was A20 already on?
jnz @F ; jump if yes
call _XMM_DisableA20 ; else turn it off again
@@:
popf ; get result of header check
je cvd_End ; jump if present
ENDIF ; CHECKXMS
cvd_NoDisk:
mov ax,1024 ; set up to return 0
cvd_End:
sub ax,1024 ; discount first 1Mb from first
; free address to get size in Kb
IF NOT CHECKXMS
pop ds
ENDIF
pop es
pop di
pop si
pop bp
ret
_CheckVDisk endp
end