summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/CHKDSK/CHKPROC.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/CHKDSK/CHKPROC.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/CHKDSK/CHKPROC.ASM')
-rw-r--r--v4.0/src/CMD/CHKDSK/CHKPROC.ASM1892
1 files changed, 1892 insertions, 0 deletions
diff --git a/v4.0/src/CMD/CHKDSK/CHKPROC.ASM b/v4.0/src/CMD/CHKDSK/CHKPROC.ASM
new file mode 100644
index 0000000..e76b78f
--- /dev/null
+++ b/v4.0/src/CMD/CHKDSK/CHKPROC.ASM
@@ -0,0 +1,1892 @@
1TITLE CHKPROC - PART1 Procedures called from chkdsk
2page ,132 ;
3
4 .xlist
5 include chkseg.inc
6 INCLUDE CHKCHNG.INC
7 INCLUDE DOSSYM.INC
8 INCLUDE CHKEQU.INC
9 INCLUDE CHKMACRO.INC
10 include pathmac.inc
11 .list
12
13
14DATA SEGMENT PUBLIC PARA 'DATA'
15 EXTRN FIXMES_ARG:word,DIREC_ARG:word
16 EXTRN NULDMES:byte,NULNZ:byte,BADCLUS:byte,NORECDOT:byte
17 EXTRN NoRecDDot:Byte
18 EXTRN BADCHAIN:byte,NDOTMES:byte,CDDDMES:byte
19 EXTRN NORECDDOT1:byte,NORECDDOT2:byte,NORECDDOT3:byte
20 EXTRN STACKMES:byte
21 EXTRN BADDPBDIR:byte, BadSubDir:byte
22 EXTRN BADTARG_PTR:byte,BADTARG2:byte,JOINMES:byte
23 EXTRN PTRANDIR:byte,PTRANDIR2:byte
24 EXTRN CROSS_ARG:word,NOISY_ARG:word
25 EXTRN FILE_ARG1:WORD,FILE_ARG2:WORD,FILE_ARG:word
26 EXTRN DOTMES:byte,NOISY:byte,DOTENT:byte,HAVFIX:byte
27 EXTRN DOFIX:byte,DIRBUF:byte,PARSTR:byte,DDOTENT:byte
28 EXTRN NUL:byte,ERRSUB:word,SECONDPASS:byte,ALLFILE:byte
29 EXTRN HIDCNT:dword,HIDSIZ:word,FILCNT:dword,FILSIZ:word ;an049;bgb
30 EXTRN DIRCNT:dword ;an049;bgb
31 EXTRN DIRSIZ:word ;an049;bgb
32 EXTRN DIRTYFAT:byte,
33 EXTRN HECODE:byte
34 EXTRN ALLDRV:byte,FIXMFLG:byte,DIRCHAR:byte
35 EXTRN BIGFAT:byte,EOFVAL:word,BADVAL:word
36 Extrn fTrunc:BYTE ;ac048;bgb
37 Extrn dirsec:word ;ac048;bgb
38
39 EXTRN THISDPB:dword,DOTSNOGOOD:byte,NUL_ARG:byte,STACKLIM:word
40 EXTRN ZEROTRUNC:byte,NAMBUF:byte,SRFCBPT:word,FATMAP:word
41 EXTRN ISCROSS:byte,MCLUS:word,CSIZE:byte,SSIZE:word,fattbl:byte
42 EXTRN DSIZE:word,ARG1:word,ARG_BUF:byte,TMP_SPC:BYTE
43 EXTRN SECBUF:word
44 EXTRN Inv_XA_Msg:Byte,Alloc_XA_Msg:Byte
45 Extrn Data_Start_Low:Word,Data_Start_High:Word
46 EXTRN Read_Write_Relative:Byte
47 EXTRN MClus:Word,Chain_End:Word
48
49XA_Buffer XAL <> ;XA buffer space to read in 1st sector ;AN000;
50Head_Mark db 0 ;Flag for MarkMap ;AN000;
51BClus dw 0 ;Bytes/Cluster
52public cross_clus
53Cross_Clus dw 0 ;Cluster crosslink occurred on
54Cluster_Count dw 0 ; ;AN000;
55First_Cluster dw 0 ; ;AN000;
56Previous_Cluster dw 0 ; ;AN000;
57XA_Pass db 0 ; ;AN000;
58File_Size_High dw 0 ; ;AN000;
59File_Size_Low dw 0 ; ;AN000;
60Chain_Size_Low dw 0 ; ;AN000;
61Chain_Size_High dw 0 ; ;AN000;
62
63
64public Head_Mark
65public BClus
66public Cluster_Count
67public First_Cluster
68public Previous_Cluster
69public XA_Pass
70public File_Size_High
71public File_Size_Low
72public Chain_Size_Low
73public Chain_Size_High
74DATA ENDS
75
76
77CODE SEGMENT PUBLIC PARA 'CODE'
78ASSUME CS:DG,DS:DG,ES:DG,SS:DG
79;Structures used by DIRPROC
80SRCHFCB STRUC
81 DB 44 DUP (?)
82SRCHFCB ENDS
83SFCBSIZ EQU SIZE SRCHFCB
84 EXTRN PRINTF_CRLF:NEAR,SUBERRP:NEAR,FCB_TO_ASCZ:NEAR
85 EXTRN FIGREC:NEAR,EPRINT:NEAR
86 EXTRN DOINT26:NEAR,PROMPTYN:NEAR
87 EXTRN DOTCOMBMES:NEAR,FATAL:NEAR,MARKMAP:NEAR,GETFILSIZ:NEAR
88 EXTRN SYSTIME:NEAR, Read_Disk:Near,DoCRLF:Near
89 extrn crosschk:near
90 extrn UNPACK:near, PACK:near
91public DOTDOTHARDWAY, NODOT, DOEXTMES1, MESD1, CANTREC, DOTGOON, NODDOT
92public DOEXTMES2, MESD2, NFIX, CANTREC2, NULLDIRERR, DOEXTMES3, DOTSBAD
93public dotsbad2, DIRPROC, STACKISOK, NOPRINT, JOINERR
94public NONULLDERr, DOTOK, DATTOK, DLINKOK, BADDSIZ, DSIZOK, CHKDOTDOT
95public DOTDOTOK, DDATTOK, DDLINKOK, BADDDSIZ, DDSIZOK, ROOTDIR
96public DODDH, DIRDONE, MOREDIR, FPROC1, NOPRINT2, HIDENFILE, NORMFILE, NEWDIR
97public DPROC1, CONVDIR, DPROC2, CANTTARG, BogusDir, ASKCONV
98public PRINTTRMES, CROSSLOOK, CHLP, CROSSLINK, CHAINDONE
99public FIXENT2, RET20, FIXENT, GETENT, CLUSISOK
100public SKIPLP, GOTCLUS, DOROOTDIR, RDRETRY, RDOK2, WANTROOT, CHECKNOFMES, ret14
101public CHECKERR, get_currdirERR, ok_pri_dir, get_thiselERR, ok_pri_el
102public get_THISEL, get_THISEL2, get_currdir, GET_END, ERRLOOP, LPDONE
103public CHECK_SPLICE, NT_SPLC, MarkFAT, Bad_Cluster, Check_Chain_Sizes
104public print_filename ;ac048;bgb
105public NOTROOT ;ac048;bgb
106public FIXDOT ;ac048;bgb
107
108
109 pathlabl chkproc
110SUBTTL DIRPROC -- Recursive directory processing
111PAGE
112;**************************************************************************
113; DOTDOTHARDWAY - change dir to the previous directory using '..'
114;
115; called by -
116;
117; inputs - parse string '..'
118;
119; outputs - new default directory
120;
121;NOTE
122; On versions of DOS < 2.50 "cd .." would fail if there was no ".."
123; entry in the current directory. On versions >= 2.50 "cd .."
124; is handled as a string manipulation and therefore should always
125; work. On < 2.50 this routine didddled the current directory string
126; INSIDE THE DOS DATA STRUCTURES. This is no longer desirable, or
127; needed.
128;**************************************************************************
129procedure dotdothardway,near
130 MOV DX,OFFSET DG:PARSTR
131 DOS_Call ChDir ; ;AC000;
132 RET
133endproc dotdothardway
134
135
136;************************************************************************** ;ac048;bgb
137; NODOT - come here if there is no . entry in the first entry of the sub- ;ac048;bgb
138; directory. The . entry is a pointer to the subdirectory itself. ;ac048;bgb
139; The entry from the search first did not find it, and the subdir is ;ac048;bgb
140; not joined. So, try to put a new . entry into the first slot. ;ac048;bgb
141; ;ac048;bgb
142; called by - nonullderr ;ac048;bgb
143; ;ac048;bgb
144; inputs - SI - points to arg_buf, which is a filespec ;ac048;bgb
145; DI - points to tmp_spc, which is a filespec ;ac048;bgb
146; AX - return value from search first ;ac048;bgb
147; ;ac048;bgb
148; outputs - if the /f parm was entered, tries to replace the . entry ;ac048;bgb
149; AX - saves the return value from search first ;ac048;bgb
150; ;ac048;bgb
151; logic: 1. go display error messages. Different messages are displayed, ;ac048;bgb
152; depending on /f and /v parms. ;ac048;bgb
153; ;ac048;bgb
154; 2. go get the sector number and read it into ram ;ac048;bgb
155; ;ac048;bgb
156; 3. if the first entry is erased (begins with hex e5), then we can ;ac048;bgb
157; fill it with the corrected . entry. Otherwise, go to #6. ;ac048;bgb
158; ;ac048;bgb
159; 4. So, fill entry with all the dir fields - name, ext, attr, date, ;ac048;bgb
160; time, size, cluster #. ;ac048;bgb
161; ;ac048;bgb
162; 5. write it back to disk. ;ac048;bgb
163; ;ac048;bgb
164; 6. go check out the .. entry ;ac048;bgb
165;************************************************************************** ;ac048;bgb
166NODOT: ;No . ;ac048;bgb
167 PUSH AX ;save the return value from search 1st ;ac048;bgb
168;display msgs ;;;;;;;;jnz doextmes1 ;ac048;bgb
169 CMP [NOISY],OFF ;was /v parm entered? ;ac048;bgb;AC000;
170; $IF Z ;display no /v msgs ;ac048;bgb
171 JNZ $$IF1
172 call suberrp ;ac048;bgb
173 ;;;;;;;;jmp short mesd1 ;ac048;bgb
174; $ELSE ;display /v msgs ;ac048;bgb
175 JMP SHORT $$EN1
176$$IF1:
177DOEXTMES1: mov si,offset dg:dotmes ;first find out where we are ;ac048;bgb
178 call get_currdirerr ;ac048;bgb
179 mov dx,offset dg:ndotmes ;print dir, dot, and 'not found' msg ;ac048;bgb
180 call eprint ;ac048;bgb
181; $ENDIF ;ac048;bgb
182$$EN1:
183 ;ac048;bgb
184;go find the sector ;ac048;bgb
185MESD1: XOR AX,AX ;set entry number to zero ;ac048;bgb
186 PUSH BX ;save ;ac048;bgb
187 PUSH BP ;save ;ac048;bgb
188 CALL GETENT ;get the sector number ;ac048;bgb
189 POP BP ;restore bp ;ac048;bgb
190 PUSH BP ;put it back ;ac048;bgb
191 CMP BYTE PTR [DI],0E5H ;is this 1st entry erased/open? ;ac048;bgb
192; $if nz ;ac048;bgb
193 JZ $$IF4
194;cant fill . entry ;JNZ CANTREC ;ac048;bgb ;Nope
195CANTREC: INC [DOTSNOGOOD] ;ac048;bgb
196 CMP [NOISY],OFF ; ;ac048;bgb ;AC000;
197; $if nz ;ac048;bgb
198 JZ $$IF5
199 ;JZ DOTGOON ;ac048;bgb
200 MOV DX,OFFSET DG:NORECDOT ;ac048;bgb
201 CALL EPRINT ;ac048;bgb
202; $endif ;ac048;bgb
203$$IF5:
204 jmp dotgoon ;ac048;bgb
205; $endif ;ac048;bgb
206$$IF4:
207
208;get filename
209fixdot: MOV SI,OFFSET DG:DOTENT ;point to valid . entry
210 MOV CX,11 ;move filename and ext
211 REP MOVSB ;Name
212 PUSH AX ;save disk number
213;move attr byte
214 MOV AL,ISDIR ;hex 10
215 STOSB ;Attribute
216; Add in time for directory - BAS July 17/85
217 ADD DI,10
218 push dx ;save starting sector number ;ac048;bgb
219 CALL SYSTIME
220 STOSW ; Time
221 MOV AX,DX
222 STOSW ; Date
223 MOV AX,[BP+6]
224 STOSW ;Alloc #
225 XOR AX,AX
226 STOSW
227 STOSW ;Size
228 pop dx ;restore starting sector number ;ac048;bgbb
229 POP AX ;
230;write back to disk
231 MOV [HAVFIX],1 ;Have a fix
232 CMP [DOFIX],0 ; /f parm entered?
233; $if nz ;ac048;bgb
234 JZ $$IF8
235 ;JZ DOTGOON ;ac048;bgbif not F
236 MOV CX,1 ;ac048;bgb
237 CALL DOINT26 ;ac048;bgb
238 ;JMP SHORT DOTGOON ;ac048;bgb
239; $endif ;ac048;bgb
240$$IF8:
241;go check out .. entry
242DOTGOON: POP BP
243 POP BX
244 POP AX
245 MOV SI,OFFSET DG:DIRBUF
246 JMP CHKDOTDOT ;Go look for ..
247;*****************************************************************************
248
249
250
251
252NODDOT label far ;No ..
253 PUSH AX ;Return from SRCH
254 CMP [NOISY],OFF ; ;AC000;
255 JNZ DOEXTMES2
256 CALL SUBERRP
257 JMP SHORT MESD2
258DOEXTMES2:
259 MOV SI,OFFSET DG:PARSTR
260 CALL get_currdirERR
261 MOV DX,OFFSET DG:NDOTMES
262 CALL EPRINT
263
264MESD2:
265 MOV AX,1
266 PUSH BX
267 PUSH BP
268 CALL GETENT
269 POP BP
270 PUSH BP
271 CMP BYTE PTR [DI],0E5H ;Place to put it?
272 JNZ CANTREC2 ;Nope
273 MOV SI,OFFSET DG:DDOTENT
274 MOV CX,11
275 REP MOVSB ;Name
276 PUSH AX
277 MOV AL,ISDIR
278 STOSB ;Attribute
279 ADD DI,10
280;
281; Add in time for directory - BAS July 17/85
282 push dx ;save starting sector number ;ac048;bgb
283 CALL SYSTIME
284 STOSW ; Time
285 MOV AX,DX
286 STOSW ; Date
287 MOV AX,[BP+4]
288 STOSW ;Alloc #
289 XOR AX,AX
290 STOSW
291 STOSW ;Size
292 pop dx ;restore starting sector number ;ac048;bgbb
293 POP AX
294 MOV [HAVFIX],1 ;Got a fix
295 CMP [DOFIX],0
296 JZ NFIX ;No fix if no F, carry clear
297 MOV CX,1
298 CALL DOINT26
299NFIX:
300 restorereg <bp,bx,ax> ;ac048;bgb
301 MOV SI,OFFSET DG:DIRBUF
302 JMP far ptr ROOTDIR ;Process files
303
304CANTREC2:
305 restorereg <bp,bx,ax> ;ac048;bgb
306 CMP [NOISY],OFF ; ;AC000;
307 JZ DOTSBAD2
308 MOV DX,OFFSET DG:NORECDDOT
309 JMP DOTSBAD
310
311NULLDIRERR label far ;dir is empty
312 CMP [NOISY],OFF ; ;AC000;
313 JNZ DOEXTMES3
314 CALL SUBERRP
315 JMP SHORT DOTSBAD2
316DOEXTMES3:
317 MOV SI,OFFSET DG:NUL
318 CALL get_currdirERR
319 MOV DX,OFFSET DG:NULDMES
320DOTSBAD: ;Can't recover
321 mov [file_arg2],offset dg:badtarg2
322 inc byte ptr [nul_arg]
323 MOV fTrunc,TRUE
324 CALL EPRINT
325dotsbad2:
326 CALL DOTDOTHARDWAY
327 INC [DOTSNOGOOD]
328 MOV SP,BP ;Pop local vars
329 POP BP ;Restore frame
330 RET 4 ;Pop args
331
332
333
334
335PAGE
336;***************************************************************************
337; DIRPROC - recursive tree walker
338;
339; called by - main-routine in chkdsk1.sal
340;
341; inputs - ax=0
342; - two words of 0 on the stack
343;
344;Recursive tree walker
345;dirproc(self,parent)
346;****************************************************************************
347DIRPROC:
348 MOV [DOTSNOGOOD],0 ;Init to dots OK - set . or .. error flag to false
349 MOV [ERRSUB],0 ;No subdir errors yet
350 PUSH BP ;Save frame pointer - 0
351 MOV BP,SP ;ffe2 - 2c = ffb6
352 SUB SP,SFCBSIZ ;Only local var
353
354; are we at stack overflow ?
355 CMP SP,[STACKLIM] ; ffb6 vs. 5943 ;an005;bgb
356; $IF NA
357 JA $$IF10
358;;;;;;;;JA STACKISOK
359 MOV BX,OFFSET DG:STACKMES ;Out of stack
360 JMP FATAL
361; $ENDIF
362$$IF10:
363
364STACKISOK:
365;print the files as they are found
366 CMP [NOISY],off ; off= 0 ;AC000;
367; $IF NZ ;if not noisy, dont print filenames
368 JZ $$IF12
369;;;;;;;;JZ NOPRINT
370 CMP [SECONDPASS],False ; ;AC000;
371; $IF Z ;only print on the first pass
372 JNZ $$IF13
373;;;;;;;;;;;;JNZ NOPRINT ;Don't do it again on second pass
374 MOV SI,OFFSET DG:NUL
375 CALL get_CURRDIR
376 mov dx,offset dg:DIREC_arg ;Tell user where we are
377 CALL PRINTf_crlf
378; $ENDIF
379$$IF13:
380; $ENDIF
381$$IF12:
382
383; initialize search fcb
384NOPRINT:
385 MOV SI,OFFSET DG:ALLFILE ;extended fcb
386 MOV DI,SP
387 PUSH DI
388 MOV CX,SFCBSIZ ;move 44dec bytes
389 REP MOVSB ;from allfile (ds:si) to es:di
390; find this file
391 POP DX ; from push bp
392 MOV BX,DX ;BX points to SRCH FCB
393 DOS_Call Dir_Search_First ;search for any file ;AC000;
394;
395 CMP WORD PTR [BP+6],0 ;attribute byte- root will = zero
396; $if z
397 JNZ $$IF16
398 jmp far ptr rootdir ;yes, we are at the root
399; $endif
400$$IF16:
401 OR AL,AL ;check return code from search first
402 JZ NONULLDERR
403 CALL CHECK_SPLICE ; See if dir is spliced
404; $if c
405 JNC $$IF18
406;;;;;;;;;;;;JC nulldirerr ; Not spliced, error
407 jmp nulldirerr
408; $endif
409$$IF18:
410JOINERR:
411 MOV SI,OFFSET DG:NUL
412 CALL get_currdir
413 mov fTrunc,TRUE
414 mov dx,offset dg:joinmes ; ;AC000;
415 call Printf_Crlf ; ;AC000;
416 mov dx,offset dg:badtarg2 ; ;AC000;
417 call Printf_CRLF ; ;AC000;
418 CALL DOTDOTHARDWAY
419 MOV SP,BP ;Pop local vars
420 POP BP ;Restore frame
421 RET 4 ;Pop args
422
423
424
425NONULLDERR:
426 MOV SI,OFFSET DG:DIRBUF + DIRNAM
427 MOV DI,OFFSET DG:DOTENT
428 MOV CX,11
429 REP CMPSB
430 JZ DOTOK ;Got a . as first entry
431 push ax ;save return code from search first ;an045;bgb
432 CALL CHECK_SPLICE ; See if dir is spliced
433; $IF C ;carry means no join on this dir ;an045;bgb
434 JNC $$IF20
435 pop ax ;restore return code ;an045;bgb
436 jmp nodot ;goto no . entry code ;an045;bgb
437; $ELSE ;no carry means dir is joined ;an045;bgb
438 JMP SHORT $$EN20
439$$IF20:
440 pop ax ;restore return code ;an045;bgb
441 jmp joinerr ;goto join error code ;an045;bgb
442; $ENDIF ;no carry means dir is joined ;an045;bgb
443$$EN20:
444;;;;;;;;JNC JOINERR ; spliced, stop ;an045;bgb
445;;;;;;;;JMP NODOT ;No . ;an045;bgb
446
447DOTOK:
448 MOV SI,OFFSET DG:DIRBUF
449 MOV AL,[SI.DIRATT]
450 TEST AL,ISDIR
451 JNZ DATTOK
452 PUSH SI ;. not a dir?
453 MOV SI,OFFSET DG:DOTMES
454 ;MOV DX,OFFSET DG:BADATT
455 mov dx,offset dg:norecddot2 ; ;AN000;
456 CALL DOTCOMBMES
457 POP SI
458 OR [SI.DIRATT],ISDIR
459 CALL FIXENT ;Fix it
460DATTOK:
461 MOV AX,[SI.DIRCLUS]
462 CMP AX,[BP+6] ;. link = MYSELF?
463 JZ DLINKOK
464 PUSH SI ;Link messed up
465 MOV SI,OFFSET DG:DOTMES
466 ;MOV DX,OFFSET DG:CLUSBAD
467 mov dx,offset dg:norecddot1 ; ;AN000;
468 CALL DOTCOMBMES
469 POP SI
470 MOV AX,[BP+6]
471 MOV [SI.DIRCLUS],AX
472 CALL FIXENT ;Fix it
473DLINKOK:
474 MOV AX,WORD PTR [SI.DIRESIZ]
475 OR AX,AX
476 JNZ BADDSIZ
477 MOV AX,WORD PTR [SI.DIRESIZ+2]
478 OR AX,AX
479 JZ DSIZOK
480BADDSIZ: ;Size should be zero
481 PUSH SI
482 MOV SI,OFFSET DG:DOTMES
483 ;MOV DX,OFFSET DG:BADSIZM
484 mov dx,offset dg:norecddot3 ; ;AN000;
485 CALL DOTCOMBMES
486 POP SI
487 XOR AX,AX
488 MOV WORD PTR [SI.DIRESIZ],AX
489 MOV WORD PTR [SI.DIRESIZ+2],AX
490 CALL FIXENT ;Fix it
491DSIZOK: ;Get next (should be ..)
492 MOV DX,BX
493 DOS_Call Dir_Search_Next ; ;AC000;
494CHKDOTDOT: ;Come here after . failure
495 OR AL,AL
496 JZ DOTDOTOK
497 JMP NODDOT ;No ..
498DOTDOTOK:
499 MOV SI,OFFSET DG:DIRBUF + DIRNAM
500 MOV DI,OFFSET DG:DDOTENT
501 MOV CX,11
502 REP CMPSB
503; $if nz
504 JZ $$IF23
505 jmp noddot
506;;; ;;;;;;;;JNZ NODDOT ;No ..
507; $endif
508$$IF23:
509 MOV SI,OFFSET DG:DIRBUF
510 MOV AL,[SI.DIRATT]
511 TEST AL,ISDIR
512 JNZ DDATTOK ;.. must be a dir
513 PUSH SI
514 MOV SI,OFFSET DG:PARSTR
515 ;MOV DX,OFFSET DG:BADATT
516 mov dx,offset dg:norecddot2 ; ;AN000;
517 CALL DOTCOMBMES
518 POP SI
519 OR [SI.DIRATT],ISDIR
520 CALL FIXENT ;Fix it
521DDATTOK:
522 PUSH SI
523 MOV AX,[SI.DIRCLUS]
524 CMP AX,[BP+4] ;.. link must be PARENT
525 JZ DDLINKOK
526 MOV SI,OFFSET DG:PARSTR
527 ;MOV DX,OFFSET DG:CLUSBAD
528 mov dx,offset dg:norecddot1 ; ;AN000;
529 CALL DOTCOMBMES
530 POP SI
531 MOV AX,[BP+4]
532 MOV [SI.DIRCLUS],AX
533 CALL FIXENT ;Fix it
534DDLINKOK:
535 MOV AX,WORD PTR [SI.DIRESIZ]
536 OR AX,AX
537 JNZ BADDDSIZ
538 MOV AX,WORD PTR [SI.DIRESIZ+2]
539 OR AX,AX
540; $if z
541 JNZ $$IF25
542 jmp DDSIZOK
543; $endif
544$$IF25:
545BADDDSIZ: ;.. size should be 0
546 PUSH SI
547 MOV SI,OFFSET DG:PARSTR
548 ;MOV DX,OFFSET DG:BADSIZM
549 mov dx,offset dg:norecddot3 ; ;AN000;
550 CALL DOTCOMBMES
551 POP SI
552 XOR AX,AX
553 MOV WORD PTR [SI.DIRESIZ],AX
554 MOV WORD PTR [SI.DIRESIZ+2],AX
555 CALL FIXENT ;Fix it
556
557
558;***************************************************************************
559; DDSIZOK - search for the next file in this directory
560;***************************************************************************
561DDSIZOK label far
562 MOV DX,BX ;search for Next entry
563 DOS_Call Dir_Search_Next ;func=12 ;AC000;
564
565ROOTDIR label far ;come here after search first .. failure also
566 OR AL,AL ; was a matching filename found?
567 JZ MOREDIR ;zero = yes ;More to go
568 CMP WORD PTR [BP+6],0 ;nz=no ;Am I the root?
569 JZ DIRDONE ;Yes, no chdir
570 MOV DX,OFFSET DG:PARSTR
571 DOS_Call ChDir ; ;AC000;
572 JNC DIRDONE ;Worked
573
574; NOTE************************************************
575; On DOS >= 2.50 "cd .." should ALWAYS work since it is
576; a string manipulation. Should NEVER get to here.
577
578 CMP [NOISY],OFF ; ;AC000;
579 JZ DODDH
580 MOV SI,OFFSET DG:NUL
581 CALL get_currdirERR
582 MOV DX,OFFSET DG:CDDDMES
583 CALL EPRINT
584DODDH:
585 CALL DOTDOTHARDWAY ;Try again
586DIRDONE:
587 MOV SP,BP ;Pop local vars
588 POP BP ;Restore frame
589 RET 4 ;Pop args
590
591
592
593;*****************************************************************
594; found at least one file in this subdir!
595;*****************************************************************
596MOREDIR:
597 MOV SI,OFFSET DG:DIRBUF ;point to where ext fcb of found file is
598 TEST [SI.DIRATT],ISDIR ;attr 010h = sub-directory
599 JNZ NEWDIR ;Is a new directory?
600 CMP [SECONDPASS],False ;no, same dir ;AC000;
601 JZ FPROC1 ;2nd pass here
602 CALL CROSSLOOK ;Check for cross links
603 JMP DDSIZOK ;Next
604
605FPROC1:
606 CMP [NOISY],OFF ; ;AC000;
607; $IF NZ ;print filenames?
608 JZ $$IF27
609 call print_filename
610; $ENDIF
611$$IF27:
612NOPRINT2:
613 mov Cluster_Count,0 ;No clusters for vol label ;AN000;
614 mov cx,0 ;setup cx for 0 size vol labels ;an016;bgb
615 TEST [SI.DIRATT],VOLIDA ;attr=08 ;Don't chase chains on labels ;AC000;
616; $IF Z ;no, regular file
617 JNZ $$IF29
618 MOV AL,81H ;Head of file
619 mov di,word ptr [si].DIRESIZ+0 ;Get file size
620 mov File_Size_Low,di ;
621 mov di,word ptr [si].DIRESIZ+2 ;
622 mov File_Size_High,di ;
623 mov di,[si].DirClus ;First cluster of file ;AN000;
624 CALL MARKFAT
625 MOV CX,Cluster_Count ;Get number of clusters
626;;;;;;;;;;;;PUSH CX ;Save them
627;;;;;;;;;;;;CALL Check_Extended_Attributes ;See if XA exist, and handle ;AN000;
628;;;;;;;;;;;;POP CX ;Get File length clusters
629;;;;;;;;;;;;ADD CX,Cluster_Count ;Add in XA clusters
630 TEST [SI.DIRATT],HIDDN ;
631 JZ NORMFILE ;
632; $ENDIF
633$$IF29:
634hidenfile:
635 add word ptr hidcnt,1 ;found another hidden file ;an049;bgb
636 adc word ptr hidcnt+2,0 ;add high word if > 64k files ;an049;bgb
637 add hidsiz,cx ;it was this many bytes ;an049;bgb
638 JMP ddsizok ;Next
639NORMFILE:
640 add word ptr filcnt,1 ;inc file counter ;an049;bgb
641 adc word ptr filcnt+2,0 ;add high word if >64k files ;an049;bgb
642 add filsiz,cx ;add in size of file ;an049;bgb
643 JMP ddsizok ;Next
644
645
646;***************************************************************************
647; NEWDIR - come here whenever you find another directory entry
648; inputs: SI - points to directory entry
649;***************************************************************************
650NEWDIR:
651 CMP [SECONDPASS],False ;are we on 2nd pass? ;AC000;
652 JZ DPROC1 ;zero means no - skip next part
653 CALL CROSSLOOK ;2nd pass - Check for cross links
654 JMP SHORT DPROC2 ;goto dproc2
655DPROC1: ;1st pass
656 MOV AL,82H ;Head of dir
657 mov di,[si].DirClus ;get 1st clus num from dir entry ;AN000;
658 mov File_Size_Low,0 ; ;Set to zero, shouldn't ;AN000;
659 mov File_Size_High,0 ; be looked at for dir ;AN000;
660 CALL MARKFAT
661 add word ptr dircnt,1 ;add 1 to the dir counter ;an047;bgb
662 adc word ptr dircnt+2,0 ;add 1 to the high word if carry ;an047;bgb
663 MOV CX,Cluster_Count ;Add count of clusters in files ;AN000;
664 CMP [ZEROTRUNC],0 ;did we modify the file size? ;an026;bgb
665 JZ DPROC2 ;Dir not truncated
666CONVDIR: ;yes, dir size truncated
667 AND [SI.DIRATT],NOT ISDIR ;Turn into file
668 CALL FIXENT
669 POP BX ;Get my SRCH FCB pointer back
670 POP [ERRSUB] ;restore from prev dir
671 JMP ddsizok ;Next
672DPROC2:
673 add dirsiz,cx ;add in siz of clusters ;an049;bgb
674; put 4 words on the stack - for next call to dirproc?
675 PUSH [ERRSUB] ;save the fcb ptr from prev dir
676 PUSH BX ;Save my srch FCB pointer
677 MOV AX,[SI].DirCLus ;get 1st cluster number
678 PUSH AX ; Give him his own first clus pointer
679 PUSH [BP+6] ; His PARENT is me
680;copy fcb name to msg string name
681 ADD SI,DIRNAM ;point to name, +08
682 MOV DI,OFFSET DG:NAMBUF
683 savereg <di,ax> ;copy to msg string
684 CALL FCB_TO_ASCZ
685 restorereg <ax,di>
686;check out validity of dir
687 OR AX,AX ;does the 1st clus in dir point to zero?
688 JZ BogusDir ; no, it is bogus
689 mov dx,di
690 DOS_Call ChDir ; chdir to it ;AC000;
691 JC CANTTARG ; carry means bad dir
692; go check out new dir
693 CALL DIRPROC
694 POP BX ;Get my SRCH FCB pointer back
695 POP [ERRSUB] ;restore from prev dir
696 CMP [DOTSNOGOOD],0
697 JNZ ASKCONV
698 JMP ddsizok ;Next
699;newdir error routines
700CANTTARG:
701;cant chdir
702 ADD SP,8 ; Clean stack
703 mov SI,dx ; Pointer to bad DIR
704 CALL get_currdirERR
705 MOV DX,OFFSET DG:BADTarg_PTR
706 mov fTrunc,TRUE
707 call printf_crlf
708 JMP ddsizok ;Next
709BogusDir:
710;bad dir entry
711 ADD SP,8 ; clean off stack
712 MOV SI,DX ; pointer to bad dir
713 CALL get_currdirERR ; output message with dir
714 MOV DX,OFFSET DG:BadSubDir ; real error message
715 CALL EPRINT ; to stderr...
716ASKCONV:
717 CMP [SECONDPASS],False ; ;AC000;
718; $if nz
719 JZ $$IF31
720 jmp ddsizok
721;;;;;;;;;;;;JNZ DDSIZOK ;Leave on second pass
722; $endif
723$$IF31:
724 cmp [NOISY],on ; /v entered ? ;An027;bgb
725; $IF E ; no, skip next msg ;An027;bgb
726 JNE $$IF33
727 MOV DX,OFFSET DG:PTRANDIR ;unrecoverable error in directory ;An027;bgb
728 call printf_crlf ;display msg ;An027;bgb
729; $ENDIF
730$$IF33:
731PRINTTRMES:
732 MOV DX,OFFSET DG:PTRANDIR2 ;either case - "convert dir to file?" ;An027;bgb
733 CALL PROMPTYN ;Ask user what to do
734; $if nz
735 JZ $$IF35
736 jmp ddsizok
737;;;;;;;;;;; JNZ DDSIZOK ;Leave on second pass
738; $endif
739$$IF35:
740 PUSH BP
741 PUSH BX
742 MOV AX,[BX+THISENT] ;Entry number
743 CALL GETENT ;Get the entry
744 MOV SI,DI
745 MOV DI,OFFSET DG:DIRBUF
746 PUSH DI
747 ADD DI,DIRNAM
748 MOV CX,32
749 REP MOVSB ;Transfer entry to DIRBUF
750 POP SI
751 PUSH SI
752 MOV SI,[SI.DIRCLUS] ;First cluster
753 CALL GETFILSIZ
754 POP SI
755 POP BX
756 POP BP
757 MOV WORD PTR [SI.DIRESIZ],AX ;Fix entry
758 MOV WORD PTR [SI.DIRESIZ+2],DX
759 JMP CONVDIR ;convert directory
760;*****************************************************************************
761;end of newdir
762;*****************************************************************************
763
764
765
766SUBTTL fat-Look routines
767PAGE
768;*****************************************************************************
769; CROSSLOOK - look at the fat, check for cross linked files
770; called by -
771;****************************************************************************
772CROSSLOOK:
773;Same as MRKFAT only simpler for pass 2
774 MOV [SRFCBPT],BX ;an014;bgb
775 MOV BX,SI ;an014;bgb
776 MOV SI,[BX.DIRCLUS] ;an014;bgb
777 CALL CROSSCHK ;an014;bgb
778 JNZ CROSSLINK ;an014;bgb
779;;;;;;;;mov XA_Pass,False ;an014;bgb ;an014;bgb
780
781CHLP:
782 PUSH BX ;an014;bgb
783 CALL UNPACK ;an014;bgb
784 POP BX ;an014;bgb
785 XCHG SI,DI ;an014;bgb
786 CMP SI,[EOFVAL] ;an014;bgb
787 jae chaindone ;an014;bgb ;an014;bgb
788;;;;;;;;JAE Check_XA_Cross ;an014;bgb ;an014;bgb
789 CALL CROSSCHK ;an014;bgb
790 JZ CHLP ;an014;bgb
791 JMP SHORT CROSSLINK ;an014;bgb
792 ;an014;bgb
793Check_XA_Cross: ; ;AN000;
794
795;;;;;;;;mov SI,[BX.DIR_XA] ;See if extended attribute ;an014;bgb ;AN000;
796;;;;;;;;cmp si,0 ;Is there? ;an014;bgb ;AN000;
797;;;;;;;;je ChainDoneJ ;No if zero ;an014;bgb ;AN000;
798; CALL CROSSCHK ;Yes, see if crosslinked ;an014;bgb ;AN000;
799; JNZ CROSSLINKJ ;NZ means yes ;an014;bgb ;AN000;
800;A_Cross_Loop: ; ;an014;bgb ;AN000;
801; PUSH BX ; ;an014;bgb ;AN000;
802; CALL UNPACK ;Get next cluster ;an014;bgb ;AN000;
803; POP BX ; ;an014;bgb ;AN000;
804; XCHG SI,DI ; ;an014;bgb ;AN000;
805; CMP SI,[EOFVAL] ;Reach the end? ;an014;bgb ;AN000;
806; JAE ChainDoneJ ;Leave if so ;an014;bgb ;AN000;
807; CALL CROSSCHK ;See if crosslink ;an014;bgb ;AN000;
808; JZ XA_Cross_Loop ;Go check next cluster if not ;AN000;
809; jmp CrossLink ;Go handle crosslink ;an014;bgb ;AN000;
810;
811
812;NOCLUSTERSJ: JMP NOCLUSTERS
813
814
815 CHASELOOP: ;an014;bgb
816 PUSH BX ;an014;bgb
817 CALL UNPACK ;an014;bgb
818 POP BX ;an014;bgb
819 INC CX ;an014;bgb
820 XCHG SI,DI ;an014;bgb
821 CMP SI,[EOFVAL] ;an014;bgb
822 JAE CHAINDONE ;an014;bgb
823 CMP SI,2 ;an014;bgb
824 JB MRKBAD ;an014;bgb
825 CMP SI,[MCLUS] ;an014;bgb
826 JBE MRKOK ;an014;bgb
827 MRKBAD: ;Bad cluster # in chain
828 PUSH CX ;an014;bgb
829 PUSH DI ;an014;bgb
830 CALL get_THISELERR ;an014;bgb
831 MOV DX,OFFSET dg:BADCHAIN ;an014;bgb
832 CALL EPRINT ;an014;bgb
833 POP SI ;an014;bgb
834 MOV DX,0FFFH ;Insert EOF ;an014;bgb
835 CMP [BIGFAT],0 ;an014;bgb
836 JZ FAT12_1 ;an014;bgb
837 MOV DX,0FFFFH ;an014;bgb
838 FAT12_1: ;an014;bgb ;an014;bgb ;an014;bgb
839 PUSH BX ;an014;bgb
840 CALL PACK ;an014;bgb
841 POP BX ;an014;bgb
842 POP CX ;an014;bgb
843 JMP SHORT CHAINDONE ;an014;bgb
844
845 MRKOK:
846 CALL MARKMAP ;an014;bgb
847 JZ CHASELOOP ;an014;bgb
848Public CrossLink
849CROSSLINK: ;File is cross linked
850 INC [ISCROSS] ;an014;bgb
851 CMP [SECONDPASS],False ; ;an014;bgb ;AC000;
852 JZ CHAINDONE ;Crosslinks only on second pass ;an014;bgb
853 mov [cross_clus],si ;Cluster number ;an014;bgb
854 CALL get_THISEL ;an014;bgb
855 Message File_Arg ;Print file out ;an014;bgb ;AN000;
856 MOV DX,OFFSET DG:CROSS_arg ;Print message out ;an014;bgb ;AC000;
857 CALL PRINTf_crlf ;an014;bgb
858Public ChainDone
859CHAINDONE:
860 TEST [BX.DIRATT],ISDIR
861 JNZ NOSIZE ;Don't size dirs
862 CMP [ISCROSS],0
863 JNZ NOSIZE ;Don't size cross linked files;an014;bgb
864 CMP [SECONDPASS],False ;
865 JNZ NOSIZE ;Don't size on pass 2 (CX garbage)
866 MOV AL,[CSIZE]
867 XOR AH,AH
868 MUL [SSIZE]
869 PUSH AX ;Size in bytes of one alloc unit
870 MUL CX
871 MOV DI,DX ;Save allocation size
872 MOV SI,AX
873 SUB AX,WORD PTR [BX.DIRESIZ]
874 SBB DX,WORD PTR [BX.DIRESIZ+2]
875 JC BADFSIZ ;Size to big
876 OR DX,DX
877 JNZ BADFSIZ ;Size to small
878 POP DX
879 CMP AX,DX
880 JB NOSIZE ;Size within one Alloc unit
881 PUSH DX ;Size too small
882 PUBLIC BadFSiz
883 BADFSIZ:
884 POP DX
885 PUSH CX ;Save size of file
886 MOV WORD PTR [BX.DIRESIZ],SI
887 MOV WORD PTR [BX.DIRESIZ+2],DI
888 CALL FIXENT2 ;Fix it
889 CALL get_THISELERR
890 MOV DX,OFFSET DG:BADCLUS
891 CALL EPRINT
892 POP CX ;Restore size of file
893 NOSIZE:
894 MOV SI,BX
895 MOV BX,[SRFCBPT]
896 RET
897
898 NOCLUSTERS:
899 ;File is zero length
900 OR SI,SI
901 JZ CHKSIZ ;Firclus is OK, Check size
902 MOV DX,OFFSET DG:NULNZ
903 ADJUST:
904 PUSH DX
905 CALL get_THISELERR
906 POP DX
907 CALL EPRINT
908 XOR SI,SI
909 MOV [BX.DIRCLUS],SI ;Set it to 0
910 MOV WORD PTR [BX.DIRESIZ],SI ;Set size too
911 MOV WORD PTR [BX.DIRESIZ+2],SI
912 CALL FIXENT2 ;Fix it
913 INC [ZEROTRUNC] ;Indicate truncation
914 JMP CHAINDONE
915
916 PUBLIC ChkSiz
917 CHKSIZ:
918 MOV DX,OFFSET DG:BADCLUS
919 CMP WORD PTR [BX.DIRESIZ],0
920 JNZ ADJUST ;Size wrong
921 CMP WORD PTR [BX.DIRESIZ+2],0
922 JNZ ADJUST ;Size wrong
923 JMP CHAINDONE ;Size OK
924
925
926SUBTTL Routines for manipulating dir entries
927PAGE
928
929FIXENT2:
930;Same as FIXENT only [SRFCBPT] points to the search FCB, BX points to the entry
931 savereg <si,bx,cx>
932 MOV SI,BX
933 MOV BX,[SRFCBPT]
934 CALL FIXENT
935 restorereg <cx,bx,si>
936RET20: RET
937
938FIXENT:
939;BX Points to search FCB
940;SI Points to Entry to fix
941 MOV [HAVFIX],1 ;Indicate a fix
942 CMP [DOFIX],0 ;did the user enter /f flag?
943 JZ fixret ;zero means no - dont fix it
944 savereg <bp,bx,si,si>
945 MOV AX,[BX+THISENT] ;Entry number
946 CALL GETENT
947 POP SI ;Entry pointer
948 ADD SI,DIRNAM ;Point to start of entry
949 MOV CX,32
950 REP MOVSB
951 INC CL
952 CALL DOINT26
953 restorereg <si,bx,bp>
954fixret: RET
955
956
957
958;***************************************************************************** ;ac048;bgb
959; GETENT - calculate, and read into ram, the sector of the directory entry ;ac048;bgb
960; that is invalid. This entry can be in either the root directory, ;ac048;bgb
961; or in a sub-directory. If it is in the root, it can be in the first ;ac048;bgb
962; sector of the root dir, or in a subsequent sector. If it is in a ;ac048;bgb
963; subdirectory, it can be in the first cluster of the subdir, or in ;ac048;bgb
964; any subsequent cluster. It can also be in the first sector of the ;ac048;bgb
965; cluster, or in any of the following sectors within that cluster. ;ac048;bgb
966; ;ac048;bgb
967; WARNING!! NOTE!! --> this procedure has a limit on the input value of 64k ;ac048;bgb
968; entries. If the disk fails on an entry in a subdir ;ac048;bgb
969; which has an invalid entry past this value, then the ;ac048;bgb
970; calling procedure will probably wrap on this word value, ;ac048;bgb
971; causing getent to calc the wrong sector, and then ;ac048;bgb
972; corrupting the disk. Not likely, but poss. ;ac048;bgb
973; ;ac048;bgb
974; called by - nodot/mesd1 - no . entry found (always subdir) ;ac048;bgb
975; - noddot/mesd2 - no .. entry found (always subdir) ;ac048;bgb
976; - askconv/printtrmes - convert dir to file (can be in root) ;ac048;bgb
977; - makfillp - find root entry in which to place lost clus ;ac048;bgb
978; ;ac048;bgb
979; inputs - AX - desired entry num (in curr dir, reffed off BP) ;ac048;bgb
980; 0=. 1=.. 2=first entry ;ac048;bgb
981; DX - number of lost clusters
982; BP - ptr to extended fcb for this dir ;ac048;bgb
983; BP+6 - 1st cluster number of this dir ;ac048;bgb
984; ;ac048;bgb
985; output - AX - contains number of the disk to use for int26 ;ac048;bgb
986; DI - points to entry in subdir in ram ;ac048;bgb
987; DX - low sector number of the dir ;ac048;bgb
988; BX - ram offset of the sector ;ac048;bgb
989; Read_Write_Relative.Start_Sector_Hi - hi sector number of the dir ;ac048;bgb
990; ;ac048;bgb
991; Regs abused - all of 'em !! (ok, well, maybe not bp...) ;ac048;bgb
992; ;ac048;bgb
993;logic: 1. make sure there will not be a problem with the cluster number. This ;ac048;bgb
994; should not be a problem, since if the cluster number is invalid, it ;ac048;bgb
995; should have been flagged by previous routines. ;ac048;bgb
996; ;ac048;bgb
997; 2. calc clus-num & offset ;ac048;bgb
998; Entries * bytes/entry / BPS --> number of sectors from the beg of ;ac048;bgb
999; the dir. There are 16 entries per sector (starting at zero). The ;ac048;bgb
1000; bytes/entry and bytes/sector are condensed, giving a div by 16, ;ac048;bgb
1001; instead of "* 32 / 512". Now we have the first cluster (0-fff7), ;ac048;bgb
1002; the sector-offset (0-fff), and the entry-offset (0-f). ;ac048;bgb
1003; ;ac048;bgb
1004; forumla: entry (0-ffff) / 16 = sector-offset (0-fff) ax ;ac048;bgb
1005; = entry-offset (0-f) dx ;ac048;bgb
1006; ;ac048;bgb
1007; 3. if we are in the root directory, then we have the correct sector ;ac048;bgb
1008; number, so just add it to the starting sector number of the ;ac048;bgb
1009; directory. ;ac048;bgb
1010; ;ac048;bgb
1011; 4. otherwise, we are in a subdirectory. Here, we need to get the ;ac048;bgb
1012; cluster-offset, since the sector-offset can be more than 1 cluster ;ac048;bgb
1013; in length. So, divide the sectors by (secs/clus) to get cluster- ;ac048;bgb
1014; offset. This value is now a power of 2, from 2 up to 16. ;ac048;bgb
1015; ;ac048;bgb
1016; / sectors/cluster (2-16) = cluster offset AL ;ac048;bgb
1017; = sector offset AH ;ac048;bgb
1018; ;ac048;bgb
1019; 5. If AL > 0, then we have to walk the fat chain to find the cluster ;ac048;bgb
1020; where this sector is. Fortunately, we have the starting cluster ;ac048;bgb
1021; number (BX), UNPACK will find the next cluster number, and we have ;ac048;bgb
1022; the number of clusters to jump (AL). So, move the appropriate ;ac048;bgb
1023; into the regs, and loop until completed. Now BX has the correct ;ac048;bgb
1024; cluster number. ;ac048;bgb
1025; ;ac048;bgb
1026; 6. Now we need to translate the cluster and sector numbers into an ;ac048;bgb
1027; absolute, double word, sector number. FIGREC will do this. ;ac048;bgb
1028; ;ac048;bgb
1029; 7. Now, from either root dir, or from subdir, we have the absolute ;ac048;bgb
1030; sector, so set up the regs, and call READ_DISK to read it into ram. ;ac048;bgb
1031; Now DX contains the sector number (low), and BX points to the ;ac048;bgb
1032; sector in ram. ;ac048;bgb
1033; ;ac048;bgb
1034; 8. Finally, get the entry-offset that we had stored on the stack, and ;ac048;bgb
1035; translate it into a byte-offset by multpying it times the number of ;ac048;bgb
1036; bytes per entry (32). Now DI points to the entry in ram. ;ac048;bgb
1037;***************************************************************************** ;ac048;bgb
1038GETENT: ;ac048;bgb
1039 mov bx,[bp+6] ;Get 1st cluster of subdir ;ac048;bgb
1040;double check for invalid cluster ;ac048;bgb
1041 cmp bx,[eofval] ;Last entry in cluster? ;ac048;bgb
1042; $IF NB ;ac048;bgb
1043 JB $$IF37
1044 mov bx,offset dg:baddpbdir ;This should never happen ;ac048;bgb
1045 jmp fatal ;Danger, warning Phil Robins;ac048;bgbon
1046; $ENDIF ;ac048;bgb
1047$$IF37:
1048 ;ac048;bgb
1049CLUSISOK: ;ac048;bgb
1050;calc cluster number and offset ;ac048;bgb
1051 mov cx,16 ;32 bytes/entry / 512 bytes/sec ;ac048;bgb
1052 xor dx,dx ;zero out hi word for divide ;ac048;bgb
1053 div cx ;NOW- bx=first clus, ax=sec-offset, dx=entry-offset ;ac048;bgb
1054 ;NOTE: ax can be > 1 cluster ;ac048;bgb
1055;are we at the root? ;ac048;bgb
1056 or bx,bx ;cluster zero? ;ac048;bgb
1057; $IF Z ;yes, then we are in root dir ;ac048;bgb
1058 JNZ $$IF39
1059 ;;;;;;;;jz wantroot ;Cluster 0 means root dir ;ac048;bgb
1060WANTROOT: push dx ;restored as di- ptr to invalid entry ;ac048;bgb
1061 mov dx,ax ;get sector offset ;ac048;bgb
1062 add dx,[dirsec] ;add in first sector of dir ;ac048;bgb
1063 mov Read_Write_Relative.Start_Sector_High,0 ;save hi value ;ac048;bgb
1064 ;;;;;;;;;;;JMP DOROOTDIR ;now ready for int25 ;ac048;bgb
1065 ;ac048;bgb
1066; $ELSE ;not in root dir ;ac048;bgb
1067 JMP SHORT $$EN39
1068$$IF39:
1069NOTROOT: div csize ;divide by sectors/cluster (2-16) ;ac048;bgb
1070 ;AL=# cluster-offset (QUO), AH= sector-offset (REM);ac048;bgb
1071 mov cl,al ;get cluster offset from al ;ac048;bgb
1072 xor ch,ch ;zero out hi byte to make word value ;ac048;bgb
1073 or cx,cx ;do we have more than one cluster worth to go yet? ;ac048;bgb
1074; $IF NZ ;yes - we have to walk the chain to find it ;ac048;bgb
1075 JZ $$IF41
1076 ;;;;;;;;JCXZ GOTCLUS ;jump if cx reg = zero ;ac048;bgb
1077 mov si,bx ;move the cluster num for input ;ac048;bgb
1078SKIPLP: call unpack ;find the next cluster number ;ac048;bgb
1079 xchg si,di ;move it into input position ;ac048;bgb
1080 loop skiplp ;do for number of cluster-offset ;ac048;bgb
1081 mov bx,si ;now we have the cluster number ;ac048;bgb
1082; $ENDIF ;ac048;bgb
1083$$IF41:
1084 ;ac048;bgb
1085;calculate the sector from the cluster & sec-offset ;ac048;bgb
1086GOTCLUS: push dx ;restored as di -> entry offset ;ac048;bgb
1087 call figrec ;Convert to sector # - ax=low, dx=hi ;ac048;bgb
1088; $ENDIF ;are we in root dir? ;ac048;bgb
1089$$EN39:
1090 ;ac048;bgb
1091DOROOTDIR: ;ac048;bgb
1092 mov bx,[secbuf] ;get offset of ram area ;ac048;bgb
1093 mov al,[alldrv] ;get drive number ;ac048;bgb
1094 dec al ;adjust for int25 ;ac048;bgb
1095RDRETRY: mov cx,1 ;read 1 sector ;ac048;bgb
1096 call Read_Disk ;do it ;ac048;bgb
1097 jnc rdok2 ;was it good? ;ac048;bgb
1098;Need to handle 'Fail' option of critical error here ;ac048;bgb
1099 JZ RDRETRY ;ac048;bgb
1100 ;ac048;bgb
1101RDOK2: pop ax ;get byte-offset into sector ;ac048;bgb
1102 mov cl,5 ;value of 32= bytes per entry ;ac048;bgb
1103 shl ax,cl ;mul entry offset to get byte offset ;ac048;bgb
1104 add ax,bx ;add in offset of dir in ram ;ac048;bgb
1105 mov di,ax ;ac048;bgb
1106 mov al,[alldrv] ;get drive number ;ac048;bgb
1107 dec al ;adjust for int26 ;ac048;bgb
1108 RET ;di now points to offending entry ;ac048;bgb
1109;***************************************************************************** ;ac048;bgb
1110
1111
1112
1113
1114CHECKNOFMES:
1115 MOV AL,1
1116 XCHG AL,[FIXMFLG]
1117 OR AL,AL
1118 JNZ RET14 ;Don't print it more than once
1119 CMP [DOFIX],0
1120 JNZ RET14 ;Don't print it if F switch specified
1121 mov dx,offset dg:FIXMES_arg
1122 CALL PRINTf_crlf
1123 call DoCRLF ; ;AN000;
1124ret14: RET
1125
1126CHECKERR:
1127 CALL CHECKNOFMES
1128 CMP [SECONDPASS],False ; ;AC000;
1129 RET
1130
1131get_currdirERR:
1132 CALL CHECKERR
1133 jz ok_pri_dir
1134 mov byte ptr [arg_buf],0
1135 ret
1136ok_pri_dir:
1137 CALL get_currdir
1138 ret
1139
1140get_thiselERR:
1141 CALL CHECKERR
1142 jz ok_pri_el
1143 mov byte ptr [arg_buf],0
1144ok_pri_el:
1145 CALL get_thisel
1146 RET
1147
1148get_THISEL:
1149 MOV SI,BX
1150 ADD SI,DIRNAM
1151;*****************************************************************************
1152; called by: checkfiles
1153; inputs: AX - number of fragments
1154; SI
1155;*****************************************************************************
1156get_THISEL2:
1157 MOV DI,OFFSET DG:NAMBUF
1158 PUSH DI
1159 CALL FCB_TO_ASCZ
1160 POP SI
1161get_currdir:
1162 PUSH SI
1163; get drive letter prefix (c:\)
1164 mov di,offset dg:arg_buf
1165 MOV al,[ALLDRV]
1166 ADD al,'@'
1167 stosb
1168 MOV al,[DRVCHAR]
1169 stosb
1170 mov al,[DIRCHAR]
1171 stosb
1172 MOV SI,DI
1173; get the name of the current directory, and put it into es:di
1174 MOV DL,[ALLDRV]
1175 DOS_Call Current_Dir ; ;AC000;
1176GET_END:
1177;find the end of the string - it will be hex zero
1178 LODSB
1179 OR AL,AL
1180 JNZ GET_END
1181;
1182 DEC SI ; Point at NUL
1183 MOV DI,SI
1184 POP SI ;point to begin of string
1185 CMP BYTE PTR [SI],0
1186 JZ LPDONE ;If tail string NUL, no '/'
1187; move '\' for between path and filename
1188 MOV al,[DIRCHAR]
1189 CMP BYTE PTR [DI - 1],AL
1190 JZ ERRLOOP ; Don't double '/' if root
1191 stosb
1192ERRLOOP:
1193; move filename from ds:si to es:di until find hex zero
1194 LODSB
1195 OR AL,AL
1196 JZ LPDONE
1197 stosb
1198 JMP ERRLOOP
1199LPDONE:
1200; finish off string with hex zero for asciiz
1201 mov al,0
1202 stosb
1203 RET
1204
1205CHECK_SPLICE:
1206; Carry set if current directory is NOT spliced (joined) onto.
1207; Carry clear if current directory is spliced (joined) onto.
1208
1209 MOV SI,OFFSET DG:NUL
1210 CALL get_currdir ; Build ASCIZ text of current dir
1211 ; at arg_buf
1212 mov si,offset dg:arg_buf
1213 mov di,offset dg:TMP_SPC
1214 DOS_Call xNameTrans ; ;AC000;
1215 JC NT_SPLC ; Say NOT spliced if error
1216 CMP WORD PTR [TMP_SPC+1],"\" SHL 8 OR ":"
1217 JNZ NT_SPLC
1218 CMP BYTE PTR [TMP_SPC+3],0
1219 JNZ NT_SPLC
1220 MOV AL,BYTE PTR [arg_buf] ; Source drive letter
1221 CMP AL,BYTE PTR [TMP_SPC] ; Different from dest if spliced
1222 JZ NT_SPLC ; Drive letter didn't change
1223 CLC
1224 RET
1225
1226NT_SPLC:
1227 STC
1228 RET
1229
1230
1231;*****************************************************************************
1232;Routine name: MarkFAT
1233;*****************************************************************************
1234;
1235;Description: Trace the fat chain for a single file, marking entries in FATMap,
1236; and handling errors -
1237; (crosslink, truncation, allocation error, invalid cluster entry)
1238;
1239; called by : moredir
1240; newdir
1241;
1242;Called Procedures: Unpack
1243; Bad_Cluster
1244; MarkMap
1245; Check_Chain_Sizes
1246; ThisEl
1247; Eprint
1248;
1249;Change History: Created 5/10/87 MT
1250;
1251;Input: BX = pointer to search FCB
1252; AL is head mark with app type =81h
1253; SI = points to dir entry
1254; DI = cluster entry of file or XA in directory
1255; File_Size_Low/High = bytes length directory or XA structure says
1256; the data area is
1257; SecondPass = TRUE/FALSE
1258; XA_Pass = TRUE/FALSE
1259; EOFVal = 0FF8h/0FFF8h
1260;
1261;Output:
1262; ZEROTRUNC is non zero if the file was trimmed to zero length
1263; ISCROSS is non zero if the file is cross linked
1264; BX,SI preserved
1265; Cluster_Count = number of clusters in chain
1266; carry flag is set if the clusters are ok
1267; fatmap entries - 81h = head of file,
1268; 01h = used cluster
1269;
1270;Psuedocode
1271;----------
1272;
1273; ZeroTrunc,IsCross = FALSE, SRFCBPT = BX, Cluster_Count = 0
1274; Get file cluster entry (CALL Unpack)
1275; IF cluster < 2 or > maximum cluster (MClus)
1276; Go handle invalid cluster (CALL Bad_Cluster)
1277; ELSE
1278; SEARCH
1279; Go mark cluster in FATMap (CALL MarkMAP)
1280; Turn off head bit on FATMap marker
1281; EXITIF Crosslink
1282; IsCross = TRUE
1283; IF SecondPass = FALSE
1284; Setup filename for message (CALL ThisEl)
1285; Display crosslink message (Call Eprint)
1286; ENDIF
1287; ORELSE (no crosslink)
1288; Get next cluster (CALL Unpack)
1289; IF Cluster >= EOFVAL [(0/F)FF8h]
1290; Verify file sizes (CALL Check_Chain_Sizes)
1291; clc (Force loop to end)
1292; ELSE
1293; IF cluster < 2 or > maximum cluster (MClus)
1294; Go handle invalid cluster (CALL Bad_Cluster)
1295; clc (Force loop to end)
1296; ELSE
1297; stc (Force loop to keep goining
1298; ENDIF
1299; ENDIF
1300; ENDLOOP clc
1301; ENDSRCH
1302; ENDIF
1303; ret
1304;*****************************************************************************
1305Procedure MarkFAT ; ;AN000;
1306 push si ;AN000;
1307 push bx ;AN000;
1308 mov Head_Mark,al ;Save flag to put in map ;AN000;
1309 mov ZeroTrunc,False ;Init values ; ;
1310 mov IsCross,False ; ; ;
1311 mov Cluster_Count,0 ;Init count of clusters ; ;
1312 mov SrFCBPt,bx ;Pointer to search FCB ; ;
1313 mov First_Cluster,di ; ;AN000;
1314 mov Previous_Cluster,di ;Init pointer
1315 cmp di,2 ;Cluster < 2? ;AC000;
1316; $IF B,OR ; or ;AC000;
1317 JB $$LL44
1318 cmp di,MClus ;Cluster > total clusters? ;AC000;
1319; $IF A ; ;AC000;
1320 JNA $$IF44
1321$$LL44:
1322 cmp word ptr [si].dirclus,0 ;if both cluster and size = 0, ;an025;bgb
1323; $IF NE,OR ;then its not an error, ;an025;bgb
1324 JNE $$LL45
1325 cmp word ptr [si].diresiz,0 ;and dont print msg ;an025;bgb
1326; $IF NE ;an025;bgb
1327 JE $$IF45
1328$$LL45:
1329 call Bad_Cluster ;Yes, go indicate bad stuff ;AN000;
1330; $ENDIF
1331$$IF45:
1332; $ELSE ;Cluster in valid range ;AN000;
1333 JMP SHORT $$EN44
1334$$IF44:
1335; $SEARCH ;Chase the cluster chain ;AN000;
1336$$DO48:
1337 mov al,Head_Mark ;Get flag for map 01 ;AC000;
1338 call MarkMap ;Mark the cluster (SI) ;AC000;
1339 push ax ;Save head mark ;AN000;
1340 lahf ;Save CY status
1341 and Head_Mark,Head_Mask ;Turn off head bit of map flag ;AC000;
1342 sahf ;Get CY flags back
1343 pop ax ;Get haed mark back ;AN000;
1344; $EXITIF C ;Quit if crosslink ;AC000;
1345 JNC $$IF48
1346 mov IsCross,True ;Set crosslink flag ;AC000;
1347 cmp SecondPass,True ;Handle crosslink 2nd pass only ;AC000;
1348; $IF E ;This is first pass ;AC000;
1349 JNE $$IF50
1350 mov Cross_Clus,di ;Put cluster in message ;AN000;
1351 push bx ;Get dir pointer into bx ;AN000;
1352 push si ; ;AN000;
1353 mov bx,si ; for the call ;AN000;
1354 call Get_ThisELErr ; ;AC000;
1355 mov dx,offset DG:Cross_arg ;Specify error message ;AC000;
1356 call EPrint ;Go print file and error ;AC000;
1357 pop si ; ;AN000;
1358 pop bx ; ;AN000;
1359 Message Cross_Arg ; ;AC000;
1360; $ENDIF ; ;AN000;
1361$$IF50:
1362; $ORELSE ;No crosslink found ;AN000;
1363 JMP SHORT $$SR48
1364$$IF48:
1365 push si ;Save dir pointer
1366 mov si,di ;Provide current cluster
1367 mov Previous_Cluster,di ;Save current cluster
1368 call UnPack ;Get next cluster entry (di) ;AC000;
1369 inc Cluster_Count ;Got a cluster ;AN000;
1370 pop si ;Get dir pointer back
1371 cmp di,EOFVal ;Is it the last clus in file? ;AC000;
1372; $IF AE ;Yes - good chain so far ;AN000;
1373 JNAE $$IF53
1374 call Check_Chain_Sizes ;Go verify file sizes ;AN000;
1375 clc ;Clear CY to force exit ;AN000;
1376; $ELSE ;Not end of chain
1377 JMP SHORT $$EN53
1378$$IF53:
1379 cmp di,2 ;Cluster < 2? ;AC000;
1380; $IF B,OR ; or ;AC000;
1381 JB $$LL55
1382 cmp di,MClus ;Cluster > total clusters? ;AC000;
1383; $IF A ;Yep ;AN000;
1384 JNA $$IF55
1385$$LL55:
1386 call Bad_Cluster ;Yes, go indicate bad stuff ;AN000;
1387 clc ;Clear CY to force loop exit ;AN000;
1388; $ELSE ;No, more clusters to go ;AN000;
1389 JMP SHORT $$EN55
1390$$IF55:
1391 stc ;Set CY to keep going ;AN000;
1392; $ENDIF ; ;AN000;
1393$$EN55:
1394; $ENDIF ;
1395$$EN53:
1396; $ENDLOOP NC ;Exit if done with chain ;AN000;
1397 JC $$DO48
1398; $ENDSRCH ;End of chain chase loop ;AN000;
1399$$SR48:
1400; $ENDIF ;
1401$$EN44:
1402 pop bx ;Restore registers ;AN000;
1403 pop si ; ;AN000;
1404 ret ; ;AN000;
1405MarkFAT endp ; ;AN000;
1406
1407;*****************************************************************************
1408;Routine name: Bad_Cluster
1409;*****************************************************************************
1410;
1411;description: IF first cluster =0, truncate file or XA to zero length.
1412; If bad cluster elsewhere, put in EOFVal.
1413;
1414;Called Procedures: Get_ThisElErr
1415; Eprint
1416; FixENT2
1417;
1418;Change History: Created 5/10/87 MT
1419;
1420;Input: First_Cluster
1421; Chain_End
1422; XA_PASS = TRUE/FALSE
1423; DI = Cluster entry
1424; SI = dir block pointer
1425; First_Cluster = first cluster or extended XA
1426; Previous_Cluster = last good cluster number
1427;
1428;Output: ZeroTrunc = TRUE/FALSE
1429;
1430;Psuedocode
1431;----------
1432;
1433; Setup filename for any messages (Call Get_ThisELErr)
1434; IF cluster = First_Cluster
1435; IF XA_PASS = FALSE
1436; Zero out file length in DIR
1437; Setup message (CALL Get_ThisElErr)
1438; Display message (Call Eprint)
1439; ELSE (XA pass)
1440; Zero out XA pointer
1441; Setup message (CALL Get_ThisElErr)
1442; Display message (Call Eprint)
1443; ENDIF
1444; Write out corrected directory (CALL FixENT2)
1445; ELSE (cluster other than first in chain)
1446; IF XA_Pass = TRUE
1447; Display Bad XA cluster message
1448; ELSE (!XA_Pass)
1449; Display bad file chain message
1450; ENDIF
1451; Move EOF into bad cluster (CALL PACK - Chain_End)
1452; ENDIF
1453; ret
1454;*****************************************************************************
1455Procedure Bad_Cluster ; ;AN000;
1456 savereg <si,di,dx,si,di,bx> ;Preserve registers ;AN000;
1457 mov bx,si ; for the call ;AN000;
1458 call Get_ThisElErr ;Setup message ;AC000;
1459 restorereg <bx,di,si>
1460 cmp di,First_Cluster ;does 1st clus point to itself? ;Need to change the directory ;AC000;
1461; $IF E,OR ;yes ; pointer if the dir cluster or ;AC000;
1462 JE $$LL62
1463 push di ;if not, try this next test ; XA is bad, or the last good ;AN000;
1464 mov di,Previous_Cluster ;get prev cluster ; entry was the dir cluster or ;AN000;
1465 cmp di,First_Cluster ;does prev clus = 1st clus? ; XA cluster. ;AN000;
1466 pop di ;means the 1st cluster is bad
1467; $IF E ;yes ; ;AN000;
1468 JNE $$IF62
1469$$LL62:
1470 cmp word ptr [si].dirclus,0 ;is cluster num already 0? ;an025;bgb
1471; $IF NE ;no, its bad ;an025;bgb
1472 JE $$IF63
1473 mov dx,offset DG:NulNZ ;1st cluster number is invalid;an025;bgb
1474 call EPrint ;Go print file and error ;an025;bgb
1475 mov word ptr [si].dirclus,0 ;set cluster number to 0 ;an025;bgb
1476 mov zerotrunc,true ;modified the file size ;an026;bgb
1477; $ENDIF ;already set to 0, dont print err msg ;an025;bgb
1478$$IF63:
1479 mov word ptr [si].DIRESIZ,0 ;set file size to 0 ;Kill the file size ;AC000;
1480 mov word ptr [si].DIRESIZ+2,0 ;Kill the file size ;AC000;0;
1481 mov bx,si ;Get pointer to directory ;AN000;
1482 call FixEnt2 ;Write out updated directory ;AC000;
1483; $ELSE ;Not first cluster in chain ;AN000;
1484 JMP SHORT $$EN62
1485$$IF62:
1486 mov dx,offset dg:Badchain ;Tell user file and error ;AN000;
1487 call EPrint ;AN000;
1488 mov dx,Chain_End ;Terminate chain at bad spot ;AC000;
1489 mov si,Previous_Cluster ;Change the last good cluster ;AC000;
1490 call Pack ;Go fix it ;AC000;
1491; $ENDIF ; ;AN000;
1492$$EN62:
1493 restorereg <dx,di,si>
1494 ret ;
1495Bad_Cluster endp ; ;AN000;
1496
1497;*****************************************************************************
1498;Routine name: Check_Chain_Sizes
1499;*****************************************************************************
1500;
1501;description: See if length of chain as listed in dir or XA matches up
1502; with the number of clusters allocated. Don't check if crosslink
1503; error, or chasing directory chain.
1504;
1505;Called Procedures: FixEnt
1506; Bad_Chain_Size
1507;
1508;
1509;Change History: Created 5/10/87 MT
1510;
1511;Input: CSIZE = sectors per cluster
1512; SSIZE = bytes per sector
1513; Cluster_Count = number of clusters in chain
1514; File_Size_Low/High = bytes dir or XA says is in chain
1515; SI = Pointer to Dir entry
1516;
1517;Output: Cluster_Count = Size of chain in clusters
1518; SI = Pointer to dir entry
1519; BX = SRFCBPT
1520;
1521;Psuedocode
1522;----------
1523;
1524; IF !Directory attribute,AND
1525; IF !Crosslinked (ISCROSS = FALSE),AND
1526; IF !Second pass (SecondPass = FALSE)
1527; Compute bytes/cluster
1528; Compute bytes/chain
1529; IF size > File_Size_High/Low
1530; Fix the size (CALL Bad_Chain_Size)
1531; ELSE
1532; Subtract file size from chain length
1533; IF Difference in Chain_Length and Size >= bytes/cluster
1534; Fix the size (CALL Bad_Chain_Size)
1535; ENDIF
1536; ENDIF
1537; ENDIF
1538; ENDIF
1539; CX = Cluster_Count (kept for compatibility with old code)
1540; BX = SRFCPT (kept for compatibility with old code)
1541; ret
1542;*****************************************************************************
1543Procedure Check_Chain_Sizes ;AN000;
1544 push si ; ;AN000;
1545 push ax ; ;AN000;
1546 test [si].DirAtt,Dir_Attribute ;Is this a directory? ;AC000;
1547; $IF Z,AND ;No ;AC000;
1548 JNZ $$IF67
1549 cmp IsCross,False ; and,is it crosslinked? ;AC000;
1550; $IF E,AND ;No ;AC000;
1551 JNE $$IF67
1552 cmp SecondPass,False ;and, is this the first pass? ;AC000;
1553; $IF E ;Yes, ;AC000;
1554 JNE $$IF67
1555 xor ax,ax ;AX =0 ;AC000;
1556 mov ax,SSize ;Get (bytes/sector) * ;AC000;
1557 mov cl,CSize ; (Sectors/cluster) ;AC000;
1558 mul cx ;AX=Bytes/cluster (< 64k) ;AC000;
1559 mov BClus,ax ;Save Bytes/cluster ;AN000;
1560 mov cx,Cluster_Count ;Number of clusters in chain ;AC000;
1561 mul cx ;DX:AX = bytes/chain ;AC000;
1562 mov Chain_Size_Low,ax ;Save allocation size in bytes ;AN000;
1563 mov Chain_Size_High,dx ; ;AN000;
1564 cmp dx,File_Size_High ;See if file size if greater ;AN000;
1565; $IF E,AND ; than chain length - if ;AN000;
1566 JNE $$IF68
1567 cmp ax,File_Size_Low ; so, than there is an ;AC000;
1568; $IF B ; allocation error. ;AC000;
1569 JNB $$IF68
1570 call Bad_Chain_Size ;Fix it! ;AC013;bgb
1571; $ELSE ;Chain larger than file ;AC000;
1572 JMP SHORT $$EN68
1573$$IF68:
1574 cmp dx,File_Size_High ;See if high part lower ;AN000;
1575; $IF B ;Chain < filsize if so ;AN000;
1576 JNB $$IF70
1577 call Bad_Chain_Size ;Fix it! ;AC013;bgb
1578; $ELSE ;Chain > filesize ;AN000;
1579 JMP SHORT $$EN70
1580$$IF70:
1581 mov cx,File_Size_Low ;See if within 1 cluster ;AN000;
1582 mov bx,File_Size_High ; ;AN000;
1583 sub ax,cx ;Subtract file size from ;AC000;
1584 sbb dx,bx ; the chain size ;AN000;
1585 cmp dx,0 ;See if within 1 cluster ;AN000;
1586; $IF NE,OR ;Not if high size set,or ;AN000;
1587 JNE $$LL72
1588 cmp ax,BClus ;Within (bytes/cluster -1)? ;AC000;
1589; $IF AE ;Nope, allocation error ;AC000;
1590 JNAE $$IF72
1591$$LL72:
1592 call Bad_Chain_Size ;Go fix the chain ;AN013;bgb
1593; $ENDIF ; ;AN000;
1594$$IF72:
1595; $ENDIF ; ;AN000;
1596$$EN70:
1597; $ENDIF ; ;AN000;
1598$$EN68:
1599; $ENDIF ; ;AN000;
1600$$IF67:
1601 mov bx,SrFCBPt ; Needed for compat ;AC000;
1602 pop ax ;Restore used regs ;AN000;
1603 pop si ;SI = Dir pointer ;AN000;
1604 ret ; ; ;
1605check_chain_sizes endp ; ;AN000;
1606
1607
1608
1609Procedure print_filename ;AN000;
1610 PUSH BX
1611 MOV BX,SI
1612 CALL get_THISEL
1613 mov dx,offset dg:noisy_arg
1614 call printf_crlf
1615 MOV SI,BX
1616 POP BX
1617 return
1618print_filename endp ; ;AN000;
1619
1620;these procedures were for the extended attribute support, which was removed ;an006;bgb
1621
1622;*****************************************************************************
1623;Routine name: Bad_Chain_Size
1624;*****************************************************************************
1625;
1626;Description: adjust
1627; filesize to allocation length.
1628;
1629;Called Procedures: Truncate_XA
1630; FixEnt2
1631; Get_ThisElErr
1632; Eprint
1633;
1634;Change History: Created 5/11/87 MT
1635;
1636;Input: XA_Pass = TRUE/FALSE
1637; Chain_Size_High/Low
1638; SI = Dir pointer
1639; Chain_Size_Low/High = length in bytes of allocation chain
1640;
1641;Output: None
1642;
1643;Psuedocode
1644;----------
1645;
1646; IF XA_Pass
1647; Delete XA chain (CALL Truncate_XA)
1648; ELSE
1649; Set directory entry to length = Total allocation size
1650; Go write out (CALL FixEnt2)
1651; Setup message (CALL Get_Thiselerr)
1652; Display it (Call Eprint)
1653; ENDIF
1654; ret
1655;*****************************************************************************
1656Procedure Bad_Chain_Size ; ;AN000;
1657 push es
1658 push ax ;Save register ;AN000;
1659
1660 push ds ;make es point to dg
1661 pop es
1662;;;;;; cmp XA_Pass,True ;Are we handling XA's? ;AN013;bgb
1663;;;;;;;;$IF E ;Yes ;AN013;bgb
1664;;;;;;;;;;;call Truncate_XA ;Go truncate the chain ;AN013;bgb
1665;;;;;;;;$ELSE ;Normal file chain ;AN013;bgb
1666 mov ax,Chain_Size_Low ;Get length of allocation ;AN000;
1667 mov dx,Chain_Size_High ; chain for filesize ;AN000;
1668 mov word ptr [si].DirESiz,ax ;Put it in the directory ;AC000;
1669 mov word ptr [si+2].DirESiz,dx ; " " " " ;AC000;
1670 push bx ; ;AN000;
1671 push si ; ;AN000;
1672 mov bx,si ;Get pointer to directory ;AN000;
1673 call FixENT2 ;Write dir to disk ;AC000;
1674 call Get_ThisElErr ;Setup message ;AC000;
1675 mov dx,offset DG:BadClus ;Specify error message ;AC000;
1676 call EPrint ;Go print file and error ;AC000;
1677 pop si ; ;AN000;
1678 pop bx ; ;AN000;
1679;;;;;;;;$ENDIF ; ;AN013;bgb
1680 pop ax ;Restore registers ;AN000;
1681 pop es
1682 ret ;
1683
1684Bad_Chain_Size endp ; ;AN000;
1685
1686;*****************************************************************************
1687;Routine name: Truncate_XA
1688;*****************************************************************************
1689;
1690;Description: If /F entered, than truncate XA chain and remove pointer.
1691; If XA allocation error, than deallocate all of XA chain.
1692;
1693;Called Procedures: Get_ThisElErr
1694; Eprint
1695; MarkMap
1696; Unpack
1697; Pack
1698;
1699;Change History: Created 5/11/87 MT
1700;
1701;Input: First_Cluster
1702; Chain_End
1703; SI = directory entry pointer
1704;
1705;
1706;Output: FATMap entries for XA chain zero'd out
1707;
1708;Psuedocode
1709;----------
1710;
1711; Set XA pointer in dir to 0
1712; Write it out (CALL FixEnt2)
1713; Setup message (Call get_ThisElErr
1714; Display message (Call Eprint)
1715; Get first cluster number (First_Cluster)
1716; DO
1717; Get first cluster entry (Call Unpack)
1718; Go mark cluster in FATMap with "Open" (CALL MarkMAP)
1719; Set cluster entry with 0000 (Call Pack)
1720; ENDDO cluster value >= EOFVal
1721; ret
1722;*****************************************************************************
1723
1724;rocedure Truncate_XA ; ;AN000;
1725;
1726; push si ;Save dir pointer ;AN000;
1727; push bx ; ;AN000;
1728; push si ; ;AN000;
1729; mov bx,si ;Get directory pointer ;AN000;
1730; call Get_ThisEl ;Setup message ;AN000;
1731; mov dx,offset DG:Alloc_XA_Msg ;Specify error message ;AC000;
1732; call EPrint ;Go print file and error ;AC000;
1733; pop si ; ;AN000;
1734; mov word ptr [si].DIR_XA,No_Ext_Attrib ;Erase XA pointer ;AN000;
1735; call FixENT2 ;Write dir entry out ;AN000;
1736; pop bx ; ;AN000;
1737; mov si,First_Cluster ;Get first cluster ;AN000;
1738; $DO ;Chase and erase XA chain ;AN000;
1739; call Unpack ;Get next cluster ;AN000;
1740; push di ;Save it- DI next, SI current ;AN000;
1741; mov al,No_Entry ;Free entry in map ;AN000;
1742; call MarkMap ; " " " " ;AN000;
1743; mov dx,No_Entry ;Free up cluster in Fat ;AN000;
1744; call Pack ; " " " " ;AN000;
1745; pop si ;Get back next cluster ;AN000;
1746; cmp si,[EOFVal] ;Reached end of chain? ;AN000;
1747; $ENDDO AE ;Keep looping if not ;AN000;
1748; pop si ;Restore Dir pointer ;AN000;
1749; ret ; ;AN000;
1750;
1751;runcate_XA endp ; ;AN000;
1752
1753;*****************************************************************************
1754;Routine name: Check_Extended_Attributes
1755;*****************************************************************************
1756;
1757;Description: Get the first cluster of XA chain, if it is zero, than erase
1758; extended attribute pointer (/F only). Otherwise, map the
1759; cluster in the FATMAP. If crosslink found on first cluster,
1760; no more processing is done. If value other than EOF mark
1761; found in first cluster
1762;
1763;Called Procedures: Load_XA
1764; Fix_Bad_XA
1765; Check_XA_Structure
1766; MarkFAT
1767;
1768;Change History: Created 5/10/87 MT
1769;
1770;Input: SI = pointer to directory entry
1771;
1772;Output: FATMap marked with XA_Cluster for each XA cluster found
1773; XA_PASS = NO
1774;
1775;Psuedocode
1776;----------
1777;
1778; IF (XA exists for file)
1779; XA_PASS = YES
1780; DI = XA entry cluster in dir
1781; Load in first sector of XA (CALL Load_XA)
1782; IF !error
1783; File_Size_Low/High = length of XA's in bytes
1784; AL = chain head mark (XA_Chain)
1785; Trace chain and map it (CALL MarkFAT)
1786; ELSE
1787; call Bad_Cluster
1788; ENDIF
1789; ENDIF
1790; ret
1791;*****************************************************************************
1792
1793;rocedure Check_Extended_Attributes ; ;AN000;
1794;
1795; push ax ;Save register ;AN000;
1796; push cx ; ;AN000;
1797; push dx ; ;AN000;
1798; push di ; ;AN000;
1799; mov ax,[si].DIR_XA ;Get first cluster of XA's ;AN000;
1800; cmp ax,No_Ext_Attrib ;Are there extended attrib's ;AN000;
1801; $IF NE ;Quit if no ;AN000;
1802; mov di,ax ;Pointer to current cluster ;AN000;
1803; mov First_Cluster,di ;Remember first cluster ;AN000;
1804; mov XA_Pass,Yes ;Indicate processing XA's ;AN000;
1805; call Load_XA ;Go load sector ;AN000;
1806; $IF NC ;CY means load error ;AN000;
1807; mov ax,XA_Buffer.XAL_TSIZE ;Get bytes in XA chain ;AN000;
1808; mov File_Size_High,0 ;Save it ;AN000;
1809; mov File_Size_Low,ax ; ;AN000;
1810; mov al,XA_Chain ;Set up mark for map ;AN000;
1811; call MarkFAT ;Go map out chain ;AN000;
1812; $ELSE ;Error on read of XA ;AN000;
1813; call Bad_Cluster ;Delete extended attribs ;AN000;
1814;; $ENDIF ; ;AN000;
1815; $ENDIF
1816; pop di ;Restore registers
1817; pop dx ; ;AN000;
1818; pop cx ; ;AN000;
1819; pop ax ; ;AN000;
1820; ret ; ;AN000;
1821;
1822;heck_Extended_Attributes endp ; ;AN000;
1823
1824
1825;*****************************************************************************
1826;Routine name: Load_XA
1827;*****************************************************************************
1828;
1829;description: Read in the first XA cluster
1830;
1831;Called Procedures: Read_Disk
1832;
1833;
1834;Change History: Created 5/13/87 MT
1835;
1836;Input: AX has start cluster of XA chain
1837; SI = dir pointer
1838;Output: CY if read failed
1839;
1840;Psuedocode
1841;----------
1842;
1843; Get start of data area
1844; Get start cluster
1845; Compute XA location from starting cluster
1846; Read it in (CALL Read_Disk)
1847; IF error
1848; stc
1849; ENDIF (NC if didn't take IF)
1850; ret
1851;*****************************************************************************
1852
1853;rocedure Load_XA ; ;AN000;
1854;
1855; push si ;Save used registers ;AN000;
1856; push cx ; ;AN000;
1857; push dx ; ;AN000;
1858; push bx ; ;AN000;
1859; sub ax,2 ;Make cluster 0 based ;AN000;
1860; mov cl,CSize ;Get sectors/cluster ;AN000;
1861; mul cl ;Offset sec in data area ;AN000;
1862; add ax,Data_Start_Low ;Get actual sector in partition ;AN000;
1863; adc dx,Data_Start_High ; " " " " ;AN000;
1864; mov Read_Write_Relative.Start_Sector_High,dx ;Setup high sector addr;AN000;
1865; mov bx,offset dg:XA_Buffer ;Read into buffer ;AN000;
1866; mov cx,1 ;Get just first sector ;AN000;
1867; mov dx,ax ;Get logical sector low ;AN000;
1868; mov al,AllDrv ;Get drive number 1=A,2=B ;AN000;
1869; dec al ;Make 0 based drive 0=A ;AN000;
1870; call Read_Disk ;Read in sector ;AN000;
1871; $IF C ;Problem? ;AN000;
1872; stc ; ;AN000;
1873; $ENDIF ; ;AN000;
1874; pop bx ;Restore registers ;AN000;
1875; pop dx ; ;AN000;
1876; pop cx ; ;AN000;
1877; pop si ; ;AN000;
1878; ret ; ;AN000;
1879;
1880;oad_XA endp ; ;AN000;
1881
1882;****************************************************************************
1883;WARNING!!! this must be the last label in the code section
1884; any changes to chkdsk.arf must take into account this area.
1885; it is used for reading things from disk into memory, such as dir
1886Public CHKPRMT_End
1887Chkprmt_End label byte
1888;****************************************************************************
1889 pathlabl chkproc
1890CODE ENDS
1891 END
1892 \ No newline at end of file