mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-12-01 18:15:47 +00:00
1408 lines
40 KiB
NASM
1408 lines
40 KiB
NASM
|
TITLE CHKPROC - Procedures called from chkdsk
|
|||
|
|
|||
|
FALSE EQU 0
|
|||
|
TRUE EQU NOT FALSE
|
|||
|
|
|||
|
DRVCHAR EQU ":"
|
|||
|
|
|||
|
INCLUDE DOSSYM.ASM
|
|||
|
|
|||
|
SUBTTL Segments used in load order
|
|||
|
|
|||
|
CODE SEGMENT PUBLIC
|
|||
|
CODE ENDS
|
|||
|
|
|||
|
CONST SEGMENT PUBLIC BYTE
|
|||
|
|
|||
|
EXTRN CLUSBAD:BYTE,BADATT:BYTE,BADSIZM:BYTE
|
|||
|
EXTRN DIRECMES:BYTE,CDDDMES:BYTE,NDOTMES:BYTE
|
|||
|
EXTRN BADTARG1:BYTE,BADTARG2:BYTE,FATALMES:BYTE
|
|||
|
EXTRN STACKMES:BYTE,BADDPBDIR:BYTE,CREATMES:BYTE
|
|||
|
EXTRN FREEBYMES_PRE:BYTE,FREEBYMESF_PRE:BYTE
|
|||
|
EXTRN FREEBYMES_POST:BYTE,FREEBYMESF_POST:BYTE
|
|||
|
EXTRN NULNZ:BYTE,NULDMES:BYTE,BADCLUS:BYTE
|
|||
|
EXTRN NORECDDOT:BYTE,NORECDOT:BYTE,DOTMES:BYTE
|
|||
|
EXTRN BADWRITE_PRE:BYTE,BADCHAIN:BYTE,CROSSMES_PRE:BYTE
|
|||
|
EXTRN BADWRITE_POST:BYTE,CROSSMES_POST:BYTE,INDENT:BYTE
|
|||
|
EXTRN PTRANDIR:BYTE,PTRANDIR2:BYTE,FREEMES:BYTE,FIXMES:BYTE
|
|||
|
|
|||
|
EXTRN NOISY:BYTE,DOFIX:BYTE,DIRBUF:WORD,DOTENT:BYTE,FIXMFLG:BYTE
|
|||
|
EXTRN HAVFIX:BYTE,SECONDPASS:BYTE,LCLUS:WORD,DIRTYFAT:BYTE
|
|||
|
EXTRN NUL:BYTE,ALLFILE:BYTE,PARSTR:BYTE,ERRSUB:WORD,USERDIR:BYTE
|
|||
|
EXTRN HIDCNT:WORD,HIDSIZ:WORD,FILCNT:WORD,FILSIZ:WORD,DIRCHAR:BYTE
|
|||
|
EXTRN DIRCNT:WORD,DIRSIZ:WORD,FRAGMENT:BYTE,HECODE:BYTE
|
|||
|
EXTRN BADSIZ:WORD,ORPHSIZ:WORD,DDOTENT:BYTE,CROSSCNT:WORD
|
|||
|
EXTRN ORPHCNT:WORD,ORPHFCB:BYTE,ORPHEXT:BYTE,ALLDRV:BYTE,DIRCHAR:BYTE
|
|||
|
|
|||
|
CONST ENDS
|
|||
|
|
|||
|
DATA SEGMENT PUBLIC WORD
|
|||
|
|
|||
|
EXTRN THISDPB:DWORD,HARDCH:DWORD,CONTCH:DWORD,USERDEV:BYTE
|
|||
|
EXTRN CSIZE:BYTE,SSIZE:WORD,DSIZE:WORD,MCLUS:WORD,NAMBUF:BYTE
|
|||
|
EXTRN DOTSNOGOOD:BYTE,ZEROTRUNC:BYTE,ISCROSS:BYTE,SRFCBPT:WORD
|
|||
|
EXTRN FATMAP:WORD,SECBUF:WORD,ERRCNT:BYTE,STACKLIM:WORD,FAT:WORD
|
|||
|
|
|||
|
DATA ENDS
|
|||
|
|
|||
|
DG GROUP CODE,CONST,DATA
|
|||
|
|
|||
|
SUBTTL Initialized Data
|
|||
|
PAGE
|
|||
|
|
|||
|
|
|||
|
CODE SEGMENT PUBLIC
|
|||
|
ASSUME CS:DG,DS:DG,ES:DG,SS:DG
|
|||
|
|
|||
|
PUBLIC INT_23,INT_24,FINDCHAIN,DONE,AMDONE,RDONE
|
|||
|
PUBLIC FATAL,DIRPROC,CHKMAP,CHKCROSS,UNPACK
|
|||
|
PUBLIC PRINTTHISEL2,CHECKERR,PRINTCURRDIRERR
|
|||
|
|
|||
|
EXTRN EPRINT:NEAR,DOCRLF:NEAR,PRINT:NEAR
|
|||
|
EXTRN PROMPTYN:NEAR,DOINT26:NEAR,SUBERRP:NEAR
|
|||
|
EXTRN DOTCOMBMES:NEAR,DISP16BITS:NEAR
|
|||
|
EXTRN CHAINREPORT:NEAR,DISPCLUS:NEAR
|
|||
|
EXTRN PRTCHR:NEAR,WDSKERR:NEAR,CHECKFILES:NEAR
|
|||
|
EXTRN FCB_TO_ASCZ:NEAR,FIGREC:NEAR,RDSKERR:NEAR
|
|||
|
|
|||
|
CHKPROC:
|
|||
|
|
|||
|
SUBTTL DIRPROC -- Recursive directory processing
|
|||
|
|
|||
|
; YOU ARE ADVISED NOT TO COPY THE FOLLOWING METHOD!!!
|
|||
|
|
|||
|
DOTDOTHARDWAY:
|
|||
|
LDS DI,[THISDPB]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV [DI.dpb_current_dir],-1 ;Invalidate path
|
|||
|
MOV SI,DI
|
|||
|
ADD SI,dpb_dir_text
|
|||
|
MOV CX,SI
|
|||
|
FINDEND:
|
|||
|
LODSB ;Scan to end of current path
|
|||
|
OR AL,AL
|
|||
|
JNZ FINDEND
|
|||
|
DEC SI ;Point at the NUL
|
|||
|
DELLOOP: ;Delete last element
|
|||
|
CMP SI,CX
|
|||
|
JZ SETROOT
|
|||
|
CMP BYTE PTR [SI],"/"
|
|||
|
JZ SETTERM
|
|||
|
CMP BYTE PTR [SI],"\"
|
|||
|
JZ SETTERM
|
|||
|
DEC SI
|
|||
|
JMP SHORT DELLOOP
|
|||
|
|
|||
|
SETTERM:
|
|||
|
MOV BYTE PTR [SI],0
|
|||
|
SETCURR:
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
MOV DX,OFFSET DG:DOTMES
|
|||
|
MOV AH,CHDIR ;Chdir to altered path
|
|||
|
INT 21H
|
|||
|
RET
|
|||
|
|
|||
|
SETROOT:
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV [DI.dpb_current_dir],0 ;Set Path to Root
|
|||
|
JMP SHORT SETCURR ;The CHDIR will fail, but who cares
|
|||
|
|
|||
|
|
|||
|
;Structures used by DIRPROC
|
|||
|
|
|||
|
SRCHFCB STRUC
|
|||
|
DB 44 DUP (?)
|
|||
|
SRCHFCB ENDS
|
|||
|
SFCBSIZ EQU SIZE SRCHFCB
|
|||
|
THISENT EQU 17H ;Relative entry number of current entry
|
|||
|
|
|||
|
DIRENT STRUC
|
|||
|
DB 7 DUP (?) ;Ext FCB junk
|
|||
|
DB ? ;Drive
|
|||
|
DIRNAM DB 11 DUP (?)
|
|||
|
DIRATT DB ?
|
|||
|
DB 10 DUP (?)
|
|||
|
DIRTIM DW ?
|
|||
|
DIRDAT DW ?
|
|||
|
DIRCLUS DW ?
|
|||
|
DIRESIZ DD ?
|
|||
|
DIRENT ENDS
|
|||
|
ENTSIZ EQU SIZE DIRENT
|
|||
|
|
|||
|
;Attribute bits
|
|||
|
|
|||
|
RDONLY EQU 1
|
|||
|
HIDDN EQU 2
|
|||
|
SYSTM EQU 4
|
|||
|
VOLIDA EQU 8
|
|||
|
ISDIR EQU 10H
|
|||
|
|
|||
|
ASSUME DS:DG
|
|||
|
|
|||
|
NODOT: ;No .
|
|||
|
PUSH AX ;Return from SRCH
|
|||
|
CMP [NOISY],0
|
|||
|
JNZ DOEXTMES1
|
|||
|
CALL SUBERRP
|
|||
|
JMP SHORT MESD1
|
|||
|
DOEXTMES1:
|
|||
|
MOV SI,OFFSET DG:DOTMES
|
|||
|
CALL PRINTCURRDIRERR
|
|||
|
MOV DX,OFFSET DG:NDOTMES
|
|||
|
CALL EPRINT
|
|||
|
MESD1:
|
|||
|
XOR AX,AX
|
|||
|
PUSH BX
|
|||
|
PUSH BP
|
|||
|
CALL GETENT
|
|||
|
POP BP
|
|||
|
PUSH BP
|
|||
|
CMP BYTE PTR [DI],0E5H ;Have place to put .?
|
|||
|
JNZ CANTREC ;Nope
|
|||
|
MOV SI,OFFSET DG:DOTENT
|
|||
|
MOV CX,11
|
|||
|
REP MOVSB ;Name
|
|||
|
PUSH AX
|
|||
|
MOV AL,ISDIR
|
|||
|
STOSB ;Attribute
|
|||
|
ADD DI,10
|
|||
|
XOR AX,AX
|
|||
|
STOSW ;Date = 0
|
|||
|
STOSW ;Time = 0
|
|||
|
MOV AX,[BP+6]
|
|||
|
STOSW ;Alloc #
|
|||
|
XOR AX,AX
|
|||
|
STOSW
|
|||
|
STOSW ;Size
|
|||
|
POP AX
|
|||
|
MOV [HAVFIX],1 ;Have a fix
|
|||
|
CMP [DOFIX],0
|
|||
|
JZ DOTGOON ;No fix if not F
|
|||
|
MOV CX,1
|
|||
|
CALL DOINT26
|
|||
|
JMP SHORT DOTGOON
|
|||
|
|
|||
|
CANTREC:
|
|||
|
INC [DOTSNOGOOD]
|
|||
|
CMP [NOISY],0
|
|||
|
JZ DOTGOON
|
|||
|
MOV DX,OFFSET DG:NORECDOT
|
|||
|
CALL EPRINT
|
|||
|
DOTGOON:
|
|||
|
POP BP
|
|||
|
POP BX
|
|||
|
POP AX
|
|||
|
MOV SI,OFFSET DG:DIRBUF
|
|||
|
JMP CHKDOTDOT ;Go look for ..
|
|||
|
|
|||
|
NODDOT: ;No ..
|
|||
|
PUSH AX ;Return from SRCH
|
|||
|
CMP [NOISY],0
|
|||
|
JNZ DOEXTMES2
|
|||
|
CALL SUBERRP
|
|||
|
JMP SHORT MESD2
|
|||
|
DOEXTMES2:
|
|||
|
MOV SI,OFFSET DG:PARSTR
|
|||
|
CALL PRINTCURRDIRERR
|
|||
|
MOV DX,OFFSET DG:NDOTMES
|
|||
|
CALL EPRINT
|
|||
|
MESD2:
|
|||
|
MOV AX,1
|
|||
|
PUSH BX
|
|||
|
PUSH BP
|
|||
|
CALL GETENT
|
|||
|
POP BP
|
|||
|
PUSH BP
|
|||
|
CMP BYTE PTR [DI],0E5H ;Place to put it?
|
|||
|
JNZ CANTREC2 ;Nope
|
|||
|
MOV SI,OFFSET DG:DDOTENT
|
|||
|
MOV CX,11
|
|||
|
REP MOVSB ;Name
|
|||
|
PUSH AX
|
|||
|
MOV AL,ISDIR
|
|||
|
STOSB ;Attribute
|
|||
|
ADD DI,10
|
|||
|
XOR AX,AX
|
|||
|
STOSW ;Date
|
|||
|
STOSW ;Time
|
|||
|
MOV AX,[BP+4]
|
|||
|
STOSW ;Alloc #
|
|||
|
XOR AX,AX
|
|||
|
STOSW
|
|||
|
STOSW ;Size
|
|||
|
POP AX
|
|||
|
MOV [HAVFIX],1 ;Got a fix
|
|||
|
CMP [DOFIX],0
|
|||
|
JZ NFIX ;No fix if no F, carry clear
|
|||
|
MOV CX,1
|
|||
|
CALL DOINT26
|
|||
|
NFIX:
|
|||
|
POP BP
|
|||
|
POP BX
|
|||
|
POP AX
|
|||
|
MOV SI,OFFSET DG:DIRBUF
|
|||
|
JMP ROOTDIR ;Process files
|
|||
|
|
|||
|
CANTREC2:
|
|||
|
POP BP
|
|||
|
POP BX
|
|||
|
POP AX
|
|||
|
CMP [NOISY],0
|
|||
|
JZ DOTSBAD
|
|||
|
MOV DX,OFFSET DG:NORECDDOT
|
|||
|
CALL EPRINT
|
|||
|
JMP DOTSBAD
|
|||
|
|
|||
|
NULLDIRERR:
|
|||
|
CMP [NOISY],0
|
|||
|
JNZ DOEXTMES3
|
|||
|
CALL SUBERRP
|
|||
|
JMP SHORT DOTSBAD
|
|||
|
DOEXTMES3:
|
|||
|
MOV SI,OFFSET DG:NUL
|
|||
|
CALL PRINTCURRDIRERR
|
|||
|
MOV DX,OFFSET DG:NULDMES
|
|||
|
CALL EPRINT
|
|||
|
DOTSBAD: ;Can't recover
|
|||
|
MOV DX,OFFSET DG:BADTARG2
|
|||
|
CALL EPRINT
|
|||
|
CALL DOTDOTHARDWAY
|
|||
|
INC [DOTSNOGOOD]
|
|||
|
JMP DIRDONE ;Terminate tree walk at this level
|
|||
|
|
|||
|
ROOTDIRJ: JMP ROOTDIR
|
|||
|
|
|||
|
PAGE
|
|||
|
DIRPROC:
|
|||
|
;Recursive tree walker
|
|||
|
;dirproc(self,parent)
|
|||
|
MOV [DOTSNOGOOD],0 ;Init to dots OK
|
|||
|
MOV [ERRSUB],0 ;No subdir errors yet
|
|||
|
PUSH BP ;Save frame pointer
|
|||
|
MOV BP,SP
|
|||
|
SUB SP,SFCBSIZ ;Only local var
|
|||
|
CMP SP,[STACKLIM]
|
|||
|
JA STACKISOK
|
|||
|
MOV BX,OFFSET DG:STACKMES ;Out of stack
|
|||
|
JMP FATAL
|
|||
|
STACKISOK:
|
|||
|
CMP [NOISY],0
|
|||
|
JZ NOPRINT
|
|||
|
CMP [SECONDPASS],0
|
|||
|
JNZ NOPRINT ;Don't do it again on second pass
|
|||
|
MOV DX,OFFSET DG:DIRECMES ;Tell user where we are
|
|||
|
CALL PRINT
|
|||
|
MOV SI,OFFSET DG:NUL
|
|||
|
CALL PRINTCURRDIR
|
|||
|
CALL DOCRLF
|
|||
|
NOPRINT:
|
|||
|
MOV SI,OFFSET DG:ALLFILE
|
|||
|
MOV DI,SP
|
|||
|
PUSH DI
|
|||
|
MOV CX,SFCBSIZ
|
|||
|
REP MOVSB ;Initialize search FCB
|
|||
|
POP DX
|
|||
|
MOV BX,DX ;BX points to SRCH FCB
|
|||
|
MOV AH,DIR_SEARCH_FIRST
|
|||
|
INT 21H
|
|||
|
CMP WORD PTR [BP+6],0 ;Am I the root
|
|||
|
JZ ROOTDIRJ ;Yes, no . or ..
|
|||
|
OR AL,AL
|
|||
|
JZ NONULLDERR
|
|||
|
JMP NULLDIRERR ;Dir is empty!
|
|||
|
NONULLDERR:
|
|||
|
MOV SI,OFFSET DG:DIRBUF + DIRNAM
|
|||
|
MOV DI,OFFSET DG:DOTENT
|
|||
|
MOV CX,11
|
|||
|
REP CMPSB
|
|||
|
JZ DOTOK ;Got a . as first entry
|
|||
|
JMP NODOT ;No .
|
|||
|
DOTOK:
|
|||
|
MOV SI,OFFSET DG:DIRBUF
|
|||
|
MOV AL,[SI.DIRATT]
|
|||
|
TEST AL,ISDIR
|
|||
|
JNZ DATTOK
|
|||
|
PUSH SI ;. not a dir?
|
|||
|
MOV SI,OFFSET DG:DOTMES
|
|||
|
MOV DX,OFFSET DG:BADATT
|
|||
|
CALL DOTCOMBMES
|
|||
|
POP SI
|
|||
|
OR [SI.DIRATT],ISDIR
|
|||
|
CALL FIXENT ;Fix it
|
|||
|
DATTOK:
|
|||
|
MOV AX,[SI.DIRCLUS]
|
|||
|
CMP AX,[BP+6] ;. link = MYSELF?
|
|||
|
JZ DLINKOK
|
|||
|
PUSH SI ;Link messed up
|
|||
|
MOV SI,OFFSET DG:DOTMES
|
|||
|
MOV DX,OFFSET DG:CLUSBAD
|
|||
|
CALL DOTCOMBMES
|
|||
|
POP SI
|
|||
|
MOV AX,[BP+6]
|
|||
|
MOV [SI.DIRCLUS],AX
|
|||
|
CALL FIXENT ;Fix it
|
|||
|
DLINKOK:
|
|||
|
MOV AX,WORD PTR [SI.DIRESIZ]
|
|||
|
OR AX,AX
|
|||
|
JNZ BADDSIZ
|
|||
|
MOV AX,WORD PTR [SI.DIRESIZ+2]
|
|||
|
OR AX,AX
|
|||
|
JZ DSIZOK
|
|||
|
BADDSIZ: ;Size should be zero
|
|||
|
PUSH SI
|
|||
|
MOV SI,OFFSET DG:DOTMES
|
|||
|
MOV DX,OFFSET DG:BADSIZM
|
|||
|
CALL DOTCOMBMES
|
|||
|
POP SI
|
|||
|
XOR AX,AX
|
|||
|
MOV WORD PTR [SI.DIRESIZ],AX
|
|||
|
MOV WORD PTR [SI.DIRESIZ+2],AX
|
|||
|
CALL FIXENT ;Fix it
|
|||
|
DSIZOK: ;Get next (should be ..)
|
|||
|
MOV DX,BX
|
|||
|
MOV AH,DIR_SEARCH_NEXT
|
|||
|
INT 21H
|
|||
|
CHKDOTDOT: ;Come here after . failure
|
|||
|
OR AL,AL
|
|||
|
JZ DOTDOTOK
|
|||
|
NODDOTJ: JMP NODDOT ;No ..
|
|||
|
DOTDOTOK:
|
|||
|
MOV SI,OFFSET DG:DIRBUF + DIRNAM
|
|||
|
MOV DI,OFFSET DG:DDOTENT
|
|||
|
MOV CX,11
|
|||
|
REP CMPSB
|
|||
|
JNZ NODDOTJ ;No ..
|
|||
|
MOV SI,OFFSET DG:DIRBUF
|
|||
|
MOV AL,[SI.DIRATT]
|
|||
|
TEST AL,ISDIR
|
|||
|
JNZ DDATTOK ;.. must be a dir
|
|||
|
PUSH SI
|
|||
|
MOV SI,OFFSET DG:PARSTR
|
|||
|
MOV DX,OFFSET DG:BADATT
|
|||
|
CALL DOTCOMBMES
|
|||
|
POP SI
|
|||
|
OR [SI.DIRATT],ISDIR
|
|||
|
CALL FIXENT ;Fix it
|
|||
|
DDATTOK:
|
|||
|
PUSH SI
|
|||
|
MOV AX,[SI.DIRCLUS]
|
|||
|
CMP AX,[BP+4] ;.. link must be PARENT
|
|||
|
JZ DDLINKOK
|
|||
|
MOV SI,OFFSET DG:PARSTR
|
|||
|
MOV DX,OFFSET DG:CLUSBAD
|
|||
|
CALL DOTCOMBMES
|
|||
|
POP SI
|
|||
|
MOV AX,[BP+4]
|
|||
|
MOV [SI.DIRCLUS],AX
|
|||
|
CALL FIXENT ;Fix it
|
|||
|
DDLINKOK:
|
|||
|
MOV AX,WORD PTR [SI.DIRESIZ]
|
|||
|
OR AX,AX
|
|||
|
JNZ BADDDSIZ
|
|||
|
MOV AX,WORD PTR [SI.DIRESIZ+2]
|
|||
|
OR AX,AX
|
|||
|
JZ DDSIZOK
|
|||
|
BADDDSIZ: ;.. size should be 0
|
|||
|
PUSH SI
|
|||
|
MOV SI,OFFSET DG:PARSTR
|
|||
|
MOV DX,OFFSET DG:BADSIZM
|
|||
|
CALL DOTCOMBMES
|
|||
|
POP SI
|
|||
|
XOR AX,AX
|
|||
|
MOV WORD PTR [SI.DIRESIZ],AX
|
|||
|
MOV WORD PTR [SI.DIRESIZ+2],AX
|
|||
|
CALL FIXENT ;Fix it
|
|||
|
DDSIZOK:
|
|||
|
MOV DX,BX ;Next entry
|
|||
|
MOV AH,DIR_SEARCH_NEXT
|
|||
|
INT 21H
|
|||
|
|
|||
|
ROOTDIR: ;Come here after .. failure also
|
|||
|
OR AL,AL
|
|||
|
JZ MOREDIR ;More to go
|
|||
|
CMP WORD PTR [BP+6],0 ;Am I the root?
|
|||
|
JZ DIRDONE ;Yes, no chdir
|
|||
|
MOV DX,OFFSET DG:PARSTR
|
|||
|
MOV AH,CHDIR ;Chdir to parent (..)
|
|||
|
INT 21H
|
|||
|
JNC DIRDONE ;Worked
|
|||
|
CMP [NOISY],0
|
|||
|
JZ DODDH
|
|||
|
MOV SI,OFFSET DG:NUL
|
|||
|
CALL PRINTCURRDIRERR
|
|||
|
MOV DX,OFFSET DG:CDDDMES
|
|||
|
CALL EPRINT
|
|||
|
DODDH:
|
|||
|
CALL DOTDOTHARDWAY ;Try again
|
|||
|
DIRDONE:
|
|||
|
MOV SP,BP ;Pop local vars
|
|||
|
POP BP ;Restore frame
|
|||
|
RET 4 ;Pop args
|
|||
|
|
|||
|
MOREDIR:
|
|||
|
MOV SI,OFFSET DG:DIRBUF
|
|||
|
TEST [SI.DIRATT],ISDIR
|
|||
|
JNZ NEWDIR ;Is a new directory
|
|||
|
CMP [SECONDPASS],0
|
|||
|
JZ FPROC1 ;First pass
|
|||
|
CALL CROSSLOOK ;Check for cross links
|
|||
|
JMP DDSIZOK ;Next
|
|||
|
FPROC1:
|
|||
|
CMP [NOISY],0
|
|||
|
JZ NOPRINT2
|
|||
|
MOV DX,OFFSET DG:INDENT ;Tell user where we are
|
|||
|
CALL PRINT
|
|||
|
PUSH BX
|
|||
|
MOV BX,SI
|
|||
|
CALL PRINTTHISEL
|
|||
|
CALL DOCRLF
|
|||
|
MOV SI,BX
|
|||
|
POP BX
|
|||
|
NOPRINT2:
|
|||
|
MOV AL,81H ;Head of file
|
|||
|
CALL MARKFAT
|
|||
|
TEST [SI.DIRATT],VOLIDA
|
|||
|
JNZ HIDENFILE ;VOL ID counts as hidden
|
|||
|
TEST [SI.DIRATT],HIDDN
|
|||
|
JZ NORMFILE
|
|||
|
HIDENFILE:
|
|||
|
INC [HIDCNT]
|
|||
|
ADD [HIDSIZ],CX
|
|||
|
JMP DDSIZOK ;Next
|
|||
|
NORMFILE:
|
|||
|
INC [FILCNT]
|
|||
|
ADD [FILSIZ],CX
|
|||
|
JMP DDSIZOK ;Next
|
|||
|
|
|||
|
NEWDIR:
|
|||
|
CMP [SECONDPASS],0
|
|||
|
JZ DPROC1
|
|||
|
CALL CROSSLOOK ;Check for cross links
|
|||
|
JMP SHORT DPROC2
|
|||
|
DPROC1:
|
|||
|
MOV AL,82H ;Head of dir
|
|||
|
CALL MARKFAT
|
|||
|
INC [DIRCNT]
|
|||
|
ADD [DIRSIZ],CX
|
|||
|
CMP [ZEROTRUNC],0
|
|||
|
JZ DPROC2 ;Dir not truncated
|
|||
|
CONVDIR:
|
|||
|
AND [SI.DIRATT],NOT ISDIR ;Turn into file
|
|||
|
CALL FIXENT
|
|||
|
JMP DDSIZOK ;Next
|
|||
|
DPROC2:
|
|||
|
PUSH [ERRSUB]
|
|||
|
PUSH BX ;Save my srch FCB pointer
|
|||
|
PUSH [SI.DIRCLUS] ;MYSELF for next directory
|
|||
|
PUSH [BP+6] ;His PARENT is me
|
|||
|
ADD SI,DIRNAM
|
|||
|
MOV DI,OFFSET DG:NAMBUF
|
|||
|
PUSH DI
|
|||
|
CALL FCB_TO_ASCZ
|
|||
|
POP DX
|
|||
|
MOV AH,CHDIR ;CHDIR to new dir
|
|||
|
INT 21H
|
|||
|
JC CANTTARG ;Barfed
|
|||
|
CALL DIRPROC
|
|||
|
POP BX ;Get my SRCH FCB pointer back
|
|||
|
POP [ERRSUB]
|
|||
|
CMP [DOTSNOGOOD],0
|
|||
|
JNZ ASKCONV
|
|||
|
JMP DDSIZOK ;Next
|
|||
|
|
|||
|
CANTTARG:
|
|||
|
POP AX ;Clean stack
|
|||
|
POP AX
|
|||
|
POP AX
|
|||
|
POP AX
|
|||
|
PUSH DX ;Save pointer to bad DIR
|
|||
|
MOV DX,OFFSET DG:BADTARG1
|
|||
|
CALL EPRINT
|
|||
|
POP SI ;Pointer to bad DIR
|
|||
|
CALL PRINTCURRDIRERR
|
|||
|
MOV DX,OFFSET DG:BADTARG2
|
|||
|
CALL EPRINT
|
|||
|
DDSIZOKJ: JMP DDSIZOK ;Next
|
|||
|
|
|||
|
ASKCONV:
|
|||
|
CMP [SECONDPASS],0
|
|||
|
JNZ DDSIZOKJ ;Leave on second pass
|
|||
|
MOV DX,OFFSET DG:PTRANDIR
|
|||
|
CMP [NOISY],0
|
|||
|
JNZ PRINTTRMES
|
|||
|
MOV DX,OFFSET DG:PTRANDIR2
|
|||
|
PRINTTRMES:
|
|||
|
CALL PROMPTYN ;Ask user what to do
|
|||
|
JNZ DDSIZOKJ ;User say leave alone
|
|||
|
PUSH BP
|
|||
|
PUSH BX
|
|||
|
MOV AX,[BX+THISENT] ;Entry number
|
|||
|
CALL GETENT ;Get the entry
|
|||
|
MOV SI,DI
|
|||
|
MOV DI,OFFSET DG:DIRBUF
|
|||
|
PUSH DI
|
|||
|
ADD DI,DIRNAM
|
|||
|
MOV CX,32
|
|||
|
REP MOVSB ;Transfer entry to DIRBUF
|
|||
|
POP SI
|
|||
|
PUSH SI
|
|||
|
MOV SI,[SI.DIRCLUS] ;First cluster
|
|||
|
CALL GETFILSIZ
|
|||
|
POP SI
|
|||
|
POP BX
|
|||
|
POP BP
|
|||
|
MOV WORD PTR [SI.DIRESIZ],AX ;Fix entry
|
|||
|
MOV WORD PTR [SI.DIRESIZ+2],DX
|
|||
|
JMP CONVDIR
|
|||
|
|
|||
|
SUBTTL FAT Look routines
|
|||
|
PAGE
|
|||
|
CROSSLOOK:
|
|||
|
;Same as MRKFAT only simpler for pass 2
|
|||
|
MOV [SRFCBPT],BX
|
|||
|
MOV BX,SI
|
|||
|
MOV SI,[BX.DIRCLUS]
|
|||
|
CALL CROSSCHK
|
|||
|
JNZ CROSSLINKJ
|
|||
|
CHLP:
|
|||
|
PUSH BX
|
|||
|
CALL UNPACK
|
|||
|
POP BX
|
|||
|
XCHG SI,DI
|
|||
|
CMP SI,0FF8H
|
|||
|
JAE CHAINDONEJ
|
|||
|
CALL CROSSCHK
|
|||
|
JZ CHLP
|
|||
|
CROSSLINKJ: JMP SHORT CROSSLINK
|
|||
|
|
|||
|
CROSSCHK:
|
|||
|
MOV DI,[FATMAP]
|
|||
|
ADD DI,SI
|
|||
|
MOV AH,[DI]
|
|||
|
TEST AH,10H
|
|||
|
RET
|
|||
|
|
|||
|
NOCLUSTERSJ: JMP NOCLUSTERS
|
|||
|
|
|||
|
MARKFAT:
|
|||
|
; Map the file and perform checks
|
|||
|
; SI points to dir entry
|
|||
|
; AL is head mark with app type
|
|||
|
; On return CX is number of clusters
|
|||
|
; BX,SI preserved
|
|||
|
; ZEROTRUNC is non zero if the file was trimmed to zero length
|
|||
|
; ISCROSS is non zero if the file is cross linked
|
|||
|
|
|||
|
MOV [ZEROTRUNC],0 ;Initialize
|
|||
|
MOV [ISCROSS],0
|
|||
|
MOV [SRFCBPT],BX
|
|||
|
MOV BX,SI
|
|||
|
XOR CX,CX
|
|||
|
MOV SI,[BX.DIRCLUS]
|
|||
|
CMP SI,2
|
|||
|
JB NOCLUSTERSJ ;Bad cluster # or nul file (SI = 0)
|
|||
|
CMP SI,[MCLUS]
|
|||
|
JA NOCLUSTERSJ ;Bad cluster #
|
|||
|
PUSH BX
|
|||
|
CALL UNPACK
|
|||
|
POP BX
|
|||
|
JZ NOCLUSTERSJ ;Bad cluster (it is marked free)
|
|||
|
CALL MARKMAP
|
|||
|
JNZ CROSSLINK
|
|||
|
AND AL,7FH ;Turn off head bit
|
|||
|
CHASELOOP:
|
|||
|
PUSH BX
|
|||
|
CALL UNPACK
|
|||
|
POP BX
|
|||
|
INC CX
|
|||
|
XCHG SI,DI
|
|||
|
CMP SI,0FF8H
|
|||
|
JAE CHAINDONE
|
|||
|
CMP SI,2
|
|||
|
JB MRKBAD
|
|||
|
CMP SI,[MCLUS]
|
|||
|
JBE MRKOK
|
|||
|
MRKBAD: ;Bad cluster # in chain
|
|||
|
PUSH CX
|
|||
|
PUSH DI
|
|||
|
CALL PRINTTHISELERR
|
|||
|
MOV DX,OFFSET DG:BADCHAIN
|
|||
|
CALL EPRINT
|
|||
|
POP SI
|
|||
|
MOV DX,0FFFH ;Insert EOF
|
|||
|
PUSH BX
|
|||
|
CALL PACK
|
|||
|
POP BX
|
|||
|
POP CX
|
|||
|
CHAINDONEJ: JMP SHORT CHAINDONE
|
|||
|
|
|||
|
MRKOK:
|
|||
|
CALL MARKMAP
|
|||
|
JZ CHASELOOP
|
|||
|
CROSSLINK: ;File is cross linked
|
|||
|
INC [ISCROSS]
|
|||
|
CMP [SECONDPASS],0
|
|||
|
JZ CHAINDONE ;Crosslinks only on second pass
|
|||
|
PUSH SI ;Cluster number
|
|||
|
CALL PRINTTHISEL
|
|||
|
CALL DOCRLF
|
|||
|
MOV DX,OFFSET DG:CROSSMES_PRE
|
|||
|
CALL PRINT
|
|||
|
POP SI
|
|||
|
PUSH BX
|
|||
|
PUSH CX
|
|||
|
MOV BX,OFFSET DG:CROSSMES_POST
|
|||
|
XOR DI,DI
|
|||
|
CALL DISP16BITS
|
|||
|
POP CX
|
|||
|
POP BX
|
|||
|
CHAINDONE:
|
|||
|
TEST [BX.DIRATT],ISDIR
|
|||
|
JNZ NOSIZE ;Don't size dirs
|
|||
|
CMP [ISCROSS],0
|
|||
|
JNZ NOSIZE ;Don't size cross linked files
|
|||
|
CMP [SECONDPASS],0
|
|||
|
JNZ NOSIZE ;Don't size on pass 2 (CX garbage)
|
|||
|
MOV AL,[CSIZE]
|
|||
|
XOR AH,AH
|
|||
|
MUL [SSIZE]
|
|||
|
PUSH AX ;Size in bytes of one alloc unit
|
|||
|
MUL CX
|
|||
|
MOV DI,DX ;Save allocation size
|
|||
|
MOV SI,AX
|
|||
|
SUB AX,WORD PTR [BX.DIRESIZ]
|
|||
|
SBB DX,WORD PTR [BX.DIRESIZ+2]
|
|||
|
JC BADFSIZ ;Size to big
|
|||
|
OR DX,DX
|
|||
|
JNZ BADFSIZ ;Size to small
|
|||
|
POP DX
|
|||
|
CMP AX,DX
|
|||
|
JB NOSIZE ;Size within one Alloc unit
|
|||
|
PUSH DX ;Size to small
|
|||
|
BADFSIZ:
|
|||
|
POP DX
|
|||
|
PUSH CX ;Save size of file
|
|||
|
MOV WORD PTR [BX.DIRESIZ],SI
|
|||
|
MOV WORD PTR [BX.DIRESIZ+2],DI
|
|||
|
CALL FIXENT2 ;Fix it
|
|||
|
CALL PRINTTHISELERR
|
|||
|
MOV DX,OFFSET DG:BADCLUS
|
|||
|
CALL EPRINT
|
|||
|
POP CX ;Restore size of file
|
|||
|
NOSIZE:
|
|||
|
MOV SI,BX
|
|||
|
MOV BX,[SRFCBPT]
|
|||
|
RET
|
|||
|
|
|||
|
NOCLUSTERS:
|
|||
|
;File is zero length
|
|||
|
OR SI,SI
|
|||
|
JZ CHKSIZ ;Firclus is OK, Check size
|
|||
|
MOV DX,OFFSET DG:NULNZ
|
|||
|
ADJUST:
|
|||
|
PUSH DX
|
|||
|
CALL PRINTTHISELERR
|
|||
|
POP DX
|
|||
|
CALL EPRINT
|
|||
|
XOR SI,SI
|
|||
|
MOV [BX.DIRCLUS],SI ;Set it to 0
|
|||
|
MOV WORD PTR [BX.DIRESIZ],SI ;Set size too
|
|||
|
MOV WORD PTR [BX.DIRESIZ+2],SI
|
|||
|
CALL FIXENT2 ;Fix it
|
|||
|
INC [ZEROTRUNC] ;Indicate truncation
|
|||
|
JMP CHAINDONE
|
|||
|
|
|||
|
CHKSIZ:
|
|||
|
MOV DX,OFFSET DG:BADCLUS
|
|||
|
CMP WORD PTR [BX.DIRESIZ],0
|
|||
|
JNZ ADJUST ;Size wrong
|
|||
|
CMP WORD PTR [BX.DIRESIZ+2],0
|
|||
|
JNZ ADJUST ;Size wrong
|
|||
|
JMP CHAINDONE ;Size OK
|
|||
|
|
|||
|
UNPACK:
|
|||
|
;Cluster number in SI, Return contents in DI, BX destroyed
|
|||
|
;ZERO SET IF CLUSTER IS FREE
|
|||
|
MOV BX,OFFSET DG:FAT
|
|||
|
MOV DI,SI
|
|||
|
SHR DI,1
|
|||
|
ADD DI,SI
|
|||
|
MOV DI,WORD PTR [DI+BX]
|
|||
|
TEST SI,1
|
|||
|
JZ HAVCLUS
|
|||
|
SHR DI,1
|
|||
|
SHR DI,1
|
|||
|
SHR DI,1
|
|||
|
SHR DI,1
|
|||
|
HAVCLUS:
|
|||
|
AND DI,0FFFH
|
|||
|
RET
|
|||
|
|
|||
|
PACK:
|
|||
|
; SI CLUSTER NUMBER TO BE PACKED
|
|||
|
; DX DATA TO BE PLACED IN CLUSTER (SI)
|
|||
|
; BX,DX DESTROYED
|
|||
|
MOV [DIRTYFAT],1 ;Set FAT dirty byte
|
|||
|
MOV [HAVFIX],1 ;Indicate a fix
|
|||
|
MOV BX,OFFSET DG:FAT
|
|||
|
PUSH SI
|
|||
|
MOV DI,SI
|
|||
|
SHR SI,1
|
|||
|
ADD SI,BX
|
|||
|
ADD SI,DI
|
|||
|
SHR DI,1
|
|||
|
MOV DI,[SI]
|
|||
|
JNC ALIGNED
|
|||
|
SHL DX,1
|
|||
|
SHL DX,1
|
|||
|
SHL DX,1
|
|||
|
SHL DX,1
|
|||
|
AND DI,0FH
|
|||
|
JMP SHORT PACKIN
|
|||
|
ALIGNED:
|
|||
|
AND DI,0F000H
|
|||
|
PACKIN:
|
|||
|
OR DI,DX
|
|||
|
MOV [SI],DI
|
|||
|
POP SI
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
|
|||
|
MARKMAP:
|
|||
|
; Mark in AL
|
|||
|
; Cluster in SI
|
|||
|
; AL,SI,CX preserved
|
|||
|
; ZERO RESET IF CROSSLINK, AH IS THE MARK THAT WAS THERE
|
|||
|
MOV DI,[FATMAP]
|
|||
|
ADD DI,SI
|
|||
|
MOV AH,[DI]
|
|||
|
OR AH,AH
|
|||
|
PUSH AX
|
|||
|
JZ SETMARK
|
|||
|
MOV AL,AH
|
|||
|
INC [CROSSCNT] ;Count the crosslink
|
|||
|
OR AL,10H ;Resets zero
|
|||
|
SETMARK:
|
|||
|
MOV [DI],AL
|
|||
|
POP AX
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
CHKMAP:
|
|||
|
;Compare FAT and FATMAP looking for badsectors orphans
|
|||
|
MOV SI,[FATMAP]
|
|||
|
INC SI
|
|||
|
INC SI
|
|||
|
MOV DX,2
|
|||
|
MOV CX,[DSIZE]
|
|||
|
CHKMAPLP:
|
|||
|
LODSB
|
|||
|
OR AL,AL
|
|||
|
JNZ CONTLP ;Already seen this one
|
|||
|
XCHG SI,DX
|
|||
|
CALL UNPACK
|
|||
|
XCHG SI,DX
|
|||
|
JZ CONTLP ;Free cluster
|
|||
|
CMP DI,0FF7H ;Bad sector?
|
|||
|
JNZ ORPHAN ;No, found an orphan
|
|||
|
INC [BADSIZ]
|
|||
|
MOV BYTE PTR [SI-1],4 ;Flag it
|
|||
|
JMP CONTLP
|
|||
|
ORPHAN:
|
|||
|
INC [ORPHSIZ]
|
|||
|
MOV BYTE PTR [SI-1],8 ;Flag it
|
|||
|
CONTLP:
|
|||
|
INC DX ;Next cluster
|
|||
|
LOOP CHKMAPLP
|
|||
|
MOV SI,[ORPHSIZ]
|
|||
|
OR SI,SI
|
|||
|
JZ RET18 ;No orphans
|
|||
|
CALL RECOVER
|
|||
|
RET18: RET
|
|||
|
|
|||
|
RECOVER:
|
|||
|
;free orphans or do chain recovery
|
|||
|
CALL CHECKNOFMES
|
|||
|
CALL DOCRLF
|
|||
|
CALL CHAINREPORT
|
|||
|
MOV DX,OFFSET DG:FREEMES
|
|||
|
CALL PROMPTYN ;Ask user
|
|||
|
JNZ NOCHAINREC
|
|||
|
JMP CHAINREC
|
|||
|
NOCHAINREC:
|
|||
|
MOV SI,[FATMAP] ;Free all orphans
|
|||
|
INC SI
|
|||
|
INC SI
|
|||
|
MOV DX,2
|
|||
|
MOV CX,[DSIZE]
|
|||
|
CHKMAPLP2:
|
|||
|
LODSB
|
|||
|
TEST AL,8
|
|||
|
JZ NEXTCLUS
|
|||
|
XCHG SI,DX
|
|||
|
PUSH DX
|
|||
|
XOR DX,DX
|
|||
|
CALL PACK ;Mark as free
|
|||
|
POP DX
|
|||
|
XCHG SI,DX
|
|||
|
NEXTCLUS:
|
|||
|
INC DX
|
|||
|
LOOP CHKMAPLP2
|
|||
|
XOR AX,AX
|
|||
|
XCHG AX,[ORPHSIZ]
|
|||
|
PUSH AX
|
|||
|
MOV DX,OFFSET DG:FREEBYMESF_PRE
|
|||
|
CMP [DOFIX],0
|
|||
|
JNZ PRINTFMES
|
|||
|
MOV DX,OFFSET DG:FREEBYMES_PRE
|
|||
|
PRINTFMES:
|
|||
|
CALL PRINT
|
|||
|
POP AX
|
|||
|
MOV BX,OFFSET DG:FREEBYMESF_POST
|
|||
|
CMP [DOFIX],0
|
|||
|
JNZ DISPFRB
|
|||
|
MOV BX,OFFSET DG:FREEBYMES_POST
|
|||
|
MOV [LCLUS],AX
|
|||
|
DISPFRB:
|
|||
|
CALL DISPCLUS ;Tell how much freed
|
|||
|
RET
|
|||
|
|
|||
|
FINDCHAIN:
|
|||
|
;Do chain recovery on orphans
|
|||
|
MOV SI,[FATMAP]
|
|||
|
INC SI
|
|||
|
INC SI
|
|||
|
MOV DX,2
|
|||
|
MOV CX,[DSIZE]
|
|||
|
CHKMAPLP3:
|
|||
|
LODSB
|
|||
|
TEST AL,8 ;Orphan?
|
|||
|
JZ NEXTCLUS2 ;Nope
|
|||
|
TEST AL,1 ;Seen before ?
|
|||
|
JNZ NEXTCLUS2 ;Yup
|
|||
|
PUSH SI ;Save search environment
|
|||
|
PUSH CX
|
|||
|
PUSH DX
|
|||
|
DEC SI
|
|||
|
OR BYTE PTR [SI],81H ;Mark as seen and head
|
|||
|
INC [ORPHCNT] ;Found a chain
|
|||
|
MOV SI,DX
|
|||
|
CHAINLP:
|
|||
|
CALL UNPACK
|
|||
|
XCHG SI,DI
|
|||
|
CMP SI,0FF8H
|
|||
|
JAE CHGOON ;EOF
|
|||
|
PUSH DI
|
|||
|
CMP SI,2
|
|||
|
JB INSERTEOF ;Bad cluster number
|
|||
|
CMP SI,[MCLUS]
|
|||
|
JA INSERTEOF ;Bad cluster number
|
|||
|
CMP SI,DI
|
|||
|
JZ INSERTEOF ;Tight loop
|
|||
|
CALL CROSSCHK
|
|||
|
TEST AH,8 ;Points to a non-orphan?
|
|||
|
JNZ CHKCHHEAD ;Nope
|
|||
|
INSERTEOF:
|
|||
|
POP SI ;Need to stick EOF here
|
|||
|
MOV DX,0FFFH
|
|||
|
CALL PACK
|
|||
|
JMP SHORT CHGOON
|
|||
|
CHKCHHEAD:
|
|||
|
TEST AH,80H ;Previosly marked head?
|
|||
|
JZ ADDCHAIN ;Nope
|
|||
|
AND BYTE PTR [DI],NOT 80H ;Turn off head bit
|
|||
|
DEC [ORPHCNT] ;Wasn't really a head
|
|||
|
POP DI ;Clean stack
|
|||
|
JMP SHORT CHGOON
|
|||
|
ADDCHAIN:
|
|||
|
TEST AH,1 ;Previosly seen?
|
|||
|
JNZ INSERTEOF ;Yup, don't make a cross link
|
|||
|
OR BYTE PTR [DI],1 ;Mark as seen
|
|||
|
POP DI ;Clean stack
|
|||
|
JMP CHAINLP ;Follow chain
|
|||
|
|
|||
|
CHGOON:
|
|||
|
POP DX ;Restore search
|
|||
|
POP CX
|
|||
|
POP SI
|
|||
|
NEXTCLUS2:
|
|||
|
INC DX
|
|||
|
LOOP CHKMAPLP3
|
|||
|
RET
|
|||
|
|
|||
|
CHAINREC:
|
|||
|
LDS DI,[THISDPB]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV CX,[DI.dpb_root_entries]
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
MOV SI,[FATMAP]
|
|||
|
INC SI
|
|||
|
INC SI
|
|||
|
MOV DI,1
|
|||
|
CALL NEXTORPH
|
|||
|
PUSH SI
|
|||
|
PUSH DI
|
|||
|
MOV SI,DI
|
|||
|
XOR AX,AX
|
|||
|
MOV DX,[ORPHCNT]
|
|||
|
MAKFILLP:
|
|||
|
PUSH AX
|
|||
|
PUSH CX
|
|||
|
PUSH DX
|
|||
|
PUSH SI
|
|||
|
CALL GETENT
|
|||
|
POP SI
|
|||
|
CMP BYTE PTR [DI],0E5H
|
|||
|
JZ GOTENT
|
|||
|
CMP BYTE PTR [DI],0
|
|||
|
JNZ NEXTENT
|
|||
|
GOTENT:
|
|||
|
MOV [HAVFIX],1 ;Making a fix
|
|||
|
CMP [DOFIX],0
|
|||
|
JZ ENTMADE ;Not supposed to, carry clear
|
|||
|
MOV [DI+26],SI ;FIRCLUS Pointer
|
|||
|
PUSH AX ;Save INT 26 data
|
|||
|
PUSH DX
|
|||
|
PUSH BX
|
|||
|
MOV AH,DISK_RESET ;Force current state
|
|||
|
INT 21H
|
|||
|
MOV DX,OFFSET DG:ORPHFCB
|
|||
|
MOV AH,FCB_OPEN
|
|||
|
OPAGAIN:
|
|||
|
INT 21H
|
|||
|
OR AL,AL
|
|||
|
JNZ GOTORPHNAM
|
|||
|
CALL MAKORPHNAM ;Try next name
|
|||
|
JMP SHORT OPAGAIN
|
|||
|
|
|||
|
GOTORPHNAM:
|
|||
|
MOV SI,OFFSET DG:ORPHFCB + 1 ;ORPHFCB Now has good name
|
|||
|
MOV CX,11
|
|||
|
REP MOVSB
|
|||
|
CALL MAKORPHNAM ;Make next name
|
|||
|
XOR AX,AX
|
|||
|
MOV CX,15
|
|||
|
REP STOSB
|
|||
|
MOV SI,[DI]
|
|||
|
INC DI ;Skip FIRCLUS
|
|||
|
INC DI
|
|||
|
PUSH DI
|
|||
|
CALL GETFILSIZ
|
|||
|
POP DI
|
|||
|
STOSW
|
|||
|
MOV AX,DX
|
|||
|
STOSW
|
|||
|
POP BX
|
|||
|
POP DX
|
|||
|
POP AX
|
|||
|
MOV CX,1
|
|||
|
CALL DOINT26
|
|||
|
ENTMADE:
|
|||
|
POP DX
|
|||
|
POP CX
|
|||
|
POP AX
|
|||
|
POP DI
|
|||
|
POP SI
|
|||
|
DEC DX
|
|||
|
OR DX,DX
|
|||
|
JZ RET100
|
|||
|
CALL NEXTORPH
|
|||
|
PUSH SI
|
|||
|
PUSH DI
|
|||
|
MOV SI,DI
|
|||
|
JMP SHORT NXTORP
|
|||
|
|
|||
|
NEXTENT:
|
|||
|
POP DX
|
|||
|
POP CX
|
|||
|
POP AX
|
|||
|
NXTORP:
|
|||
|
INC AX
|
|||
|
LOOP MAKFILLPJ
|
|||
|
POP AX ;Clean Stack
|
|||
|
POP AX
|
|||
|
SUB [ORPHCNT],DX ;Couldn't make them all
|
|||
|
MOV DX,OFFSET DG:CREATMES
|
|||
|
CALL EPRINT
|
|||
|
RET100: RET
|
|||
|
|
|||
|
MAKFILLPJ: JMP MAKFILLP
|
|||
|
|
|||
|
NEXTORPH:
|
|||
|
PUSH AX
|
|||
|
LODSB
|
|||
|
INC DI
|
|||
|
CMP AL,89H
|
|||
|
POP AX
|
|||
|
JZ RET100
|
|||
|
JMP SHORT NEXTORPH
|
|||
|
|
|||
|
MAKORPHNAM:
|
|||
|
PUSH SI
|
|||
|
MOV SI,OFFSET DG:ORPHEXT - 1
|
|||
|
NAM0:
|
|||
|
INC BYTE PTR [SI]
|
|||
|
CMP BYTE PTR [SI],'9'
|
|||
|
JLE NAMMADE
|
|||
|
MOV BYTE PTR [SI],'0'
|
|||
|
DEC SI
|
|||
|
JMP NAM0
|
|||
|
|
|||
|
NAMMADE:
|
|||
|
POP SI
|
|||
|
RET
|
|||
|
|
|||
|
GETFILSIZ:
|
|||
|
;SI is start cluster, returns filesize as DX:AX
|
|||
|
XOR AX,AX
|
|||
|
NCLUS:
|
|||
|
CALL UNPACK
|
|||
|
XCHG SI,DI
|
|||
|
INC AX
|
|||
|
CMP SI,0FF8H
|
|||
|
JAE GOTEOF
|
|||
|
CMP SI,2
|
|||
|
JAE NCLUS
|
|||
|
GOTEOF:
|
|||
|
MOV BL,[CSIZE]
|
|||
|
XOR BH,BH
|
|||
|
MUL BX
|
|||
|
MUL [SSIZE]
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CHKCROSS:
|
|||
|
;Check for Crosslinks, do second pass if any to find pairs
|
|||
|
MOV SI,[CROSSCNT]
|
|||
|
OR SI,SI
|
|||
|
JZ RET8 ;None
|
|||
|
CALL DOCRLF
|
|||
|
INC [SECONDPASS]
|
|||
|
XOR AX,AX
|
|||
|
PUSH AX
|
|||
|
PUSH AX
|
|||
|
CALL DIRPROC ;Do it again
|
|||
|
RET8: RET
|
|||
|
|
|||
|
SUBTTL AMDONE - Finish up routine
|
|||
|
PAGE
|
|||
|
AMDONE:
|
|||
|
ASSUME DS:NOTHING
|
|||
|
CMP [DIRTYFAT],0
|
|||
|
JZ NOWRITE ;FAT not dirty
|
|||
|
CMP [DOFIX],0
|
|||
|
JZ NOWRITE ;Not supposed to fix
|
|||
|
REWRITE:
|
|||
|
LDS BX,[THISDPB]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV CL,[BX.dpb_FAT_size] ;Sectors for one fat
|
|||
|
XOR CH,CH
|
|||
|
MOV DI,CX
|
|||
|
MOV CL,[BX.dpb_FAT_count] ;Number of FATs
|
|||
|
MOV DX,[BX.dpb_first_FAT] ;First sector of FAT
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
MOV [ERRCNT],CH
|
|||
|
MOV BX,OFFSET DG:FAT
|
|||
|
MOV AL,[ALLDRV]
|
|||
|
DEC AL
|
|||
|
MOV AH,'1'
|
|||
|
PUSH CX
|
|||
|
WRTLOOP:
|
|||
|
XCHG CX,DI
|
|||
|
PUSH DX
|
|||
|
PUSH CX
|
|||
|
PUSH DI
|
|||
|
PUSH AX
|
|||
|
INT 26H ;Write out the FAT
|
|||
|
MOV [HECODE],AL
|
|||
|
POP AX ;Flags
|
|||
|
JNC WRTOK
|
|||
|
INC [ERRCNT]
|
|||
|
MOV DX,OFFSET DG:BADWRITE_PRE
|
|||
|
CALL PRINT
|
|||
|
POP AX
|
|||
|
PUSH AX
|
|||
|
MOV DL,AH
|
|||
|
CALL PRTCHR
|
|||
|
MOV DX,OFFSET DG:BADWRITE_POST
|
|||
|
CALL PRINT
|
|||
|
WRTOK:
|
|||
|
POP AX
|
|||
|
POP CX
|
|||
|
POP DI
|
|||
|
POP DX
|
|||
|
INC AH
|
|||
|
ADD DX,DI
|
|||
|
LOOP WRTLOOP ;Next FAT
|
|||
|
POP CX ;Number of FATs
|
|||
|
CMP CL,[ERRCNT] ;Error on all?
|
|||
|
JNZ NOWRITE ;no
|
|||
|
CALL WDSKERR
|
|||
|
JZ REWRITE
|
|||
|
NOWRITE:
|
|||
|
MOV AH,DISK_RESET ;Invalidate any buffers in system
|
|||
|
INT 21H
|
|||
|
MOV DX,OFFSET DG:USERDIR ;Recover users directory
|
|||
|
MOV AH,CHDIR
|
|||
|
INT 21H
|
|||
|
CMP BYTE PTR [FRAGMENT],1 ;Check for any fragmented files?
|
|||
|
JNZ DONE ;No -- we're finished
|
|||
|
CALL CHECKFILES ;Yes -- report any fragments
|
|||
|
DONE:
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV DL,[USERDEV] ;Recover users drive
|
|||
|
MOV AH,SET_DEFAULT_DRIVE
|
|||
|
INT 21H
|
|||
|
RET
|
|||
|
|
|||
|
SUBTTL Routines for manipulating dir entries
|
|||
|
PAGE
|
|||
|
FIXENT2:
|
|||
|
;Same as FIXENT only [SRFCBPT] points to the search FCB, BX points to the entry
|
|||
|
PUSH SI
|
|||
|
PUSH BX
|
|||
|
PUSH CX
|
|||
|
MOV SI,BX
|
|||
|
MOV BX,[SRFCBPT]
|
|||
|
CALL FIXENT
|
|||
|
POP CX
|
|||
|
POP BX
|
|||
|
POP SI
|
|||
|
RET20: RET
|
|||
|
|
|||
|
FIXENT:
|
|||
|
;BX Points to search FCB
|
|||
|
;SI Points to Entry to fix
|
|||
|
MOV [HAVFIX],1 ;Indicate a fix
|
|||
|
CMP [DOFIX],0
|
|||
|
JZ RET20 ;But don't do it!
|
|||
|
PUSH BP
|
|||
|
PUSH BX
|
|||
|
PUSH SI
|
|||
|
PUSH SI ;Entry pointer
|
|||
|
MOV AX,[BX+THISENT] ;Entry number
|
|||
|
CALL GETENT
|
|||
|
POP SI ;Entry pointer
|
|||
|
ADD SI,DIRNAM ;Point to start of entry
|
|||
|
MOV CX,32
|
|||
|
REP MOVSB
|
|||
|
INC CL
|
|||
|
CALL DOINT26
|
|||
|
POP SI
|
|||
|
POP BX
|
|||
|
POP BP
|
|||
|
RET
|
|||
|
|
|||
|
GETENT:
|
|||
|
;AX is desired entry number (in current directory)
|
|||
|
;
|
|||
|
;DI points to entry in SECBUF
|
|||
|
;AX DX BX set to do an INT 26 to write it back out (CX must be reset to 1)
|
|||
|
;ALL registers destroyed (via int 25)
|
|||
|
LDS DI,[THISDPB]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV BX,[DI.dpb_current_dir]
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
CMP BX,0FF8H
|
|||
|
JB CLUSISOK
|
|||
|
MOV BX,OFFSET DG:BADDPBDIR ;This should never happen
|
|||
|
JMP FATAL
|
|||
|
CLUSISOK:
|
|||
|
MOV CL,4
|
|||
|
SHL AX,CL
|
|||
|
XOR DX,DX
|
|||
|
SHL AX,1
|
|||
|
RCL DX,1 ;Account for overflow
|
|||
|
MOV CX,[SSIZE]
|
|||
|
AND CL,255-31 ;Must be a multiple of 32
|
|||
|
DIV CX ;DX is position in sector, AX is dir sector #
|
|||
|
OR BX,BX
|
|||
|
JZ WANTROOT
|
|||
|
DIV [CSIZE] ;AL # clusters to skip, AH position in cluster
|
|||
|
MOV CL,AL
|
|||
|
XOR CH,CH
|
|||
|
JCXZ GOTCLUS
|
|||
|
MOV SI,BX
|
|||
|
SKIPLP:
|
|||
|
CALL UNPACK
|
|||
|
XCHG SI,DI
|
|||
|
LOOP SKIPLP
|
|||
|
MOV BX,SI
|
|||
|
GOTCLUS:
|
|||
|
PUSH DX ;Position in sector
|
|||
|
CALL FIGREC ;Convert to sector #
|
|||
|
DOROOTDIR:
|
|||
|
MOV BX,[SECBUF]
|
|||
|
MOV AL,[ALLDRV]
|
|||
|
DEC AL
|
|||
|
RDRETRY:
|
|||
|
PUSH AX
|
|||
|
PUSH DX
|
|||
|
PUSH BX
|
|||
|
MOV CX,1
|
|||
|
INT 25H ;Read it
|
|||
|
MOV [HECODE],AL
|
|||
|
POP AX ;FLAGS
|
|||
|
POP BX
|
|||
|
POP DX
|
|||
|
POP AX
|
|||
|
JNC RDOK2
|
|||
|
CALL RDSKERR
|
|||
|
JZ RDRETRY
|
|||
|
RDOK2:
|
|||
|
POP DI ;Offset into sector
|
|||
|
ADD DI,BX ;Add sector base offset
|
|||
|
RET
|
|||
|
|
|||
|
WANTROOT:
|
|||
|
PUSH DX
|
|||
|
LDS DI,[THISDPB]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV DX,AX
|
|||
|
ADD DX,[DI.dpb_dir_sector]
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
JMP DOROOTDIR
|
|||
|
|
|||
|
CHECKNOFMES:
|
|||
|
MOV AL,1
|
|||
|
XCHG AL,[FIXMFLG]
|
|||
|
OR AL,AL
|
|||
|
JNZ RET14 ;Don't print it more than once
|
|||
|
CMP [DOFIX],0
|
|||
|
JNZ RET14 ;Don't print it if F switch specified
|
|||
|
PUSH DX
|
|||
|
MOV DX,OFFSET DG:FIXMES
|
|||
|
CALL PRINT
|
|||
|
POP DX
|
|||
|
RET
|
|||
|
|
|||
|
CHECKERR:
|
|||
|
CALL CHECKNOFMES
|
|||
|
CMP [SECONDPASS],0
|
|||
|
RET14: RET
|
|||
|
|
|||
|
PRINTCURRDIRERR:
|
|||
|
CALL CHECKERR
|
|||
|
JNZ RET14
|
|||
|
CALL PRINTCURRDIR
|
|||
|
JMP SHORT ERREX
|
|||
|
|
|||
|
PRINTTHISELERR:
|
|||
|
CALL CHECKERR
|
|||
|
JNZ RET14
|
|||
|
CALL PRINTTHISEL
|
|||
|
ERREX:
|
|||
|
CALL DOCRLF
|
|||
|
RET
|
|||
|
|
|||
|
PRINTTHISEL:
|
|||
|
MOV SI,BX
|
|||
|
ADD SI,DIRNAM
|
|||
|
PRINTTHISEL2:
|
|||
|
MOV DI,OFFSET DG:NAMBUF
|
|||
|
PUSH DI
|
|||
|
CALL FCB_TO_ASCZ
|
|||
|
POP SI
|
|||
|
PRINTCURRDIR:
|
|||
|
PUSH SI
|
|||
|
MOV DL,[ALLDRV]
|
|||
|
ADD DL,'@'
|
|||
|
CALL PRTCHR
|
|||
|
MOV DL,DRVCHAR
|
|||
|
CALL PRTCHR
|
|||
|
LDS SI,[THISDPB]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
CMP [SI.dpb_current_dir],0
|
|||
|
JZ CURISROOT
|
|||
|
MOV DL,[DIRCHAR]
|
|||
|
CALL PRTCHR
|
|||
|
ADD SI,dpb_dir_text
|
|||
|
PCURRLP:
|
|||
|
LODSB
|
|||
|
OR AL,AL
|
|||
|
JZ CURISROOT
|
|||
|
MOV DL,AL
|
|||
|
CALL PRTCHR
|
|||
|
JMP PCURRLP
|
|||
|
|
|||
|
CURISROOT:
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
POP SI
|
|||
|
CMP BYTE PTR [SI],0
|
|||
|
JZ LPDONE ;If tail string NUL, no '/'
|
|||
|
MOV DL,[DIRCHAR]
|
|||
|
CALL PRTCHR
|
|||
|
ERRLOOP:
|
|||
|
LODSB
|
|||
|
OR AL,AL
|
|||
|
JZ LPDONE
|
|||
|
MOV DL,AL
|
|||
|
CALL PRTCHR
|
|||
|
JMP ERRLOOP
|
|||
|
LPDONE:
|
|||
|
RET
|
|||
|
|
|||
|
FATAL:
|
|||
|
;Unrecoverable error
|
|||
|
MOV DX,OFFSET DG:FATALMES
|
|||
|
CALL PRINT
|
|||
|
MOV DX,BX
|
|||
|
CALL PRINT
|
|||
|
MOV DL,[USERDEV] ;At least leave on same drive
|
|||
|
MOV AH,SET_DEFAULT_DRIVE
|
|||
|
INT 21H
|
|||
|
INT 20H
|
|||
|
|
|||
|
|
|||
|
INT_24_RETADDR DW OFFSET DG:INT_24_BACK
|
|||
|
|
|||
|
INT_24 PROC FAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
|||
|
PUSHF
|
|||
|
PUSH CS
|
|||
|
PUSH [INT_24_RETADDR]
|
|||
|
PUSH WORD PTR [HARDCH+2]
|
|||
|
PUSH WORD PTR [HARDCH]
|
|||
|
RET
|
|||
|
INT_24 ENDP
|
|||
|
|
|||
|
INT_24_BACK:
|
|||
|
CMP AL,2 ;Abort?
|
|||
|
JNZ IRETI
|
|||
|
CALL DONE ;Forget about directory, restore users drive
|
|||
|
INT 20H
|
|||
|
IRETI:
|
|||
|
IRET
|
|||
|
|
|||
|
INT_23:
|
|||
|
LDS DX,[HARDCH]
|
|||
|
MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
|
|||
|
INT 21H
|
|||
|
LDS DX,[CONTCH]
|
|||
|
MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
|
|||
|
INT 21H
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
MOV [FRAGMENT],0
|
|||
|
RDONE:
|
|||
|
CALL NOWRITE ;Restore users drive and directory
|
|||
|
INT 20H
|
|||
|
|
|||
|
CODE ENDS
|
|||
|
END CHKPROC
|
|||
|
|