1 PAGE
90,132 ;AN000;\ f\eA\b\e2
2 TITLE TREE
.SAL - DISPLAY THE SUBDIRECTORY TREE
;AN000;
3 LISTPARM
= 1 ;AN000;0=SUPPRESS LIST; 1=ALLOW LIST
5 ;****************** START OF SPECIFICATIONS *****************************
8 ; DESCRIPTIVE NAME: Tree structure of subdirectories is displayed.
10 ; FUNCTION: Displays to standard output a graphic representation
11 ; of the subdirectory tree structure, beginning
12 ; with the specified subdirectory, and optionally
13 ; displaying all filenames in that tree.
17 ; INPUT: (DOS COMMAND LINE PARAMETERS)
19 ; [d:][path] TREE [D:][path] [/F] [/A]
22 ; [d:][path] - Path where the TREE command resides.
24 ; [D:][path] - Display of subdirectories starts with this
25 ; specified subdirectory. If this is not
26 ; specified, the default is the drive root directory.
28 ; [/F] - This requests the files in each subdirectory
29 ; in addition to the subdirectories themselves
32 ; [/A] - This requests use of alternate graphic chars
34 ; EXIT-NORMAL: ERRORLEVEL 0 - Normal completion
36 ; EXIT-ERROR: ERRORLEVEL 1 - I/O error
38 ; ERRORLEVEL 2 - Incorrect DOS version
40 ; ERRORLEVEL 3 - Control Break termination
42 ; EFFECTS: The result is a display of the Tree of subdirectories.
43 ; No changes are made to the system, to the current subdirectory,
44 ; nor to the current DOS default drive.
46 ; 1. NO FILES, JUST SUBDIRECTORIES
57 ; 2. FILES AND SUBDIRECTORIES
86 ; INCLUDED FILES: TREEQU.INC - EQUATES
87 ; PATHMAC.INC - PATHGEN MACRO
89 ; INTERNAL REFERENCES:
92 ; BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS
93 ; DEFINE_GRAPHICS - GET GRAPHIC CHARS FROM MSG
94 ; PARSE - TOKENIZE THE DOS COMMAND LINE PARMS
95 ; VERIFY_DRIVE - CHECK IF USER DRIVE ID IS OK
96 ; INIT_CONDITIONS - GET INITIAL SUBDIR, APPEND,CTL_BREAK
97 ; GET_VOL_LABEL - GET VOLUME LABEL ON SPECIFIED DRIVE
98 ; VOLSER - DISPLAY VOLUME SERIAL NUMBER, IF ANY AN001
99 ; LEN_ASCIIZ - GET LENGTH OF ASCIIZ STRING
100 ; EXECUTE - LOOK THRU DIRECTORY LIST FOR SUBDIRS
101 ; ANY_MORE_SUBDIR - LOOK AHEAD,SEE IF MORE SUBDIR
102 ; FIND_TYPE_NORMAL - PROCESS NORMAL, NON-DIR, FILES
103 ; FIND_TYPE_DIR - PROCESS THE DIRECTORY
104 ; NEXT_LEVEL - SET UP TO LOOK AT LOWER LEVEL SUBDIR
105 ; BEGIN_FIND - DO FIND FIRST FILE
106 ; FIND_NEXT - LOOK FOR NEXT ENTRY IN DIRECTORY
107 ; SHOW_FN - DISPLAY THE FILENAME FOUND
108 ; FLN_TO_BUF - MOVE FILENAME TO BUFFER
109 ; GRAF_TO_BUF - SELECT LEADING GRAPHIC CHAR FOR BUF
110 ; BLANK_DASH - PUT BLANKS OR DASHES BEFORE FILENAME
111 ; FIX_GRAF - CHANGE CURRENT GRAPHIC FOR NEXT LINE
112 ; ANY_SUBDIRS - DISPLAY MSG IF NO SUBDIRS PRINTED
113 ; DO_WRITE - SEND STRING TO STDOUT
114 ; IF_NOMOREFILES - ASK EXTENDED ERROR FOR WHY IS ERROR
115 ; GET_EXTERR - CALL EXTENDED ERROR
116 ; SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG
117 ; BREAK_HANDLER - CONTROL BREAK VECTOR POINTS HERE
118 ; RESTORE - RETURN TO INITIAL DOS DEFAULT DRIVE
119 ; MYERRORHANDLER - SERVICE CRITICAL ERROR HANDLER
120 ; CHK_DBCS -SEE IF SPECIFIED BYTE IS A DBCS LEAD BYTE
123 ; PSP - Contains the DOS command line parameters.
124 ; STACK - Dynamic allocation of workareas.
126 ; EXTERNAL REFERENCES:
128 ; SYSDISPMSG (FAR) - MESSAGE DISPLAY ROUTINE
129 ; SYSLOADMSG (FAR) - SYSTEM MESSAGE LOADER
130 ; PARSER (NEAR) - INTERROGATE DOS COMMAND LINE PARMS
133 ; DTA - defined by the DOS FINDFIRST function.
136 ; This module should be processed with the SALUT pre-processor
137 ; with the re-alignment not requested, as:
141 ; To assemble these modules, the sequential or alphabetical
142 ; ordering of segments may be used.
144 ; Sample LINK command:
148 ; Where the TREE.ARF is defined as:
155 ; These modules should be linked in this order. The load module is
156 ; a COM file. It should be converted via EXE2BIN to a .COM file.
158 ; REVISION HISTORY: A000 Version 4.00: add PARSER, System Message Handler,
159 ; Display graphically the subdirectories and their files.
160 ; A001 DCR 27, display vol serial number, if present.
161 ; A002 Add support for /A switch for alternate graphics.
162 ; A003 PTM 471 Avoid duplicate switches
163 ; A004 PTM 537 Display parm in error
164 ; A005 PTM 692 Remove period from vol label field
165 ; A006 PTR1044 Append interface change
166 ; A007 PTM1082 Critical error handler
167 ; A008 PTM1199 DEFAULT DIR OF TARGET ALTERED
168 ; A009 PTM1416 INT24 CLOBBERED USER'S RESPONSE
169 ; A010 PTM1406 GET MEDIA ID WITH 69H, NOT IOCTL
170 ; A011 PTM1821 COPYRIGH.INC moved to within msgserv.asm
171 ; A012 PTM2352 DBCS ENABLING, CHECKING FOR "\"
172 ; A013 PTM3512 PATHGEN
173 ; A014 PTM3560 INVALID PATH DOES NOT DISPLAY PATHNAME
175 ; Label: The following notice is found in the OBJ code generated from
176 ; the "TREESYSM.SAL" module:
178 ; "Version 4.00 (C) Copyright 1988 Microsoft
179 ; "Licensed Material - Program Property of Microsoft
181 ;****************** END OF SPECIFICATIONS *****************************
183 %
OUT COMPONENT
=TREE
, MODULE
=TREE
.SAL... ;AN000;
185 HEADER
<MACRO DEFINITIONS
> ;AN000;
186 INCLUDE PATHMAC
.INC ;AN013;
187 ; = = = = = = = = = = = =
188 FIXLIST
MACRO LP
,DOIT
;;AN000;
193 ; = = = = = = = = = = = =
194 HEADER
MACRO TEXT
;;AN000;
195 FIXLIST LISTPARM
,.XLIST
;;AN000;
197 FIXLIST LISTPARM
,.LIST
;;AN000;
200 ; = = = = = = = = = = = =
201 ; $SALUT (0,36,41,52) ;AN000;
202 DOSCALL
MACRO FN
,SF
;;AN000;
203 IFNB
<FN
> ;;AN000;ARE THERE ANY PARMS AT ALL?
205 MOV AX,(FN
SHL 8)+SF
;;AN000;AH=FN;AH=SF
206 ELSE ;;AN000;SINCE THERE IS NO SUB FUNC
212 ; = = = = = = = = = = = =
213 ; $SALUT (0,14,19,36) ;AN000;
214 HEADER
<EQUATES
- DOS FUNCTION CALLS
> ;AN000;
215 INCLUDE TREEQU
.INC ;AN000;EQUATES, CONTROL BLOCKS
216 ; = = = = = = = = = = = =
217 LISTPARM
= 1 ;AN000;PERMIT LISTING
219 HEADER
<STATIC DATA AREA
> ;AN000;
220 CSEG
SEGMENT PARA
PUBLIC 'CODE' ;AN000;
221 ASSUME
CS:CSEG
,DS:CSEG
,ES:CSEG
,SS:CSEG
;AN000;AS SET BY DOS LOADER
222 ; $SALUT (4,3,8,36) ;AN000;
223 EXTRN SUBLIST_PARSE
:WORD ;AN004;PARSE ERROR XX - %0
225 EXTRN MSGNUM_VOL
:WORD ;AN000;"Directory PATH listing for Volume %1"
226 EXTRN SUBLIST_VOL
:WORD ;AN000;SUBLIST TO VOL LABEL IN FIX_DTA_FILN
228 EXTRN MSGNUM_LIST
:WORD ;AN000;"Directory PATH listing"
230 EXTRN MSGNUM_INVPATH
:WORD ;AN000;"INVALID PATH"
231 EXTRN SUBLIST_INVPATH
:WORD ;AN014;THE ASCIIZ PATH CONSIDERED INVALID
233 EXTRN MSGNUM_EXTERR
:WORD ;AN000;ALL EXTENDED ERRORS
234 EXTRN MSGNUM_NOSUB
:WORD ;AN000;"No subdirectories exists"
236 EXTRN MSGNUM_SERNO
:WORD ;AN001;"Volume Serial Number is %1-%2"
237 EXTRN SUBLIST_6A
:WORD ;AN001;FIRST PART OF SERIAL NUMBER
238 EXTRN SUBLIST_6B
:WORD ;AN001;SECOND PART OF SERIAL NUMBER
240 EXTRN CURRENT_PARM
:WORD ;AN000;POINT TO NEXT PARM TO PARSE
241 EXTRN ORDINAL
:WORD ;AN000;NUMBER OF CURRENT PARM
242 EXTRN LAST_BYTE
:BYTE ;AN000;TAG AT END OF USED MEMORY, BEFORE STACK
244 EXTRN SYSDISPMSG
:NEAR ;AN000;MESSAGE DISPLAY ROUTINE
245 EXTRN SYSLOADMSG
:NEAR ;AN000;SYSTEM MESSAGE LOADER
246 EXTRN SYSGETMSG
:NEAR ;AN002;SYSTEM MESSAGE LOCATER ROUTINE
247 EXTRN PARSER
:NEAR ;AN000;INTERROGATE DOS COMMAND LINE PARMS
248 ; = = = = = = = = = = = =
249 ; $SALUT (0,14,19,36) ;AN000;
251 PUBLIC COMMAND
;AN000;
252 COMMAND
DB 128 DUP (?
) ;AN000;DOS INPUT COMMAND LINE
253 ; = = = = = = = = = = = =
254 ORG 100H
;AN000;REQUIRED LOCATION OF ENTRY POINT
255 START: JMP BEGIN
;AN000;DOS ENTRY POINT
256 ; = = = = = = = = = = = =
257 ;THERE ARE TWO SETS OF DEFINITIONS OF THE GRAPHIC CHARACTERS USED IN THE DISPLAY.
258 ;THE FIRST SET LOOKS THE BEST, BUT ON SOME PRINTERS IS A TEDIOUS, SLOW PROCESS.
259 ;THERE ARE SOME CODEPAGES THAT DO NOT HAVE THESE SAME GRAPHIC CHARACTERS IN
260 ;THESE CORRESPONDING CODE POINT POSITIONS. JAPAN HAS ITS KATAKANA CHARACTER
261 ;SET WHERE THESE GRAPHICS ARE DEFINED, AND WOULD THUS NOT WANT TO USE THIS
262 ;FIRST GRAPHIC CHARACTERS SET. THE SECOND SET OF EQUATES DEFINE ALTERNATE
263 ;CHARACTERS THAT, ALTHOUGH THE OUTPUT DOES NOT LOOK AS GOOD, AT LEAST WILL
264 ;PRINT NORMALLY, AND DOES USE THE TRADITIONAL ASCII LOWER 128 AS ITS CODE
265 ;POINTS, THUS WOULD BE AVAILABLE FOR THOSE OTHER CODEPAGES, LIKE JAPAN'S.
267 ;IF IT BECOMES DESIRABLE TO GENERATE YET ANOTHER DEFINITION OF THESE CHARACTERS,
268 ;THE REQUIREMENTS ARE:
269 ; 1. NONE OF THE FOUR CAN BE BLANK
270 ; 2. EACH OF THE FOUR MUST BE UNIQUE
271 ; 3. EACH CHAR MUST BE A SINGLE BYTE (NO DBCS)
274 ;THIS SET OF GRAPHIC CHARACTERS ARE ACTUALLY DEFINED BY THE MESSAGE 7,
275 ;WHERE TRANSLATORS HAVE PROVIDED THE CHARACTERS COMPATABLE WITH THEIR
276 ;NATIONAL CHARACTER CODEPAGE SET.
277 GRAF_TABLE
LABEL BYTE ;AN002;DEFINITION OF FOUR GRAPHIC CHARACTERS
278 PUBLIC GRAF_TABLE
;AN002;
279 GRAF_ELBO
DB "À" ;AN000;192 DECIMAL ASCII VAL
280 GRAF_DASH
DB "Ä" ;AN000;196 DECIMAL ASCII VALUE
281 GRAF_TEE
DB "Ã" ;AN000;195 DECIMAL ASCII VALUE
282 GRAF_BAR
DB "³" ;AN000;179 DECIMAL ASCII VALUE
285 ; ALTERNATE SET OF GRAPHIC CHARACTERS
286 ;IF THE "/A" SWITCH IS SPECIFIED, THIS SET OF FOUR CHARACTERS WILL
287 ;OVERLAY THE ABOVE SET OF GRAPHIC CHARACTERS.
289 GRAF_TABLE_ALT
LABEL BYTE ;AN002;ALTERNATE SET OF GRAPHIC CHARACTERS
290 PUBLIC GRAF_TABLE_ALT
;AN002;
291 A_GRAF_ELBO
DB "\" ;AN000;
292 A_GRAF_DASH DB "-" ;AN000;
293 A_GRAF_TEE DB "+" ;AN000;
294 A_GRAF_BAR DB "|" ;AN000;
296 ; = = = = = = = = = = = =
297 FLAGS DB 0 ;AN000;INITIALIZE ALL FLAGS TO "FALSE
"
298 PUBLIC FLAGS,F_SWITCH ;AN000;ADD ENTRIES IN LINK MAP
299 F_DEF_PAT_TAR EQU 40H ;AN008;IF ON, DEFAULT SUBDIR OF TARGET DRIVE IS KNOWN
300 ;IF OFF, DEF SUBDIR OF TARGET NOT KNOWN ;AN008;
301 F_SUBDIR EQU 20H ;AN000;IF ON, A SUBDIR HAS BEEN DISPLAYED
302 ;IF OFF, A SUBDIR HAS NOT YET BEED DISPLAYED
303 F_FAILING EQU 10H ;AN000;IF ON, DO NOT RESTORE SUBDIR ON FAILING DRIVE
304 ;IF OFF, DO RESTORE SUBDIR ON TARGET DRIVE ;AN000;
305 F_FLN EQU 08H ;AN000;IF ON, A FILENAME HAS BEEN DISPLAYED
306 ;IF OFF, NO FILNAME FOR THIS SUBDIR YET
307 F_FIRSTIME EQU 04H ;AN000;IF ON, DISPLAY OF NAME ALREADY DONE
308 ;IF OFF, DISPLAY OF NAME NEVER DONE
309 F_SWITCH EQU 02H ;AN000;IF ON, THE /F SPECIFIED
310 ;IF OFF, THEN /F NOT SPECIFIED
311 F_APPEND EQU 01H ;AC006;IF ON, DOS APPEND IS IN THE MULTIPLEXOR
312 ;IF OFF, DOS APPEND IS NOT THE MULTIPLEXOR
314 APPEND_FLAGS DW 0 ;AN006;RECORDS ORIGINAL STATE OF APPEND
319 ;0001H = ENABLE APPEND
321 DBCSENV DD 0 ;AN000;POINTER TO DBCS RANGES
322 ORIG_AX DW 0 ;AN000;DRIVE VERIFICATION FROM DOS AT ENTRY
323 CURRENT_COL DW 1 ;AN000;IN BUF, WHERE IS ELBO/TEE?
324 ; INITIALLY SET TO START IN COLUMN ONE
325 MEDIA_ID_BUF A_MEDIA_ID_INFO <> ;AN001;AREA TO READ VOL SERIAL NUMBER WITH GET_MEDIA_ID
326 BUF DB ((DASH_NUM+1)*LEVEL_LIMIT) DUP(0) ;AN000;HAS ELBO,TEE,DASH,NUL ENDED
327 JUSTIN_CASE DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW
328 CRLF DB CR,LF,NUL ;AN000;LINE TERMINATOR
329 LEN_CRLF EQU 2 ;AN000;LENGTH OF CR, LF FIELDS IN PREVIOUS MSG
330 EXITFL DB EXOK ;AN000;RETURN CODE, INITIALLY "NORMAL
"
331 ; (SEE INCLUDED FILE OF EQUATES FOR DEFINITIONS OF VALUES)
333 ; REMEMBER THE DOS DEFAULT DRIVE AND SUBDIRECTORY
334 DEFAULT_DR DB ? ;AN000;ALPHA LETTER OF DOS DEFAULT DRIVE
335 START_DR_NUM DB ? ;AN000;NUMERIC VALUE OF DOS DEFAULT DRIVE
336 ; WHERE 0=A:, 1=B:, ETC...
337 DEFAULT_PATH DB BACK_SLASH ;AN000;FIRST BYTE OF PATH IS BACKSLASH
338 DB MAX_PATH DUP(0) ;AN000;ORIGINAL DEFAULT PATH
339 JUSTIN_CASE2 DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW
340 OLDINT23 DD ? ;AN000;ORIGINAL CONTENTS OF CTRL-BREAK VECTOR
341 OLDINT24 DD ? ;AN000;ORIGINAL CONTENTS OF CRITICAL ERROR VECTOR
343 FIX_DTA_RES DB 21 DUP(?) ;AN000;RESERVED FOR FIND NEXT CALLS
344 FIX_DTA_ATTR DB ? ;AN000;ATTRIBUTE
345 FIX_DTA_TIME DW ? ;AN000;TIME
346 FIX_DTA_DATE DW ? ;AN000;DATE
347 FIX_DTA_LSIZ DW ? ;AN000;LOW WORD OF FILE SIZE
348 FIX_DTA_HSIZ DW ? ;AN000;HIGH WORD OF FILE SIZE
349 FIX_DTA_FILN DB 13 DUP(?) ;AN000;FILENAME, WITH PERIOD, +0 BYTE
350 PUBLIC FIX_DTA_FILN ;AN000;USED TO DISPLAY VOLUME LABEL
351 STAR_STAR DB "*.*",0 ;AN000;UNIVERSAL FILENAME, +0
352 STAR_STAR_L EQU $-STAR_STAR ;AN000;LENGTH OF UNIVERSAL FILENAME, INCL NUL
353 SAVEFILN DB 13 DUP(?) ;AN000;COPY OF FIX_DTA_FILN, ABOVE
354 ; THIS NEXT SET OF WORKSPACE DEFINES THE PATH BEING PROCESSED.
355 ; THESE ITEMS MUST REMAIN TOGETHER, IN THIS ORDER:
356 START_DRIVE DB 0,":" ;AN000;DRIVE LETTER NEEDS TO BE FILLED IN HERE
357 PUBLIC START_DRIVE,START_PATH ;AN000;
358 START_PATH DB PERIOD ;AN000;AREA TO RECEIVE STARTING PATH ASCIIZ
359 DB (MAX_PATH+SIZE FIX_DTA_FILN) DUP(0) ;AN000;
360 JUSTIN_CASE3 DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW
361 ; END OF CONTIGUOUS WORKSPACE DEFINING PATH
362 ; = = = = = = = = = = = =
363 PATHLABL TREE ;AN013;
364 HEADER <BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS> ;AN000;
365 ; $SALUT (4,3,8,36) ;AN000;
366 BEGIN PROC NEAR ;AN000;
368 ;INPUT - DOS COMMAND LINE PARMS, AS DEFINED IN MODULE PROLOG.
369 ; CONTROL IS PASSED HERE FROM "START
" AT ORG 100H.
370 ; AX IS SET BY DOS TO FLAG ANY INVALID DRIVE SPECIFIED ON PARMS.
371 ;OUTPUT - "EXITFL
" HAS ERRORLEVEL RETURN CODE
372 ; = = = = = = = = = = = =
374 MOV ORIG_AX,AX ;AN000;SAVE ORIGINAL VALUE OF AX
376 ;SINCE THIS IS A .COM STYLE UTILITY, THE SEG ID IN THE MSG SUBLIST
377 ;CANNOT BE SET BY THE LOADER, BUT MUST BE SET HERE, AT RUN TIME.
379 MOV SUBLIST_VOL.SUB_VALUE_SEG,CS ;AN000;MAKE SUBLIST VARIABLE ADDRESSABLE
380 MOV SUBLIST_6A.SUB_VALUE_SEG,CS ;AN001;
381 MOV SUBLIST_6B.SUB_VALUE_SEG,CS ;AN001;
382 MOV SUBLIST_PARSE.SUB_VALUE_SEG,CS ;AN004;
383 MOV SUBLIST_INVPATH.SUB_VALUE_SEG,CS ;AN014;
385 CALL SYSLOADMSG ;AN000; INIT SYSMSG HANDLER
387 ; $IF C ;AN000; IF THERE WAS A PROBLEM
389 CALL SYSDISPMSG ;AN000; LET HIM SAY WHY HE HAD A PROBLEM
391 MOV EXITFL,EXVER ;AN000; TELL ERRORLEVEL BAD DOS VERSION
392 ; $ELSE ;AN000; SINCE SYSDISPMSG IS HAPPY
395 CLD ;AN000;CLEAR DIRECTION FLAG TO AUTO-INCREMENT
397 ; GET CURRENT DRIVE ID
398 DOSCALL CURRDISK ;AN000;(19H) SET AL=0 IF A:, 1 IF B:, ETC...
400 MOV START_DR_NUM,AL ;AN000;SAVE NUMERIC VALUE OF DOS DEFAULT DRIVE
401 ADD AL,DRIVEA ;AN000;CONVERT DRIVE NUMBER TO LETTER
402 MOV DEFAULT_DR,AL ;AN000;REMEMBER ALPHA OF DEFAULT DRIVE
403 ; OF FILENAME TO BE SEARCHED FOR
404 ; RECORD THE INITIAL SET UP
405 CALL INIT_CONDITIONS ;AC007;SET DTA,APPEND STATUS,CAPTURE CTL-BREAK VEC
408 CALL DEFINE_GRAPHICS ;AN002;GET PROPER GRAPHIC CHARS FROM MSG
410 CALL PARSE ;AN000;LOOK AT DOS COMMAND LINE PARAMETERS,
411 ; AND DISPLAY ERR MSG IF BAD
412 ; $IF NC ;AN000;PARMS ARE OK?
415 ; "CURRDISK
" AL=0 DRIVE A:, AL=1 DRIVE B: ETC...
416 ; "GET_CUR_DIR
" AL=0 DEFAULT DRIVE, AL=1 DRIVE A: ETC...
417 ; "SELECT_DISK
" AL=0 DRIVE A:, AL=1 DRIVE B: ETC...
418 ; SO... THE NUMBER WE HAVE HERE AGREES WITH "SELECT_DISK
", BUT
419 ; WE MUST ADD ONE WHEN WE DO THE "GET_CUR_DIR
".
421 ; GET CURRENT DIRECTORY OF TARGET DRIVE
422 ;DS:SI = POINTER TO 64 BYTE USER AREA
423 ;DL = DRIVE NUM (0=DEF, 1=A, ETC)
424 ;OUTPUT: DS:SI POINTS TO FULL PATH NAME
425 ; "DEFAULT_PATH
" WILL HAVE THE DOS DEFAULT SUBDIRECTORY PATH.
427 MOV SI,OFFSET DEFAULT_PATH+1 ;AN000;PASS 64 BYTE AREA
428 MOV DL,START_DRIVE ;AN000;PASS NUMERIC VALUE
429 SUB DL,DRIVEA ;AN000; OF DRIVE TO BE SCANNED
430 INC DL ;AN000;SEE "CURIOUS ODDITY
" ABOVE...
431 DOSCALL GET_CUR_DIR ;AN000;(47H) GET THE CURRENT SDIR OF TARGET DRIVE
433 OR FLAGS,F_DEF_PAT_TAR ;AN008;INDICATE DEFAULT PATH OF TARGET IS KNOWN
436 ; DISPLAY FUNCTION HEADER
437 CALL GET_VOL_LABEL ;AN000;GET VOLUME LABEL TO FIX_DTA_FILN
439 ; DISPLAY VOLUME SERIAL ID
440 CALL EXECUTE ;AN000;DISPLAY THE SET OF SUBDIRS
442 CALL ANY_SUBDIRS ;AN000;DISPLAY FINAL MSG IN CASE NO SUBDIRS
444 ; $ELSE ;AN000;SINCE PARMS HAD A PROBLEM,
447 MOV EXITFL,EXERR ;AN000;SET ERROR RETURN CODE
448 ; $ENDIF ;AN000;PARMS OK?
450 ; RESTORE SYSTEM TO INITIAL CONDITIONS
451 CALL RESTORE ;AN007;RETURN TO INITIAL DOS DEFAULT DRIVE,
452 ; THE INITIAL DEFAULT PATH,
453 ; AND THE INITIAL "APPEND
" STATE.
454 ; $ENDIF ;AN000;OK WITH SYSDISPMSG?
457 MOV AL,EXITFL ;AN000;PASS BACK ERRORLEVEL RET CODE
458 DOSCALL RET_CD_EXIT ;AN000;(4CH) RETURN TO DOS WITH RET CODE
460 INT 20H ;AN000; IF ABOVE NOT WORK, EXIT ANYWAY
462 ;FOR CONTROL-BREAK, "TREE
" WILL EXIT TO DOS AT "CTL_BREAK
" PROC
465 ; = = = = = = = = = = = =
466 HEADER <DEFINE_GRAPHICS - GET GRAPHIC CHARS FROM MSG> ;AN002;
467 DEFINE_GRAPHICS PROC NEAR ;AN002;
468 PUBLIC DEFINE_GRAPHICS ;AN002;
469 ;INPUT - MESSAGE 7 HAS THE FOUR GRAPIC CHARS, DEFINED BY THE TRANSLATORS
470 ; TO BE ACCEPTABLE TO THIS NATIONAL CODEPAGE.
471 ;OUTPUT- THE "GRAF_TABLE
" AREA IS Revised TO HAVE THE 4 GRAPHIC CHARS
472 ; AS DEFINED BY THE MESSAGE
473 ; = = = = = = = = = = = =
474 ; DEFINE THE GRAPHIC CHARACTERS
475 MOV AX,GRAPHIC_MSGNUM ;AN002;REQUEST THE MESSAGE WITH GRAPHIC CHAR DEFS
476 MOV DH,UTILITY_MSG_CLASS ;AN002;
477 CALL SYSGETMSG ;AN002;ASK WHERE THOSE GRAPHIC CHARS ARE
478 ;IF ANY PROBLEM HERE, JUST LEAVE
479 ; THE GRAPHICS AS DEFINED AT ASSEMBLY TIME.
480 ; $IF NC ;AN002;IF ALL OK, DS:SI POINTS TO MESSAGE
482 LEA DI,GRAF_TABLE ;AN002;POINT TO WHERE GRAPHIC CHARS ARE TO GO
483 LODSW ;AN002;GET FIRST PAIR OF CHARS
484 STOSW ;AN002;SAVE THEM
485 LODSW ;AN002;GET SECOND PAIR OF CHARS
486 STOSW ;AN002;AND SAVE THEM ALSO
490 DEFINE_GRAPHICS ENDP ;AN002;
491 ; = = = = = = = = = = = =
492 HEADER <PARSE - TOKENIZE THE DOS COMMAND LINE PARMS> ;AN000;
493 PARSE PROC NEAR ;AN000;
495 ;INPUT - PSP HAS DOS COMMAND LINE PARAMETERS
496 ;OUTPUT- CARRY IS SET IF THERE IS A PROBLEM
497 ; CARRY IS CLEAR IF PARMS ARE OK
499 ; IF THERE WERE ANY PARMS, THEY ARE MOVED FROM THE PSP
500 ; INTO THE STRING, "COMMAND
", WHERE THE PARSER WILL LOOK AT THEM.
502 ; IF THE SWITCH "/F
" WAS SPECIFIED, "F_SWITCH
" IS SET TO "ON"
503 ; IF THE SWITCH IS NOT SPECIFIED, "F_SWITCH
" IS LEFT "OFF
".
505 ; IF THERE ARE NO PARMS, THE DEFAULTS OF CURRENT DRIVE AND CURRENT
506 ; SUBDIRECTORY ARE SET UP TO BE WHERE THE SUBDIR SEARCH WILL
507 ; START, AND THE "/F
" SWITCH IS ASSUMED NOT SPECIFIED, SO
508 ; THE DEFAULT DISPLAY WILL SHOW SUBDIRS ONLY, NO FILES.
510 ; "START_DRIVE
" EITHER HAS THE SPECIFIED STARTING DRIVE, OR
511 ; WILL HAVE THE CURRENT DOS DEFAULT DRIVE.
512 ; "START_PATH
" EITHER WILL HAVE THE SPECIFIED STARTING PATH, OR
513 ; WILL HAVE THE CURRENT DEFAULT PATH
514 ; = = = = = = = = = = = =
516 MOV CURRENT_PARM,OFFSET COMMAND+1 ;AN000;SET POINT TO BEGINNING OF STRING
517 MOV ORDINAL,ZERO ;AN000;START WITH FIRST PARM
518 CALL PARSER ;AN000;INTERROGATE THE DOS COMMAND LINE PARMS
519 ;OUTPUT: SET CARRY IF PROBLEM
520 ; CLEAR CARRY IF ALL OK
521 ; $IF NC ;AN000;IF ALL OK SO FAR WITH PARSER,
523 CMP START_DRIVE,NUL ;AN000;SEE IF START_DRIVE FILLED IN YET
524 ; $IF E ;AN000;NO, NOT FILLED IN YET
526 MOV AL,DEFAULT_DR ;AN000;GET ALPHA LETTER OF DEFAULT DRIVE
527 MOV START_DRIVE,AL ;AN000;SET WHERE TO SEARCH FOR SUBDIRS
528 CLC ;AN000;NO ERROR SO FAR
529 ; $ELSE ;AN000;SINCE START_DRIVE WAS SPECIFIED
532 CALL VERIFY_DRIVE ;AN000;SEE IF USER SPECIFIED DRIVE IS OK, AND
533 ; IF SO, CHANGE DOS DEFAULT DRIVE TO IT
534 ;CARRY WILL BE SET IF ERROR
536 ;IF A NEW DRIVE WAS SPECIFIED,
537 ; DEFAULT DRIVE HAS BEEN CHANGED TO
538 ; NEW DEFAULT DRIVE, USER SPECIFIED
540 ; $ENDIF ;AN000;FILLED IN START_DRIVE YET?
542 ; $IF NC ;AN000;IF ALL OK SO FAR,
544 CMP START_PATH,NUL ;AN000;SEE IF START_PATH FILLED IN YET
545 ; $IF E ;AN000;NO, NOT FILLED IN YET,
547 MOV DI,OFFSET START_PATH ;AN000;SET WHERE TO PUT STARTING PATH
548 MOV AL,BACK_SLASH ;AN000;START CURRENT SUBDIR AT ROOT
549 STOSB ;AN000; SO START WITH BACK SLASH
551 ;DI POINTS TO BYTE AFTER BACK SLASH
552 ; JUST ADDED TO "START_PATH
"
554 MOV SI,DI ;AN000;DS:SI = POINTER TO 64 BYTE USER AREA
555 MOV DL,DEFDRIVE ;AN000;DL = DRIVE NUM (0=DEF, 1=A, ETC)
556 DOSCALL GET_CUR_DIR ;AN000;(47H) GET CURRENT DIRECTORY
557 ;OUTPUT: DS:SI POINTS TO FULL PATH NAME
558 ; $ENDIF ;AN000;START_PATH FILLED IN YET?
560 CLC ;AN000;INDICATE NO PROBLEM WITH PARMS
561 ; $ENDIF ;AN000;ALL OK SO FAR?
563 ; $ENDIF ;AN000;ALL OK WITH PARSER?
565 RET ;AN000;RETURN TO CALLER
567 ; = = = = = = = = = = = =
568 HEADER <VERIFY_DRIVE - CHECK IF USER DRIVE ID IS OK> ;AN000;
569 VERIFY_DRIVE PROC NEAR ;AN000;
570 PUBLIC VERIFY_DRIVE ;AN000;
571 ;THE USER HAS SPECIFIED A DRIVE LETTER. VERIFY IT IS A PROPER DRIVE.
572 ;IF THE DRIVE LETTER SPECIFIED IS THE SAME AS THE DEFAULT DRIVE, IT IS OK.
573 ;IF DIFFERENT, ADDITIONAL VERIFICATION TESTS MUST BE MADE.
574 ;THIS TEST IS DONE BY TRYING TO CHANGE THE CURRENT DRIVE TO THE SPECIFIED
575 ; DRIVE, THEN BY ASKING WHAT IS THE CURRENT DRIVE. IF THE CURRENT DRIVE
576 ; HAS CHANGED FROM WHAT IT WAS ORIGINALLY, THEN THE NEW DRIVE LETTER IS OK.
577 ; IF IT DID NOT CHANGE, THEN IT WAS A BOGUS DRIVE LETTER AND WE QUIT.
579 ;INPUT: "START_DRIVE
" - USER SPECIFIED DRIVE LETTER TO BE TESTED
580 ; "DEFAULT_DR
" - ORIGINAL DOS DEFAULT DRIVE
581 ; "START_DR_NUM
" - NUMERIC EQUIVALENT OF THE ORIGINAL DOS DEFAULT DRIVE
582 ; "ORIG_AX
" - HAS FLAGS TO VERIFY DRIVE, SET BY DOS AT LOAD TIME.
583 ;OUTPUT: CARRY SET IF BAD, CARRY CLEAR IF OK
584 ; IF BAD, ERROR MESSAGE IS DISPLAYED: "INVALID DRIVE SPECIFICATION
"
585 ; = = = = = = = = = = = =
586 MOV DL,START_DRIVE ;AN000;USING THE DRIVE SPECIFIED IN PARMS,
587 CMP DL,DEFAULT_DR ;AN000;DID PARMS SPECIFY DRIVE SAME AS DEFAULT?
588 ; $IF NE ;AN000;IF DRIVE SPECIFIED IS DIFFERENT
590 MOV AX,ORIG_AX ;AN000;GET DRIVE VERIFICATION FLAGS, SAVED FROM AX
591 OR AL,AH ;AN000;COMBINE FLAGS FOR BOTH DRIVE ID'S, IF GIVEN
592 ; $IF NZ,OR ;AN000;IF THERE IS A PROBLEM, OR...
595 SUB DL,DRIVEA ;AN000;CONVERT DRIVE LETTER TO DRIVE NUMBER
596 ; DL=DRIVE NUMBER (0=A,1=B)
597 DOSCALL SELECT_DISK ;AN000;(0EH) SET DEFAULT DRIVE
598 ;OUTPUT: AL=NUM. OF DRIVES (MIN 5) (NOT USED);AN000;
599 ; (NOT INTERESTED...)
600 DOSCALL CURRDISK ;AN000;(19H) GET CURRENT DEFAULT DRIVE
601 ;OUTPUT: AL = CURRENT DRIVE
603 CMP AL,START_DR_NUM ;AN000;HAS THE ORIGINAL DOS DEFAULT DRIVE CHANGED?
605 ; $IF E ;AN000;IF NO CHANGE, THEN USER SPECIFIED
609 MOV MSGNUM_EXTERR,INVDRSPEC ;AN000;"INVALID DRIVE SPECIFICATION
"
610 MOV DI,OFFSET MSGNUM_EXTERR ;AN000;
611 CALL SENDMSG ;AN000;TELL USER HE SAID BAD DRIVE LETTER
613 STC ;AN000;RETURN AN ERROR
614 ; $ENDIF ;AN000;NO CHANGE?
616 ; $ELSE ;AN000;SINCE DRIVE SPECIFIED IS THE SAME
620 ; $ENDIF ;AN000;NEW DRIVE SPECIFIED?
622 RET ;AN000;RETURN TO CALLER
623 VERIFY_DRIVE ENDP ;AN000;
624 ; = = = = = = = = = = = =
625 HEADER <INIT_CONDITIONS - GET INITIAL SUBDIR, APPEND,CTL_BREAK> ;AN000;
626 INIT_CONDITIONS PROC NEAR ;AN000;
627 PUBLIC INIT_CONDITIONS ;AN000; MAKE ENTRY IN LINK MAP
628 ;INPUT - "START_DR_NUM
" WILL HAVE THE NUMERIC VALUE OF DOS DEFAULT DRIVE.
629 ; - "DEFAULT_DR
" WILL HAVE THE LETTER DRIVE ID OF DOS DEFAULT DRIVE.
630 ;OUTPUT - "APPEND_FLAGS
" RECORDS ORIGINAL STATUS OF /X OF APPEND.
631 ; APPEND IS COMMANDED TO HALT ITS /X PROCESSING.
632 ; CONTROL BREAK VECTOR IS ALTERED TO POINT TO MY HANDLER.
633 ; = = = = = = = = = = = =
634 ; SET UP THE LOCAL DTA
635 MOV DX,OFFSET FIX_DTA_RES ;AN000;PASS POINTER TO DTA BUFFER
636 DOSCALL SET_DTA ;AN000;(1AH) SET DTA FOR FIND FIRST/NEXT
637 ; GET CURRENT APPEND STATUS
638 MOV AX,APPEND_CHECK ;AN006;SEE IF APPEND IS ACTIVE
639 INT 2FH ;AN006;CALL THE MULTIPLEXOR FUNCTION
641 OR AL,AL ;AN006;TEST THE RESULTS
642 ; $IF NZ,AND ;AN006;IF INSTALLED
645 MOV AX,APPEND_VERSION ;AN006;ASK IF DOS VERSION OF APPEND
646 INT 2FH ;AN006;CALL THE MULTIPLEXOR FUNCTION
647 CMP AX,DOS_APPEND_VER ;AN006;IS THIS THE DOS VERSION OF APPEND
648 ; $IF E ;AN006;YES, DEAL WITH THIS VERSION
650 OR FLAGS,F_APPEND ;AN000;FLAG IT AS THE DOS VERSION
651 MOV AX,GET_APPEND ;AN000;
652 INT 2FH ;AN000;READ STATUS OF /X FROM APPEND
653 ;OUTPUT-BX=(SEE "APPEND_FLAGS
" FOR DEFINITION
654 MOV APPEND_FLAGS,BX ;AC006;REMEMBER APPEND STATUS
655 ; $ENDIF ;AN000;APPEND INSTALLED?
659 ; CAPTURE THE CRITICAL ERROR VECTOR
660 PUSH ES ;AN000;SAVE SEGREG
661 ;AL = INTERRUPT NUMBER
662 DOSCALL GET_VECTOR,VEC_CRITERR ;AN000;(3524H) GET INTERRUPT VECTOR
663 ;OUTPUT: ES:BX = CONTENTS OF VECTOR
664 MOV WORD PTR OLDINT24,BX ;AN000;SAVE THE ORIGINAL
665 MOV WORD PTR OLDINT24+WORD,ES ;AN000; CRITICAL ERROR HANDLER VECTOR
666 POP ES ;AN000;RESTORE SEGREG
668 MOV DX,OFFSET MYERRORHANDLER ;AN000;DS:DX = VECTOR TO INT HANDLER
669 ;AL = INTERRUPT NUMBER
670 DOSCALL SET_VECTOR,VEC_CRITERR ;AN000;(25H) SET INTERRUPT VECTOR
672 ; CAPTURE THE CONTROL BREAK VECTOR
673 PUSH ES ;AN000;SAVE SEGREG
674 ;AL = INTERRUPT NUMBER
675 DOSCALL GET_VECTOR,VEC_CTLBREAK ;AN000;(3523H) GET INTERRUPT VECTOR
676 ;OUTPUT: ES:BX = CONTENTS OF VECTOR
677 MOV WORD PTR OLDINT23,BX ;AN000;SAVE THE ORIGINAL
678 MOV WORD PTR OLDINT23+WORD,ES ;AN000; CTRL-BREAK VECTOR
679 POP ES ;AN000;RESTORE SEGREG
681 MOV DX,OFFSET BREAK_HANDLER ;AN000;DS:DX = VECTOR TO INT HANDLER
682 ;AL = INTERRUPT NUMBER
683 DOSCALL SET_VECTOR,VEC_CTLBREAK ;AN000;(25H) SET INTERRUPT VECTOR
685 ; STOP THE APPEND FUNCTION.
686 MOV AX,SET_APPEND ;AN000;CHANGE APPEND /X STATUS
687 XOR BX,BX ;AN000;REQUEST TERMINATION OF /X SUPPORT OF APPEND
688 INT 2FH ;AN000;SET IT
690 RET ;AN000;RETURN TO CALLER
691 INIT_CONDITIONS ENDP ;AN000;
692 ; = = = = = = = = = = = =
693 HEADER <GET_VOL_LABEL - GET VOLUME LABEL ON SPECIFIED DRIVE> ;AN000;
694 GET_VOL_LABEL PROC NEAR ;AN000;
695 PUBLIC GET_VOL_LABEL ;AN000;MAKE ENTRY IN LINK MAP
696 ;INPUT - "START_PATH
" IS ASCIIZ OF STARTING PATH
697 ;OUTPUT - "FIX_DTA_FILN
" WILL HAVE ASCIIZ STRING OF VOLUMN LABEL.
698 ; STARTING DRIVE AND PATH TO SPECIFIED SUBDIR IS DISPLAYED.
699 ; = = = = = = = = = = = =
701 MOV CX,ATTR_VOLID ;AN000;REQUEST THE VOLUME ID
702 MOV DX,OFFSET STAR_STAR ;AN000;PASS FILENAME TO BE LOOKED FOR
703 DOSCALL FINDFIRST ;AN000;LOOK FOR VOLUME LABEL
705 ; $IF NC ;AN000;IF LABEL FOUND OK,
708 ;FIX_DTA_FILN HAS VOLUME LABEL
709 MOV DI,OFFSET MSGNUM_VOL ;AN000; "Directory PATH listing for Volume %
1"
710 MOV AX,WORD PTR FIX_DTA_FILN+9 ;AN005;CONVERT LABELNAME FROM
711 MOV WORD PTR FIX_DTA_FILN+8,AX ;AN005; 12345678.123 FORMAT
712 MOV AX,WORD PTR FIX_DTA_FILN+11 ;AN005; TO REMOVE PERIOD
713 MOV WORD PTR FIX_DTA_FILN+10,AX ;AN005; TO BECOME 12345678123 INSTEAD
714 ; $ELSE ;AN000;SINCE LABEL NOT FOUND,
717 MOV DI,OFFSET MSGNUM_LIST ;AN000; "Directory PATH listing
"
718 ; $ENDIF ;AN000;LABEL FOUND?
720 CALL SENDMSG ;AN000;DISPLAY STARTING MESSAGE
722 CALL VOLSER ;AN001;DISPLAY VOLUME SERIAL NUMBER, IF ANY
725 ; DISPLAY THE STARTING DRIVE AND SUBDIRECTORY
726 MOV DX,OFFSET START_DRIVE ;AN000;PASS POINTER TO STRING TO BE DISPLAYED
727 CALL LEN_ASCIIZ ;AN000;SETS CX = NUMBER OF BYTES TO WRITE
729 ;DS:DX = ADDRESS OF DATA TO WRITE
730 CALL DO_WRITE ;AN000;DISPLAY STARTING SUBDIR TO STDOUT
732 RET ;AN000;RETURN TO CALLER
733 GET_VOL_LABEL ENDP ;AN000;
734 ; = = = = = = = = = = = =
735 HEADER <VOLSER - DISPLAY VOLUME SERIAL NUMBER, IF ANY> ;AN001;
736 VOLSER PROC NEAR ;AN001;
737 PUBLIC VOLSER ;AN001;
738 ;IF THE MEDIA SUPPORTS A VOL SERIAL NUMBER, DISPLAY IT
739 ; = = = = = = = = = = = =
741 MOV BH,ZERO ;AN001;BH=0, RES
742 MOV BL,START_DRIVE ;AN001;GET LETTER OF DRIVE BEING LOOKED AT
743 SUB BL,DRIVEA-1 ;AN001;(BACK UP 40H) BL=DRIVE NUM (1=A:, 2=B:, ETC)
744 MOV DX,OFFSET MEDIA_ID_BUF ;AN001;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC)
745 DOSCALL GSET_MEDIA_ID,GET_ID ;AC010;(6900H) GET MEDIA ID
746 ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
748 ; $IF NC ;AN001;IF THE GET MEDIA ID WORKED OK,
751 ; NOTE: IN THE FOLLOWING TWO SUBLISTS, WE ARE GOING TO DISPLAY, IN HEX,
752 ; A CONSECUTIVE SET OF 4 BYTES, THE VOLUME SERIAL NUMBER. THE ORDER OF
753 ; THESE TWO WORDS OF HEX IS, LEAST SIGNIFICANT WORD FIRST, THEN THE
754 ; MOST SIGNIFICANT WORD. WHEN DISPLAYED, THE MOST SIGNIFICANT IS TO BE
755 ; DISPLAYED FIRST, SO THE VALUE AT SERIAL+2 GOES TO THE 6A SUBLIST,
756 ; AND THE LEAST SIGNIFICANT VALUE AT SERIAL+0 GOES TO THE SECOND POSITION,
757 ; REPRESENTED BY THE 6B SUBLIST.
759 LEA AX,MEDIA_ID_BUF.MI_SERIAL ;AN001;GET POINTER TO DATA TO BE PRINTED
760 MOV SUBLIST_6B.SUB_VALUE,AX ;AN001; INTO THE SUBLIST FOR %2
762 LEA AX,MEDIA_ID_BUF.MI_SERIAL+WORD ;AN001;GET POINTER TO DATA TO BE PRINTED
763 MOV SUBLIST_6A.SUB_VALUE,AX ;AN001; INTO THE SUBLIST FOR %1
765 ;"Volume Serial Number is %
1-%
2"
766 MOV DI,OFFSET MSGNUM_SERNO ;AN001;DISPLAY THE NEW SERIAL NUMBER
767 CALL SENDMSG ;AN001;DISPLAY THE MESSAGE
769 ; $ENDIF ;AN001;IS VOL SERIAL NUM PRESENT?
771 RET ;AN001;RETURN TO CALLER
773 ; = = = = = = = = = = = =
774 HEADER <LEN_ASCIIZ - GET LENGTH OF ASCIIZ STRING> ;AN000;
775 LEN_ASCIIZ PROC NEAR ;AN000;
776 PUBLIC LEN_ASCIIZ ;AN000;MAKE ENTRY IN LINK MAP
777 ;INPUT - ES:DX = POINTS TO START OF ASCIIZ STRING
778 ;OUTPUT - CX = LENGTH OF CHARACTERS, INCLUDING THE NUL AT THE END
779 ; = = = = = = = = = = = =
781 PUSH AX ;AN000;SAVE THE CALLER'S
782 PUSH DI ;AN000; REGISTERS
783 MOV CX,FULL_SEG_SIZE ;AN000;BETTER FIND THAT NUL SOMEWHERE...
784 MOV DI,DX ;AN000;SET INDEX TO WALK THRU THE STRING
785 MOV AL,NUL ;AN000;THIS IS THE CHAR I AM LOOKING FOR
786 REPNE SCASB ;AN000;LOOK FOR IT
788 SUB DI,DX ;AN000;TAKE AWAY WHERE WE STARTED, FROM WHERE WE AT
789 MOV CX,DI ;AN000; TO FIND NOW FAR WE MOVED
790 POP DI ;AN000;RESTORE THE CALLER'S
791 POP AX ;AN000; REGISTERS
793 RET ;AN000;RETURN TO CALLER
794 LEN_ASCIIZ ENDP ;AN000;
795 ; = = = = = = = = = = = =
796 HEADER <EXECUTE - LOOK THRU DIRECTORY LIST FOR SUBDIRS> ;AN000;
797 EXECUTE PROC NEAR ;AN000;
798 PUBLIC EXECUTE ;AN000;MAKE ENTRY IN LINK MAP
799 ;BECAUSE OF THE RECURSIVE NATURE OF THIS ROUTINE, ALL ITS LOCAL WORKAREA
800 ;MUST BE DYNAMICALLY ALLOCATED BY USING A PORTION OF THE STACK. AS EACH
801 ;LOWER LEVEL OF STACK IS PROCESSED, A NEW CALL IS MADE TO THIS SUBROUTINE
802 ;WHICH THEN CREATES A NEW WORKAREA FOR THAT SUBDIRECTORY.
803 ;THE CURRENT STACK SIZE IS CHECKED TO SEE IF THERE IS ENOUGH ROOM FOR
804 ;THE NEW STACK WORKAREA.
805 ;INPUT:START_PATH - STRING OF PATHNAME OF PATH TO BE PROCESSED
806 ;OUTPUT: WHEN THIS PROC RETURNS, ALL FILES IN THIS SUBDIR AND LOWER
807 ; LEVELS OF SUBDIRS HAVE BEEN PROCESSED.
808 ; = = = = = = = = = = = =
810 PUSH BP ;AN000;SAVE CALLER'S BP REG
811 SUB SP,WA_SIZE ;AN000;ALLOCATE STACK SPACE AS WORKAREA
812 MOV BP,SP ;AN000;SET BASE FOR WORKAREA CALLED "FRAME
"
815 SUB AX,OFFSET LAST_BYTE ;AN000;WHERE MY CODE ENDS
816 CMP AX,MIN_STACK ;AN000;IS THE MINIMUM STACK REMAINING?
817 ; $IF AE ;AN000;IF ENUF STILL THERE, CONTINUE,
820 CMP START_PATH,BACK_SLASH ;AN000;WAS A BACKSLASH SDIR SPECIFIED,
821 ; $IF NE ;AN000;NO BACKSLASH USED
823 MOV DX,OFFSET START_PATH ;AN000;POINT TO SPECIFIED PATH
824 DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT DIR
826 ; $IF NC ;AN000;IF CHDIR WORKED OK,
828 MOV DL,START_DRIVE ;AN000;GET TARGET DRIVE
829 SUB DL,DRIVEA-1 ;AN000;CONVERT TO NUM (A=1,B=2,ETC.)
830 LEA SI,[BP].FRAM_CURR_PATH+1 ;AN000;WHERE TO PUT PATH
831 MOV [BP].FRAM_CURR_PATH,BACK_SLASH ;AN000;
832 DOSCALL GET_CUR_DIR ;AN000;FIND WHERE WE ARE NOW
834 LEA SI,[BP].FRAM_CURR_PATH ;AN000;WHERE PATH WENT, WITH BACKSLASH
835 MOV DI,OFFSET START_PATH ;AN000;WHERE TO PUT IT
836 MOV CX,MAX_PATH+1 ;AN000;MOVE FULL LENGTH PLUS BACKSLASH
837 REP MOVSB ;AN000; TO START_PATH
839 ; $ENDIF ;AN000;CHDIR OK?
842 ; $ELSE ;AN000;SINCE SPECIFIED PATH STARTS WITH BACKSLASH
845 MOV SI,OFFSET START_PATH ;AN000;USING THE STARTING PATH,
846 LEA DI,[BP].FRAM_CURR_PATH ;AN000;SAVE IT IN THE STACK WORKAREA
847 ;(at times like this, sure is nice to
848 ; have ES=SS. .EXE would be a problem..)
849 MOV CX,MAX_PATH+1 ;AN000;MOVE THE ENTIRE STARTING PATH+LEADING "\"
850 REP MOVSB ;AN000;INTO THE WORKAREA
852 MOV DX,OFFSET START_PATH
;AN000;POINT TO SPECIFIED PATH
853 DOSCALL CHDIR
;AN000;(3BH) CHANGE CURRENT SDIR TO SPECIFIED SDIR
855 ; $ENDIF ;AN000;PERIOD SDIR SPECIFIED?
858 ; $IF NC ;AN000;IF CHDIR WORKED OK,
860 CALL ANY_MORE_SUBDIR
;AN000;SEE IF MORE SUBDIRS BELOW THIS ONE
861 ;SETS "FRAM_CHAR" TO:
862 ; "ELBO" - NO MORE DIR BELOW THIS ONE
863 ; "TEE" - THERE IS ANOTHER DIR BELOW HERE
864 TEST FLAGS
,F_SWITCH
;AN000;ARE ALL FILES ASKED FOR?
865 ; (TEST WILL CLEAR CARRY FLAG)
866 ; $IF NZ ;AN000;IS /F SET?
868 CALL FIND_TYPE_NORMAL
;AN000;DISPLAY ALL THE FILENAMES
872 CALL FIND_TYPE_DIR
;AN000;DISPLAY ALL THE DIRECTORIES
874 ; $ELSE ;AN000;SINCE CHDIR FAILED
877 MOV DI,OFFSET MSGNUM_INVPATH
;AN000;"INVALID PATH"
878 CALL SENDMSG
;AN000;SAY WHY I QUIT
880 MOV EXITFL
,EXERR
;AN000;SET ERROR FLAG TO QUIT
881 ; $ENDIF ;AN000;CHDIR OK?
883 ;FINISHED WITH THIS SUBDIRECTORY, SO
884 ; $ELSE ;AN000;SINCE STACK TOO SMALL
887 MOV DI,OFFSET MSGNUM_EXTERR
;AN000;DESCRIPTOR FOR EXTENDED ERRORS
888 MOV [DI].MSG_NUM
,INSUF_MEM
;AN000;"INSUFFICIENT MEMORY"
891 MOV EXITFL
,EXERR
;AN000;SET ERRORLEVEL RET CODE
894 ADD SP,WA_SIZE
;AN000;DISCARD WORKAREA
895 POP BP ;AN000;RESTORE CALLER'S BP REG
896 RET ;AN000;RETURN TO CALLER
898 ; = = = = = = = = = = = =
899 HEADER
<ANY_MORE_SUBDIR
- LOOK AHEAD
,SEE
IF MORE SUBDIR
> ;AN000;
900 ANY_MORE_SUBDIR PROC
;AN000;
901 ;HAVING JUST DONE A FIND FIRST/NEXT FOR A SUBDIRECTORY,LOOK FOR ANOTHER
902 ;INPUT: BP=DYNAMIC WORKAREA
903 ; "FLAGS" FIRST TIME SWITCH
904 ; FOR FIRST TIME, "START_DRIVE" AND "START_PATH" SET WITH WHERE TO LOOK.
905 ; FIX_DTA_FILN MAY HAVE LATEST FILE PROCESSED, OR NOTHING
906 ;OUTPUT:"FRAM_CHAR"="ELBO" = NO MORE SUBDIRS AFTER THIS ONE.
907 ; "FRAM_CHAR"="TEE" = ANOTHER SUBDIR AFTER THIS ONE
908 ; "EXITFL" SET TO NON ZERO IF REAL ERROR OCCURRED.
909 ; FIX_DTA_FILN IS RESTORED TO WHATEVER IT HAD.
910 ; = = = = = = = = = = = =
911 MOV SI,OFFSET FIX_DTA_FILN
;AN000;FROM THE DTA, FILENAME AREA
912 MOV DI,OFFSET SAVEFILN
;AN000; TO A TEMPORARY LOCATION
913 MOV CX,LENGTH SAVEFILN
;AN000; SAVE THE ENTIRE FILENAME FIELD
914 REP MOVSB ;AN000; INTO THE TEMPORARY LOCATION
916 TEST FLAGS
,F_FIRSTIME
;AN000;IS THIS THE FIRST TIME?
917 ; $IF Z ;AN000;IF THE FIRST TIME
919 MOV CX,ATTR_DIR
;AN000;SET ATTRIBUTE TO SUBDIR
920 MOV DX,OFFSET STAR_STAR
;AN000;PASS FILENAME TO BE LOOKED FOR
921 DOSCALL FINDFIRST
;AN000;
923 ; $ELSE ;AN000;SINCE NOT FIRST TIME
926 DOSCALL FINDNEXT
;AN000;LOOK FOR ANOTHER SUBDIR
928 ; $ENDIF ;AN000;FIRSTIME?
930 ; $SEARCH COMPLEX ;AN000;
933 DOSCALL FINDNEXT
;AN000;LOOK FOR ANOTHER SUBDIR
936 ; $EXITIF C ;AN000;IF ERROR WITH FINDNEXT
938 CALL IF_NOMOREFILES
;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES
939 ;CY NOT SET = "NO MORE FILES"
940 ;CY IS SET = OTHER PROBLEM, "EXITFL" SET
941 MOV AL,GRAF_ELBO
;AN002;CHANGE TO ELBO
942 MOV [BP].FRAM_CHAR
,AL ;AC002;SAY NO MORE SUBDIR
943 ; $ORELSE ;AN000;SINCE NO ERROR WITH FINDNEXT
946 CMP FIX_DTA_ATTR
,ATTR_DIR
;AN000;DID I FIND A SUBDIR?
947 ; $ENDLOOP E,AND ;AN000;FINDNEXT OK?
949 CMP FIX_DTA_FILN
,PERIOD
;AN000;IS THIS FILENAME STARTING WITH "PERIOD"?
950 ; $ENDLOOP NE ;AN000;IF NOT, FOUND A REAL SUBDIR
952 MOV AL,GRAF_TEE
;AN002;CHANGE TO TEE
953 MOV [BP].FRAM_CHAR
,AL ;AN002;SAY STILL MORE SUBDIR
957 TEST FLAGS
,F_FIRSTIME
;AN000;IS THIS THE FIRST TIME?
958 ; $IF NZ ;AN000;IF NOT THE FIRST TIME
960 MOV DI,OFFSET FIX_DTA_RES
;AN000;MOVE TO THE FIXED DTA AREA
961 LEA SI,[BP].FRAM_DTA_RES
;AN000; FROM DYNAMIC AREA IN STACK
962 MOV CX,LENGTH FIX_DTA_RES
;AN000;SET COUNT TO FIELD SIZE
963 REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK
967 MOV DI,OFFSET FIX_DTA_FILN
;AN000;FROM A TEMPORARY LOCATION
968 MOV SI,OFFSET SAVEFILN
;AN000; TO THE DTA, FILENAME AREA
969 MOV CX,LENGTH SAVEFILN
;AN000; RESTORE THE ENTIRE FILENAME FIELD
970 REP MOVSB ;AN000; FROM THE TEMPORARY LOCATION
972 RET ;AN000;RETURN TO CALLER
973 ANY_MORE_SUBDIR ENDP
;AN000;
974 ; = = = = = = = = = = = =
975 HEADER
<FIND_TYPE_NORMAL
- PROCESS NORMAL
, NON
-DIR
, FILES
> ;AN000;
976 FIND_TYPE_NORMAL PROC
NEAR ;AN000;
977 PUBLIC FIND_TYPE_NORMAL
;AN000;MAKE ENTRY IN LINK MAP
978 ;INPUT - PB=BASE OF FRAME, DYNAMIC WORKAREA WITH DTA
979 ;OUTPUT - CY SET IF A PROBLEM, AND "EXITFL" HAS ERROR CODE
980 ; CY CLEAR IF NORMAL "NO MORE FILES" FROM FIND FIRST/NEXT.
981 ; = = = = = = = = = = = =
983 AND FLAGS
,0FFH-F_FLN
;AN000;CLEAR INDICATOR FOR THIS SUBDIR
984 ; TO SAY NO FILES PRINTED YET FOR THIS SDIR ;AN000;
985 MOV CX,ATTR_NORMAL
;AN000;SET TO LOOK FOR ALL FILES
986 CALL BEGIN_FIND
;AN000;DO FIND FIRST
988 ; $DO ;AN000;STEP THRU EACH ENTRY IN THIS SUBDIR
990 ; $LEAVE C ;AN000;QUIT IF ERROR
992 OR FLAGS
,F_FLN
;AN000;REQUEST THIS PRINTOUT BE DONE
993 CALL SHOW_FN
;AN000;SHOW THIS FILE JUST FOUND
995 CALL FIND_NEXT
;AN000;LOOK FOR ANOTHER
997 ; $ENDDO ;AN000;LEAVE WILL QUIT IF PROBLEM WITH FINDNEXT
1000 CALL IF_NOMOREFILES
;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES
1001 ;CY NOT SET = "NO MORE FILES"
1002 ;CY IS SET = OTHER PROBLEM, "EXITFL" SET
1003 ; $IF NC ;AN000;IF NO MORE FILES,
1005 MOV AL,BLANK
;AN000;
1006 MOV DI,OFFSET FIX_DTA_FILN
;AN000;WHERE NAME IS TO GO
1007 MOV CX,LENGTH FIX_DTA_FILN
;AN000;NO. BYTES IN FILENAME FIELD
1008 REP STOSB ;AN000;FILL FILENAME FIELD WITH BLANKS
1010 MOV AL,ATTR_NORMAL
;AN000;SAY IT IS JUST A FILENAME
1011 CALL SHOW_FN
;AN000;OUTPUT A BLANK LINE
1013 ; $ENDIF ;AN000;NO MORE FILES?
1016 RET ;AN000;RETURN TO CALLER
1017 FIND_TYPE_NORMAL ENDP
;AN000;
1018 ; = = = = = = = = = = = =
1019 HEADER
<FIND_TYPE_DIR
- PROCESS THE DIRECTORY
> ;AN000;
1020 FIND_TYPE_DIR PROC
NEAR ;AN000;
1021 PUBLIC FIND_TYPE_DIR
;AN000;MAKE ENTRY IN LINK MAP
1022 ;INPUT - PB=BASE OF FRAME, DYNAMIC WORKAREA WITH DTA
1023 ;OUTPUT - CY SET IF A PROBLEM
1024 ; CY CLEAR IF NORMAL "NO MORE FILES" FROM FIND FIRST/NEXT.
1025 ; = = = = = = = = = = = =
1026 OR FLAGS
,F_FLN
;AN000;PERMIT DISPLAY OF BUFFER
1027 MOV CX,ATTR_DIR
;AN000;LOOK FOR DIRECTORY ATTRIBUTE
1028 CALL BEGIN_FIND
;AN000;DO FIND FIRST
1030 ; $SEARCH ;AN000;STEP THRU EACH ENTRY IN THIS SUBDIR
1032 ; $LEAVE C ;AN000;QUIT IF ERROR
1034 CMP FIX_DTA_FILN
,PERIOD
;AN000;WAS THAT A "PERIOD" FILENAME?
1035 ; $IF NE ;AN000;IF NOT, GO CHECK IT OUT
1037 MOV AL,FIX_DTA_ATTR
;AN000;LOOK AT ATTRIB OF THIS FILE
1038 CMP AL,ATTR_DIR
;AN000;IS THIS A DIRECTORY?
1039 ; $IF E ;AN000;IF DIR,
1041 CALL SHOW_FN
;AN000;SHOW THIS FILE JUST FOUND
1043 ADD CURRENT_COL
,DASH_NUM
+1 ;AN000;LOCATE SDIR NAME IN PRINTOUT LINE
1044 MOV SI,CURRENT_COL
;AN000;
1045 LEA SI,BUF
-1[SI] ;AN000;POINT AT SUBDIR NAME JUST PRINTED
1046 MOV DI,OFFSET FIX_DTA_FILN
;AN000;WHERE "NEXT_LEVEL" EXPECTS IT
1047 MOV CX,LENGTH FIX_DTA_FILN
;AN000;
1048 REP MOVSB ;AN000;SET UP SUBDIR NAME TO GO PROCESS
1050 CALL NEXT_LEVEL
;AN000;SHIFT TO LOWER LEVEL SUBDIRECTORY
1052 CALL EXECUTE
;AN000;RECURSIVE CALL, PROCESS NEW LEVEL OF SUBDIR
1054 SUB CURRENT_COL
,DASH_NUM
+1 ;AN000;BACK TO ORIGINAL LEVEL
1055 LEA DX,[BP].FRAM_CURR_PATH
;AN000;DS:DX = POINTER TO ASCIIZ STRING
1056 DOSCALL CHDIR
;AN000;(3BH) CHANGE CURRENT DIRECTORY
1057 ;GO BACK TO THE DIRECTORY THIS LEVEL OF
1058 ; STACK WORKAREA HAS BEEN DEALING WITH,
1059 ; SINCE "EXECUTE" HAD CHANGED IT TO WORK ON
1060 ; A LOWER SUBDIRECTORY.
1061 ; $ENDIF ;AN000;DIR?
1063 ; $ENDIF ;AN000;"PERIOD" FILENAME?
1065 CMP EXITFL
,EXOK
;AN000;ANY ERRORS SO FAR?
1066 ; $EXITIF NE,NUL ;AN000;YES, QUIT THIS MESS; OTHERWISE KEEP LOOKING
1068 CALL FIND_NEXT
;AN000;LOOK FOR ANOTHER
1070 ; $ENDLOOP ;AN000;LEAVE WILL QUIT IF PROBLEM WITH FINDNEXT
1073 CMP EXITFL
,EXOK
;AN000;IF NO ERROR FOUND SO FAR
1076 CALL IF_NOMOREFILES
;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES
1077 ;CY NOT SET = "NO MORE FILES"
1078 ;CY IS SET = OTHER PROBLEM, "EXITFL" SET
1079 ; $ENDIF ;AN000;ANY ERRORS SO FAR?
1083 RET ;AN000;RETURN TO CALLER
1084 FIND_TYPE_DIR ENDP
;AN000;
1085 ; = = = = = = = = = = = =
1086 HEADER
<NEXT_LEVEL
- SET UP TO LOOK
AT LOWER LEVEL SUBDIR
> ;AN000;
1087 NEXT_LEVEL PROC
NEAR ;AN000;
1088 PUBLIC NEXT_LEVEL
;AN000;
1089 ;INPUT: FIX_DTA_FILN - FILE NAME OF LOWER LEVEL SUBDIR
1090 ;OUTPUT: START_PATH - HAS COMPLETE PATH TO THE NEW LEVEL SUBDIR
1091 ; = = = = = = = = = = = =
1093 MOV SI,OFFSET START_PATH
+1 ;AN000;WHERE TO SAVE CURRENT PATH
1094 MOV DL,DEFDRIVE
;AN000;DL = DRIVE NUM (0=DEF, 1=A, ETC)
1095 DOSCALL GET_CUR_DIR
;AN000;(47H) GET CURRENT DIRECTORY
1096 ;OUTPUT: DS:SI POINTS TO FULL PATH NAME
1097 DEC SI ;AN012;START SCAN AT START_PATH
1098 CALL SCAN_DBCS
;AN012;GET LAST 2 CHARS IN DL,DH
1099 ; SI NOW AT END OF STRING
1100 MOV DI,SI ;AN012;GET POINTER TO NUL
1101 CMP DL,BACK_SLASH
;AN000;
1102 ; $IF NE ;AN012;IF PATH NOT ALREADY TERMINATED WITH A "\"
1104 MOV BYTE PTR [DI],BACK_SLASH
;AN000;TERMINATE PREVIOUS PATH
1105 INC DI ;AN000;DI POINTS TO NEXT NUL AT END OF STRING
1106 ; $ENDIF ;AN000;END IN "\"?
1108 MOV SI,OFFSET FIX_DTA_FILN
;AN000;GET NAME OF NEW SUBDIR
1109 MOV CX,LENGTH FIX_DTA_FILN
;AN000;
1110 REP MOVSB ;AN000;ADD THE NEW SUBDIR TO END
1112 AND FLAGS
,0FFH - F_FIRSTIME
;AN000;IN NEW SUBDIR, REQUEST FIND FIRST TO START
1113 RET ;AN000;RETURN TO CALLER
1114 NEXT_LEVEL ENDP
;AN000;
1115 ; = = = = = = = = = = = =
1116 HEADER
<SCAN_DBCS
- FIND LAST
2 SBCS CHARS
IN ASCIIZ
> ;AN000;
1117 SCAN_DBCS PROC
NEAR ;AN000;
1118 PUBLIC SCAN_DBCS
;AN000;
1119 ;INPUT: DS:SI = ASCIIZ STRING TO BE SCANNED
1120 ;OUTPUT: DL=LAST SBCS CHAR BEFORE NUL
1121 ; DH=NEXT TO LAST SBCS CHAR BEFORE NUL
1122 ; IF NO SBCS CHAR FOUND, DL OR DH WILL BE NUL
1123 ; SI=OFFSET TO NUL DELIMITER
1125 XOR DX,DX ;AN000;CLEAR CHAR ACCUMULATOR
1128 LODSB ;AN000;GET NEXT CHAR FROM DS:SI TO AL
1129 CMP AL,NUL
;AN000;IS THAT THE DELIMITER?
1130 ; $LEAVE E ;AN000;FOUND THE END, SO QUIT
1132 CALL CHK_DBCS
;AN000;IS THIS THE FIRST OF A DBCS PAIR?
1134 ; $IF C ;AN000;IF SO, FOUND A DBCS PAIR
1136 INC SI ;AN000;SKIP ITS PARTNER
1137 MOV AL,NUL
;AN000;PASS BACK A NUL, INSTEAD OF AN SBCS CHAR
1140 MOV DH,DL ;AN000;SAVE PREVIOUS CHAR
1141 MOV DL,AL ;AN000;REMEMBER THE CHAR JUST FOUND
1145 DEC SI ;AN000;LODSB SET SI ONE BEYOND NUL
1146 ; SO SET SI BACK TO POINT TO THE NUL
1147 RET ;AN000;RETURN TO CALLER
1148 SCAN_DBCS ENDP
;AN000;
1149 ; = = = = = = = = = = = =
1150 HEADER
<BEGIN_FIND
- DO FIND FIRST
FILE> ;AN000;
1151 BEGIN_FIND PROC
NEAR ;AN000;
1152 PUBLIC BEGIN_FIND
;AN000;MAKE ENTRY IN LINK MAP
1153 ;INPUT- CURRENT DOS DEFAULT DRIVE HAS TARGET DRIVE TO BE RESEARCHED.
1154 ; CURRENT DEFAULT SUBDIRECTORY HAS SUBDIR TO BE RESEARCHED.
1155 ; CX = ATTRIBUTE OF FILE TYPE TO LOOK FOR
1156 ; BP = OFFSET OF DYNAMIC WORKAREA
1157 ;OUTPUT - DTA IS SET UP WITH FIRST FILE FOUND, READY TO BE USED BY FIND NEXT.
1158 ; WORKAREA HAS SAVED THE RESULT OF FINDFIRST.
1159 ; = = = = = = = = = = = =
1161 MOV DX,OFFSET STAR_STAR
;AN000;PASS FILENAME TO BE LOOKED FOR
1162 DOSCALL FINDFIRST
;AN000;(4EH) LOOK FOR FIRST SUBDIRECTORY
1164 MOV SI,OFFSET FIX_DTA_RES
;AN000;MOVE FROM THE FIXED DTA AREA
1165 LEA DI,[BP].FRAM_DTA_RES
;AN000; TO THE DYNAMIC AREA IN STACK
1166 MOV CX,LENGTH FIX_DTA_RES
;AN000;SET COUNT TO FIELD SIZE
1167 REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK
1169 RET ;AN000;RETURN TO CALLER
1170 BEGIN_FIND ENDP
;AN000;
1171 ; = = = = = = = = = = = =
1172 HEADER
<FIND_NEXT
- LOOK FOR NEXT
ENTRY IN DIRECTORY
> ;AN000;
1173 FIND_NEXT PROC
NEAR ;AN000;
1174 PUBLIC FIND_NEXT
;AN000;
1175 ;INPUT: RESERVED FIELD, LEFT FROM PREVIOUS FIND FIRST/NEXT, IN [BP].FRAM_DTA_RES
1176 ;OUTPUT: [BP].FRAM_DTA_RES UPDATED WITH NEW RESERVED DATA, FROM CURRENT DTA
1177 ; FIX_DTA.? FIELDS ARE SET UP TO DEFINE NEW FILE JUST FOUND.
1178 ; CY SET IF NO MORE FILES FOUND, CY CLEAR IF A NEW FILE FOUND.
1179 ; = = = = = = = = = = = =
1180 LEA SI,[BP].FRAM_DTA_RES
;AN000;GET WHAT WAS LEFT FROM LAST FIND
1181 MOV DI,OFFSET FIX_DTA_RES
;AN000;INTO THE FIXED DTA AREA
1182 MOV CX,LENGTH FIX_DTA_RES
;AN000;SET COUNT TO FIELD SIZE
1183 REP MOVSB ;AN000;SET UP DTA FOR FIND
1185 DOSCALL FINDNEXT
;AN000;(4FH) CARRY WILL BE SET TO REFLECT RESULT
1187 MOV SI,OFFSET FIX_DTA_RES
;AN000;MOVE FROM THE FIXED DTA AREA
1188 LEA DI,[BP].FRAM_DTA_RES
;AN000; TO THE DYNAMIC AREA IN STACK
1189 MOV CX,LENGTH FIX_DTA_RES
;AN000;SET COUNT TO FIELD SIZE
1190 REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK
1192 RET ;AN000;RETURN TO CALLER
1193 FIND_NEXT ENDP
;AN000;
1194 ; = = = = = = = = = = = =
1195 HEADER
<SHOW_FN
- DISPLAY THE FILENAME FOUND
> ;AN000;
1196 SHOW_FN PROC
NEAR ;AN000;
1197 PUBLIC SHOW_FN
;AN000;MAKE ENTRY IN LINK MAP
1198 ;INPUT - BP=OFFSET TO WORKAREA IN STACK
1199 ; AL=ATTRIBUTE OF FILENAME AS DEFINED IN DIR ENTRY
1200 ; FLAGS (F_FLN) INDICATOR OF FLN HAVING BEEN PRINTED
1201 ;OUTPUT - "BUF" IS SET UP TO CONTAIN THE DISPLAY LINE, AND IS SENT TO STDOUT.
1202 ; = = = = = = = = = = = =
1203 ;DESCRIPTION OF THE LINE TO BE DISPLAYED, IN "BUF":
1204 ;"CURRENT_COL" HAS COL NUMBER WHERE LEADING GRAPHIC IS TO GO.
1205 ;"DASH_NUM" IS THE NUM OF DASHES THAT IMMEDIATELY FOLLOWS THE LEADING
1206 ; GRAPHIC. (FOR SUBDIRECTORIES ONLY - FOR REGULAR FILENAMES, THIS
1207 ; FIELD WOULD HAVE SPACES INSTEAD OF DASHES.)
1208 ;"FLN_INDENT" IS THE NUMBER OF SPACES TO BE PUT RIGHT IN FRONT OF A
1209 ; FILENAME. FOR SUBDIRS, THERE IS NO SUCH FIELD
1210 ;EXAMPLE, FOR SUBDIRS
1212 ; FOR ORDINARY FILES
1213 ; ³xxxssssANY_FILN.EXT (WHERE x AND s ARE SPACES)
1214 ; = = = = = = = = = = = =
1216 CMP FIX_DTA_FILN
,PERIOD
;AN000;DOES FILENAME START WITH PERIOD?
1217 ; $IF NE ;AN000;IF NOT, CONTINUE...
1219 MOV BL,AL ;AN000;SAVE FILE ATTRIBUTE IN AL INTO BL
1221 CALL FLN_TO_BUF
;AN000; MOVE NAME OF FILE TO OUTPUT BUFFER
1223 CALL GRAF_TO_BUF
;AN000;DETERMINE LEADING GRAPHIC FOR BUFFER
1225 CALL BLANK_DASH
;AN000;PUT BLANKS OR DASHES INTO BUF BEFORE FILENAME
1227 ; BUFFER INITIALIZED, DISPLAY IT
1229 MOV DX,OFFSET BUF
;AN000;DISPLAY FILENAME OF FILE FOUND
1230 CALL LEN_ASCIIZ
;AN000;SET CX=LEN OF DX@ BUFFER, UP THRU NUL
1232 DEC CX ;AN000;FORGET THE NUL
1233 TEST FLAGS
,F_FLN
;AN000;HAVE ANY FLN BEEN PRINTED YET?
1234 ; $IF NZ ;AN000;IF SO, PRINT THIS
1236 CALL DO_WRITE
;AN000;DISPLAY FILENAME IN DX TO STDOUT
1238 ; $ENDIF ;AN000;FILES PRINTED YET?
1240 ; CLEAN UP BUFFER FOR NEXT TIME
1242 CALL FIX_GRAF
;AN000;SET UP GRAPHIC FOR NEXT LINE
1244 MOV AL,[BP].FRAM_CHAR
;AN000;GET ALTERED GRAPHIC CHAR
1245 MOV DI,CURRENT_COL
;AN000;FIND WHERE IN "BUF"
1246 LEA DI,BUF
-1[DI] ;AN000; TO PUT ALTERED GRAPHIC
1247 STOSB ;AN000;STORE ALTERED GRAPHIC INTO BUFFER
1249 CMP BL,ATTR_DIR
;AN000;LOOK AT ATTRIB OF FILENAME
1250 ; $IF E ;AN000;IF IS A SUBDIRECTORY
1252 OR FLAGS
,F_SUBDIR
;AN000;SAY, "A SUBDIR HAS BEEN PRINTED"
1254 MOV DI,CURRENT_COL
;AN000;GET COL NUM OF ELBO/TEE
1255 LEA DI,BUF
[DI] ;AN000;POINT TO JUST AFTER ELBO/TEE
1256 MOV AL,BLANK
;AN000;BLANK OUT THE HORIZONTAL DASHES
1257 MOV CX,DASH_NUM
;AN000;HOW MANY DASHES WERE PUT IT
1258 REP STOSB ;AN000;WIPE OUT THOSE DASHES FOR NEXT GUY
1261 ; $ENDIF ;AN000;PERIOD FILENAME?
1263 RET ;AN000;RETURN TO CALLER
1264 SHOW_FN ENDP
;AN000;
1265 ; = = = = = = = = = = = =
1266 HEADER
<FLN_TO_BUF
- MOVE FILENAME TO BUFFER
> ;AN000;
1267 FLN_TO_BUF PROC
NEAR ;AN000;
1268 PUBLIC FLN_TO_BUF
;AN000;
1269 ;INPUT: CURRENT_COL - INDEX INTO "BUF" WHERE THIS DISPLAY STARTS
1270 ; FIX_DTA_FILN - NAME OF FILE TO BE DISPLAYED
1271 ;OUTPUT: "BUF" HAS LEADING GRAPHIC AND FILENAME READY FOR DISPLAY.
1272 ; = = = = = = = = = = = =
1273 MOV DI,CURRENT_COL
;AN000;
1274 CMP BL,ATTR_DIR
;AN000;LOOK AT ATTRIB OF FILENAME
1275 ; $IF NE ;AN000;IF NOT A SUBDIRECTORY
1277 LEA DI,BUF
+DASH_NUM
+FLN_INDENT
[DI] ;AN000;SET DESTINATION TO "BUF"+
1278 ; $ELSE ;AN000;SINCE IT IS SUBDIRECTORY
1281 LEA DI,BUF
+DASH_NUM
[DI] ;AN000;SET DESTINATION TO "BUF"+
1284 MOV CX,LENGTH FIX_DTA_FILN
;AN000;SET COUNT TO MOVE ENTIRE FILE NAME
1285 MOV SI,OFFSET FIX_DTA_FILN
;AN000;FROM DTA OF FIND FIRST
1288 LODSB ;AN000;GET FIRST\NEXT CHAR OF FILENAME
1289 STOSB ;AN000;MOVE THAT BYTE TO OUTPUT MSG FIELD
1290 CMP AL,NUL
;AN000;IS THIS THE NUL CHAR DELIMITER?
1291 ; $LEAVE E ;AN000;QUIT IF NUL FOUND
1293 ; $ENDDO LOOP ;AN000;
1296 RET ;AN000;RETURN TO CALLER
1297 FLN_TO_BUF ENDP
;AN000;
1298 ; = = = = = = = = = = = =
1299 HEADER
<GRAF_TO_BUF
- SELECT LEADING GRAPHIC CHAR FOR BUF
> ;AN000;
1300 GRAF_TO_BUF PROC
NEAR ;AN000;
1301 PUBLIC GRAF_TO_BUF
;AN000;
1302 ;INPUT: BL = ATTRIBUTE OF FILENAME
1303 ; FLAGS (F_FIRSTIME BIT)
1304 ; FRAM_CHAR = LEADING CHAR, FOR FILENAME DISPLAY
1305 ; CURRENT_COL = WHERE IN BUF TO PUT CHARS
1306 ; BUF = TO RECEIVE LEADING CHAR
1307 ;OUTPUT: BUF HAS LEADING CHAR
1308 ; = = = = = = = = = = = =
1309 TEST FLAGS
,F_SWITCH
;AN000;ARE FILENAMES TO BE LISTED
1310 ; $IF Z ;AN000;NO, JUST SUBDIRS
1312 OR FLAGS
,F_FIRSTIME
;AN000;DO NOT DO FIND FIRST SUBDIR
1315 CMP BL,ATTR_DIR
;AN000;LOOK AT ATTRIB OF FILENAME
1316 ; $IF E ;AN000;IF A SUBDIR
1318 CALL ANY_MORE_SUBDIR
;AN000;SEE IF ANOTHER SUBDIR AFTER THIS ONE
1320 ; $ELSE ;AN000;SINCE NOT A SUBDIR
1323 TEST FLAGS
,F_FIRSTIME
;AN000;IS THIS THE FIRST TIME HERE?
1324 ; $IF Z ;AN000;IF FIRST TIME,
1326 CALL FIX_GRAF
;AN000;SET UP GRAPHIC FOR NEXT LINE
1328 ; $ENDIF ;AN000;FIRST TIME?
1330 ; $ENDIF ;AN000;SUBDIR?
1332 OR FLAGS
,F_FIRSTIME
;AN000;FLAG, THIS HAS BEEN DONE
1333 MOV AL,[BP].FRAM_CHAR
;AN000;START BUF WITH CURRENT GRAPHIC CHAR
1334 MOV DI,CURRENT_COL
;AN000;
1335 LEA DI,BUF
-1[DI] ;AN000;
1337 RET ;AN000;RETURN TO CALLER
1338 GRAF_TO_BUF ENDP
;AN000;
1339 ; = = = = = = = = = = = =
1340 HEADER
<BLANK_DASH
- PUT BLANKS
OR DASHES BEFORE FILENAME
> ;AN000;
1341 BLANK_DASH PROC
NEAR ;AN000;
1342 PUBLIC BLANK_DASH
;AN000;
1343 ;INPUT: BL - FILE ATTRIBUTE
1344 ; CURRENT_COL - WHERE THIS DISPLAY STARTS IN "BUF"
1345 ; BUF - PARTLY READY CHARS FOR DISPLAY
1346 ;OUTPUT: BUF HAS PROPER CHARS BETWEEN LEADING GRAPHIC AND FILENAME FIELDS.
1347 ; = = = = = = = = = = = =
1348 CMP BL,ATTR_DIR
;AN000;LOOK AT ATTRIB OF FILENAME
1349 ; $IF NE ;AN000;IF NOT A SUBDIRECTORY
1351 MOV AL,BLANK
;AN000;PUT IN BLANKS
1352 MOV CX,DASH_NUM
+ FLN_INDENT
;AN000;SPECIFY HOW MANY BLANKS TO PUT IN
1353 ; $ELSE ;AN000;SINCE IT IS A SUBDIR
1356 MOV AL,GRAF_DASH
;AN000;PUT IN THE DASHES
1357 MOV CX,DASH_NUM
;AN000;SPECIFY HOW MANY DASHES TO PUT IN
1360 MOV DI,CURRENT_COL
;AN000;GET COL NUM OF ELBO/TEE
1361 LEA DI,BUF
[DI] ;AN000;POINT TO JUST AFTER ELBO/TEE
1362 REP STOSB ;AN000;ADD DASHES/BLANKS TO PRINT LINE IN "BUF"
1363 RET ;AN000;RETURN TO CALLER
1364 BLANK_DASH ENDP
;AN000;
1365 ; = = = = = = = = = = = =
1366 HEADER
<FIX_GRAF
- CHANGE CURRENT GRAPHIC FOR NEXT LINE
> ;AN000;
1367 PUBLIC FIX_GRAF
;AN000;MAKE ENTRY IN LINK MAP
1368 FIX_GRAF PROC
NEAR ;AN000;
1369 ;IN THE WORKAREA, IS A CHAR THAT SHOWS WHAT HAS BEEN FOUND REGARDING ANY
1370 ;LOWER LEVELS OF SUBDIRS.
1371 ;WHEN DISPLAYING A SUBDIR, THE PRINT LINE STARTS EITHER WITH "ELBO",
1372 ;MEANING, NO LOWER LEVELS AFTER THIS ONE, OR WITH "TEE" WHICH MEANS
1373 ;THERE IS ANOTHER LEVEL OF SUBDIR BELOW THIS ONE. AFTER THE DISPLAY,
1374 ;THE REST OF THE DISPLAY OF FILENAMES WITHIN THIS SUBDIR, WILL SHOW
1375 ;THIS CHARACTER, BUT IN A Revised FORMAT. THIS SUBROUTINE PERFORMS
1376 ;THE MODIFICATION, AS:
1377 ;CHANGE "ELBO" TO "BLANK, OR CHANGE "TEE" TO "VERTICAL BAR".
1378 ;INPUT: BP=POINTER TO STACK WORKAREA
1379 ; FRAM_CHAR=FIELD IN WORKAREA WITH CHAR TO BE Revised
1380 ; = = = = = = = = = = = =
1381 PUSH AX ;AN002;SAVE WORK REG
1382 MOV AL,GRAF_ELBO
;AN002;GET ELBO CHAR
1383 CMP [BP].FRAM_CHAR
,AL ;AN000;FOR NEXT DISPLAY LINE AFTER THIS ONE,
1384 ; $IF E ;AN000;IF CURRENT LINE STARTS WITH "ELBO"
1386 MOV [BP].FRAM_CHAR
,BLANK
;AN000;CHANGE IT TO JUST A BLANK
1387 ; $ELSE ;AN000;SINCE NOT ELBO
1390 MOV AL,GRAF_TEE
;AN002;GET THE TEE CHAR
1391 CMP [BP].FRAM_CHAR
,AL ;AC002;CHANGE A "TEE"
1394 MOV AL,GRAF_BAR
;AN002;GET BAR CHAR
1395 MOV [BP].FRAM_CHAR
,AL ;AC002; TO A VERTICAL "BAR"
1398 ; $ENDIF ;AN000;ELBO?
1400 POP AX ;AN002;RESTORE REG
1401 RET ;AN000;RETURN TO CALLER
1402 FIX_GRAF ENDP
;AN000;
1403 ; = = = = = = = = = = = =
1404 HEADER
<ANY_SUBDIRS
- DISPLAY MSG
IF NO SUBDIRS PRINTED
> ;AN000;
1405 ANY_SUBDIRS PROC
NEAR ;AN000;
1406 ;INPUT:FLAGS (F_SUBDIR BIT) IS SET IF ANY SUBDIR HAD BEEN DISPLAYED. IF THIS
1407 ; BIT IS OFF, THEN DISPLAY THE MESSAGE
1408 ; = = = = = = = = = = = =
1410 TEST FLAGS
,F_SUBDIR
;AN000;HAVE ANY SUBDIRS BEEN PRINTED YET?
1411 ; $IF Z ;AN000;NO, NONE PRINTED SO FAR
1413 MOV DI,OFFSET MSGNUM_NOSUB
;AN000;"No sub-directories exist"
1414 CALL SENDMSG
;AN000;DISPLAY THE MESSAGE
1416 ; $ENDIF ;AN000;ANY SUBDIRS PRINTED?
1418 RET ;AN000;RETURN TO CALLER
1419 ANY_SUBDIRS ENDP
;AN000;
1420 ; = = = = = = = = = = = =
1421 HEADER
<DO_WRITE
- SEND STRING TO STDOUT
> ;AN000;
1422 DO_WRITE PROC
NEAR ;AN000;
1423 PUBLIC DO_WRITE
;AN000;
1424 ;AFTER THE REQUESTED STRING IS SEND TO STDOUT, IT IS TERMINATED BY CR,LF
1425 ;INPUT: DX=OFFSET TO STRING TO BE WRITTEN
1427 ;OUTPUT: STRING IS SENT TO STDOUT, FOLLOWED BY CR,LF.
1428 ; BX = SAVED AND RESTORED.
1429 ; = = = = = = = = = = = =
1431 PUSH BX ;AN000;SAVE CALLER'S REG
1432 MOV BX,STDOUT
;AN000;BX = FILE HANDLE
1433 DOSCALL WRITE
;AN000;(40H) WRITE FUNCTION
1435 MOV DX,OFFSET CRLF
;AN000;CLOSE MSG WITH CRLF
1436 MOV CX,LEN_CRLF
;AN000;
1437 DOSCALL WRITE
;AN000;(40H) WRITE FUNCTION
1439 POP BX ;AN000;RESTORE CALLER'S REG
1440 RET ;AN000;RETURN TO CALLER
1441 DO_WRITE ENDP
;AN000;
1442 ; = = = = = = = = = = = =
1443 HEADER
<IF_NOMOREFILES
- ASK EXTENDED ERROR FOR WHY IS ERROR
> ;AN000;
1444 IF_NOMOREFILES PROC
NEAR ;AN000;
1445 PUBLIC IF_NOMOREFILES
;AN000;
1446 ;INPUT - A DOS FUNCTION HAS JUST RETURNED WITH A CARRY INDICATING ERROR
1447 ;OUTPUT - AX=EXTENDED ERROR CODE
1448 ; IF THE ERROR IS JUST A NO MORE FILES, CARRY IS CLEAR
1449 ; IF ANY OTHER ERROR, THEN CARRY IS SET, AND "EXITFL" HAS RET CODE
1450 ; = = = = = = = = = = = =
1452 CALL GET_EXTERR
;AN000;GET THE EXTENDED ERROR TO AX
1454 CMP AX,NO_MORE_FILES
;AN000;SEE IF FILE WAS NOT FOUND
1455 ; $IF E ;AN000;IF NO MORE FILES,
1457 CLC ;AN000;INDICATE A NORMAL RETURN
1458 ; $ELSE ;AN000;SINCE ERROR IS SOMETHING ELSE
1461 STC ;AN000;INDICATE AN ABNORMAL RETURN
1462 MOV EXITFL
,EXERR
;AN000;INDICATE A PROBLEM TO RETURN CODE
1463 ; $ENDIF ;AN000;NO MORE FILES?
1466 RET ;AN000;RETURN TO CALLER
1467 IF_NOMOREFILES ENDP
;AN000;
1468 ; = = = = = = = = = = = =
1469 HEADER
<GET_EXTERR
- CALL EXTENDED ERROR
> ;AN000;
1470 GET_EXTERR PROC
NEAR ;AN000;
1471 PUBLIC GET_EXTERR
;AN000;
1472 ;INPUT - A DOS FUNCTION HAS JUST RETURNED WITH A CARRY INDICATING ERROR
1473 ;OUTPUT: AX HAS EXTENDED ERROR CODE
1474 ; NOTE: OTHER REGS, BX, CX, NORMALLY SET BY THE EXTERROR CALL
1475 ; ARE NOT KEPT. THESE CONTAIN "LOCUS" AND SECONDARY LEVEL CODES
1476 ; THAT ARE NOT USED.
1477 ; = = = = = = = = = = = =
1478 PUSH BX ;AN000;SAVE THE
1479 PUSH DS ;AN000; CALLER'S
1480 PUSH ES ;AN000; REGISTERS
1483 MOV BX,LEVEL_0
;AN000;BX=LEVEL NUMBER
1484 DOSCALL EXTERROR
;AN000;(59H) SET REGS TO SAY WHY PROBLEM
1486 POP CX ;AN000;RESTORE REGS
1487 POP ES ;AN000; CLOBBERED BY
1488 POP DS ;AN000; THE DOSCALL
1491 RET ;AN000;RETURN TO CALLER
1492 GET_EXTERR ENDP
;AN000;
1493 ; = = = = = = = = = = = =
1494 HEADER
<SENDMSG
- PASS
IN REGS
DATA FROM MSG DESCRIPTOR TO DISP MSG
> ;AN000;
1495 SENDMSG PROC
NEAR ;AN000;
1496 PUBLIC SENDMSG
;AN000;
1497 ; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
1498 ; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
1499 ; IF CARRY CLEAR, ALL OK
1500 ; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
1502 ; = = = = = = = = = = = =
1504 PUSH BX ;AN000; SAVE CALLER'S REGS
1509 ; PASS PARMS TO MESSAGE HANDLER IN
1510 ; THE APPROPRIATE REGISTERS IT NEEDS.
1511 MOV AX,[DI].MSG_NUM
;AN000; MESSAGE NUMBER
1512 MOV BX,[DI].MSG_HANDLE
;AN000; HANDLE TO DISPLAY TO
1513 MOV SI,[DI].MSG_SUBLIST
;AN000; OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
1514 MOV CX,[DI].MSG_COUNT
;AN000; NUMBER OF %PARMS, 0 IF NONE
1515 MOV DX,[DI].MSG_CLASS
;AN000; CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
1516 CALL SYSDISPMSG
;AN000; DISPLAY THE MESSAGE
1518 ; $IF C ;AN000; IF THERE IS A PROBLEM,
1520 ; AX=EXTENDED ERROR NUMBER
1521 MOV DI,OFFSET MSGNUM_EXTERR
;AN000; GET REST OF ERROR DESCRIPTOR
1522 MOV BX,[DI].MSG_HANDLE
;AN000; HANDLE TO DISPLAY TO
1523 MOV SI,[DI].MSG_SUBLIST
;AN000; OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
1524 MOV CX,[DI].MSG_COUNT
;AN000; NUMBER OF %PARMS, 0 IF NONE
1525 MOV DX,[DI].MSG_CLASS
;AN000; CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
1526 CALL SYSDISPMSG
;AN000; TRY TO SAY WHAT HAPPENED
1528 STC ;AN000; REPORT PROBLEM
1529 ; $ENDIF ;AN000; PROBLEM WITH DISPLAY?
1532 POP SI ;AN000; RESTORE CALLER'S REGISTERS
1537 RET ;AN000;RETURN TO CALLER
1538 SENDMSG ENDP
;AN000;
1539 ; = = = = = = = = = = =
1540 HEADER
<BREAK_HANDLER
- CONTROL
BREAK VECTOR POINTS HERE
> ;AN000;
1541 BREAK_HANDLER PROC
FAR ;AN000;"FAR" HERE IS REQUIRED FOR
1542 PUBLIC BREAK_HANDLER
;AN000; BREAK INTERRUPT HANDLERS
1543 ;THE INT 23H VECTOR HAS BEEN SET TO POINT HERE.
1544 ;THIS ROUTINE GETS CONTROL IF CONTROL-BREAK IS PRESSED.
1545 ;OUTPUT: THE "STC" REQUESTS THAT DOS ABORT WHEN I RETURN.
1546 ; THERE IS NO ERRORLEVEL VALUE TO BE PASSED BACK TO DOS AT THIS POINT.
1548 CALL RESTORE ;AN000;PUT THINGS BACK LIKE THEY WERE
1550 DOSCALL RET_CD_EXIT
,EXCTL
;AN000;RETURN TO DOS, WITH CTL-BREAK ERROR CODE
1551 INT 20H
;AN000;IN CASE ABOVE FAILS
1553 ;NOTE: THIS IS NOT THE MAIN EXIT FROM "TREE".
1554 ; THE USUAL EXIT IS IN "BEGIN" PROC.
1555 BREAK_HANDLER ENDP
;AN000;
1556 ; = = = = = = = = = = = =
1557 HEADER
<RESTORE - RETURN TO INITIAL DOS DEFAULT DRIVE
> ;AN000;
1558 RESTORE PROC
NEAR ;AN000;
1559 PUBLIC RESTORE ;AN000;
1560 ;SET DOS DEFAULT DRIVE BACK TO THE INITIAL VALUE, AND
1561 ; RESTORE THE INITIAL DEFAULT PATH,
1562 ; AND THE INITIAL "APPEND" STATE,
1563 ; AND THE ORIGINAL CONTROL BREAK VECTOR.
1564 ;INPUT - "DEFAULT_DR" SET TO ALPHA LETTER OF ORIGINAL DOS DEFAULT DRIVE.
1565 ; "START_DR_NUM" SET TO NUMERIC VALUE OF ORIGINAL DOS DEFAULT DRIVE
1566 ; "DEFAULT_PATH" SET TO ORIGINAL CURRENT PATH OF DOS DEFAULT DRIVE
1567 ; "APPEND_FLAGS" HAS ORIGINAL STATUS OF /X OF APPEND
1568 ; "OLDINT23" HAS ORIGINAL OWNER OF CONTROL BREAK VECTOR 23H
1569 ; "OLDINT24" HAS ORIGINAL OWNER OF CRITICAL ERROR VECTOR 24H
1570 ; = = = = = = = = = = = =
1572 TEST FLAGS
,F_FAILING
;AN000;IS RESTORING SUBDIR PERMITTED?
1573 ; $IF Z,AND ;AN000;YES, DO IT
1575 TEST FLAGS
,F_DEF_PAT_TAR
;AN000;HAS ORIGINAL SUBDIR BE FOUND YET?
1576 ; $IF NZ ;AN000;YES, DO IT
1579 ; RESTORE THE CURRENT SUBDIRECTORY TO ITS ORIGINAL PATH
1581 MOV DX,OFFSET DEFAULT_PATH
;AN000;DS:DX = POINTER TO ASCIIZ STRING
1582 DOSCALL CHDIR
;AN000;(3BH) CHANGE CURRENT DIRECTORY
1587 ; RESTORE THE DOS DEFAULT DRIVE TO ITS ORIGINAL DRIVE
1589 MOV DL,START_DR_NUM
;AN000; DL=DRIVE NUMBER (0=A,1=B)
1590 DOSCALL SELECT_DISK
;AN000;(0EH) SETS DEFAULT DRIVE
1592 ; SET APPEND BACK TO ITS ORIGINAL STATUS
1594 TEST FLAGS
,F_APPEND
;AN006;IF DOS VERSION OF APPEND IS ACTIVE
1595 ; $IF NZ ;AN006;IT NEEDS TO BE FIXED BACK LIKE IT WAS
1597 MOV AX,SET_APPEND
;AN000;RESTORE APPEND TO PREVIOUS /X STATUS
1598 MOV BX,APPEND_FLAGS
;AC006;GET PREVIOUS STATUS
1599 INT 2FH
;AN000;SET IT BACK AS IT WAS
1601 ; $ENDIF ;AN006;DOS VERSION OF APPEND?
1604 ; FIXUP THE CONTROL BREAK VECTOR TO ITS ORIGINAL CONTENTS
1606 PUSH DS ;AN000;SAVE THE SEGREG
1607 LDS DX,OLDINT23
;AN000;USING THE ORIGINAL CONTENTS OF THE VECTOR
1608 ;DS:DX = DWORD POINTER TO BE PUT INTO VECTOR
1609 DOSCALL SET_VECTOR
,VEC_CTLBREAK
;AN000;(25H) RESTORE THE ORIG INT 23 HANDLER
1611 POP DS ;AN000;RESTORE THE SEGREG
1613 ; FIXUP THE CRITICAL ERROR VECTOR TO ITS ORIGINAL CONTENTS
1615 PUSH DS ;AN000;SAVE THE SEGREG
1616 LDS DX,OLDINT24
;AN000;USING THE ORIGINAL CONTENTS OF THE VECTOR
1617 ;DS:DX = DWORD POINTER TO BE PUT INTO VECTOR
1618 DOSCALL SET_VECTOR
,VEC_CRITERR
;AN000;(25H) RESTORE THE ORIG INT 24 HANDLER
1620 POP DS ;AN000;RESTORE THE SEGREG
1621 RET ;AN000;RETURN TO CALLER
1622 RESTORE ENDP
;AN000;
1623 ; = = = = = = = = = = = =
1624 HEADER
<MYERRORHANDLER
- SERVICE CRITICAL ERROR HANDLER
> ;AN000;
1625 MYERRORHANDLER PROC
NEAR ;AN000;
1626 ;INPUT: DOS HAS CALLED THE CRITICAL ERROR INTERRUPT, VECTOR 24
1627 ; AL=FAILING DRIVE NUMBER (A:=0; B:=1; ETC.)
1628 ;OUTPUT: EITHER TREE IS TERMINATED (ON ABORT OR FAIL), OR
1629 ; AL HAS OPERATOR RESPONSE, AND IRET BACK TO DOS TO HANDLE IT.
1630 ; = = = = = = = = = = = =
1631 ASSUME
CS:CSEG
;AN000;ONLY THE CS REG IS WORTH A HOOT
1632 ASSUME
DS:NOTHING
;AN000;
1633 ASSUME
ES:NOTHING
;AN000;
1634 ASSUME
SS:NOTHING
;AN000;
1636 PUSH AX ;AN000;SAVE FAILING DRIVE NUMBER (A:=0, B:=1, ETC)
1637 PUSHF ;AN000;SAVE THE FLAGS
1638 ;(THIS IS NEEDED BECAUSE THE OLD INT 24
1639 ; HANDLER WILL EXIT WITH AN "IRET")
1640 CALL DWORD PTR OLDINT24
;AN000;INVOKE THE DOS ERROR HANDLER
1641 ;RESPONSE WILL BE RETURNED IN AL
1646 CMP AL,ABORT
;AN000;DID USER SAY ABORT ?
1647 ; $IF GE ;AN000;YES, PROCESS "ABORT"
1649 PUSH CS ;AN000;SET UP SEGREGS
1650 PUSH CS ;AN000; SO "RESTORE" WILL LIKE THEM
1653 ASSUME
DS:CSEG
,ES:CSEG
;AN000;TELL THE ASSEMBLER WHAT I JUST DID
1654 POP AX ;AN007;GET AL=FAILING DRIVE NUMBER
1655 MOV AH,START_DRIVE
;AN007;GET THE TARGET DRIVE BEING USED
1656 SUB AH,DRIVEA
;AN007; A:=0, B:=1, ETC
1657 CMP AH,AL ;AN007;IS START DRIVE SAME AS FAILING DRIVE?
1658 ; $IF E ;AN007;IF SAME DRIVE
1660 OR FLAGS
,F_FAILING
;AN007;REQUEST CHDIR ON FAILING DRIVE NOT TO BE DONE
1664 CALL RESTORE ;AN000;RESTORE ORIGINAL CONDITIONS
1666 DOSCALL RET_CD_EXIT
,EXABORT
;AN000;QUIT, RETURN ERRORLEVEL CODE TO DOS
1667 ; = = = = = = = = = = = = = = = = =
1670 ADD SP,WORD ;AC009;UNDO THE PUSH AX ABOVE
1672 MYERRORHANDLER ENDP
;AN000;
1673 ; = = = = = = = = = = = =
1674 HEADER
<CHK_DBCS
-SEE
IF SPECIFIED
BYTE IS A DBCS LEAD
BYTE> ;AN012;
1675 ;*****************************************************************************
1676 ; Check DBCS environment
1677 ;*****************************************************************************
1679 ; Function: Check if a specified byte is in ranges of the DBCS lead bytes
1680 ; Input: AL = Code to be examined
1681 ; Output: If CF is on then a lead byte of DBCS
1682 ; Register: FL is used for the output, others are unchanged.
1684 PUBLIC CHK_DBCS
;AN012;
1685 Chk_DBCS PROC
;AN012;
1686 PUSH DS ;AN012;save these regs, about to be clobbered
1688 LDS SI,DBCSENV
;AN012;GET VECTOR OF DBCS RANGES
1690 ASSUME
DS:NOTHING
;AN012;that function clobbered old DS
1692 OR SI,SI ;AN012;IS THIS VECTOR SET YET?
1693 ; $IF Z ;AN012;NO, GO GET THE VECTOR
1696 DOSCALL DBCS_ENV
,GET_DBCS_ENV
;AN012;SET DS:SI TO POINT TO DBCS VECTOR
1698 MOV WORD PTR DBCSENV
,SI ;AN012;SAVE THE DBCS VECTOR OFFSET
1699 MOV WORD PTR DBCSENV
+WORD,DS ;AN012; AND ITS SEGID
1700 POP AX ;AN012;REGAIN THE CHAR TO BE CHECKED
1705 CMP WORD PTR [SI],NUL
;AN012;vector ends with a nul terminator entry
1706 ; $LEAVE E ;AN012;if that was the terminator entry, quit
1708 CMP AL,[SI] ;AN012;look at LOW value of vector
1709 ; $EXITIF NB,AND ;AN012;if this byte is in range with respect to LOW
1711 CMP AL,[SI+1] ;AN012;look at HIGH value of vector
1712 ; $EXITIF NA ;AN012;if this byte is still in range
1714 STC ;AN012;set flag to say, found a DBCS char.
1715 ; $ORELSE ;AN012;since char not in this vector
1718 ADD SI,WORD ;AN012;go look at next vector in dbcs table
1719 ; $ENDLOOP ;AN012;go back and check out new vector entry
1722 CLC ;AN012;set flag to say this is not a DBCS character
1725 POP SI ;AN012;restore the regs
1728 ASSUME
DS:CSEG
;AN012;tell masm, DS back to normal
1731 Chk_DBCS ENDP
;AN012;
1732 ; = = = = = = = = = = = =
1733 PATHLABL TREE
;AN013;