summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/CHKDSK/CHKPROC2.ASM
blob: 8a3bde8c47cfdc100cba07ab19ad219494b5abdc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
TITLE	CHKPROC2 - PART2 Procedures called from chkdsk
page	,132					;

	.xlist
	include chkseg.inc							;an005;bgb
	INCLUDE CHKCHNG.INC
	INCLUDE DOSSYM.INC
	INCLUDE CHKEQU.INC
	INCLUDE CHKMACRO.INC
	include pathmac.inc

CONST	SEGMENT PUBLIC PARA  'DATA'
	EXTRN	FIXMES_ARG:word 						;an049;bgb
	EXTRN	FATAL_ARG:word
	EXTRN	BADW_ARG:word,FATAL_END:word
	EXTRN	badrw_num:word,BADRW_STR:WORD,HAVFIX:byte
	EXTRN	DIRTYFAT:byte,CROSSCNT:dword,DOFIX:byte,SECONDPASS:byte
	EXTRN	BADSIZ:word,ORPHSIZ:word,ORPHFCB:byte
	EXTRN	HECODE:byte,USERDIR:byte,FRAGMENT:byte
	EXTRN	ORPHEXT:byte,ALLDRV:byte,FIXMFLG:byte,DIRCHAR:byte
	EXTRN	EOFVAL:word,BADVAL:word
	extrn	fTrunc:BYTE
CONST	ENDS

DATA	SEGMENT PUBLIC PARA 'DATA'
	extrn	fatcnt:byte, orph_arg:word			  ;an005;bgb;an049;bgb
	EXTRN	THISDPB:dword,NUL_ARG:byte
	EXTRN	NAMBUF:byte,SRFCBPT:word,FATMAP:word
	EXTRN	MCLUS:word,CSIZE:byte,SSIZE:word
	EXTRN	DSIZE:word,ARG_BUF:byte,ERRCNT:byte
	EXTRN	USERDEV:byte,HARDCH:dword,CONTCH:dword
	EXTRN	ExitStatus:Byte,Read_Write_Relative:Byte
	extrn	bytes_per_sector:word						;an005;bgb
	extrn	fattbl_seg:word, fatsiz:word,  paras_per_fat:word		;an005;bgb
	extrn	fatmsg1:word							;an024;bgb
	extrn	fatmsg2:word							;an024;bgb
	EXTRN	dbcs_vector:byte						;an055;bgb
	EXTRN	dbcs_vector_off:word						;an055;bgb
	EXTRN	dbcs_vector_seg:word						;an055;bgb
DATA	ENDS

CODE	SEGMENT PUBLIC PARA 'CODE'
ASSUME	CS:DG,DS:DG,ES:DG,SS:DG
	EXTRN	PRINTF_CRLF:NEAR,FCB_TO_ASCZ:NEAR
	EXTRN	PROMPTYN:NEAR,DIRPROC:NEAR
	EXTRN	DOCRLF:NEAR,UNPACK:NEAR,PACK:NEAR
	EXTRN	CHECKNOFMES:NEAR
	EXTRN	multiply_32_bits:near					     ;an047;bgb
	extrn	nowrite:near, done:near, pack:near, unpack:near
	extrn	promptrecover:near, findchain:near
public RECOVER, DoAsk
public MAKORPHNAM, NAM0, NAMMADE
public GETFILSIZ, NCLUS, GOTEOF, CHKCROSS, RET8
public FATAL, hav_fatal_arg,  INT_23, RDONE
public Systime									;an005;bgb
public int_24									;an005;bgb
public CHECK_DBCS_CHARACTER							;an055;bgb
	.list



	pathlabl chkproc2
;*****************************************************************************
; RECOVER -
; free orphans or do chain recovery.  Note that if we have NOT been able to
; process the entire tree (due to inability to CHDIR), we temporarily set
; DoFix to FALSE, do the operation, and then reset it.
;
; inputs:   si - total number of clusters
;	    es - points to fatmap
;
; outputs:  orphaned clusters are converted to files
; LOGIC
;	- display dont fix msg if appropriate
;	- display number of lost clusters
;	- ask the user if he wants the chains converted to files
;***************************************************************************
RECOVER:
    mov     al,1
    xchg    al,[fixmflg]
    or	    al,al
;   $IF     Z				; where there any errors found?
    JNZ $$IF1
	cmp	[dofix],0		; yes - is the /f flag off?
;	$IF	Z			; yes - display the dont fix msg
	JNZ $$IF2
	    mov     dx,offset dg:FIXMES_arg
	    CALL    PRINTf_crlf
	    call    DoCRLF			    ;				    ;AN000;
;	$ENDIF
$$IF2:
;   $ENDIF
$$IF1:
    CALL    DOCRLF
CHAINREPORT:
;;;;mov     si,orphsiz		   ;get number of bad clusters found (recover)	;an005;bgb;an049;bgb
;;;;mov     [orph_num],si	   ; Prints "XXX lost clusters found in YYY chains.";an049;bgb
    call    findchain		   ;   On entry SI is the XXX value and the YYY value is
    mov     dx,offset dg:orph_arg  ;   in orphan-count.
    call    printf_crlf
    TEST    fTrunc,-1
;   $IF     NZ
    JZ $$IF5
	XOR	AX,AX	     ; We have truncated the scan.  Set DoFix to FALSE,
	XCHG	AL,DoFix     ; do the operation and then restore things.
	PUSH	AX
	CALL	PromptRecover
	POP	AX
	MOV	DoFix,AL
DoAsk:
;   $ELSE
    JMP SHORT $$EN5
$$IF5:
	CALL	PromptRecover
;   $ENDIF
$$EN5:
    return








;*****************************************************************************
;*****************************************************************************
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 - calculate the file size based on the number of clusters.
;
; WARNING!! NOTE!! -->
;
; called by - PROCEDURE NAME
;
; inputs: AX -
;	  BX -
;	  CX -
;	  DX -
;	  SP -
;	  BP -
;	  SI - conatins the starting cluster number
;	  DI -
;	  DS -
;	  ES -
;
; output: AX - low word of the file size
;	  BX -
;	  CX -
;	  DX - hi  word of the file size
;	  SP -
;	  BP -
;	  SI -
;	  DI -
;	  DS -
;	  ES -
;
; Regs abused - none
;
;logic: 1. save bx & cx for 32 bit mul
;
;	2. zero out file size results
;
;	3. do for all clusters:
;
;	   4. get the next one and inc cluster counter
;
;	5. multiply clusters times sectors per cluster to give
;	   number of sectors in file.  This can be a 2 word value - DX:AX.
;
;	6. multiply the sectors times the number of bytes per sector.  This
;	   yields the number of bytes in the file.
;*****************************************************************************
;SI is start cluster, returns filesize as DX:AX
Procedure getfilsiz,near
    savereg <bx,cx>
	XOR	AX,AX			;zero out low word
	XOR	DX,DX			;zero out high word
	OR	SI,SI			;did we get a zero cluster?
;	$if	NZ
	JZ $$IF8
;	    $DO 			;do for all clusters
$$DO9:
NCLUS:		CALL	UNPACK		;find the next cluster
		XCHG	SI,DI		;put output into input for unpack
		INC	AX		;found another cluster
		CMP	SI,[EOFVAL]	;did we find last cluster?
;	    $leave    ae		;yes, so exit loop
	    JAE $$EN9
					;;;;;;;CMP     SI,2
					;;;;;;;JAE     NCLUS
;	    $enddo
	    JMP SHORT $$DO9
$$EN9:
GOTEOF:
	    MOV     BL,[CSIZE]		;get sectors per cluster
	    XOR     BH,BH
	    MUL     BX			;clusters * secs/cluster = sectors
	    mov     bx,dx		;get high num for 32bit mult
	    mov     cx,ssize		;cx = word to mult with
	    call    multiply_32_bits	;mul bx:ax * cx
	    mov     dx,bx		;save high word
;	$endif
$$IF8:
    restorereg <bx,cx>
  return
EndProc getfilsiz



;*****************************************************************************
;*****************************************************************************
Public Chkcross
CHKCROSS:
;Check for Crosslinks, do second pass if any to find pairs
	MOV	SI,word ptr CROSSCNT
	cmp	word ptr crosscnt,0	;if there is at least one crossed
;	$if	nz,or
	JNZ $$LL13
	cmp	word ptr crosscnt+2,0
;	$if	nz
	JZ $$IF13
$$LL13:
	    CALL    DOCRLF		;display another line
	    MOV     SecondPass,True	;	     ;				     ;AC000;
	    XOR     AX,AX		;
	    PUSH    AX
	    PUSH    AX
	    CALL    DIRPROC			    ;Do it again
;	$endif
$$IF13:
RET8:	RET



;*****************************************************************************
;*****************************************************************************
FATAL:
;Unrecoverable error
	mov	dx,offset dg:FATAL_arg
	mov	[fatmsg1],bx							;an024;bgb
	cmp	byte ptr [nul_arg],0
	jnz	hav_fatal_arg
	mov	[fatmsg2],offset dg:fatal_end
hav_fatal_arg:
	CALL	PRINTf_crlf
	MOV	DL,[USERDEV]			;At least leave on same drive
	DOS_Call Set_Default_Drive		;				;AC000;
						;MOV	 AH,EXIT
	mov	ExitStatus,Bad_Exit		;Get return code			;AC000;
						;INT	 21H
	ret					;Ret Main_Init for common exit




;*****************************************************************************
;*****************************************************************************
iNT_24	PROC	FAR
aSSUME	DS:NOTHING,ES:NOTHING,SS:NOTHING
	PUSHF
	push	ax				;Save AX register		;AN000;
	test	al,Disk_Error			;Is it a disk critical err?
;	$IF	Z				;Yes
	JNZ $$IF15
	   mov	   ax,di			;Get error (DI low)		;AN000;
	   cmp	   al,Write_Protect		;Special case errors		;AN000;
;	   $IF	   E,OR 			;If write protect or		;AN000;
	   JE $$LL16
	   cmp	   al,Drive_Not_Ready		; if drive not ready		;AN000;
	   pop	   ax				;Balance stack again		;AN000;
;	   $IF	   E				;				;AN000;
	   JNE $$IF16
$$LL16:
	      CALL    dword ptr HardCh		; let parent's handler decide what to do
;	   $ELSE				;Other error			;AN000;
	   JMP SHORT $$EN16
$$IF16:
	      pop     ax			;balance stack			;AN000;
	      mov     al,Critical_Error_Fail	;Fail the operation		;AN000;
;	   $ENDIF				;				;AN000;
$$EN16:
;	$ELSE					;Not disk error
	JMP SHORT $$EN15
$$IF15:
	   CALL    dword ptr HardCh		; let parent's handler decide what to do
;	$ENDIF
$$EN15:
	CMP	AL,2				;Abort? 			;AC000;
;	$IF	E				;Yes				;AC000;
	JNE $$IF21
	   STI					;Turn off Interrupts
	   CALL    DONE 			;Forget about directory, restore users drive
	   mov	   ExitStatus,Bad_Exit		;Get return code			;AN000;
;	$ENDIF					;AN000;
$$IF21:
	IRET
iNT_24	ENDP




;*****************************************************************************
;*****************************************************************************
INT_23	proc	far
	STI
	LDS	DX,[HARDCH]
	mov	al,24h				;				;AC000;
	DOS_Call Set_Interrupt_Vector		;				;AC000;
	LDS	DX,cs:[CONTCH]							;ac039;bgb
	mov	al,23h				;				;AC000;
	DOS_Call Set_Interrupt_Vector		;				;AC000;
	PUSH	CS
	POP	DS
ASSUME	DS:DG
	MOV	[FRAGMENT],0
RDONE:
	CALL	NOWRITE 			;Restore users drive and directory
						;MOV	 AH,EXIT
						;MOV	 AL,0FFH
						;INT	 21H
	mov	ExitStatus,Bad_Exit		;Get return code			;AC000;
	stc
	ret					;Ret for common exit			;AN000;
int_23	endp





;*****************************************************************************
;*****************************************************************************
;
; Systime returns the current date in AX, current time in DX
;   AX - HHHHHMMMMMMSSSSS  hours minutes seconds/2
;   DX - YYYYYYYMMMMDDDDD  years months days
;
public	Systime
Systime:
	DOS_Call Get_Time			;				;AC000;
	SHL	CL,1				;Minutes to left part of byte
	SHL	CL,1
	SHL	CX,1				;Push hours and minutes to left end
	SHL	CX,1
	SHL	CX,1
	SHR	DH,1				;Count every two seconds
	OR	CL,DH				;Combine seconds with hours and minutes
	MOV	DX,CX
	PUSH	DX				; Save time
;
; WARNING!  MONTH and YEAR must be adjacently allocated
;
	DOS_Call Get_Date			;				;AC000;
	SUB	CX, 1980
	MOV	AX, CX
	MOV	CL, 4
	SHL	AL, CL				; Push year to left for month
	OR	AL, DH				; move in month
	MOV	CL,4
	SHL	AX,CL				;Push month to left to make room for day
	SHL	AX,1
	OR	AL, DL
	POP	DX				; Restore time
	XCHG	AX, DX				; Switch time and day
	return


;*****************************************************************************	;an055;bgb
;Routine name: Check_DBCS_CharACter						;an055;bgb
;*****************************************************************************	;an055;bgb
;										;an055;bgb
;Description: Check if specified byte is in rANges of DBCS vectors		;an055;bgb
;										;an055;bgb
;Called Procedures: None							;an055;bgb
;										;an055;bgb
;ChANge History: Created	6/12/87 	MT				;an055;bgb
;										;an055;bgb
;Input: AL = CharACter to check for DBCS lead charACter 			;an055;bgb
;	DBCS_Vector = YES/NO							;an055;bgb
;										;an055;bgb
;Output: CY set if DBCS charACter						;an055;bgb
;	 DBCS_VECTOR = YES							;an055;bgb
;										;an055;bgb
;										;an055;bgb
;Psuedocode									;an055;bgb
;----------									;an055;bgb
;	Save registers								;an055;bgb
;	IF DBCS vector not found						;an055;bgb
;	   Get DBCS environmental vector (INT 21h				;an055;bgb
;	   Point at first set of vectors					;an055;bgb
;	ENDIF									;an055;bgb
;	SEARCH									;an055;bgb
;	LEAVE End of DBCS vectors						;an055;bgb
;	EXITIF CharACter > X1,AND  (X1,Y1) are environment vectors		;an055;bgb
;	EXITIF CharACter < Y1							;an055;bgb
;	  STC (DBCS charACter)							;an055;bgb
;	ORELSE									;an055;bgb
;	   Inc pointer to next set of vectors					;an055;bgb
;	ENDLOOP 								;an055;bgb
;	   CLC (Not DBCS charACter)						;an055;bgb
;	ENDSRCH 								;an055;bgb
;	Restore registers							;an055;bgb
;	ret									;an055;bgb
;*****************************************************************************	;an055;bgb
DBCS_Vector_Size	equ 2							;an055;bgb
end_of_vector		equ 0							;an055;bgb
Procedure	Check_DBCS_Character		      ; 			;an055;bgb
	push	ds				;Save registers 		;an055;bgb
	push	si				; "  "	  "  "			;an055;bgb
	push	ax				; "  "	  "  "			;an055;bgb
;;;;;;;;push	ds				; "  "	  "  "			;an055;bgb
;;;;;;;;pop	es				;Establish addressability	;an055;bgb
	cmp	byte ptr es:DBCS_VECTOR,Yes	;Have we set this yet?		;an055;bgb
;	$IF	NE				;Nope				;an055;bgb
	JE $$IF23
	   push    ax				   ;Save input charACter	   ;an055;bgb
	   mov	   al,0 			;Get DBCS environment vectors	;an055;bgb
	   DOS_Call Hongeul			;  "  "    "  " 		;an055;bgb
	   mov	   byte ptr es:DBCS_VECTOR,YES	;Indicate we've got vector      ;an055;bgb
	   mov	   es:DBCS_Vector_Off,si	;Save the vector		;an055;bgb
	   mov	   ax,ds			;				;an055;bgb
	   mov	   es:DBCS_Vector_Seg,ax	;				;an055;bgb
	   pop	   ax				   ;Restore input charACter	   ;an055;bgb
;	$ENDIF					; for next time in		;an055;bgb
$$IF23:
	mov	si,es:DBCS_Vector_Seg		;Get saved vector pointer	;an055;bgb
	mov	ds,si				;				;an055;bgb
	mov	si,es:DBCS_Vector_Off		;				;an055;bgb
;	$SEARCH 				;Check all the vectors		;an055;bgb
$$DO25:
	   cmp	   word ptr ds:[si],End_Of_Vector ;End of vector table? 	;an055;bgb
;	$LEAVE	E				;Yes, done			;an055;bgb
	JE $$EN25
	   cmp	   al,ds:[si]			;See if char is in vector	;an055;bgb
;	$EXITIF AE,AND				;If >= to lower, ANd		;an055;bgb
	JNAE $$IF25
	   cmp	   al,ds:[si+1] 		; =< thAN higher rANge		;an055;bgb
;	$EXITIF BE				; then DBCS charACter		;an055;bgb
	JNBE $$IF25
	   stc					;Set CY to indicate DBCS	;an055;bgb
;	$ORELSE 				;Not in rANge, check next	;an055;bgb
	JMP SHORT $$SR25
$$IF25:
	   add	   si,DBCS_Vector_Size		;Get next DBCS vector		;an055;bgb
;	$ENDLOOP				;We didn't find DBCS char       ;an055;bgb
	JMP SHORT $$DO25
$$EN25:
	   clc					;Clear CY for exit		;an055;bgb
;	$ENDSRCH				;				;an055;bgb
$$SR25:
	pop	ax				;Restore registers		;an055;bgb
	pop	si				; "  "	  "  "			;an055;bgb
	pop	ds				;Restore data segment		;an055;bgb
	ret					;				;an055;bgb
Check_DBCS_CharACter endp			;				;an055;bgb



	pathlabl chkproc2
CODE	ENDS
	END