7 ;-----------------------------------------------------------------------------
11 ; Author: G. G. A. Network version
12 ; B. A. F.` DOS changes
14 ; Syntax: From the DOS command line:
16 ; APPEND [d:]path[[;[d:]path]...]
17 ; - Used to specify the directories to be
18 ; searched after the working directory.
21 ; - Used to release all appended directories.
24 ; - Used to show appended directories.
28 ; APPEND [[d:]path | | /X | /E | /X /E]
29 ; - [d:]path Normal support and Set path
31 ; - /X Extended support, SEARCH, FIND and EXEC
32 ; - /E Use DOS Environment for path(s)
35 ; @@01 07/11/86 Fix hang in TopView start PTM P00000??
36 ; @@02 07/28/86 Fix APPEND size problem PTM P0000045
37 ; @@03 07/29/86 Fix APPEND status with /E problem PTM P00000??
38 ; @@04 07/30/86 Fix second APPEND hang PTM P0000053
39 ; @@05 08/13/86 Fix parameter error PTM P0000125
40 ; @@06 08/20/86 Fix APPEND xxx fails in TopView PTM P0000217
41 ; @@07 08/21/86 Resurrect APPEND version message PTM P0000252
42 ; @@08 08/21/86 APPEND=path first time hangs PTM P0000254
43 ; @@09 08/22/86 APPEND gets wrong path under nested COMMAND PTM P0000276
44 ; @@10 08/28/86 Change message for @@05 PTM P0000291
45 ; @@11 09/10/86 Support message profile and make
46 ; msg length variable. R.G. PTM P0000479
47 ; @@12 09/25/86 Allow second external append call. (RG) PTM P0000515
48 ; @@13 09/30/86 APPEND gets wrong path under nested COMMAND PTM P0000600
49 ; Again. Fix in COMMAND now, so remove @@09 changes
50 ; @@14 10/01/86 Lower case drive in path files PTM P0000600
51 ; @@15 10/06/86 Include "," and "=" in skip leading of
52 ; argument area parsing. PTM P0000677
53 ; @@16 10/06/86 Fix not using full APPEND path PTM P0000794
54 ; @@17 12/03/86 When searching for "APPEND=" string in
55 ; environment, make sure delimiter precedes.(RG) PTM P0000893
57 ;-------------------------------------------------------------------
59 ; AN000 3.30 changes, GGA 6/87 new code. P000
60 ; AN001 Support DRIVE and PATH modes D043
61 ; AN002 Add truename function P1276
62 ; AN003 Add extended handle open function D250
64 ; AN006 Add DBCS support
65 ; AN007 Release Environmental Vector space P2666
66 ; AN008 Allow equal symbol with append - APPEND=A:/1; P2901
67 ; AN009 Release Environmental Vector on only the P3333
68 ; first invocation of APPEND
69 ; AN010 display invalid parm from command line P3908
72 ;-----------------------------------------------------------------------------
74 ;-----------------------------------------------------------------------------
75 ;06-02-86 0.0 Begin conversion to PC/DOS version
76 ;06-20-86 0.0 End conversion to PC/DOS version
80 cseg
segment public para
'CODE'
82 assume
ds:nothing
,es:nothing
84 ;-----------------------------------------------------------------------------
86 ;-----------------------------------------------------------------------------
90 NETSYSUTIL EQU
0C2H ; SYSTEM UTILITIES
91 NETENQ EQU
07H ; ENQ RESOURCE
92 NETDEQ EQU
08H ; DEQ RESOURCE
94 TCBR_APPEND EQU
001H ; APPEND ACTIVE
96 DOSSERVER EQU 5
DH ; SERVER OPERATION
97 DOSSETERROR EQU
0AH ; SET EXTENDED ERROR
108 DPL_XID
DW 0 ;RESERVED
109 DPL_UID
DW 0 ;SERVER USER ID
110 DPL_PID
DW 0 ;REDIRECTOR PROCESS ID
114 include appendp
.inc ; parseing stuff for append ;AN004;
116 ; extrn end_address:near ; end of stay resident stuff
118 ; extrn bad_append_msg:byte ; messages
119 ; extrn path_error_msg:byte
120 ; extrn parm_error_msg:byte
121 ; extrn path_parm_error_msg:byte
122 ; extrn no_append_msg:byte ; @@05
123 ; extrn append_assign_msg:byte
124 ; extrn append_TV_msg:byte ; @@01
125 ; extrn bad_DOS_msg:byte
126 ; extrn second_APPEND_msg:byte ; @@04
128 ; extrn len_bad_append_msg:word ;@@11
129 ; extrn len_path_error_msg:word ;@@11
130 ; extrn len_parm_error_msg:word ;@@11
131 ; extrn len_path_parm_error_msg:word ;@@11
132 ; extrn len_no_append_msg:word ;@@11
133 ; extrn len_append_assign_msg:word ;@@11
134 ; extrn len_append_TV_msg:word ;@@11
135 ; extrn len_bad_DOS_msg:word ;@@11
136 ; extrn len_second_APPEND_msg:word ;@@11
138 ; Environmental Vector
140 PSP_Env equ 2
ch ;Environmental vector segment in PSP ;an007; dms;
144 DOS_function equ 21h
; DOS function call interrupt
145 int_function equ 2fh
; DOS internal function interrupt, used
146 ; to verify APPEND presence
147 termpgm equ 20h
; @@05
152 get_vector equ 3521h
; DOS function call to get INT 21 vector
153 set_vector equ 2521h
; DOS function call to set INT 21 vector
154 get_intfcn equ 352fh
; DOS function call to get INT 2f vector
155 set_intfcn equ 252fh
; DOS function call to set INT 2f vector
156 get_version equ 30h
; DOS function call to get DOS version number
157 get_DTA equ 2fh
; DOS function get DTA
158 set_DTA equ 1
ah ; DOS function set DTA
159 get_crit_err equ 3524h
; DOS function call to get INT 24 vector
160 set_crit_err equ 2524h
; DOS function call to set INT 24 vector
161 get_PSP equ 62h
; DOS function call to get PSP address
162 Free_Alloc_Mem equ 49h
; DOS function call to free alloc. mem. ;an007; dms;
164 print_string equ
09h ; DOS function call to get print a string
165 ctrl_break equ 33h
; DOS function call to get/set ctrl-break
167 awrite equ 40h
; write function
168 get_dir equ 47h
; get current dir
169 change_dir equ 3
bh ; change dir
170 get_disk equ 19h
; get current disk
171 change_disk equ
0eh ; change disk
172 term_stay equ 31h
; terminate a process and stay resident
173 term_proc equ 4
ch ; terminate a process
175 redir_flag equ
0000000000001000B ; redir flag for net installation check
177 ; DOS INT 2f function for APPEND presence
179 append_2f equ
0b7h ; int 2f function code for append
180 applic_2f equ
0aeh ; int 2f function code for applications
181 COMMAND_2f equ
-1 ; int 2f subfunction code for COMMAND call
182 append_inst equ
0ffh ; flag means append is there
184 ; INT 2f sub-function codes ;AN000;
186 are_you_there equ
0 ; function code for presence check
187 old_dir_ptr equ
1 ; means APPEND 1.0 is trying to run
188 get_app_version equ
2 ; fun code for get ver request
189 tv_vector equ
3 ; fun code for set TV vector
190 dir_ptr equ
4 ; function code to return dirlist ptr
191 get_state equ
6 ; function code to return append ;AN001;
193 set_state equ
7 ; function code to set append ;AN001;
196 DOS_version equ 10h
; function call to get DOS version
197 true_name equ 11h
; one-shot truename fcn for ASCIIZ ops ;AN002;
199 ; DOS INT 21 function calls that APPEND traps
208 ext_handle_opn equ 6
ch ;AN003;
210 break macro ; this is a dummy break macro so PDB.INC
211 endm
; won't blow up in the build
213 ; define some things for PDB (PSP) ;AN002;
215 include pdb
.inc ;AN002;
217 true_name_flag equ
01h ; flag for true name function ;AN002;
218 eo_create equ
00f0h ; mask to check extended opens for create ;AN003;
220 ; Error codes that don't mean stop looking
222 FCB_failed equ
0ffh ; FCB open failed
223 FCB_file_not_found equ
2 ; file not found on FCB open
224 handle_file_not_found equ
2 ; file not found on handle open
225 handle_path_not_found equ
3 ; path not found on handle open
226 FCB_no_more_files equ
18 ; no more matching files
227 handle_no_more_files equ
18 ; no more matching files
229 ; Equates for TOPVIEW barrier
230 TV_TRUE equ
-1 ; this was changed from TRUE ;AN000;
231 ; because 3.30 parser uses TRUE ;AN000;
240 STDOUT equ
0001h ; standard output file
241 STDERR equ
0002h ; standard error file
246 ;-----------------------------------------------------------------------------
248 ;-----------------------------------------------------------------------------
250 version_loc: ; version number
251 db major_version
,minor_version
252 ; dw message_list ; pointer to message table
255 vector_offset dw 0 ; save pointer to old int 21 here
257 crit_vector_offset dw 0 ; save pointer to old int 24 here
258 crit_vector_segment dw 0
259 intfcn_offset dw 0 ; save pointer to old int 2f here
261 dirlst_offset dw 0 ; save pointer to dir list here
263 tv_vec_off dw 0 ; save TV vector here
266 pars_off dd cseg
: SysParse
; save pointer to parser here
267 ;pars_off dw offset SysParse ; save pointer to parser here
270 app_dirs_seg dw 0 ; save ES here during FCB
272 FCB_ptr dd 0 ; save pointer to FCB here
273 handle_ptr dd 0 ; save pointer to ASCIIZ string here
276 stack_segment dw 0 ; Calling process stack
278 incoming_AX dw 0 ; AX saved at entry to interrupt handler
279 incoming_CX dw 0 ; CX saved at entry to interrupt handler
281 incoming_BX dw 0 ; BX saved at entry to interrupt handler
282 incoming_ES dw 0 ; ES saved at entry to interrupt handler
284 ax_after_21 dw 0 ; AX saved after call to real INT 21
285 ; temp_DS_save dw 0 ; DS saved during stack ops
286 temp_CS_save dw 0 ; CS saved during stack ops (set_return_flags)
287 temp_IP_save dw 0 ; IP saved during stack ops (set_return_flags)
288 FCB_drive_id db 0 ; save the drive id for FCB opens here
290 ;------------------------
291 ; DBCS stuff here ;AN006;
293 DBCSEV_OFF
DW 0 ; OFFSET OF DBCS EV ;AN006;
294 DBCSEV_SEG
DW 0 ; SEGMENT OF DBCS EV ;AN006;
296 ;DEFAULT DBCS ENVIRONMENTAL VECTOR ;AN006;
297 EVEV
DB 00H,00H ;AN006;
301 dbcs_fb dw 0 ; offset of DBCS first byte chars found
302 ;------------------------
304 initial_pass dw 0 ; flag used to indicate inital APPEND ;AN007;
306 incoming_DX dw 0 ; used for saves for extended open ;AN003;
307 incoming_SI dw 0 ; used for saves for extended open ;AN003;
308 incoming_DI dw 0 ; used for saves for extended open ;AN003;
309 incoming_DS dw 0 ; used for saves for extended open ;AN003;
310 true_name_count dw 0 ; used to save number of chars in true_name dir ;AN003;
312 int_save_ip dw 0 ; save registers here during critical
313 int_save_cs dw 0 ; error handler stack ops
315 work_disk db "?:\" ; user's working disk
316 work_dir db 64 dup(" ") ; user's working dir
317 app_disk db "?
:\" ; user's working disk
318 app_dir db 64 dup(" ") ; user's append disk's working dir
319 ctrl_break_state db 0 ; save the old ctrl-break state here
321 end_search db 0 ; end search flag
322 try_dir db 128 dup (0) ; try this dir
323 fname db 15 dup (0) ; 8.3 filename stripped from original
325 app_dirs_ptr dw 0 ; pointer to appended dir to try
327 set_name db "SET " ; SET command
329 setappend_name db "SET " ; SET command
330 append_id db "APPEND=" ; display from here for user
333 db 128 dup (0) ; area for storing appended dirs
334 db 0 ; just to insure that the last dir is null terminated
335 semicolon db ";",0 ; null list
337 ; Flags / barriers added for TopView
339 tv_flag db 0 ; flag to indicate re-entr from TopView
341 parse_flag db 0 ; flag used by APPEND parsing
343 FCB_ext_err db 0 ; flag used to indicate that FCB
344 ; open failed and ext err was done
345 crit_err_flag db 0 ; flag used to indicate that a critical
347 ext_err_flag db 0 ; flag used to indicate that ext err
348 ; must be set 0 = don't set, 1 = do set
349 in_middle db 0 ; flag used to tell if we made it to
350 ; middle of string before finding a space
351 equal_found db 0 ; multiple = check
352 ;crit_sect_flag db 0 ; critical section flag
354 stack_area dw 99 dup(0) ; stack area for append
357 net_config dw 0 ; flag word for what (if any) network
358 ; config we are running under
359 ; as long as this word is zero, a clear determination
360 ; has not been made about the configuration
363 ext_err_dpl DPL
<> ; reserve a DPL for get/set extended error code
366 save_ext_err DPL
<> ; reserve a DPL for first extended
369 ;------------------------------------------------------------------- ;AN001;
371 ; mode_flags This status word is used to control the various ;AN001;
372 ; APPEND functions and modes. ;AN001;
374 ;------------------------------------------------------------------- ;AN001;
375 mode_flags dw Path_mode
+ Drive_mode
+ Enabled
;AN001;
376 ; mode control flags ;AN001;
377 ; initially - path, drive and ;AN001;
380 ; equates for mode_flags follow: ;AN001;
382 X_mode equ 8000h
; in /X mode
383 E_mode equ 4000h
; in /E mode
384 Path_mode equ 2000h
; PATH in string OK ;AN001;
385 Drive_mode equ 1000h
; DRIVE in string OK ;AN001;
386 Enabled equ
0001h ; APPEND enabled ;AN001;
388 ;-------------------------------------------------------------------
390 cmd_name@
dd ?
; internal name string
392 expected_error dw ?
; error to do append scan
393 expected_ext_error dw ?
; error to do append scan
395 cmd_env dw ?
; pointer to COMMANDs environment
396 cmd_buf dw ?
; CMDBUF offset (in SS)
398 incoming_DTA dd ?
; user's DTA (on EXEC)
399 exec_DTA db 21+1+2+2+2+2+13 dup(0) ; find DTA for exec emulation
401 old_syntax db 0 ; using network syntax
403 res_append db 0 ; resident append call ; @@05
405 abort_sp dw ?
; sp to restore on errors ; @@05
409 crlf_len equ
$ - crlf
411 ;******************************************************************* ;an010;bgb
412 ; parser message display area ;an010;bgb
413 ;******************************************************************* ;an010;bgb
414 inv_parm db 0bh ;length ;an010;bgb
415 db 0 ;reserved ;an010;bgb
416 si_off dw 0 ;put offset of command line here ;an010;bgb
417 si_seg dw 0 ;put segment of command line here ;an010;bgb
418 db 0 ;use percent zero ;an010;bgb
419 db Left_Align
+Char_Field_ASCIIZ
;type of data ;an010;bgb
420 db 128 ;max width ;an010;bgb
421 db 1 ;min width ;an010;bgb
422 db ' ' ;pad char ;an010;bgb
424 ;-------------------------------------------------------------------
426 ; resident message area
428 ;-------------------------------------------------------------------
430 MSG_SERVICES
<MSGDATA
>
431 MSG_SERVICES
<DISPLAYmsg
,CHARmsg
> ;an010;bgb
432 MSG_SERVICES
<APPEND
.CLA
,APPEND
.CL1
,APPEND
.CTL
>
435 ;-----------------------------------------------------------------------------
437 ;-----------------------------------------------------------------------------
439 ;-----------------------------
440 ; save and restore register macros
463 ;-----------------------------
464 ; this macro is used instead of the normal POPF instruction to help
465 ; prevent a 286 bug from occurring
475 ;----------------------------- ; @@12
476 ; check character ; @@12
478 chkchar
macro char
; @@12
487 ;-----------------------------------------------------------------------------
488 ; resident routine - control transferred here on INT 21
489 ; check to see if this call has a function code we are interested in
490 ;-----------------------------------------------------------------------------
495 jmp check_fcb_open
; @@01
499 pushf ; save the user's flags (old stack)
501 cmp tv_flag
,TV_TRUE
; see if in TV ;AN000;
502 je use_old
; yes, old_vect
504 check_fcb_open: ; @@01
506 ;------------------------------------------------------------------- ;AN001;
507 ; first, check to see if APPEND disabled, if so, skip everything ;AN001;
508 ; and go to real INT 21 handler ;AN001;
509 ;------------------------------------------------------------------- ;AN001;
510 test mode_flags
,Enabled
; APPEND disabled? ;AN001;
511 jz real_jump
; yes, skip all other checks ;AN001;
513 cmp ah,FCB_opn
; FCB open?
514 jump E
,FCB_open
; yes, do the APPEND
516 cmp ah,handle_opn
; handle open?
517 jump E
,handle_open
; yes, do the APPEND
519 cmp ah,ext_handle_opn
; extended handle open? ;AN003;
520 jump E
,ext_handle_open
; yes, do the APPEND ;AN003;
522 cmp ah,file_sz
; file size?
523 jump E
,FCB_open
; yes, do the APPEND
526 test mode_flags
,X_mode
; /X mode not selected
529 cmp ah,FCB_sch1
; search?
530 jump E
,FCB_search1
; yes, do the APPEND
532 cmp ah,handle_fnd1
; find?
533 jump E
,handle_find1
; yes, do the APPEND
535 cmp tv_flag
,TV_TRUE
; cant do in TopView ;AN000;
537 cmp ax,exec_proc
*256+0 ; EXEC?
538 jump E
,exec_pgm
; yes, do the APPEND
540 cmp ax,exec_proc
*256+3 ; EXEC?
541 jump E
,exec_pgm
; yes, do the APPEND
544 ;-----------------------------------------------------------------------------
545 ; By here, we know that the call was not one we are interested in,
546 ; pass through to old INT 21.
547 ; Since this is done with a jmp, control will pass back to original caller
548 ; after DOS is finished.
549 ;-----------------------------------------------------------------------------
552 cmp tv_flag
,TV_TRUE
; see if called by TV ;AN000;
553 jne use_old
; yes, use old vect
555 popff
; restore user's flags
556 jmp dword ptr tv_vec_off
; pass through to TV
559 popff
; restore user's flags (old stack)
560 jmp dword ptr Vector_Offset
; jump to old INT 21
563 ;-----------------------------------------------------------------------------
564 ; FCB_search1 - this routine handles FCB search first calls
565 ;-----------------------------------------------------------------------------
568 mov expected_ext_error
,fcb_no_more_files
571 ;-----------------------------------------------------------------------------
572 ; FCB_open - this routine handles FCB open calls
573 ;-----------------------------------------------------------------------------
576 mov expected_ext_error
,fcb_file_not_found
578 call check_config
; check the config flags
579 call crit_sect_set
; set critical section flag
583 mov incoming_AX
,ax ; save user's AX
584 mov word ptr FCB_ptr
+0,dx ; save FCB pointer
585 mov word ptr FCB_ptr
+2,ds
587 popff
; restore user's flags
588 call int_21
; try the open
591 mov AX_after_21
,ax ; save AX as it came back from INT
592 pushf ; save flags from operation
593 cmp al,FCB_failed
; open failed ?
594 je check_error
; yes, lets check extended error
595 jmp set_return_flags
; no, fix the stack, then ret to caller
598 call get_ext_err_code
; get the extended error code
599 mov FCB_ext_err
,1 ; set FCB ext error
600 call save_first_ext_err
; save first extended error code
601 mov ax,ext_err_dpl
.DPL_AX
; get error in ax
602 cmp ax,expected_ext_error
; file not found?
603 je FCB_openx2
; yes, lets look around for file
604 lea dx,save_ext_err
;
605 call set_ext_err_code
; set the extended error code
606 jmp set_return_flags
; no, fix the stack, then return
610 ; set up APPEND's stack
612 popff
; get rid of the flags from the
614 ; mov temp_DS_save,ds ; Save DS reg
615 mov stack_segment
,ss ; Save it
616 mov stack_offset
,sp ; Save it
617 mov ax,cs ; Get current segment
618 mov ss,ax ; and point stack seg here
619 lea sp,append_stack
; set up new stack
621 save_regs
; save registers
623 push cs ; establish addressability
626 call ctrl_break_set
; set ctrl-break handler
627 call crit_err_set
; set crit err handler
629 mov ext_err_flag
,1 ; flag for setting critical error
633 les bx,dword ptr FCB_ptr
; ES:BX points to FCB
634 mov ah,ES:byte ptr [bx] ; get FCB drive spec
635 cmp ah,-1 ; extended FCB?
637 add bx,1+5+1 ; point to real drive letter
638 mov ah,ES:byte ptr [bx] ; get FCB drive spec
641 mov FCB_drive_id
,ah ; save it for later
642 mov ES:byte ptr [bx],0 ; zero the drive field out to
645 mov ah,get_disk
; get disk
646 call int_21
; call DOS INT 21 handler
648 add al,"A" ; make it a character
649 mov work_disk
,al ; save it
651 mov ah,get_dir
; get directory
652 xor dx,dx ; default drive
653 lea si,work_dir
; save area
654 call int_21
; call DOS INT 21 handler
656 call address_path
; get address of path
657 cmp es: byte ptr [di],";" ; is the append list null?
658 jump E
,null_list
; exit append
659 mov app_dirs_seg
,es ; save app dirs segment
663 lea di,try_dir
; destination
664 call get_app_dir
; copy dir to try into try_dir
665 mov app_dirs_ptr
,si ; save updated pointer
668 ;-----------------------------
670 mov app_disk
,0 ; zero for current dir
671 cmp try_dir
+1,":" ; see if we have a drive
672 jne no_drive
; char should be a colon
674 ; yes, there was a drive specified, must do the change disk function call
676 mov ah,change_disk
; change disk
677 mov dl,try_dir
; get the char representation of the drive
678 mov app_disk
,dl ; save it away for later use
680 sub dl,"A" ; convert from char to drive spec
681 call int_21
; call DOS INT 21 handler
682 ; jc check_end_dir_list ; there was an error, see if there is
685 cmp crit_err_flag
,0 ; did we experience a critical error
686 jne set_err_code
; yes, fake a file_not_found
689 mov ah,get_dir
; get directory
690 xor dx,dx ; default drive
691 lea si,app_dir
; save area
692 call int_21
; call DOS INT 21 handler
694 ; check to see if there was a critical error
696 cmp crit_err_flag
,0 ; did we experience a critical error
697 je cd_worked
; no, the cd worked
698 jmp short set_err_code
701 pushf ; save everything again
703 push cs ; re-establish addressability
707 xor ah,ah ; make ax look like open failed
709 mov ax_after_21
,ax ; save it away so we can restore it below
714 lea dx,try_dir
; point dx to dir to try
715 mov ah,change_dir
; change dir to appended directory
716 call int_21
; call DOS INT 21 handler
718 ; try the open in this dir
720 restore_regs
; make regs look like when user
721 mov ax,incoming_AX
; called us
723 call int_21
; call DOS INT 21 handler
724 mov ax_after_21
,ax ; save AX
725 cmp crit_err_flag
,0 ; did we get critical error?
726 jne save_regs_and_set
; yes, fake a file_not_found
727 cmp al,FCB_failed
; did open work?
729 call get_ext_err_code
; get the extended error code
732 pushf ; save everything again
735 push cs ; re-establish addressability
738 ; restore user's working disk and restore the dir on the appended drive
740 mov ah,change_disk
; change disk back to our original
743 sub dl,"A" ; convert from char to drive spec
744 call int_21
; call DOS INT 21 handler
746 mov ah,change_dir
; change dir
747 lea dx,app_disk
; save area (this time include drive)
748 call int_21
; call DOS INT 21 handler
750 ; this is for ..\dirname ptr
752 mov ah,change_dir
; change dir
753 lea dx,work_disk
; save area (this time include drive)
754 call int_21
; call DOS INT 21 handler
756 mov ax,ax_after_21
; restore AX
757 cmp al,FCB_failed
; did open work?
759 mov ax,ext_err_dpl
.DPL_AX
760 cmp ax,expected_ext_error
761 jne no_more_to_try
; not file not found
764 mov es,app_dirs_seg
; restore es
766 cmp si,null
; should we try again?
767 je no_more_to_try
; no
768 jmp try_another1
; yes
771 mov byte ptr ext_err_flag
,0 ; the open worked, no need to set ext err code
775 ; restore user's working disk and dir
777 ; The following code up to label "null_list" which
778 ; restores the user's drive and path was moved in front
779 ; of the code to restore the drive spec in FCB.
781 mov ah,change_disk
; change disk
784 sub dl,"A" ; convert from char to drive spec
785 call int_21
; call DOS INT 21 handler
787 mov ah,change_dir
; change dir
788 lea dx,work_disk
; save area (this time include drive)
789 call int_21
; call DOS INT 21 handler
792 mov ah,FCB_drive_id
; get FCB drive spec
793 ; cmp ah,0 ; did they ask for default drive?
794 ; je fix_drive_spec ; yes, leave it alone
795 jmp short fix_drive_spec
797 set_disk: ; set drive number in FCB
798 mov ah,work_disk
; no, give them the found drive spec
799 sub ah,"A"-1 ; convert from char to drive spec
801 ; ah has proper drive spec to put into FCB, do it
804 les bx,dword ptr FCB_ptr
; ES:BX points to FCB
805 cmp ES:byte ptr[bx],-1 ; extended FCB
806 jne not_ext_FCB2
; put in the proper drive spec
807 add bx,1+5+1 ; point to real drive letter
810 mov ES:byte ptr [bx],ah
813 call ctrl_break_restore
814 call crit_err_restore
816 ; find out if there is a need to set the extended error code
818 cmp ext_err_flag
,0 ; do we need to set the extended error code?
819 je no_ext_err
; no, finish up
826 call set_ext_err_code
; yes, go set the ext error info
828 ; all done with append, clean things back up for the user
831 restore_regs
; restore registers
833 jmp reset_stack
; fix stack, ret to caller
836 ;-----------------------------------------------------------------------------
837 ; handle_find - APPEND handle find function
838 ;-----------------------------------------------------------------------------
841 mov incoming_CX
,cx ; save user's CX
842 mov expected_error
,handle_no_more_files
843 ; mov expected_ext_error,handle_no_more_files
844 jmp short handle_openx
846 ;-----------------------------------------------------------------------------
847 ; exec_pgm - APPEND exec program function
848 ;-----------------------------------------------------------------------------
851 mov incoming_BX
,bx ; save user's ES:BX
853 mov expected_error
,handle_file_not_found
854 ; mov expected_ext_error,handle_no_more_files
855 jmp short handle_openx
857 ;----------------------------------------------------------------------------- ;AN003;
858 ; ext_handle_open - APPEND extended handle open function ;AN003;
859 ;----------------------------------------------------------------------------- ;AN003;
860 ext_handle_open: ;AN003;
861 test dx,eo_create
; does this call specify create? ;AN003;
862 jz no_eo_create
; no, we can continue ;AN003;
864 jmp real_jump
; yes, do nothing but pass on to real ;AN003;
865 ; INT 21 handler ;AN003;
867 ; getting here means the caller did not specify the create option ;AN003;
869 no_eo_create: ;AN003;
871 mov incoming_BX
,bx ; save user's registers ;AN003;
872 mov incoming_CX
,cx ; extended open sure does use a lot ;AN003;
873 mov incoming_DX
,dx ; of registers ;AN003;
874 mov incoming_SI
,si ;AN003;
875 mov incoming_DI
,di ;AN003;
876 mov incoming_ES
,es ;AN003;
877 mov incoming_DS
,ds ;AN003;
879 mov expected_error
,handle_file_not_found
;AN003;
880 jmp short handle_openx
; for now ... ;AN003;
882 ;-----------------------------------------------------------------------------
883 ; handle_open - APPEND handle open function
884 ;-----------------------------------------------------------------------------
887 mov expected_error
,handle_file_not_found
888 ; mov expected_ext_error,handle_file_not_found
891 call check_config
; check the config flags
892 call crit_sect_set
; set critical section flag
894 call tv_barrier
; no op on exec
896 mov incoming_AX
,ax ; save user's AX
897 mov word ptr handle_ptr
+0,dx ; save path pointer
898 mov word ptr handle_ptr
+2,ds
900 popff
; restore user's flags
901 call int_21
; try the open
904 mov AX_after_21
,ax ; save AX as it came back from INT
905 pushf ; save flags from operation
907 ; find out if we had an error, and if so was it the one we were
910 jc what_happened
; yes, lets find out what happened
911 mov incoming_AX
,-1 ; insure no exec done later
912 jmp set_return_flags
; no, fix the stack, then ret to caller
913 ; this means that the real call worked,
914 ; APPEND does not need to do anything
917 ; cmp ax,handle_path_not_found ; normal errors
918 ; je handle_search ; yes, look for the file
919 cmp ax,expected_error
; was the error file not found?
920 je handle_search
; yes, look for the file
921 jmp set_return_flags
; no, fix the stack, then ret to caller
925 call get_ext_err_code
; get the extended error code information
927 ; set up APPEND's stack
928 popff
; get rid of the flags from the
930 ; mov temp_DS_save,ds ; Save DS reg
931 mov stack_segment
,ss ; Save it
932 mov stack_offset
,sp ; Save it
933 mov ax,cs ; Get current segment
934 mov ss,ax ; and point stack seg here
935 lea sp,append_stack
; set up new stack
937 save_regs
; save registers
939 push cs ; establish addressability
946 ; all done with the prep stuff, let's get down to business
948 ;------------------------------------------------------------------- ;AN001;
950 ; before doing anything else, check DRIVE and PATH modes ;AN001;
952 ;------------------------------------------------------------------- ;AN001;
955 pushf ; save flags ;AN001;
956 push ax ; save AX ;AN001;
958 cmp incoming_AX
,exec_proc
*256 ; is this call an exec?
962 ;-------------------------------------------------------------------
963 ; Set up ES:SI to point to incoming string
964 ;-------------------------------------------------------------------
966 cmp incoming_AX
,ext_handle_opn
*256+0 ;is this call an ext open? ;AN003;
968 mov si,incoming_SI
; DS:SI points to original name for ex open ;AN003;
969 mov es,incoming_DS
; but this code wants ES:SI to point to it ;AN003;
970 lea di,fname
; DS:DI points to fname area ;AN003;
971 jmp eo_skip3
; skip the old stuff ;AN003;
974 les si,dword ptr handle_ptr
; ES:SI points to original handle
975 lea di,fname
; DS:DI points to fname area
977 ;-------------------------------------------------------------------
979 test mode_flags
,Drive_mode
; Drive_mode enabled?
980 jnz check_path_mode
; yes, go check path mode
982 call check_for_drive
; no, find out if there is a drive
984 cmp ax,0 ; was there a drive letter?
985 je check_path_mode
; no, go check path mode
987 ;-------------------------------------------------------------------
988 ; getting here means that Drive_mode is disabled and that a drive letter
989 ; was found. This means we give up on this APPEND operation
991 jmp drive_or_path_conflict
995 test mode_flags
,Path_mode
; Path_mode enabled?
996 jnz drive_and_path_ok
; yes, go do the APPEND function
998 call check_for_path
; no, find out if there is a path
1001 cmp ax,0 ; was there a path?
1002 jne drive_or_path_conflict
; no, go do the APPEND function
1005 call check_for_drive
; no, find out if there is a drive
1007 cmp ax,0 ; was there a drive letter?
1008 je drive_and_path_ok
; no, everything is OK
1009 ; yes, fall through and exit w/error
1011 ;------------------------------------------------------------------- ;AN001;
1012 ; getting here means that Drive_mode is disabled and that a drive ;AN001;
1013 ; letter was found. This means we give up on this APPEND operatio ;AN001; n
1015 drive_or_path_conflict:
1017 pop ax ; clean up stack
1020 ; restore_regs ; restore some regs ;AN002;
1023 mov ext_err_flag
,1 ; we need to set extended error info
1024 mov ax,expected_error
; make ax look like we got file not found
1025 mov ax_after_21
,ax ; save it away so we can restore it below
1026 popff
; get flags from stack
1027 stc ; set the carry flag
1028 pushf ; put 'em back
1033 drive_and_path_ok: ;AN001;
1034 pop ax ; restore AX ;AN001;
1035 popff
; restore flags ;AN001;
1037 ;------------------------------------------------------------------- ;AN001;
1038 ; end of code to check DRIVE and PATH modes ;AN001;
1039 ;------------------------------------------------------------------- ;AN001;
1041 cmp incoming_AX
,ext_handle_opn
*256+0 ;is this call an ext open? ;AN003;
1043 mov si,incoming_SI
; DS:SI points to original name for ex open ;AN003;
1044 mov es,incoming_DS
; but this code wants ES:SI to point to it ;AN003;
1045 lea di,fname
; DS:DI points to fname area ;AN003;
1046 jmp eo_skip1
; skip the old stuff ;AN003;
1049 les si,dword ptr handle_ptr
; ES:SI points to original handle
1050 lea di,fname
; DS:DI points to fname area
1052 call get_fname
; strip just the 8.3 filename from
1053 ; the original ASCIIZ string
1054 call address_path
; address the path
1055 cmp es: byte ptr [di],";" ; is append list null ?
1056 jump E
,no_more_to_try2
; exit append
1058 mov si,di ; pointer to list of appended directories
1059 pushf ; push flags onto stack just for the
1064 lea di,try_dir
; buffer to be filled with dir name
1067 call get_app_dir
; this routine will return with a dir
1069 mov true_name_count
,cx ; save number of chars for later us ;AN003;
1071 mov app_dirs_ptr
,si ; save updated pointer
1074 ;-----------------------------
1077 call append_fname
; glue the filename onto the end of the dir to try
1080 ; we now have an ASCIIZ string that includes the original 8.3 filename
1081 ; and one of the appended dir paths
1085 lea dx,try_dir
; point to new ASCIIZ string
1087 cmp incoming_AX
,ext_handle_opn
*256+0 ; extended open? ;AN003;
1090 ; this is an extended open call ;AN003;
1094 mov si,dx ; ext open wants DS:SI -> filename ;AN003;
1098 mov ax,incoming_AX
; function code ;AN003;
1099 mov bx,incoming_BX
; mode word ;AN003;
1100 mov cx,incoming_CX
; attributes ;AN003;
1101 mov dx,incoming_DX
; flags ;AN003;
1102 mov es,incoming_ES
; ES:DI parm_list pointer ;AN003;
1103 mov di,incoming_DI
;AN003;
1105 call int_21
; try the extended open ;AN003;
1107 restore_regs
;AN003;
1108 pushf ; save flags ;AN003;
1109 ; mov es,incoming_ES ; restore es as it was ;AN003;
1110 jmp not_exec2
; go find out what happened ;AN003;
1114 cmp incoming_AX
,exec_proc
*256+0 ; exec pgm call
1117 ; this is an exec call ;AN003;
1123 mov word ptr incoming_DTA
+0,bx ; save callers DTA
1124 mov word ptr incoming_DTA
+2,es
1130 lea dx,exec_DTA
; set for fake exec search
1136 mov ah,handle_fnd1
; precess search by finds
1137 mov expected_error
,handle_no_more_files
1141 push es ; save append's ES
1142 push bx ; save append's BX
1143 mov es,incoming_ES
; must restore ES before doing the call ; fix for P37, GGA 9/10/87
1144 mov bx,incoming_BX
; must resatore user's ES:BX
1146 call int_21
; try the open
1148 pop bx ; restore append's BX
1149 pop es ; restore append's es
1151 cmp incoming_AX
,exec_proc
*256+0 ; exec pgm call
1157 mov dx,word ptr incoming_DTA
+0 ; restore callers DTA
1158 mov ds,word ptr incoming_DTA
+2
1166 jnc found_it_remote
; all done
1168 cmp crit_err_flag
,0 ; process critical errors
1171 cmp ax,handle_path_not_found
; normal errors
1172 je should_we_look_more
1174 cmp ax,expected_error
; was the error we found file not found?
1175 je should_we_look_more
; yes, look some more
1176 jmp no_more_to_try2
; no, any other error, we pack it in
1178 should_we_look_more:
1179 mov si,app_dirs_ptr
; yes, see if we should look more
1180 cmp si,null
; should we try again?
1182 jmp try_another2
; yes
1187 mov ext_err_flag
,1 ; we need to set extended error info
1188 mov ax,expected_error
; make ax look like we got file not found
1189 mov ax_after_21
,ax ; save it away so we can restore it below
1190 popff
; get clags from stack
1191 stc ; set the carry flag
1192 pushf ; put 'em back
1196 found_it_remote: ; come here only if the file was found in
1197 ; an appended directory
1198 mov ax_after_21
,ax ; save AX
1202 ; Find out if this process has the true_name flag set in thier PSP. ;AN002;
1203 ; At this point, DS:DX points to the true name of the found file ;AN002;
1206 push ax ; save some regs ;AN002;
1209 mov ah,get_PSP
; function code for get PSP operation ;AN002;
1210 call int_21
; get the PSP, segment returned in BX ;AN002;
1211 mov es,bx ; need to use it as a segment ;AN002;
1212 mov di,PDB_Append
; get pointer to APPEND flag in PDB ;AN002;
1214 mov ax,es:[di] ; get APPEND flag into AX ;AN002;
1215 test ax,true_name_flag
; is true name flag armed? ;AN002;
1216 jz no_true_name
; no, don't copy true name ;AN002;
1218 sub ax,true_name_flag
; clear true name flag ;AN002;
1219 mov es:[di],ax ; save it in PSP ;AN002;
1221 mov di,word ptr handle_ptr
+0 ; get user's buffer pointer ES:DI ;AN002;
1222 mov es,word ptr handle_ptr
+2 ;AN002;
1224 ; find out if this is a handle find or an open or an exec
1226 cmp incoming_AX
,exec_proc
*256+0 ; exec?
1227 je no_true_name
; yes, do nothing with true name
1229 cmp incoming_AX
,handle_fnd1
*256+0 ; handle find?
1230 jne not_hf
; no, go do the easy stuff
1232 ; function we are doing is a handle find, must get part of true_name
1233 ; string from append path, part from DTA. Messy!
1235 lea si,try_dir
; buffer that has last APPEND path tried
1237 mov cx,true_name_count
; get number of chars in true_name dir ;AN002;
1239 copy_true_name_loop2:
1240 mov ah,ds:[si] ; get byte of append dir path ;AN002;
1241 mov es:[di],ah ; copy it to user's buffer ;AN002;
1242 inc si ; in this loop, the null is not copied ;AN002;
1244 loop copy_true_name_loop2
;AN002;
1248 mov ah,"\" ; get a \
1249 mov es:[di],ah ; copy it
1250 inc di ; increment pointer
1252 ; we have copied the first part of the string, now get the real filename
1267 copy_true_name_loop3:
1268 mov ah,ds:[si+30] ; get byte of actual filename ;AN002;
1269 mov es:[di],ah ; copy it to user's buffer ;AN002;
1270 cmp ah,null ; is it a null? ;AN002;
1271 je true_name_copied ; yes, all done ;AN002;
1272 inc si ; in this loop the null is copied ;AN002;
1274 jmp copy_true_name_loop3 ;AN002;
1277 mov si,dx ; make DS:SI point to true name
1279 copy_true_name_loop: ;AN002;
1280 mov ah,ds:[si] ; get byte of true name ;AN002;
1281 mov es:[di],ah ; copy it to user's buffer ;AN002;
1282 cmp ah,null ; is it a null? ;AN002;
1283 je true_name_copied ; yes, all done ;AN002;
1286 jmp copy_true_name_loop ;AN002;
1288 true_name_copied: ;AN002;
1290 no_true_name: ;AN002;
1291 restore_regs ; restore some regs ;AN002;
1297 call ctrl_break_restore ; restore normal control break address
1298 call crit_err_restore ; restore normal critical error address
1300 ; find out if there is a need to set the extended error code
1302 cmp ext_err_flag,0 ; do we need to set the extended error code?
1303 je no_ext_err2 ; no, finish up
1305 call set_ext_err_code ; yes, go set the ext error info
1307 ; reset flags, and pack it in
1311 restore_regs ; restore registers
1312 pushf ; put the real flags on the stack
1314 jmp reset_stack ; fix stack, ret to caller
1317 ;-------------------------------------------------------------------
1319 ; support routines for drive and path mode checking
1322 ;-------------------------------------------------------------------
1325 check_for_drive: ; input: ES:SI -> original string
1326 ; output: AX = 0 no drive present
1327 ; output: AX = -1 drive present
1329 xor ax,ax ; assume no drive letter present
1331 cmp es: byte ptr [si+1],':' ; is the second char a ":"?
1332 jne exit_check_for_drive ; no, skip setting the flag
1334 mov ax,-1 ; yes, set the flag
1336 exit_check_for_drive:
1340 ;-------------------------------------------------------------------
1342 check_for_path: ; input: ES:SI -> original string
1343 ; output: AX = 0 no path present
1344 ; output: AX = -1 path present
1346 push si ; save pointer
1348 xor ax,ax ; assume no path present
1351 ; walk the string and look for "/", or "\". Any of these mean that a
1357 mov al,es: byte ptr [si] ; is this a dbcs char? ;AN006;
1358 call Chk_DBCS
;AN006;
1361 jnc no_dbcs1
; no, keep looking ;AN006;
1363 add si,2 ; yes, skip it and the next char ;AN006;
1364 jmp walk_handle_string
; the next char could be a "\", but ;AN006;
1365 ; would not mean a path was found ;AN006;
1368 cmp es: byte ptr [si],"\" ; is the char a "\"?
1369 je found_path
; yes, set flag and return
1370 cmp es: byte ptr [si],"/" ; is the char a "/"?
1371 je found_path
; yes, set flag and return
1372 cmp es: byte ptr [si],0 ; is the char a null
1373 je exit_check_for_path
; yes, got to the end of the
1376 inc si ; point to next char
1377 jmp walk_handle_string
; and look again
1380 mov ax,-1 ; yes, set the flag
1382 exit_check_for_path:
1387 ;-----------------------------------------------------------------------------
1388 ; Entry point for interrupt 2f handler
1389 ;-----------------------------------------------------------------------------
1392 cmp ah,append_2f
; is this function call for append?
1393 ;;;;;; je do_appends ; @@12
1395 jmp do_appends
; @@12
1397 cmp ah,applic_2f
; is this function call for applications
1402 cmp dx,-1 ; not COMMAND call
1404 cmp al,0 ; match name request
1407 mov cmd_buf
,bx ; save CMDBUF offset
1410 mov al,append_inst
; inidicate I want this command
1415 cmp al,1 ; match name request
1418 ; save pointer to parser
1420 mov word ptr pars_off
+0,di ; ES:DI points to COMMAND.COM's parser
1421 mov word ptr pars_off
+2,es ; save it for later
1423 mov cmd_env
,bx ; save env pointer address
1426 call COMMAND_begin
; process internal command
1431 ; cmp al,2 ; set COMMAND active ; @@13; @@09
1432 ; jne ck03 ; @@13; @@09
1433 ; mov cmd_active,1 ; @@13; @@09
1436 ; cmp al,3 ; set COMMAND in active ; @@13; @@09
1437 ; jne ck04 ; @@13; @@09
1438 ; mov cmd_active,0 ; @@13; @@09
1443 ;*******************************************************************************
1444 ; The following old code is commented out. @@12
1445 ;*******************************************************************************
1446 ;check_cmd_name: ; see if internal APPEND
1453 ; cmp ds:byte ptr[si],6 ; length must match
1455 ; comp append_id,6,[si+1] ; see if APPEND is command
1462 ;*********************************************************************
1463 check_cmd_name: ; See if APPEND @@12
1469 mov si,cmd_buf
; DS:SI -> cmd buf ended with cr @@12
1470 add si,2 ; 1st 2 bytes garbage @@12
1472 ccn_skip_leading: ; @@12
1473 lodsb ; skip leading stuff @@12
1475 call Chk_DBCS
; find out if this is DBCS ;AN006;
1476 jnc no_dbcs2
; no, keep looking ;AN006;
1477 lodsb ; yes, skip it and the next byte ;AN006;
1478 jmp ccn_skip_leading
; the second byte will be skipper when ;AN006;
1479 ; we go back through ;AN006;
1482 cmp al," " ; blank @@12
1483 je ccn_skip_leading
; @@12
1484 cmp al,tab_char
; tab @@12
1485 je ccn_skip_leading
; @@12
1486 cmp al,"," ; comma @@12
1487 je ccn_skip_leading
; @@12
1488 cmp al,"=" ; equal @@12
1489 je ccn_skip_leading
; @@12
1490 cmp al,";" ; semi-colon @@12
1491 je ccn_skip_leading
; @@12
1492 cmp al,"\" ; back slash @@12
1493 je ccn_skip_leading ; @@12
1494 cmp al,cr ; bad ret for early terminate @@12
1496 cmp al,0 ; reset z for no match @@12
1499 mov di,si ; di -> beginning of possible @@12
1500 dec di ; "APPEND
" string @@12
1507 call Chk_DBCS ;AN006;
1508 jnc no_dbcs3 ; no, carry on ;AN006;
1509 add si,2 ; yes, skip it and the next byte ;AN006;
1513 cmp al,"\" ; move di up upon "\" @@12
1520 cmp al," " ; look for separator @@12
1521 je ccn_30
; if found, then have command @@12
1526 cmp al,tab_char
; @@12
1536 jne ccn_ret
; no match @@12
1539 chkchar
"A" ; look for "APPEND" string @@12
1545 ; exit with z set for match @@12
1555 ;------------------------------------------------------------------- ;AN000;
1557 ; do_appends ;AN000;
1559 ; This is the INT 2F handler for the APPEND ;AN000;
1560 ; subfunction ;AN000;
1562 ; New functions added for 3.30: ;AN000;
1566 ; Get /X status ;AN000;
1568 ; Input: AX = B706 ;AN000;
1570 ; Output: BX = 0000 /X not active ;AN000;
1571 ; = 0001 /X active ;AN000;
1575 ; Set /X status ;AN000;
1577 ; Input: AX = B707 ;AN000;
1579 ; BX = 0000 turn /X off ;AN000;
1580 ; BX = 0001 turn /X on (active) ;AN000;
1582 ;------------------------------------------------------------------- ;AN000;
1585 cmp al,are_you_there
; is the function request for presence?
1588 mov al,-1 ; set flag to indicate we are here
1589 iret ; return to user
1592 cmp al,dir_ptr
; is the function request for pointer?
1595 les di,dword ptr dirlst_offset
; return dirlist pointer to caller
1599 cmp al,get_app_version
; is the function request for version?
1600 jne ck3
; no, check for next function
1602 mov ax,-1 ; yes, set NOT NETWORK version
1606 cmp al,tv_vector
; is the function request for TV vector?
1607 jne ck4
; no, check for old dir ptr
1609 mov tv_vec_seg
,es ; yes, save the TV vector
1612 push cs ; set ES:DI to tv ent pnt
1616 xor byte ptr tv_flag
,TV_TRUE
; set flag ;AN000;
1620 cmp al,old_dir_ptr
; is it the old dir ptr
1621 jne ck5
; no, pass it on
1627 call sysloadmsg
;AN000;
1629 mov ax,1 ; message number ;AN000;
1630 mov bx,STDERR
; handle ;AN000;
1631 xor cx,cx ; sub count ;AN000;
1632 xor dl,dl ; no input ;AN000;
1633 mov dh,-1 ; message class ;AN000;
1634 call sysdispmsg
;AN000;
1638 call terminate
; exit to DOS ; @@05
1641 cmp al,DOS_version
; is it the new version check
1642 jne ck6
; no, pass it on
1644 mov ax,mode_flags
; set mode bits
1645 xor bx,bx ; destroy registers
1647 mov dl,byte ptr version_loc
; major version num
1648 mov dh,byte ptr version_loc
+1 ; minor version num
1652 cmp al,get_state
; is it get state call? ;AN001;
1653 jne ck7
; no, look some more ;AN000;
1655 mov bx,mode_flags
; get mode bits ;AN000;
1656 iret ; return to user ;AN000;
1659 cmp al,set_state
; is it set state call? ;AN001;
1660 jne ck8
; no, look some more ;AN000;
1662 mov mode_flags
,bx ; save the new state ;AN001;
1667 cmp al,true_name
; is it the set true name function? ;AN002;
1668 jne ck9
; no, look some more ;AN002;
1670 push ax ; save some regs ;AN002;
1676 ; get the PSP and then get the APPEND flags byte
1678 mov ah,get_PSP
; function code to get PSP address ;AN002;
1679 call int_21
; get the PSP address ;AN002;
1680 mov es,bx ; need to use it as a segment ;AN002;
1681 mov di,PDB_Append
; get pointer to APPEND flag in PDB ;AN002;
1683 ; is the flag already set?
1685 mov ax,es:[di] ; get APPEND flag into AX ;AN002;
1686 test ax,true_name_flag
; is it set? ;AN002;
1687 jnz no_set_true_name
; yes, do nothing ;AN002;
1689 ; set the true_name flag
1691 set_true_name: ;AN002;
1692 add ax,true_name_flag
; set true name flag ;AN002;
1693 mov es:[di],ax ; save in PSP ;AN002;
1696 pop di ; restore some regs ;AN002;
1701 iret ; return ;AN002;
1705 ;-------------------------------------------------------------------
1706 ; fill in additional 2F functions here
1707 ;-------------------------------------------------------------------
1709 pass_it_on: ; the function call (ah) was not for append
1710 jmp dword ptr intfcn_Offset
; jump to old INT 2f
1713 ;-----------------------------------------------------------------------------
1714 ; Entry point for interrupt 24 handler
1715 ;-----------------------------------------------------------------------------
1719 mov crit_err_flag
,0ffh ; set critical error flag
1720 mov al,3 ; fail int 21h
1724 ;-----------------------------------------------------------------------------
1725 ; miscellaneous routines
1726 ;-----------------------------------------------------------------------------
1727 ;-----------------------------------------------------------------------------
1729 ;-----------------------------------------------------------------------------
1733 cmp tv_flag
,TV_TRUE
; in Topview ;AN000;
1737 mov ax,2002h
; wait on DOS barrier
1743 ;-----------------------------
1744 ; check_config - this routine is called by both the FCB and handle open
1745 ; code. I checks the net_config flag to see if it is zero, if so it
1746 ; does an installation check. If it is non-zero, nothing is done.
1750 push ax ; save a few registers
1753 ; examine the config flag to see if we already know what config we have
1756 jne do_not_look
; we know config already
1758 ; the flag word has not been set before, go find out what config we have
1760 mov ax,0b800h ; installation code function code
1761 int 2fh
; do the installation check
1763 mov net_config
,bx ; save flag word for later
1766 pop bx ;restore regs and leave
1770 ;*( Chk_DBCS ) *************************************************************
1772 ;* Function: Check if a specified byte is in ranges of the DBCS lead bytes*
1773 ;* Attention: If your code is resident, comment out the lines marked *
1777 ;* AL = Code to be examined *
1781 ;* If CF is on then a lead byte of DBCS *
1784 ;* FL is used for the output, others are unchanged. *
1786 ;***************************************************************************
1790 ; CMP CS:DBCSEV_SEG,0 ; ALREADY SET ? ;**
1792 MOV SI,OFFSET EVEV
; SET DEFAULT OFFSET ;**
1794 POP DS ; SET DEFAULT SEGMENT ;**
1796 MOV AX,6300H
; GET DBCS EV CALL
1798 MOV CS:DBCSEV_OFF
,SI ;**
1799 MOV CS:DBCSEV_SEG
,DS ;**
1802 MOV SI,CS:DBCSEV_OFF
;**
1803 MOV DS,CS:DBCSEV_SEG
;**
1825 ;-----------------------------
1826 ; append_fname - glues the fname onto the end of the dir to try
1832 lea di,try_dir
; destination, sort of (dir name)
1833 lea si,fname
; source (filename)
1835 ; find the end of the dir name
1837 mov dbcs_fb
,-1 ; set flag for no dbcs first byte chars ;AN006;
1840 mov al,byte ptr [di] ; get a char from dir name
1841 cmp al,null
; are we at the end?
1842 je end_of_dir
; yes, add on the fname
1844 call Chk_DBCS
; char is in al ;AN006;
1845 jnc no_dbcs4
; no, keep looking ;AN006;
1846 mov dbcs_fb
,di ; save offset ;AN006;
1847 inc di ; skip second byte
1850 inc di ; no, keep stepping
1853 ; now it is time to append the filename
1856 mov al,byte ptr [di-1] ; get last char of dir name
1857 cmp al,"\" ; is it a dir seperator?
1858 jne check_next_dir_sep ; no, check the next dir sep char ;AN006;
1860 sub di,2 ; yes, must find out if real dir sep ;AN006;
1861 ; or DBCS second byte ;AN006;
1862 cmp dbcs_fb,di ; is the char before our dir sep a DBCS ;AN006;
1863 ; first byte? ;AN006;
1864 jne no_dbcs4a ; no, must check for the next dir sep ;AN006;
1865 ; yes, this means we must put in a dir sep ;AN006;
1866 add di,2 ; restore di ;AN006;
1867 jmp put_in_dir_sep ; put int the dir sep char ;AN006;
1870 add di,1 ; restore di, then check next dir sep ;AN006;
1873 cmp al,"/" ; is it the other dir seperator?
1874 je add_fname ; yes, no need to add one
1875 put_in_dir_sep: ;AN006;
1876 mov al,"\" ; get dir seperator
1877 stosb ; add to end of dir
1880 lodsb ; get a char from fname
1881 stosb ; copy the char
1882 cmp al,null
; are we at the and of the filename?
1883 je eo_name
; yes, all done!
1897 ;-----------------------------
1898 ; get_fname strips out the 8.3 filename from the original ASCIIZ string
1900 ; INPUT: ES:SI points to original string
1901 ; DS:DI points to area for filename
1905 mov bx,si ; save the pointer
1906 mov dbcs_fb
,-1 ; set the dbcs flag off ;AN006;
1909 mov ah,ES:byte ptr [si] ; get a char from the source
1910 cmp ah,null
; is it a null?
1911 je got_the_end
; yes, we found the end
1913 call chk_dbcs
; is this char a DBCS first byte? ;AN006;
1914 jnc no_dbcs5
; no, carry on
1915 mov dbcs_fb
,si ; yes, save pointer
1916 inc si ; skip second byte
1919 inc si ; no, point to next char
1920 jmp gfn1
; loop till end found
1923 mov ah,ES:byte ptr [si] ; get a char
1924 cmp ah,"/" ; did we find a /
1925 je went_too_far
; yes, we found the start
1926 cmp ah,"\" ; did we find a \
1927 je found_bslash ; yes, we found the start ;AN006;
1928 cmp ah,":" ; did we find a :
1929 je went_too_far ; yes, we found the start
1930 cmp si,bx ; are we back to the original start?
1931 je got_the_beg ; yes, we found the start of the fname
1932 dec si ; step back a char, then look some more
1935 found_bslash: ; found a backslash, must figure out if ;AN006;
1936 ; is second byte of DBCS ;AN006;
1937 dec si ; point to next char ;AN006;
1938 cmp si,dbcs_fb ; do they match?
1939 jne no_dbcs5a ; no, fix up si and carry on ;AN006;
1940 dec si ; skip dbcs byte and loop some more ;AN006;
1941 jmp got_the_end ;AN006;
1944 inc si ; went too far by one extra ;AN006;
1947 inc si ; went one char too far back
1949 ; ES:SI now points to the beginning of the filename
1952 mov ah,ES:byte ptr [si] ; get a char from the source
1953 mov byte ptr [di],ah ; copy to dest
1954 cmp ah,null ; did we just copy the end?
1955 je done_with_fname ; yes, all done
1956 inc si ; no, get the next char
1958 cmp di,offset app_dirs_ptr ; make sure we dont try to copy past the
1959 je done_with_fname ; area
1965 ;-----------------------------
1966 ; this code executed to return to caller after APPEND's stack has been
1971 ; reset the stack ;AN002;
1973 popff ; restore flags from real open
1974 mov ss,Stack_Segment ; Get original stack segment
1975 mov sp,Stack_Offset ; Get original stack pointer
1976 pushf ; put the flags on the old stack
1979 ;-----------------------------
1980 ; before jumping to this routine, SS:SP must point to the caller's stack,
1981 ; and the flags from the real INT 21 operation must have been pushed
1985 ; must be sure to clear the true_name flag before leaving ;AN002;
1987 push ax ; save some regs ;AN002;
1992 mov ah,get_PSP ; function code for get PSP operation ;AN002;
1993 call int_21 ; get the PSP, segment returned in BX ;AN002;
1994 mov es,bx ; need to use it as a segment ;AN002;
1995 mov di,PDB_Append ; get pointer to APPEND flag in PDB ;AN002;
1997 mov ax,es:[di] ; get APPEND flag into AX ;AN002;
1998 test ax,true_name_flag ; is true name flag armed? ;AN002;
1999 jz reset_stack2 ; no, don't copy true name ;AN002;
2001 sub ax,true_name_flag ; clear true name flag ;AN002;
2002 mov es:[di],ax ; save it in PSP ;AN002;
2005 reset_stack2: ;AN002;
2007 pop di ; restore ;AN002;
2012 cmp tv_flag,TV_TRUE ;AN000;
2015 mov ax,2003h ; clear open barrier
2019 ; pop down to the old flags on the user's stack
2023 cmp incoming_AX,exec_proc*256+0 ; need to do exec
2025 popff ; discard bad flags
2026 mov ax,incoming_AX ; set exec parms
2028 push ds ; save DS, this must be done ;an005;
2029 ; to pervent DS from being trashed on return to caller ;an005;
2036 call int_21 ; issue the exec
2038 pop ds ; restore DS ; an005;
2043 popff ; get flags from real int 21 (old stack)
2044 pop temp_IP_save ; save IP, CS
2046 lahf ; save flags in AH
2047 popff ; pop old flags off stack
2048 sahf ; replace old with new
2050 ; push the new flags onto the stack, then fix CS and IP on stack
2052 pushf ; push new flags onto stack
2053 push temp_CS_save ; restore IP, CS
2055 mov ax,AX_after_21 ; Set AX as it was after open
2057 call crit_sect_reset ; clear the critical section flag
2058 iret ; return to the calling routine
2061 ;-----------------------------
2062 ; This routine is used to extract an appended dir from the dir list
2063 ; On entry, DS:DI points to an area for the appended dir
2064 ; and ES:SI points to the source string
2068 xor cx,cx ; keep a count of chars in cx ;AN003;
2070 mov ah,es:byte ptr [si] ; get the char, and copy it into dest
2071 cmp ah,null ; find a null?
2072 je no_more_dirs ; yes, inform caller that this is the last one
2074 cmp ah,";" ; check to see if we are at the end of a dir
2075 je update_pointer
; yes,
2077 mov byte ptr [di],ah ; if not null or semi-colon, then copy it
2078 inc si ; increment both pointers
2080 inc cx ; count of chars ;AN003;
2081 jmp copy_dir
; do it some more
2084 inc si ; point to next char
2085 mov ah,es:byte ptr [si] ; get char ; @@16
2086 cmp ah,null
; did we reach the end of the dir list?
2089 cmp ah,";" ; is is a semi-colon
2095 xor si,si ; set end search flag
2098 mov byte ptr [di],null
; null terminate destination
2099 ret ; return to caller
2101 ;-----------------------------
2102 ; set ctrl-break check off
2103 ; first, save the old state so we can restore it later,
2104 ; then turn ctrl-break checking off
2108 mov ah,ctrl_break
; function code for ctrl-break check
2109 xor al,al ; 0 = get current state
2110 call int_21
; call DOS INT 21 handler
2112 mov ctrl_break_state
,dl ; save the old ctrl-break state
2114 mov ah,ctrl_break
; function code for ctrl-break check
2115 mov al,01 ; set current state
2117 call int_21
; call DOS INT 21 handler
2121 ;-----------------------------
2122 ; restore ctrl-break checking flag to the way it was
2124 mov ah,ctrl_break
; function code for ctrl-break check
2125 mov al,01 ; set current state
2126 mov dl,ctrl_break_state
; get the way is was before we messed with it
2127 call int_21
; call DOS INT 21 handler
2130 ;-----------------------------
2131 ; restore ctrl-break checking flag to the way it was
2133 mov ah,ctrl_break
; function code for ctrl-break check
2134 mov al,01 ; set current state
2135 mov dl,ctrl_break_state
; get the way is was before we messed with it
2139 ;-----------------------------
2142 mov crit_err_flag
,0 ; clear the critical error flag
2144 mov ax,get_crit_err
; Get INT 24h vector
2145 call int_21
; call DOS INT 21 handler
2147 mov crit_vector_offset
,bx ; Save it
2148 mov ax,es ; es hase segment for resident code
2149 mov crit_vector_segment
,ax
2151 lea dx,crit_err_handler
; DS:DX = New INT 21h vector
2152 mov ax,set_crit_err
; function code for setting critical error vector
2153 call int_21
; call DOS INT 21 handler
2154 ret ; go back to the caller
2157 ;-----------------------------
2160 push ds ; save ds for this function
2161 mov ax,set_crit_err
; function code for setting critical error vector
2162 mov dx,crit_vector_offset
; get old int 24 offset
2163 mov ds,crit_vector_segment
; get old int 24 segment
2164 call int_21
; call INT 21
2168 ;-----------------------------
2169 ; crit_sect_set - issues an enque request to the server to protect
2170 ; against reentry. This request is issued only if the network is started,
2171 ; and then, only for RCV, MSG, and SRV configurations
2178 mov ax,net_config
; check the server config flag
2179 cmp ax,0 ; is it zero?
2180 je dont_set_crit_sect
; yes, skip it
2182 cmp ax,redir_flag
; is it a redir?
2183 je dont_set_crit_sect
; yes, skip it
2184 ; otherwise, issue the request
2186 ; the config flag was not zero or redir, so set crit section
2193 dont_set_crit_sect: ; because of the config we don't want
2194 pop es ; to set critical section
2200 ;-----------------------------
2206 mov ax,net_config
; check the server config flag
2207 cmp ax,0 ; is it zero?
2208 je not_set
; yes, skip it
2210 cmp ax,redir_flag
; is it a redir?
2211 je not_set
; yes, skip it
2213 mov ah,NETSYSUTIL
; turn critical section off
2224 ;-----------------------------
2225 ; save_first_ext_err - this routine is used to save the extended
2226 ; error info after the first FCB open.
2231 mov ax,ext_err_dpl
.DPL_AX
; copy all registers
2232 mov save_ext_err
.DPL_AX
,ax
2233 mov ax,ext_err_dpl
.DPL_BX
2234 mov save_ext_err
.DPL_BX
,ax
2235 mov ax,ext_err_dpl
.DPL_CX
2236 mov save_ext_err
.DPL_CX
,ax
2237 mov ax,ext_err_dpl
.DPL_DX
2238 mov save_ext_err
.DPL_DX
,ax
2239 mov ax,ext_err_dpl
.DPL_SI
2240 mov save_ext_err
.DPL_SI
,ax
2241 mov ax,ext_err_dpl
.DPL_DI
2242 mov save_ext_err
.DPL_DI
,ax
2243 mov ax,ext_err_dpl
.DPL_DS
2244 mov save_ext_err
.DPL_DS
,ax
2245 mov ax,ext_err_dpl
.DPL_ES
2246 mov save_ext_err
.DPL_ES
,ax
2251 ;-----------------------------
2252 ; get_ext_err_code - this routine is used to get the extended error
2253 ; info for the error that cause append to start its search
2256 push ax ; save register that are changed by this
2257 push bx ; DOS function
2264 ; get the extended error information
2266 mov ah,59h
; function code for get extended error
2267 xor bx,bx ; version number
2268 call int_21
; get the extended error
2270 ; save it away in a DPL for set_ext_error_code
2271 ; all fields in the DPL will be filled in except the last three,
2272 ; which will be left at zero
2274 mov ext_err_dpl
.DPL_AX
,ax
2275 mov ext_err_dpl
.DPL_BX
,bx
2276 mov ext_err_dpl
.DPL_CX
,cx
2277 mov ext_err_dpl
.DPL_DX
,dx
2278 mov ext_err_dpl
.DPL_SI
,si
2279 mov ext_err_dpl
.DPL_DI
,di
2280 mov ext_err_dpl
.DPL_DS
,ds
2281 mov ext_err_dpl
.DPL_ES
,es
2284 ; restore regs and return
2287 pop es ; restore registers
2295 ;-----------------------------
2296 ; set_ext_err_code - this routine is used to get the extended error
2297 ; info for the error that cause append to start its search
2298 ; CS:DX points to return list
2300 push ax ; save register that are changed by this
2301 push ds ; DOS function
2303 ; get the extended error information
2305 mov ah,DOSSERVER
; function code for DOSSERVER call
2306 mov al,DOSSETERROR
; sub-function code for set extended error
2309 call int_21
; set the extended error
2311 ; restore regs and return
2313 pop ds ; restore registers
2317 ;-----------------------------
2318 ; This routine is used to initiate DOS calls from within the APPEND interrupt
2319 ; handlers. An INT instruction can not be used because it would cause APPEND
2322 ; SS, SP saved incase call is EXEC which blows them away
2324 cmp tv_flag
,TV_TRUE
; see if being re-entered ;AN000;
2325 jne use_old_vec
; yes, pass through to DOS
2327 pushf ; to comp for iret pops
2328 call dword ptr tv_vec_off
; Call INT 21h
2332 cmp vector_segment
,0 ; not installed yet
2335 pushf ; to comp for iret pops
2336 call dword ptr vector_offset
; Call INT 21h
2343 ;-----------------------------
2344 ; This routine is used to locate the current APPEND path string
2348 address_status: ; @@13
2349 test mode_flags
,E_mode
2353 mov ax,append_2f
*256+dir_ptr
; get from buffer
2358 get_env_mode: ; get from environment
2359 ; cmp cmd_active,0 ; different logic ; @@13; @@09
2360 ; jne use_cmd_env ; if in COMMAND ; @@13; @@09
2363 call int_21
; get the PSP
2365 mov bx,002ch ; address environment
2366 mov ax,es:word ptr[bx]
2369 cmp ax,0 ; PSP pointer is set
2370 je address_pathx
; @@13
2372 ; cmp cmd_env,0 ; have not set my pointer yet
2373 ; je address_pathx ; @@13
2374 ; mov es,cmd_env ; @@13
2376 mov di,0 ; start at start
2377 cmp es:byte ptr[di],0 ; no environment
2380 cmp es:word ptr[di],0 ; at environment end
2388 comp
,6+1,append_id
; string = "APPEND="
2396 at_appendeq: ; must insure this is @@17
2397 cmp di,0 ; genuine "APPEND=" string @@17
2398 je at_appendeq_genuine
; if start of environ ok @@17
2399 dec di ; else check that 0 @@17
2400 cmp es:byte ptr[di],0 ; precedes string @@17
2401 je at_appendeq_10
; jmp if ok @@17
2402 add di,8 ; else cont.search after @@17
2403 jmp find_append
; "=" @@17
2404 at_appendeq_10: ; @@17
2406 at_appendeq_genuine: ; @@17
2407 add di,6+1 ; skip APPEND=
2408 cmp es:byte ptr[di],0 ; null value
2409 je no_appendeq
; treat as not found
2410 cmp es:byte ptr[di]," "
2412 cmp es:byte ptr[di],";"
2417 no_appendeq: ; not found, use default
2418 lea di,semicolon
; null list
2424 ;----------------------------- ; @@03
2425 ; This routine is used to locate the current APPEND path string ; @@03
2426 ; result to ES:DI. Used by APPEND status. ; @@03
2428 ;address_status: ; @@13; @@03
2429 ; test mode_flags,E_mode ; @@13; @@03
2430 ; jump Z,address_pathx ; @@13; @@03
2431 ; jmp use_cmd_env ; @@13; @@03
2433 cap_dl: ; convert dl to uppercase
2434 cmp dl,"a" ; find out if we have a lower case; @@14
2435 jb cap_dlx
; char ; @@14
2438 sub dl,"a"-"A" ; convert char to upper case ; @@14
2442 ; end_address: ; this is the end of the TSR stuff ;AN002;
2445 ;-----------------------------------------------------------------------------
2446 ; Main routine. Used to determine if APPEND has been loaded
2447 ; before. If not, load resident portion of APPEND. Then handle setting
2448 ; or displaying appended directory list.
2449 ;-----------------------------------------------------------------------------
2451 main_begin: ; DOS entry point
2453 mov ax,seg mystack
; set up stack
2459 mov res_append
,0 ; set external copy ; @@05
2461 push cs ; make DS point to CS
2464 push cs ; make ES point to CS
2468 ; find out if append has been loaded ; @@04
2470 mov ah,append_2f
; int 2f function code for append ; @@04
2471 mov al,are_you_there
; function code to ask if append ; @@04
2472 ; has been loaded ; @@04
2473 int int_function
; @@04
2475 cmp al,append_inst
; is append there? ; @@04
2476 jne not_there_yet
; no ; @@04
2478 mov dx,0 ; set for network version ; @@07
2479 mov ah,append_2f
; int 2F function code for append ; @@07
2480 mov al,DOS_version
; function code for get version ; @@07
2481 int int_function
; @@07
2482 cmp dx,word ptr version_loc
; does the version match? ; @@07
2483 jne bad_append_ver
; no, cough up an error messsage ; @@07
2486 call sysloadmsg
;AN000;
2488 mov ax,9 ; message number ;AN000;
2489 mov bx,STDERR
; handle ;AN000;
2490 xor cx,cx ; sub count ;AN000;
2491 xor dl,dl ; no input ;AN000;
2492 mov dh,-1 ; message class ;AN000;
2493 call sysdispmsg
;AN000;
2494 ; mov cx,len_second_APPEND_msg; length of string ;AN000; ; @@04
2495 ; lea dx,second_APPEND_msg ; second load message ;AN000; ; @@04
2496 ; call print_STDERR ; display error message ;AN000; ; @@04
2497 ; lea dx,crlf ; carriage return, line feed ; @@04
2498 ; mov cx,crlf_len ; length of string ; @@04
2499 ; call print_STDERR ; @@04
2501 mov al,0fch ; second load ; @@05
2502 call terminate
; exit to DOS ; @@05
2504 bad_append_ver: ; append version mismatch ; @@07
2505 call sysloadmsg
;AN000;
2507 mov ax,1 ; message number ;AN000;
2508 mov bx,STDERR
; handle ;AN000;
2509 xor cx,cx ; sub count ;AN000;
2510 xor dl,dl ; no input ;AN000;
2511 mov dh,-1 ; message class ;AN000;
2512 call sysdispmsg
;AN000;
2513 ; mov cx,len_bad_append_msg ;AN000; ; @@07
2514 ; lea dx,bad_append_msg ; bad app message ;AN000; ; @@07
2515 ; call print_STDERR ;AN000; ; @@07
2516 ; lea dx,crlf ; carriage return, line feed ; @@07
2517 ; mov cx,crlf_len ; length of string ; @@07
2518 ; call print_STDERR ; @@07
2519 mov ax,0feh ; bad APPEND version ; @@05
2520 call terminate
; exit to DOS ; @@05
2522 not_there_yet: ; @@04
2524 mov cs:initial_pass
,-1 ; set a flag for initial pass ;AN007;
2525 call do_command
; do actual APPEND
2527 mov bx,4 ; close all standard files
2529 mov ah,3eh
; close file handle
2534 call set_vectors
; set append vectors on success ; @@05
2536 call Release_Environment
; release the environmental vector space ;an007; dms;
2538 lea dx,end_address
+15 ; normal end
2539 mov cl,4 ; calc end address in paragraphs
2541 mov ah,get_PSP
; calc space from PSP to my code ; @@02
2545 add dx,ax ; calc length to keep ; @@02
2546 mov al,0 ; exit with no error
2552 COMMAND_begin: ; COMMAND entry point
2554 mov word ptr cmd_name@
+0,si ; save internal command buffer @
2555 mov word ptr cmd_name@
+2,ds
2558 mov abort_sp
,sp ; save sp for aborts ; @@05
2559 mov res_append
,1 ; set resident copy ; @@05
2560 call do_command
; do actual APPEND
2561 abort_exit: ; exit to abort append ; @@05
2562 mov sp,abort_sp
; @@05
2567 mov es:byte ptr[di],0 ; set no command now
2573 test mode_flags
,E_mode
; no /E processing
2576 mov ax,append_2f
*256+dir_ptr
; int 2f function code for append
2582 ; mov ah,get_PSP ; set new command
2586 mov bx,cmd_buf
; command line iput buffer
2587 inc bx ; skip max length
2588 mov es:byte ptr[bx],3+1+6+1
2589 mov di,bx ; address command line buffer
2590 inc di ; skip current length
2595 move
,3+1+6+1,setappend_name
; set in "SET APPEND="
2598 cmp ds:byte ptr[si],";" ; null list is special case
2603 jmp short copy_path_done
2612 mov es:byte ptr[di],cr
; set end delimiter
2615 mov al,3 ; SET length
2619 move
,8,set_name
; set up "SET" command
2621 mov ax,0 ; set to do SET
2629 do_command: ; APPEND process
2631 ; set ctrl-break check off
2632 ; first, save the old state so we can restore it later,
2633 ; then turn ctrl-break checking off
2635 mov ah,ctrl_break
; function code for ctrl-break check
2636 xor al,al ; 0 = get current state
2639 mov ctrl_break_state
,dl ; save the old ctrl-break state
2641 mov ah,ctrl_break
; function code for ctrl-break check
2642 mov al,01 ; set current state
2646 ; find out if append has been loaded
2648 mov ah,append_2f
; int 2f function code for append
2649 mov al,are_you_there
; function code to ask if append
2653 cmp al,append_inst
; is append there?
2654 jne not_already_there
; yes, don't try to put it
2655 jmp already_there
; yes, don't try to put it
2658 ; get DOS version and decide if it is in the allowed range for
2662 mov ah,get_version
; lets find out if we should do it
2663 call int_21
; try the open
2664 cmp ax,expected_version
; compare with DOS version
2667 jmp check_assign
; valid range
2668 ; lets see if assign has been loaded
2670 ; Break it to the user that he's trying to do an APPEND with
2671 ; the wrong DOS version
2674 cmp al,01 ; DOS 1x or below has no handle fcns ; fixed P134 9/10/87 - gga
2676 ; lea dx,bad_DOS_msg ; bad DOS message ;AN000;
2677 ; mov ah,print_string ;AN000;
2678 ; call int_21 ;AN000;
2679 call sysloadmsg
;AN000;
2681 mov ax,8 ; message number ;AN000;
2682 mov bx,NO_HANDLE
; no handle ;AN000;
2683 xor cx,cx ; sub count ;AN000;
2684 xor dl,dl ; no input ;AN000;
2685 mov dh,-1 ; message class ;AN000;
2686 call sysdispmsg
;AN000;
2689 call ctrl_break_rest
2690 int termpgm
; return to DOS ; @@05
2694 call sysloadmsg
;AN000;
2696 mov ax,8 ; message number ;AN000;
2697 mov bx,STDERR
; handle ;AN000;
2698 xor cx,cx ; sub count ;AN000;
2699 xor dl,dl ; no input ;AN000;
2700 mov dh,-1 ; message class ;AN000;
2701 call sysdispmsg
;AN000;
2703 ; mov cx,len_bad_DOS_msg ; length of string ;AN000;
2704 ; lea dx,bad_DOS_msg ; bad DOS message ;AN000;
2705 ; call print_STDERR ; display error message ;AN000;
2707 call ctrl_break_rest
2708 mov al,0ffh ; bad DOS version ; @@05
2709 call terminate
; exit to DOS ; @@05
2716 jmp check_TopView
; ASSIGN has not been loaded, ; @@01
2718 ; ASSIGN has been loaded before APPEND, bad news!
2721 call sysloadmsg
;AN000;
2723 mov ax,6 ; message number ;AN000;
2724 mov bx,STDERR
; handle ;AN000;
2725 xor cx,cx ; sub count ;AN000;
2726 xor dl,dl ; no input ;AN000;
2727 mov dh,-1 ; message class ;AN000;
2728 call sysdispmsg
;AN000;
2730 ; mov cx,len_append_assign_msg; length of string
2731 ; lea dx,append_assign_msg
2732 ; call print_STDERR ; display error message
2733 jmp conflict_exit
; @@01
2735 check_Topview: ; @@01
2736 mov bx,0 ; incase not there ; @@01
2737 mov ax,10h
*256+34 ; TopView version check ; @@01
2740 jnz TopView_there
; @@01
2741 jmp replace_vector
; TopView has not been loaded, ; @@01
2743 ; TopView has been loaded before APPEND, bad news! ; @@01
2745 TopView_there: ; @@01
2746 ; mov cx,len_append_TV_msg ; length of string ; @@01
2747 ; lea dx,append_TV_msg ; @@01
2748 ; call print_STDERR ; display error message ; @@01
2749 call sysloadmsg
;AN000;
2751 mov ax,7 ; message number ;AN000;
2752 mov bx,STDERR
; handle ;AN000;
2753 xor cx,cx ; sub count ;AN000;
2754 xor dl,dl ; no input ;AN000;
2755 mov dh,-1 ; message class ;AN000;
2756 call sysdispmsg
;AN000;
2759 conflict_exit: ; @@01
2760 call ctrl_break_rest
2762 call terminate
; exit to DOS ; @@05
2764 ; get pointer to dir list, on return ES:DI points to buffer
2768 ; This code has been moved to main_begin ; @@07
2770 ; make sure the right version of APPEND has been loaded ; @@07
2773 ; mov dx,0 ; set for network version ; @@07
2774 ; mov ah,append_2f ; int 2F function code for append ; @@07
2775 ; mov al,DOS_version ; function code for get version ; @@07
2776 ; int int_function ; @@07
2777 ; cmp dx,word ptr version_loc ; does the version match? ; @@07
2778 ; jump NE,bad_append_ver ; no, cough up an error messsage ; @@07
2780 process_args: ; process all arguments
2782 ;-------------------------------------------------------------------
2783 mov si,0081h ; DS:SI points to argument area
2784 mov cs:byte ptr e_switch
+9,0 ; turn /E switch off
2786 process_argsx: ; process all arguments
2790 ; make sure that the /PATH and /X switches are re-enabled, and
2791 ; various flags are cleared
2794 mov cs:byte ptr x_switch
+9,ah ; re-enable /X switch
2795 mov cs:byte ptr path_switch
+9,ah ; re-enable /PATH switch
2796 mov cs:byte ptr x_result
.$P_Type
,0 ; clear flag
2797 mov cs:byte ptr path_result
.$P_Type
,0 ; clear flag
2798 mov cs:byte ptr dirs_result
.$P_Type
,0 ; clear flag
2799 mov cs:parse_flag
,0 ; clear parse flag
2801 ; set up things to call PARSER
2803 push cs ; make sure ES points to segment where
2804 pop es ; parm block info is
2805 lea di,cs:p_block2
; ES:DI points to parm block, for secondary parsing
2808 xor cx,cx ; ordinal value, must start as 0
2809 xor dx,dx ; must be 0
2811 call Scan_For_Equal
; yes - let's see if we have "=" symbol ;an008; dms;
2812 ; parse past it if we do
2815 call dword ptr pars_off
; call to COMMAND.COM's parser
2817 cmp ax,-1 ; end of line?
2818 jne not_end_of_line
; no, carry on
2819 jmp end_of_line_reached
; yes, go figure out what we got
2823 cmp ax,0 ; no, find out if there an error
2824 je not_parse_error
; no, carry on
2825 jmp parse_error
; yes, go display the error message
2827 ; got here without any errors, set the proper bits in mode_flags
2830 mov cs: parse_flag
,0ffh ; set parse flag
2834 cmp e_result
.$P_Type
,3 ; was there a /E in this pass?
2835 jne check_x
; no, look for an X
2837 mov byte ptr e_switch
+9,0 ; turn this off so we don't allow another
2838 mov e_result
.$P_Type
,0 ; clear this so we don't get fooled later
2840 or mode_flags
,E_mode
; set E mode on
2842 jmp get_pars_info
; go get another argument
2845 cmp x_result
.$P_Type
,3 ; was there a /X on this pass? list index
2846 je set_x
; yes, and it was /X w/o ON or OFF
2848 cmp x_result
.$P_Type
,2 ; was there a /X on this pass? list index
2851 mov byte ptr x_switch
+9,0 ; turn this off so we don't allow another
2852 mov x_result
.$P_Type
,0 ; clear this so we don't get fooled later
2854 cmp x_result
.$P_Item_Tag
,1 ; was /X or /X:ON specified?
2855 je set_x
; yes, set X mode on
2856 and mode_flags
,NOT x_mode
; no, clear it
2860 or mode_flags
,x_mode
2864 cmp path_result
.$P_Type
,2 ; was there a /path on this pass? list index
2867 xor ah,ah ; turn this off so we don't allow
2868 mov byte ptr path_switch
+9,ah ; another
2869 mov path_result
.$P_Type
,0 ; clear this so we don't get fooled later
2872 cmp path_result
.$P_Item_Tag
,1 ; was /PATH:ON specified?
2873 je set_path
; yes, set PATH mode
2874 and mode_flags
,NOT path_mode
; no, clear it
2878 or mode_flags
,path_mode
; set PATH mode on
2881 ; find out if dirs specified
2884 cmp dirs_result
.$P_Type
,3 ; was a simple string returned?
2885 je check_dirs2
; yes, carry on
2886 jmp get_pars_info
; no, all done for now
2888 ; set up stuff to do the dirs copy
2896 lds si,dword ptr dirs_result
.$P_Picked_Val
; get pointer to dirs string
2897 mov dirs_result
.$P_Type
,0 ; clear this so we don't get fooled later
2899 mov di,0 ; set incase int 2f not installed ; @@08
2901 mov ax,append_2f
*256+dir_ptr
; es:di -> internal result area ; @@08
2902 int int_function
; @@08
2903 mov ax,es ; see if active yet ; @@08
2905 jnz copy_dirs_loop
; ok, do the copy ; @@08
2906 push cs ; not active, set myself ; @@08
2908 lea di,app_dirs
; @@08
2911 movs es: byte ptr[di],ds:[si]; copy char
2913 cmp byte ptr ds:[si-1],0 ; is char a null
2925 jmp get_pars_info
; no error yet, loop till done
2927 end_of_line_reached:
2928 mov old_syntax
,0 ; process old format operands
2930 cmp cs:initial_pass
,-1 ; is this the first APPEND ;AN006;
2931 je first_one
; yes, clear flag and exit ;AN006;
2933 cmp cs:parse_flag
,0 ; if this flag is off, means null command line
2934 ; was nothing on the command line
2935 je display_dirs
; go display the dirs
2938 mov cs:initial_pass
,0 ; clear first pass flag ;AN006;
2942 call ctrl_break_rest
; reset control break checking
2943 mov ax,0 ; set string
2944 ret ; exit to COMMAND
2948 push ax ;save parser error code ;an010;bgb
2949 call sysloadmsg
;AN000;
2950 pop ax ;restore parser error coed ;an010;bgb
2951 call do_parse_err
;an010;bgb
2952 jmp bad_parmx
; display message and get out
2954 ;-------------------------------------------------------------------
2956 ; mov si,0081h ; point si to argument area
2960 ;process_argsx: ; process all arguments
2961 ; mov di,0 ; set incase int 2f not installed ; @@08
2963 ; mov ax,append_2f*256+dir_ptr ; es:di -> internal result area ; @@08
2964 ; int int_function ; @@08
2965 ; mov ax,es ; see if active yet ; @@08
2967 ; jnz have_ptr ; @@08
2968 ; push cs ; not active, set myself ; @@08
2970 ; lea di,app_dirs ; @@08
2973 ;; step through the DOS command line argument area, and copy the new dir
2974 ;; list to the proper place in APPEND. This requires some parsing for
2975 ;; spaces, tabs chars, equal signs, as well as conversion to upper case
2977 ; cmp byte ptr[si],"=" ; APPEND=path is OK syntax
2980 ;skip_leading: ; skip leading spaces
2987 ; je skip_leading ; @@15
2989 ; je skip_leading ; @@15
2990 ; cmp al,cr ; did we have command line arguments?
2991 ; jump E,display_dirs ; no, display the dirs currently appended
2992 ; cmp al,"/" ; is it a parm starter? ; @@05
2993 ; jump E,bad_path_parm ; yes, it's an error ; @@05
2997 ; lodsb ; get char from command line area
2998 ; cmp al,cr ; are we at the end?
2999 ; jump E,found_end ; yes, display the currently appended dirs
3000 ; cmp al," " ; is it a space?
3001 ; je found_space ; yes, at end
3002 ; cmp al,tab_char ; is it a tab?
3003 ; je found_space ; yes, treat it like a space
3004 ; cmp al,"/" ; is it a parm starter?
3005 ; je bad_path_parm ; yes, it's an error ; @@05
3006 ; cmp al,"a" ; find out if we have a lower case char
3007 ; jb copy_char ; @@14
3009 ; ja copy_char ; @@14
3010 ; sub al,"a"-"A" ; convert char to upper case ; @@14
3013 ; mov in_middle,-1 ; say that we made it to the middle
3014 ; stosb ; no, copy char into resident storage area
3015 ; jmp copy_args ; do it some more
3018 ; cmp in_middle,0 ; set the space flag then go through
3019 ; jump E,copy_args ; loop some more
3022 ; cmp in_middle,0 ; if I found the end of string but not
3023 ; jump E,display_dirs ; in the middle, go display some dirs
3025 ; mov es:byte ptr [di],0 ; null terminate the string
3030 ;skip_trailing: ; skip end spaces
3036 ; cmp al,"/" ; path and parm not together ; @@05
3037 ; je bad_path_parm ; @@05
3038 ; cmp al,cr ; only white space allowed at end
3042 ; cmp old_syntax,0 ; go back to normal mode
3046 ; call ctrl_break_rest ; reset control break checking
3047 ; mov ax,0 ; set string
3048 ; ret ; exit to COMMAND
3050 bad_path: ; bad paath operand
3051 ; mov cx,len_path_error_msg ; length of string
3052 ; lea dx,path_error_msg
3053 call sysloadmsg
;AN000;
3055 mov ax,3 ; message number ;AN000;
3056 mov bx,STDERR
; handle ;AN000;
3057 xor cx,cx ; sub count ;AN000;
3058 xor dl,dl ; no input ;AN000;
3059 mov dh,-1 ; message class ;AN000;
3060 ;gga call sysdispmsg ;AN000;
3064 bad_path_parm: ; bad parameter ; @@05
3065 ; mov cx,len_path_parm_error_msg ; length of string ; @@05
3066 ; lea dx,path_parm_error_msg ; @@05
3067 call sysloadmsg
;AN000;
3068 mov ax,3 ; message number ;AN000;
3069 mov bx,STDERR
; standard error ;AN000;
3070 xor cx,cx ; sub count ;AN000;
3071 xor dl,dl ; no input ;AN000;
3072 mov dh,-1 ; message class ;AN000;
3073 jmp short bad_parmx
; @@05
3074 bad_parm: ; bad parameter
3075 ; mov cx,len_parm_error_msg ; length of string
3076 ; lea dx,parm_error_msg
3077 call sysloadmsg
;AN000;
3079 mov ax,3 ; message number ;AN000;
3080 mov bx,STDERR
; standard error ;AN000;
3081 xor cx,cx ; sub count ;AN000;
3082 xor dl,dl ; no input ;AN000;
3083 mov dh,-1 ; message class ;AN000;
3085 bad_parmx: ; bad parameter
3089 ; call print_STDERR ; display error message
3090 lea si,inv_parm
; point to msg parm ;an010;bgb
3091 call sysdispmsg
;AN000;
3093 call ctrl_break_rest
3095 call terminate
; exit to DOS ; @@05
3097 ; This code has been moved to main_begin ; @@07
3098 ;bad_append_ver: ; append version mismatch ; @@07
3102 ; mov cx,len_bad_append_msg ; @@07
3103 ; lea dx,bad_append_msg ; bad app message ; @@07
3104 ; call print_STDERR ; @@07
3105 ; lea dx,crlf ; carriage return, line feed ; @@07
3106 ; mov cx,crlf_len ; length of string ; @@07
3107 ; call print_STDERR ; @@07
3109 ; call ctrl_break_rest ; @@07
3110 ; mov ax,0feh ; bad APPEND version ; @@05
3111 ; call terminate ; exit to DOS ; @@05
3113 ; Display currently appended directories
3116 call address_status
; get working path ; @@03
3121 cmp es:byte ptr[di],";" ; no append now
3124 ; count the chars in the dir list, cx will hold the count
3127 sub si,6+1 ; move pointer to APPEND
3128 mov dx,si ; save pointer to string
3132 lodsb ; get character
3133 cmp al,null
; are we at end?
3134 je print_it
; yes, print it
3135 inc cx ; look at the next character
3136 jmp scanit
; loop till we find the end
3139 call print_STDOUT
; display appended dirs
3142 lea dx,crlf
; carriage return, line feed
3143 mov cx,crlf_len
; length of string
3148 cmp old_syntax
,0 ; process old format operands
3150 mov si,0081h ; set up rescan
3157 mov old_syntax
,0 ; after first time this must be off
3158 call ctrl_break_rest
; reset control break checking
3159 mov ax,-1 ; no action
3160 ret ; exit to COMMAND
3166 call sysloadmsg
;AN000;
3168 mov ax,5 ; message number ;AN000;
3169 mov bx,STDERR
; handle ;AN000;
3170 xor cx,cx ; sub count ;AN000;
3171 xor dl,dl ; no input ;AN000;
3172 mov dh,-1 ; message class ;AN000;
3173 call sysdispmsg
;AN000;
3175 ; lea dx,no_append_msg ; no dirs message ;AN000;
3176 ; mov cx,len_no_append_msg ; length of string ;AN000;
3177 ; call print_STDOUT ;AN000;
3179 jmp exit_append2
; APPEND = = fix ;GGA
3182 ;-------------------------------------------------------------------
3183 ; Getting here means that APPEND has not been loaded yet. Get the
3184 ; old vector, save it, and point the vector to the new routine.
3185 ;-------------------------------------------------------------------
3190 mov si,0081h ; point si to argument area
3195 ; Process /X and /E parameters
3197 skip_leading2: ; skip leading spaces
3203 ; cmp al,cr ; at end
3206 ; jne set_old_syntax
3226 ; test mode_flags,X_mode ; no duplicates allowed
3228 ; or mode_flags,X_mode
3232 ; test mode_flags,E_mode ; no duplicates allowed
3234 ; or mode_flags,E_mode
3236 ; jmp skip_leading2 ; loop some more
3238 ;; test mode_flags,0 ; no /? switches on old mode
3239 ;; jne bad_path_parmy
3246 set_vectors: ; set append hooks ; @@05
3249 ; Get INT 2f vector. Save to call older 2f handlers
3251 mov ax,get_intfcn
; Get INT 2fh vector
3253 mov intfcn_offset
,bx ; Save it
3254 mov intfcn_segment
,es
3258 mov ax,get_vector
; Get INT 21h vector
3260 mov vector_offset
,bx ; Save it
3261 mov vector_segment
,es
3267 lea dx,intfcn_hook
; DS:DX = New INT 2fh vector
3268 mov ax,set_intfcn
; Hook the interrupt
3271 lea dx,interrupt_hook
; DS:DX = New INT 21h vector
3272 mov ax,set_vector
; Hook the interrupt
3275 mov dirlst_segment
,cs ; save the address of the dirlist
3277 mov dirlst_offset
,dx
3282 terminate: ; terminate to dos or return ; @@05
3283 cmp res_append
,0 ; @@05
3285 call Release_Environment
; release environmental vector ;ac009; dms;
3286 mov ah,term_proc
; return to DOS on first time ; @@05
3289 mov ax,-1 ; set abort requested ; @@05
3290 jmp abort_exit
; must go back to COMMAND ; @@05
3294 mov bx,STDOUT
; Standard output device handle
3295 mov ah,awrite
; function code for write
3300 mov bx,STDERR
; Standard output device handle
3305 Release_Environment: ;an007; dms;
3307 push ax ;save regs ;an007; dms;
3308 push bx ; ;an007; dms;
3309 push es ; ;an007; dms;
3310 mov ah,Get_PSP
; get the PSP segment ;an007; dms;
3311 call int_21
; invoke INT 21h ;an007; dms;
3312 mov es,bx ; BX contains PSP segment - put in ES ;an007; dms;
3313 mov bx,word ptr es:[PSP_Env
]; get segment of environmental vector ;an007; dms;
3314 mov es,bx ; place segment in ES for Free Memory ;an007; dms;
3315 mov ah,Free_Alloc_Mem
; Free Allocated Memory ;an007; dms;
3316 int 21h
; invoke INT 21h ;an007; dms;
3317 pop es ; restore regs ;an007; dms;
3318 pop bx ; ;an007; dms;
3319 pop ax ; ;an007; dms;
3321 ret ; return to caller ;an007; dms;
3323 ;=========================================================================
3324 ; Scan_For_Equal : This routine scans the command line from the
3325 ; beginning until it encounters anything other
3326 ; than the equal, tab, or space characters.
3327 ; Register SI is sent back to the caller pointing
3328 ; to the character that does not meet the match
3331 ; Inputs : DS:SI - pointer to next parm
3333 ; Outputs : SI - adjusted to byte not matching the following:
3341 ;=========================================================================
3345 push ax ; save regs ;an008; dms;
3346 push cx ; ;an008; dms;
3348 xor cx,cx ; clear cx ;an008; dms;
3349 mov cl,byte ptr ds:[80h
] ; get length of command line ;an008; dms;
3351 Scan_For_Equal_Loop:
3353 cmp cx,0 ; at end? ;an008; dms;
3354 jbe Scan_For_Equal_Exit
; exit loop ;an008; dms;
3355 mov al,byte ptr ds:[si] ; get 1st. character ;an008; dms;
3356 call Chk_DBCS
; DBCS lead byte? ;an008; dms;
3357 jnc Scan_For_Equal_No_DBCS
; no ;an008; dms;
3358 cmp byte ptr ds:[si],81h
; blank lead byte ;an008; dms;
3359 jne Scan_For_Equal_Exit
; exit with adjusted SI ;an008; dms;
3360 cmp byte ptr ds:[si+1],40h
; DBCS blank ;an008; dms;
3361 jne Scan_For_Equal_Exit
; exit with adjusted SI ;an008; dms;
3363 add si,2 ; yes - DBCS lead byte ;an008; dms;
3364 sub dx,2 ; decrease counter ;an008; dms;
3365 jmp Scan_For_Equal_Loop
3367 Scan_For_Equal_No_DBCS:
3369 cmp al,"=" ; = found? ;an008; dms;
3370 je Scan_For_Equal_Next
; next character ;an008; dms;
3371 cmp al,20h
; space? ;an008; dms;
3372 je Scan_For_Equal_Next
; next character ;an008; dms;
3373 cmp al,09h ; tab? ;an008; dms;
3374 je Scan_For_Equal_Next
; next character ;an008; dms;
3375 jmp Scan_For_Equal_Exit
; exit with adjusted SI ;an008; dms;
3377 Scan_For_Equal_Next:
3379 inc si ; adjust ptr ;an008; dms;
3380 dec cx ; decrease counter ;an008; dms;
3381 jmp Scan_For_Equal_Loop
; continue loop ;an008; dms;
3383 Scan_For_Equal_Exit:
3385 pop cx ; ;an008; dms;
3386 pop ax ; ;an008; dms;
3388 ret ; return to caller ;an008; dms;
3392 ;========================================================================= ;an010;bgb
3393 ; do_parse_err : This routine sets up for the display of a parse ;an010;bgb
3394 ; error, and displays the offending parameter. ;an010;bgb
3396 ; Inputs : DS:SI - points just past offending parm in command line ;an010;bgb
3398 ; Outputs : si_off- parm for msg ret. ;an010;bgb
3399 ; si_seg- parm for msg ret. ;an010;bgb
3400 ; command line - hex zero at end of offending parm ;an010;bgb
3402 ; Date : 3/29/88 ;an010;bgb
3403 ; Version : DOS 4.0 (wow!) ;an010;bgb
3404 ;========================================================================= ;an010;bgb
3405 do_parse_err PROC
;an010;bgb
3406 ;;;;;;;;mov ax,3 ;removed- parser handles this ;an010;bgb
3407 mov bx,STDERR
; handle ;an010;bgb
3408 ;;;;;;;;xor cx,cx ; sub count ;an010;bgb
3409 mov cx,1 ;display invalid parm ;an010;bgb
3410 xor dl,dl ; no input ;an010;bgb
3411 mov dh,02 ; message class of parse error ;an010;bgb
3412 ;;;;;;;;mov cs:si_off,81h ;initialize pointer ;an010;bgb
3414 dec si ;point to last byte of invalid parm ;an010;bgb
3415 public decsi
;an010;bgb
3416 decsi: cmp byte ptr [si],' ' ;are we pointing to a space? ;an010;bgb
3417 ; $IF E,OR ;if so, we dont want to do that ;an010;bgb
3419 cmp byte ptr [si],0dh ;are we pointing to CR? ;an010;bgb
3420 ; $IF E ;if so, we dont want to do that ;an010;bgb
3423 dec si ;find the last byte of parm ;an010;bgb
3424 jmp decsi
;an010;bgb
3427 mov byte ptr [si+1],00 ;zero terminate display string ;an010;bgb
3429 public nextsi
;an010;bgb
3430 dec si ;look at previous char ;an010;bgb
3431 cmp byte ptr [si],' ' ;find parm separator ;an010;bgb
3432 jnz nextsi
;loop until begin of parm found ;an010;bgb
3434 mov cs:si_off
,si ;mov si into display parms ;an010;bgb
3435 mov cs:si_seg
,ds ;initialize pointer ;an010;bgb
3436 ret ; return to caller ;an010;bgb
3437 do_parse_err ENDP
;an010;bgb
3440 ;-------------------------------------------------------------------
3442 ;-------------------------------------------------------------------
3444 MSG_SERVICES
<LOADmsg
>
3445 MSG_SERVICES
<APPEND
.CLB
,APPEND
.CL2
,APPEND
.CTL
>
3447 end_address: ; this is the end of the TSR stuff ;AN004;
3449 include parse
.asm
; include the parser code
3453 sseg
segment para
stack 'STACK'