Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

922 lines
22 KiB

  1. page ,132
  2. ; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
  3. ; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
  4. TITLE Part7 COMMAND Transient Routines
  5. ;/*
  6. ; * Microsoft Confidential
  7. ; * Copyright (C) Microsoft Corporation 1991
  8. ; * All Rights Reserved.
  9. ; */
  10. ;
  11. ; Revision History
  12. ; ================
  13. ; M003 SR 07/16/90 Made Execute public to jump to it for
  14. ; LoadHigh support
  15. ;
  16. ; M025 SR 9/12/90 Removed calls to SetStdInOn,SetStdInOff
  17. ; SetStdOutOn & SetStdOutOff.
  18. ;
  19. ; More misc routines
  20. .xlist
  21. .xcref
  22. include comsw.asm
  23. include dossym.inc
  24. include syscall.inc
  25. include comseg.asm
  26. include comequ.asm
  27. .list
  28. .cref
  29. CODERES SEGMENT PUBLIC BYTE ;AC000;
  30. ;; EXTRN RSTACK:BYTE
  31. CodeRes ENDS
  32. DATARES SEGMENT PUBLIC BYTE ;AC000;
  33. EXTRN CALL_FLAG:BYTE
  34. EXTRN EchoFlag:BYTE
  35. EXTRN EXEC_BLOCK:BYTE
  36. EXTRN EXTCOM:BYTE
  37. EXTRN LenMsgOrPathBuf:ABS
  38. EXTRN PIPEFLAG:BYTE
  39. EXTRN PIPEPTR:WORD
  40. EXTRN PIPESTR:BYTE
  41. EXTRN RESTDIR:BYTE
  42. EXTRN RE_OUT_APP:BYTE
  43. EXTRN RE_OUTSTR:BYTE
  44. EXTRN SAFEPATHBUFFER:BYTE
  45. extrn RStack:word
  46. ifdef BETA3WARN
  47. %out Take this out before we ship
  48. EXTRN Beta3Warned:byte
  49. EXTRN TrnSeg:word
  50. endif
  51. DATARES ENDS
  52. TRANDATA SEGMENT PUBLIC BYTE ;AC000;
  53. EXTRN BADDRV_PTR:WORD
  54. EXTRN BADNAM_PTR:WORD
  55. EXTRN COMTAB:BYTE ;AC000;
  56. EXTRN extend_buf_ptr:word ;AN000;
  57. EXTRN msg_disp_class:byte ;AN000;
  58. ifdef BETA3WARN
  59. %out Take this out before we ship
  60. EXTRN Beta3WarnMsg:byte
  61. endif
  62. TRANDATA ENDS
  63. TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
  64. EXTRN arg:byte ; the arg structure!
  65. EXTRN ALLSWITCH:WORD
  66. EXTRN APPEND_EXEC:BYTE ;AN041;
  67. EXTRN CHKDRV:BYTE
  68. EXTRN COMBUF:BYTE
  69. EXTRN COMSW:WORD
  70. EXTRN EXECPATH:BYTE
  71. EXTRN EXEC_ADDR:DWORD
  72. EXTRN FILTYP:BYTE
  73. EXTRN IDLEN:BYTE
  74. EXTRN KPARSE:BYTE ;AC000;
  75. EXTRN PARM1:BYTE
  76. EXTRN PARM2:BYTE
  77. EXTRN PathPos:word
  78. EXTRN RESSEG:WORD
  79. EXTRN RE_INSTR:BYTE
  80. EXTRN SPECDRV:BYTE
  81. EXTRN SWITCHAR:BYTE
  82. EXTRN switch_list:byte
  83. EXTRN TRAN_TPA:WORD
  84. EXTRN EXECPATH_SIZE:WORD
  85. EXTRN EXECEXT_TYPE:WORD
  86. IF IBM
  87. EXTRN ROM_CALL:BYTE
  88. EXTRN ROM_CS:WORD
  89. EXTRN ROM_IP:WORD
  90. ENDIF
  91. TRANSPACE ENDS
  92. TRANCODE SEGMENT PUBLIC byte
  93. ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
  94. EXTRN APPEND_PARSE:NEAR ;AN010;
  95. EXTRN BATCOM:NEAR
  96. EXTRN DOCOM1:NEAR
  97. EXTRN PIPEERRSYN:NEAR
  98. EXTRN TCOMMAND:NEAR
  99. IF IBM
  100. EXTRN ROM_EXEC:NEAR
  101. EXTRN ROM_SCAN:NEAR
  102. ENDIF
  103. PUBLIC CERROR
  104. PUBLIC DRVBAD
  105. PUBLIC EXTERNAL
  106. PUBLIC FNDCOM
  107. PUBLIC PRESCAN
  108. PUBLIC SWITCH
  109. public Lh_Execute ; M051
  110. ASSUME DS:TRANGROUP
  111. ;---------------------------
  112. ; We can get rid of this switch processing code if we can take
  113. ; care of the remaining two calls to switch, later in the file.
  114. ; However, I have not checked whether or not any other files use
  115. ; switch -- after all, it IS public!
  116. ;---------------------------
  117. SWCOUNT EQU 6 ; Length of switch_list
  118. RETSW:
  119. XCHG AX,BX ; Put switches in AX
  120. return
  121. SWITCH:
  122. XOR BX,BX ; Initialize - no switches set
  123. SWLOOP:
  124. INVOKE SCANOFF ; Skip any delimiters
  125. CMP AL,[SWITCHAR] ; Is it a switch specifier?
  126. JNZ RETSW ; No -- we're finished
  127. OR BX,fSwitch ; Indicate there is a switch specified
  128. INC SI ; Skip over the switch character
  129. INVOKE SCANOFF
  130. CMP AL,0DH
  131. JZ RETSW ; Oops
  132. INC SI
  133. ; Convert lower case input to upper case
  134. INVOKE UPCONV
  135. MOV DI,OFFSET TRANGROUP:switch_list
  136. MOV CX,SWCOUNT
  137. REPNE SCASB ; Look for matching switch
  138. JNZ BADSW
  139. MOV AX,1
  140. SHL AX,CL ; Set a bit for the switch
  141. OR BX,AX
  142. JMP SHORT SWLOOP
  143. BADSW:
  144. JMP SHORT SWLOOP
  145. DRVBAD:
  146. MOV DX,OFFSET TRANGROUP:BADDRV_ptr
  147. JMP CERROR
  148. externalj:
  149. jmp EXTERNAL
  150. fndcom: ; search the internal command table
  151. OR AL,AL ; Get real length of first arg
  152. jz externalj ; If 0, it must begin with "\" so has
  153. ; to be external.
  154. ; barryf code starts here
  155. ifndef NEC_98
  156. IF IBM
  157. call test_append ; see if APPEND installed
  158. je contcom ; not loaded
  159. append_internal:
  160. mov cl,TRANGROUP:IDLEN
  161. mov ch,0
  162. mov pathpos,cx
  163. inc append_exec ;AN041; set APPEND to ON
  164. invoke ioset ; re-direct the o'l io
  165. mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set
  166. mov DX,-1 ; set invoke function
  167. mov di,offset TRANGROUP:APPEND_PARSE;AN010; Get the entry point for PARSE for APPEND
  168. mov AX,0AE01H
  169. int 2FH ; execute command
  170. cmp TRANGROUP:IDLEN,0 ; execute requested
  171. ;; je Cmd_done
  172. jne contcom
  173. jmp Cmd_done
  174. contcom: ; continue with internal scan
  175. ENDIF
  176. else ;NEC_98
  177. call test_append ; see if APPEND installed
  178. je contcom ; not loaded
  179. append_internal:
  180. mov cl,TRANGROUP:IDLEN
  181. mov ch,0
  182. mov pathpos,cx
  183. inc append_exec ;AN041; set APPEND to ON
  184. invoke ioset ; re-direct the o'l io
  185. mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set
  186. mov DX,-1 ; set invoke function
  187. mov di,offset TRANGROUP:APPEND_PARSE;AN010; Get the entry point for PARSE for APPEND
  188. mov AX,0AE01H
  189. int 2FH ; execute command
  190. cmp TRANGROUP:IDLEN,0 ; execute requested
  191. ;; je Cmd_done
  192. jne contcom
  193. jmp Cmd_done
  194. contcom: ; continue with internal scan
  195. endif ;NEC_98
  196. ; barryf code ends here
  197. mov DI, OFFSET TRANGROUP:COMTAB
  198. XOR CX,CX
  199. findcom:
  200. mov SI, offset TRANGROUP:IDLEN+1 ; pointer to command argument
  201. mov CL, [DI] ; load length of internal command
  202. inc di ; advance past length
  203. jcxz externalj ; if it's zero, we're out of internals
  204. cmp CL, IDLEN ; that of the command argument
  205. jnz abcd ; lengths not equal ==> strings not eq
  206. MOV PathPos,CX ; store length of command
  207. repz cmpsb
  208. abcd:
  209. lahf ; save the good ol' flags
  210. add DI, CX ; skip over remaining internal, if any
  211. mov AL, BYTE PTR [DI] ; load drive-check indicator byte (DCIB)
  212. mov [CHKDRV], AL ; save command flag byte in chkdrv
  213. inc DI ; increment DI (OK, OK, I'll stop)
  214. mov BX, WORD PTR [DI] ; load internal command address
  215. inc DI ; skip over the puppy
  216. inc DI
  217. mov DX, WORD PTR [DI] ; load ptr to help msg #s
  218. inc DI
  219. inc DI
  220. sahf ; remember those flags?
  221. jnz findcom ; well, if all the cmps worked...
  222. ;
  223. ; All messages get redirected.
  224. ;
  225. cmp append_exec,0 ;AN041; APPEND just executed?
  226. jnz dont_set_io ;AN041; Yes - this junk is already set
  227. invoke ioset ; re-direct the ol' i/o
  228. dont_set_io: ;AN041;
  229. ;
  230. ; Check for /?. Certain commands, flagged fLimitHelp,
  231. ; respond to /? only if it is the only command-line argument.
  232. ;
  233. mov ax,[COMSW] ; AX = switches after command
  234. or ax,[ALLSWITCH] ; AX = all switches
  235. and ax,SwitchQues
  236. jz drive_check ; /? not in command line
  237. test [CHKDRV],fLimitHelp
  238. jz do_help ; /? allowed in combination
  239. ;
  240. ; Make sure /? is the only argument on the command line.
  241. ;
  242. cmp [arg.argvcnt],2
  243. jne drive_check ; /? not only arg - ignore
  244. ;
  245. ; Note: this is all the check we need, even against things like /??.
  246. ; Our argv parser breaks /?? into two args, /? and ?.
  247. ;
  248. do_help:
  249. ; DX = ptr to word list of msg #s, terminated by zero word
  250. mov si,dx ; SI = ptr to list of msg #s
  251. mov ax,NO_SUBST ; AL = no subst's code
  252. push ax ; build subst block on stack
  253. next_help_msg:
  254. lodsw ; AX = help msg # or zero
  255. or ax,ax
  256. jz help_done
  257. push ax ; SS:SP = ptr to subst block
  258. ; (msg # and no_subst byte)
  259. ; We assume DS = SS.
  260. mov dx,sp ; DS:DX = ptr to subst block
  261. invoke Std_PrintF ; display help message
  262. pop ax ; remove msg # from stack
  263. jmp next_help_msg
  264. help_done:
  265. pop ax ; clean up stack
  266. jmp TCommand
  267. drive_check:
  268. test [CHKDRV], fCheckDrive ; did we wanna check those drives?
  269. jz nocheck
  270. mov AL, [PARM1] ; parse_file_descriptor results tell
  271. or AL, [PARM2] ; us whether those drives were OK
  272. cmp AL, -1
  273. jnz nocheck
  274. jmp drvbad
  275. ;
  276. ; The user may have omitted the space between the command and its arguments.
  277. ; We need to copy the remainder of the user's command line into the buffer.
  278. ; Note that thisdoes not mess up the arg structure; it points into COMBUF not
  279. ; into the command line at 80.
  280. ;
  281. nocheck:
  282. call cmd_copy
  283. switcheck:
  284. test [CHKDRV], fSwitchAllowed ; Does the command take switches
  285. jnz realwork ; Yes, process the command
  286. call noswit ; No, check to see if any switches
  287. jnz realwork ; None, process the command
  288. mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
  289. MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
  290. mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number
  291. jmp CERROR ; Print error and chill out...
  292. realwork:
  293. call BX ; do some real work, at last
  294. ; See if we're in a batch CALL command. If we are, reprocess the command line,
  295. ; otherwise, go get another command.
  296. Cmd_done:
  297. push cs ; g restore data segment
  298. pop ds ; g
  299. push ds ; g save data segment
  300. mov ds,[resseg] ; g get segment containing call flag
  301. ASSUME ds:resgroup
  302. cmp call_flag, call_in_progress ; G Is a call in progress?
  303. mov call_flag, 0 ; G Either way, reset flag
  304. pop ds ; g get data segment back
  305. jz incall ; G
  306. jmp tcommand ; chill out...
  307. incall:
  308. JMP DOCOM1
  309. noswit:
  310. push di ; Save di
  311. mov di,81h ; di = ptr to command args
  312. mov si,80h ; Get address of length of command args
  313. lodsb ; Load length
  314. mov cl,al ; Move length to cl
  315. xor ch,ch ; Zero ch
  316. mov al,[SWITCHAR] ; al = switch character
  317. cmp al,0 ; Turn off ZF
  318. repnz scasb ; Scan for a switch character and return
  319. pop di ; with ZF set if one was found
  320. ret
  321. EXTERNAL:
  322. ifndef NEC_98
  323. IF IBM
  324. call test_append ; check to see if append installed
  325. je not_barryf ; no - truly external command
  326. jmp append_internal ; yes - go to Barryf code
  327. not_barryf:
  328. ENDIF
  329. else ;NEC_98
  330. call test_append ; check to see if append installed
  331. je not_barryf ; no - truly external command
  332. jmp append_internal ; yes - go to Barryf code
  333. not_barryf:
  334. endif ;NEC_98
  335. MOV [FILTYP],0
  336. MOV DL,[SPECDRV]
  337. MOV [IDLEN],DL
  338. IF IBM
  339. MOV [ROM_CALL],0
  340. PUSH DX
  341. MOV DX,OFFSET TRANGROUP:IDLEN
  342. CALL ROM_SCAN
  343. POP DX
  344. JNC DO_SCAN
  345. INC [ROM_CALL]
  346. JMP short PostSave
  347. DO_SCAN:
  348. ENDIF
  349. IF IBM
  350. PostSave:
  351. ENDIF
  352. ;
  353. ; when ntvdm execs via GetNextVdmCommand, execpath is already
  354. ; fully qualified application name. We know this because the
  355. ; vdminfo is filled
  356. ;
  357. ; Note that EXECPATH_SIZE is used only once(the one we got it from
  358. ; CMDGETNEXTCMD bop). And that is why we reset it everytime after
  359. ; we have accessed it. For other executables, we do the regular
  360. ; search(processing a batch file, for example).
  361. ;
  362. ; Two pieces of information we got from 32bits:
  363. ; (1). the application full path name(in EXECPATH)
  364. ; (2). the application file extention type(in EXECEXT_TYPE)
  365. ; EXECEXT_TYPE 2 -> .BAT
  366. ; 4 -> .EXE
  367. ; 8 -> .COM
  368. ; >8 -> unknown
  369. ; for unknown extention type, we simply launch it because
  370. ; (1). DOS doesn't impose any extention on program file.
  371. ; (2). If we ever get here, we are sure that the program file
  372. ; is a valid DOS executable(otherwise, CreateProcess would
  373. ; have failed and we won't have any file to execute).
  374. ;
  375. ;
  376. xor ax, ax
  377. xchg ax, [EXECPATH_SIZE] ;get and set
  378. or ax, ax ;do we have appname already?
  379. mov ax, [EXECEXT_TYPE] ;
  380. jnz execute_with_type ;yes, No search
  381. MOV DI,OFFSET TRANGROUP:EXECPATH
  382. MOV BYTE PTR [DI],0 ; Initialize to current directory
  383. IF IBM
  384. CMP [ROM_CALL],0
  385. JNZ NeoExecute
  386. ENDIF
  387. invoke path_search ; find the mother (result in execpath)
  388. execute_with_type:
  389. or AX, AX ; did we find anything?
  390. je badcomj45 ; null means no (sob)
  391. cmp AX, 04H ; 04H and 08H are .exe and .com
  392. ; sixteen-bit machine ought
  393. jnl execute ; to be able to handle a SIXTEEN-BIT
  394. ; DISPLACEMENT!!
  395. jmp batcom ; 02H is .bat
  396. BADCOMJ45:
  397. ifdef BETA3WARN
  398. JMP BADCOM
  399. else
  400. JMP short BADCOM
  401. endif
  402. ASSUME DS:TRANGROUP,ES:TRANGROUP
  403. EXECUTE:
  404. NeoExecute:
  405. invoke IOSET
  406. ;M051
  407. ; Previously LoadHigh was jumping to the execute label above. This was wrong
  408. ;because IOSET was getting invoked twice resulting in 2 sets of redirections.
  409. ;After a close, this would still leave one open active resulting in sharing
  410. ;errors on subsequent opens of the redirected file.
  411. ;
  412. Lh_Execute: ;M051
  413. MOV ES,[TRAN_TPA]
  414. MOV AH,DEALLOC
  415. INT 21h ; Now running in "free" space
  416. MOV ES,[RESSEG]
  417. ASSUME ES:RESGROUP
  418. INC [EXTCOM] ; Indicate external command
  419. MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure
  420. ; this flag value for re-entry to COMMAND
  421. MOV SI,OFFSET TRANGROUP:EXECPATH
  422. MOV DI,OFFSET RESGROUP:SAFEPATHBUFFER
  423. MOV CX,LenMsgOrPathBuf
  424. CLD
  425. LE_copy_loop:
  426. lodsb
  427. stosb
  428. cmp al, 0
  429. je LE_copy_done
  430. loop LE_copy_loop
  431. ;; the program name is too long, terminate it with
  432. ;; null character. The Exec call will fail and we will print out error message
  433. ;; see command1.asm
  434. mov byte ptr es:[di - 1], 0
  435. LE_copy_done:
  436. MOV DI,FCB
  437. MOV SI,DI
  438. MOV CX,052H ; moving (100h-5Ch)/2 = 80h-2Eh
  439. REP MOVSW ; Transfer parameters to resident header
  440. MOV DX,OFFSET RESGROUP:SAFEPATHBUFFER
  441. PUSH ES
  442. POP DS
  443. ASSUME DS:RESGROUP
  444. MOV BX,OFFSET RESGROUP:EXEC_BLOCK
  445. MOV AX,EXEC SHL 8
  446. IF IBM
  447. TEST [ROM_CALL],-1
  448. JZ OK_EXEC
  449. JMP ROM_EXEC
  450. OK_EXEC:
  451. ENDIF
  452. ;
  453. ; we are now running in free space. anything we do from here on may get
  454. ; trashed. Move the stack (also in free space) to allocated space because
  455. ; since EXEC restores the stack, somebody may trash what is on the stack.
  456. ;
  457. MOV CX,ES
  458. MOV SS,CX
  459. MOV SP,OFFSET DATARES:RStack
  460. ifdef BETA3WARN
  461. %out Take this out before we ship
  462. cmp Beta3Warned, 0
  463. jne NoWarning
  464. mov Beta3Warned, 0ffh
  465. push ax
  466. push cx
  467. push dx
  468. push ds
  469. mov ah, 2ah ; get date
  470. int 21h
  471. cmp cx, 1991
  472. jb nwx
  473. ja bwarn
  474. cmp dh, 4
  475. jb nwx
  476. bwarn:
  477. mov ds, trnseg
  478. assume ds:trangroup
  479. mov dx, offset trangroup:Beta3WarnMsg
  480. mov ah, 9
  481. int 21h
  482. ; wait till a key is hit
  483. @@:
  484. mov ah, 6 ; console I/O
  485. mov dl, 0ffh ; Read
  486. int 21h
  487. jz @b
  488. nwx:
  489. pop ds
  490. assume ds:resgroup
  491. pop dx
  492. pop cx
  493. pop ax
  494. NoWarning:
  495. endif
  496. JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident
  497. ASSUME DS:TRANGROUP
  498. BADCOM:
  499. PUSH CS
  500. POP DS
  501. MOV DX,OFFSET TRANGROUP:BADNAM_ptr
  502. CERROR:
  503. INVOKE std_eprintf
  504. JMP TCOMMAND
  505. ;
  506. ; Prescan converts the input buffer into a canonicalized form. All
  507. ; redirections and pipes are removed.
  508. ;
  509. PRESCAN: ; Cook the input buffer
  510. ASSUME DS:TRANGROUP,ES:TRANGROUP
  511. XOR CX,CX
  512. MOV ES,[RESSEG]
  513. ASSUME ES:RESGROUP
  514. MOV SI,OFFSET TRANGROUP:COMBUF+2
  515. MOV DI,SI
  516. CountQuotes:
  517. LODSB ; get a byte
  518. CMP AL,22h ; is it a quote?
  519. JNZ CountEnd ; no, try for end of road
  520. INC CH ; bump count
  521. JMP CountQuotes ; go get next char
  522. CountEnd:
  523. CMP AL,13 ; end of road?
  524. JNZ CountQuotes ; no, go back for next char
  525. ;;;; IFDEF DBCS 3/3/KK
  526. PUSH CX ; save count
  527. MOV SI,DI ; get back beginning of buffer
  528. KanjiScan:
  529. LODSB ; get a byte
  530. INVOKE TestKanj ; is it a leadin byte
  531. JZ KanjiQuote ; no, check for quotes
  532. ifdef NEC_98
  533. if BUGFIX
  534. cmp byte ptr [si],' '
  535. jb kanjiQuote
  536. endif
  537. endif ;NEC_98
  538. MOV AH,AL ; save leadin
  539. LODSB ; get trailing byte
  540. CMP AX,DB_SPACE ; is it Kanji space
  541. JNZ KanjiScan ; no, go get next
  542. MOV [SI-2],2020h ; replace with spaces
  543. JMP KanjiScan ; go get next char
  544. KanjiQuote:
  545. CMP AL,22h ; beginning of quoted string
  546. JNZ KanjiEnd ; no, check for end
  547. DEC CH ; drop count
  548. JZ KanjiScan ; if count is zero, no quoting
  549. KanjiQuoteLoop:
  550. LODSB ; get next byte
  551. CMP AL,22h ; is it another quote
  552. JNZ KanjiQuoteLoop ; no, get another
  553. DEC CH ; yes, drop count
  554. JMP KanjiScan ; go get next char
  555. KanjiEnd:
  556. CMP AL,13 ; end of line character?
  557. JNZ KanjiScan ; go back to beginning
  558. POP CX ; get back original count
  559. ;;;; ENDIF 3/3/KK
  560. MOV SI,DI ; restore pointer to begining
  561. PRESCANLP:
  562. LODSB
  563. ;;;; IFDEF DBCS 3/3/KK
  564. INVOKE TESTKANJ
  565. JZ NOTKANJ6
  566. ifdef NEC_98
  567. if BUGFIX
  568. cmp byte ptr [si],' '
  569. jb NOTKANJ6
  570. endif
  571. endif ;NEC_98
  572. MOV [DI],AL
  573. INC DI ; fake STOSB into DS
  574. LODSB ; grab second byte
  575. MOV [DI],AL ; fake stosb into DS
  576. INC DI
  577. INC CL
  578. INC CL
  579. JMP PRESCANLP
  580. NOTKANJ6:
  581. ;;;; ENDIF 3/3/KK
  582. CMP AL,'"' ; " character
  583. JNZ TRYGREATER
  584. DEC CH
  585. JZ TRYGREATER
  586. QLOOP:
  587. MOV [DI],AL
  588. INC DI
  589. INC CL
  590. LODSB
  591. CMP AL,'"' ; " character
  592. JNZ QLOOP
  593. DEC CH
  594. TRYGREATER:
  595. CMP AL,rabracket
  596. JNZ NOOUT
  597. ;
  598. ; We have found a ">" char. We need to see if there is another ">"
  599. ; following it.
  600. ;
  601. CMP BYTE PTR [SI],al
  602. JNZ NOAPPND
  603. LODSB
  604. INC [RE_OUT_APP] ; Flag >>
  605. NOAPPND:
  606. ;
  607. ; Now we attempt to find the file name. First, scan off all whitespace
  608. ;
  609. INVOKE SCANOFF
  610. CMP AL,labracket ;AN040; was there no filename?
  611. JZ REOUT_ERRSET ;AN040; yes - set up error
  612. CMP AL,0DH
  613. JNZ GOTREOFIL
  614. ;
  615. ; There was no file present. Set us up at end-of-line.
  616. ;
  617. REOUT_ERRSET: ;AN040; set up for an error
  618. mov byte ptr [di], 0dh ; Clobber first ">"
  619. MOV WORD PTR [RE_OUTSTR],09H ; Cause an error later
  620. JMP PRESCANEND
  621. GOTREOFIL:
  622. PUSH DI
  623. MOV DI,OFFSET RESGROUP:RE_OUTSTR
  624. MOV BX,DI
  625. PUSH ES
  626. SETREOUTSTR: ; Get the output redirection name
  627. ; MSKK06 07/14/89
  628. push cx ; save cx
  629. mov cx,64+13 ; CX = max string length
  630. SETREOUTSTR_LOOP:
  631. LODSB
  632. CMP AL,0DH
  633. JZ GOTRESTR_J
  634. INVOKE DELIM
  635. JZ GOTRESTR_J
  636. CMP AL,[SWITCHAR]
  637. JZ GOTRESTR_J
  638. CMP AL,'"' ;AN033; Is the character a quote?
  639. JZ PIPEERRSYNJ5_J ;AN033; Yes - get out quick - or system crashes
  640. CMP AL,labracket ;AN002; Is char for input redirection
  641. JZ ABRACKET_TERM ;AN002; yes - end of string
  642. CMP AL,rabracket ;AN002; Is char for output redirection
  643. JNZ NO_ABRACKET ;AN002; no - not end of string
  644. ABRACKET_TERM: ;AN002; have end of string by < or >
  645. DEC SI ;AN002; back up over symbol
  646. MOV AL,BLANK ;AN002; show delimiter as char
  647. GOTRESTR_J:
  648. pop cx ; MSKK06 07/14/89
  649. JMP SHORT GOTRESTR ;AN002; go process it
  650. NO_ABRACKET: ;AN002; NOT AT END OF STRING
  651. STOSB ; store it into resgroup
  652. ifdef DBCS
  653. invoke testkanj
  654. jz @f ; if not lead byte of DBCS
  655. jcxz gotrestr_j ; if no tail byte
  656. lodsb
  657. cmp al,0dh
  658. jz gotrestr_j ; if tail byte does't come and ends
  659. stosb ; copy tail byte
  660. dec cx
  661. @@:
  662. endif
  663. LOOP SETREOUTSTR_LOOP ; MSKK06 07/14/89
  664. jmp GOTRESTR_j
  665. PIPEERRSYNJ5_J:
  666. pop cx ; recover CX
  667. jmp short PIPEERRSYNJ5
  668. NOOUT:
  669. CMP AL,labracket
  670. JNZ CHKPIPE
  671. mov bx,si ; Save loc of "<"
  672. INVOKE SCANOFF
  673. CMP AL,rabracket ;AN040; was there no filename?
  674. JZ REIN_ERRSET ;AN040; yes - set up error
  675. CMP AL,0DH
  676. JNZ GOTREIFIL
  677. REIN_ERRSET: ;AN040; set up for error
  678. mov byte ptr [di],0dh ; Clobber "<"
  679. MOV WORD PTR [RE_INSTR],09H ; Cause an error later
  680. JMP SHORT PRESCANEND
  681. GOTREIFIL:
  682. PUSH DI
  683. MOV DI,OFFSET TranGROUP:RE_INSTR
  684. MOV BX,DI
  685. PUSH ES
  686. PUSH CS
  687. POP ES ; store in TRANGROUP
  688. JMP SHORT SETREOUTSTR ; Get the input redirection name
  689. CHKPIPE:
  690. MOV AH,AL
  691. CMP AH,AltPipeChr
  692. JZ IsPipe3
  693. CMP AH,vbar
  694. JNZ CONTPRESCAN
  695. IsPipe3:
  696. ;
  697. ; Only push the echo flag if we are entering the pipe for the first time.
  698. ;
  699. CMP PipeFlag,0
  700. JNZ NoEchoPush
  701. SHL EchoFlag,1 ; push echo state and turn it off
  702. NoEchoPush:
  703. INC [PIPEFLAG]
  704. INVOKE SCANOFF
  705. CMP AL,0DH
  706. JZ PIPEERRSYNJ5
  707. CMP AL,AltPipeChr
  708. JZ PIPEERRSYNJ5
  709. CMP AL,vbar ; Double '|'?
  710. JNZ CONTPRESCAN
  711. PIPEERRSYNJ5:
  712. PUSH ES
  713. POP DS ; DS->RESGROUP
  714. JMP PIPEERRSYN
  715. ;
  716. ; Trailing :s are allowed on devices. Check to be sure that there is more
  717. ; than just a : in the redir string.
  718. ;
  719. GOTRESTR:
  720. XCHG AH,AL
  721. mov al,':'
  722. SUB BX,DI ; compute negatinve of number of chars
  723. CMP BX,-1 ; is there just a :?
  724. JZ NotTrailCol ; yep, don't change
  725. CMP BYTE PTR ES:[DI-1],al ; Trailing ':' OK on devices
  726. JNZ NOTTRAILCOL
  727. DEC DI ; Back up over trailing ':'
  728. NOTTRAILCOL:
  729. XOR AL,AL
  730. STOSB ; NUL terminate the string
  731. POP ES
  732. POP DI ; Remember the start
  733. CONTPRESCAN:
  734. MOV [DI],AH ; "delete" the redirection string
  735. INC DI
  736. CMP AH,0DH
  737. JZ PRESCANEND
  738. INC CL
  739. JMP PRESCANLP
  740. PRESCANEND:
  741. CMP [PIPEFLAG],0
  742. JZ ISNOPIPE
  743. MOV DI,OFFSET RESGROUP:PIPESTR
  744. MOV [PIPEPTR],DI
  745. MOV SI,OFFSET TRANGROUP:COMBUF+2
  746. INVOKE SCANOFF
  747. PIPESETLP: ; Transfer the pipe into the resident
  748. LODSB ; pipe buffer
  749. STOSB
  750. CMP AL,0DH
  751. JNZ PIPESETLP
  752. ISNOPIPE:
  753. MOV [COMBUF+1],CL
  754. CMP [PIPEFLAG],0
  755. PUSH CS
  756. POP ES
  757. return
  758. cmd_copy proc near
  759. MOV SI,OFFSET TRANGROUP:COMBUF+2
  760. INVOKE Scanoff ; advance past separators...
  761. add si,PathPos
  762. mov di,81h
  763. xor cx,cx
  764. CmdCopy:
  765. lodsb
  766. stosb
  767. cmp al,0dh
  768. jz CopyDone
  769. inc cx
  770. jmp CmdCopy
  771. CopyDone:
  772. mov byte ptr ds:[80h],cl ; Store count
  773. ret
  774. cmd_copy endp
  775. test_append proc near
  776. mov BX,offset TRANGROUP:COMBUF ; barry can address
  777. mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set
  778. mov DX,-1 ; set install check function
  779. mov AX,0AE00H
  780. int 2FH ; see if loaded
  781. cmp AL,00H
  782. ret
  783. test_append endp
  784. TRANCODE ENDS
  785. END
  786.