1 TITLE CHKPROC2
- PART2 Procedures called
from chkdsk
5 include chkseg
.inc ;an005;bgb
12 CONST
SEGMENT PUBLIC PARA
'DATA'
13 EXTRN FIXMES_ARG
:word ;an049;bgb
15 EXTRN BADW_ARG
:word,FATAL_END
:word
16 EXTRN badrw_num
:word,BADRW_STR
:WORD,HAVFIX
:byte
17 EXTRN DIRTYFAT
:byte,CROSSCNT
:dword,DOFIX
:byte,SECONDPASS
:byte
18 EXTRN BADSIZ
:word,ORPHSIZ
:word,ORPHFCB
:byte
19 EXTRN HECODE
:byte,USERDIR
:byte,FRAGMENT
:byte
20 EXTRN ORPHEXT
:byte,ALLDRV
:byte,FIXMFLG
:byte,DIRCHAR
:byte
21 EXTRN EOFVAL
:word,BADVAL
:word
25 DATA SEGMENT PUBLIC PARA
'DATA'
26 extrn fatcnt
:byte, orph_arg
:word ;an005;bgb;an049;bgb
27 EXTRN THISDPB
:dword,NUL_ARG
:byte
28 EXTRN NAMBUF
:byte,SRFCBPT
:word,FATMAP
:word
29 EXTRN MCLUS
:word,CSIZE
:byte,SSIZE
:word
30 EXTRN DSIZE
:word,ARG_BUF
:byte,ERRCNT
:byte
31 EXTRN USERDEV
:byte,HARDCH
:dword,CONTCH
:dword
32 EXTRN ExitStatus
:Byte,Read_Write_Relative
:Byte
33 extrn bytes_per_sector
:word ;an005;bgb
34 extrn fattbl_seg
:word, fatsiz
:word, paras_per_fat
:word ;an005;bgb
35 extrn fatmsg1
:word ;an024;bgb
36 extrn fatmsg2
:word ;an024;bgb
37 EXTRN dbcs_vector
:byte ;an055;bgb
38 EXTRN dbcs_vector_off
:word ;an055;bgb
39 EXTRN dbcs_vector_seg
:word ;an055;bgb
42 CODE SEGMENT PUBLIC PARA
'CODE'
43 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
44 EXTRN PRINTF_CRLF
:NEAR,FCB_TO_ASCZ
:NEAR
45 EXTRN PROMPTYN
:NEAR,DIRPROC
:NEAR
46 EXTRN DOCRLF
:NEAR,UNPACK
:NEAR,PACK
:NEAR
47 EXTRN CHECKNOFMES
:NEAR
48 EXTRN multiply_32_bits
:near ;an047;bgb
49 extrn nowrite
:near, done
:near, pack
:near, unpack
:near
50 extrn promptrecover
:near, findchain
:near
52 public MAKORPHNAM
, NAM0
, NAMMADE
53 public GETFILSIZ
, NCLUS
, GOTEOF
, CHKCROSS
, RET8
54 public FATAL
, hav_fatal_arg
, INT_23
, RDONE
55 public Systime
;an005;bgb
56 public int_24
;an005;bgb
57 public CHECK_DBCS_CHARACTER
;an055;bgb
63 ;*****************************************************************************
65 ; free orphans or do chain recovery. Note that if we have NOT been able to
66 ; process the entire tree (due to inability to CHDIR), we temporarily set
67 ; DoFix to FALSE, do the operation, and then reset it.
69 ; inputs: si - total number of clusters
70 ; es - points to fatmap
72 ; outputs: orphaned clusters are converted to files
74 ; - display dont fix msg if appropriate
75 ; - display number of lost clusters
76 ; - ask the user if he wants the chains converted to files
77 ;***************************************************************************
82 ; $IF Z ; where there any errors found?
84 cmp [dofix
],0 ; yes - is the /f flag off?
85 ; $IF Z ; yes - display the dont fix msg
87 mov dx,offset dg
:FIXMES_arg
96 ;;;;mov si,orphsiz ;get number of bad clusters found (recover) ;an005;bgb;an049;bgb
97 ;;;;mov [orph_num],si ; Prints "XXX lost clusters found in YYY chains.";an049;bgb
98 call findchain
; On entry SI is the XXX value and the YYY value is
99 mov dx,offset dg
:orph_arg
; in orphan-count.
104 XOR AX,AX ; We have truncated the scan. Set DoFix to FALSE,
105 XCHG AL,DoFix
; do the operation and then restore things.
126 ;*****************************************************************************
127 ;*****************************************************************************
130 MOV SI,OFFSET DG
:ORPHEXT
- 1
133 CMP BYTE PTR [SI],'9'
135 MOV BYTE PTR [SI],'0'
146 ;*****************************************************************************
147 ; GETFILSIZ - calculate the file size based on the number of clusters.
149 ; WARNING!! NOTE!! -->
151 ; called by - PROCEDURE NAME
159 ; SI - conatins the starting cluster number
164 ; output: AX - low word of the file size
167 ; DX - hi word of the file size
177 ;logic: 1. save bx & cx for 32 bit mul
179 ; 2. zero out file size results
181 ; 3. do for all clusters:
183 ; 4. get the next one and inc cluster counter
185 ; 5. multiply clusters times sectors per cluster to give
186 ; number of sectors in file. This can be a 2 word value - DX:AX.
188 ; 6. multiply the sectors times the number of bytes per sector. This
189 ; yields the number of bytes in the file.
190 ;*****************************************************************************
191 ;SI is start cluster, returns filesize as DX:AX
192 Procedure getfilsiz
,near
194 XOR AX,AX ;zero out low word
195 XOR DX,DX ;zero out high word
196 OR SI,SI ;did we get a zero cluster?
199 ; $DO ;do for all clusters
201 NCLUS: CALL UNPACK
;find the next cluster
202 XCHG SI,DI ;put output into input for unpack
203 INC AX ;found another cluster
204 CMP SI,[EOFVAL
] ;did we find last cluster?
205 ; $leave ae ;yes, so exit loop
213 MOV BL,[CSIZE
] ;get sectors per cluster
215 MUL BX ;clusters * secs/cluster = sectors
216 mov bx,dx ;get high num for 32bit mult
217 mov cx,ssize
;cx = word to mult with
218 call multiply_32_bits
;mul bx:ax * cx
219 mov dx,bx ;save high word
228 ;*****************************************************************************
229 ;*****************************************************************************
232 ;Check for Crosslinks, do second pass if any to find pairs
233 MOV SI,word ptr CROSSCNT
234 cmp word ptr crosscnt
,0 ;if there is at least one crossed
237 cmp word ptr crosscnt
+2,0
241 CALL DOCRLF
;display another line
242 MOV SecondPass
,True
; ; ;AC000;
246 CALL DIRPROC
;Do it again
253 ;*****************************************************************************
254 ;*****************************************************************************
257 mov dx,offset dg
:FATAL_arg
258 mov [fatmsg1
],bx ;an024;bgb
259 cmp byte ptr [nul_arg
],0
261 mov [fatmsg2
],offset dg
:fatal_end
264 MOV DL,[USERDEV
] ;At least leave on same drive
265 DOS_Call Set_Default_Drive
; ;AC000;
267 mov ExitStatus
,Bad_Exit
;Get return code ;AC000;
269 ret ;Ret Main_Init for common exit
274 ;*****************************************************************************
275 ;*****************************************************************************
277 aSSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
279 push ax ;Save AX register ;AN000;
280 test al,Disk_Error
;Is it a disk critical err?
283 mov ax,di ;Get error (DI low) ;AN000;
284 cmp al,Write_Protect
;Special case errors ;AN000;
285 ; $IF E,OR ;If write protect or ;AN000;
287 cmp al,Drive_Not_Ready
; if drive not ready ;AN000;
288 pop ax ;Balance stack again ;AN000;
292 CALL dword ptr HardCh
; let parent's handler decide what to do
293 ; $ELSE ;Other error ;AN000;
296 pop ax ;balance stack ;AN000;
297 mov al,Critical_Error_Fail
;Fail the operation ;AN000;
300 ; $ELSE ;Not disk error
303 CALL dword ptr HardCh
; let parent's handler decide what to do
306 CMP AL,2 ;Abort? ;AC000;
309 STI ;Turn off Interrupts
310 CALL DONE
;Forget about directory, restore users drive
311 mov ExitStatus
,Bad_Exit
;Get return code ;AN000;
320 ;*****************************************************************************
321 ;*****************************************************************************
326 DOS_Call Set_Interrupt_Vector
; ;AC000;
327 LDS DX,cs:[CONTCH
] ;ac039;bgb
329 DOS_Call Set_Interrupt_Vector
; ;AC000;
335 CALL NOWRITE
;Restore users drive and directory
339 mov ExitStatus
,Bad_Exit
;Get return code ;AC000;
341 ret ;Ret for common exit ;AN000;
348 ;*****************************************************************************
349 ;*****************************************************************************
351 ; Systime returns the current date in AX, current time in DX
352 ; AX - HHHHHMMMMMMSSSSS hours minutes seconds/2
353 ; DX - YYYYYYYMMMMDDDDD years months days
357 DOS_Call Get_Time
; ;AC000;
358 SHL CL,1 ;Minutes to left part of byte
360 SHL CX,1 ;Push hours and minutes to left end
363 SHR DH,1 ;Count every two seconds
364 OR CL,DH ;Combine seconds with hours and minutes
368 ; WARNING! MONTH and YEAR must be adjacently allocated
370 DOS_Call Get_Date
; ;AC000;
374 SHL AL, CL ; Push year to left for month
375 OR AL, DH ; move in month
377 SHL AX,CL ;Push month to left to make room for day
380 POP DX ; Restore time
381 XCHG AX, DX ; Switch time and day
385 ;***************************************************************************** ;an055;bgb
386 ;Routine name: Check_DBCS_CharACter ;an055;bgb
387 ;***************************************************************************** ;an055;bgb
389 ;Description: Check if specified byte is in rANges of DBCS vectors ;an055;bgb
391 ;Called Procedures: None ;an055;bgb
393 ;ChANge History: Created 6/12/87 MT ;an055;bgb
395 ;Input: AL = CharACter to check for DBCS lead charACter ;an055;bgb
396 ; DBCS_Vector = YES/NO ;an055;bgb
398 ;Output: CY set if DBCS charACter ;an055;bgb
399 ; DBCS_VECTOR = YES ;an055;bgb
402 ;Psuedocode ;an055;bgb
403 ;---------- ;an055;bgb
404 ; Save registers ;an055;bgb
405 ; IF DBCS vector not found ;an055;bgb
406 ; Get DBCS environmental vector (INT 21h ;an055;bgb
407 ; Point at first set of vectors ;an055;bgb
410 ; LEAVE End of DBCS vectors ;an055;bgb
411 ; EXITIF CharACter > X1,AND (X1,Y1) are environment vectors ;an055;bgb
412 ; EXITIF CharACter < Y1 ;an055;bgb
413 ; STC (DBCS charACter) ;an055;bgb
415 ; Inc pointer to next set of vectors ;an055;bgb
417 ; CLC (Not DBCS charACter) ;an055;bgb
419 ; Restore registers ;an055;bgb
421 ;***************************************************************************** ;an055;bgb
422 DBCS_Vector_Size equ
2 ;an055;bgb
423 end_of_vector equ
0 ;an055;bgb
424 Procedure Check_DBCS_Character
; ;an055;bgb
425 push ds ;Save registers ;an055;bgb
426 push si ; " " " " ;an055;bgb
427 push ax ; " " " " ;an055;bgb
428 ;;;;;;;;push ds ; " " " " ;an055;bgb
429 ;;;;;;;;pop es ;Establish addressability ;an055;bgb
430 cmp byte ptr es:DBCS_VECTOR
,Yes
;Have we set this yet? ;an055;bgb
431 ; $IF NE ;Nope ;an055;bgb
433 push ax ;Save input charACter ;an055;bgb
434 mov al,0 ;Get DBCS environment vectors ;an055;bgb
435 DOS_Call Hongeul
; " " " " ;an055;bgb
436 mov byte ptr es:DBCS_VECTOR
,YES
;Indicate we've got vector ;an055;bgb
437 mov es:DBCS_Vector_Off
,si ;Save the vector ;an055;bgb
438 mov ax,ds ; ;an055;bgb
439 mov es:DBCS_Vector_Seg
,ax ; ;an055;bgb
440 pop ax ;Restore input charACter ;an055;bgb
441 ; $ENDIF ; for next time in ;an055;bgb
443 mov si,es:DBCS_Vector_Seg
;Get saved vector pointer ;an055;bgb
444 mov ds,si ; ;an055;bgb
445 mov si,es:DBCS_Vector_Off
; ;an055;bgb
446 ; $SEARCH ;Check all the vectors ;an055;bgb
448 cmp word ptr ds:[si],End_Of_Vector
;End of vector table? ;an055;bgb
449 ; $LEAVE E ;Yes, done ;an055;bgb
451 cmp al,ds:[si] ;See if char is in vector ;an055;bgb
452 ; $EXITIF AE,AND ;If >= to lower, ANd ;an055;bgb
454 cmp al,ds:[si+1] ; =< thAN higher rANge ;an055;bgb
455 ; $EXITIF BE ; then DBCS charACter ;an055;bgb
457 stc ;Set CY to indicate DBCS ;an055;bgb
458 ; $ORELSE ;Not in rANge, check next ;an055;bgb
461 add si,DBCS_Vector_Size
;Get next DBCS vector ;an055;bgb
462 ; $ENDLOOP ;We didn't find DBCS char ;an055;bgb
465 clc ;Clear CY for exit ;an055;bgb
466 ; $ENDSRCH ; ;an055;bgb
468 pop ax ;Restore registers ;an055;bgb
469 pop si ; " " " " ;an055;bgb
470 pop ds ;Restore data segment ;an055;bgb
472 Check_DBCS_CharACter endp
; ;an055;bgb