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.

1825 lines
55 KiB

  1. page ,132
  2. ; SCCSID = @(#)tcode.asm 1.1 85/05/14
  3. ; SCCSID = @(#)tcode.asm 1.1 85/05/14
  4. TITLE Part1 COMMAND Transient Routines
  5. ;/*
  6. ; * Microsoft Confidential
  7. ; * Copyright (C) Microsoft Corporation 1991
  8. ; * All Rights Reserved.
  9. ; */
  10. ;
  11. ; Revision History
  12. ; ================
  13. ;
  14. ; M025 SR 9/12/90 Removed calls to SetStdInOn,SetStdInOff
  15. ; SetStdOutOn & SetStdOutOff.
  16. ;
  17. .xlist
  18. .xcref
  19. include comsw.asm
  20. include dossym.inc
  21. include syscall.inc
  22. include comseg.asm
  23. include comequ.asm
  24. include cmdsvc.inc
  25. include mult.inc
  26. ifdef NEC_98
  27. include pdb.inc
  28. endif ;NEC_98
  29. include vint.inc
  30. .list
  31. .cref
  32. Prompt32 equ 1
  33. Start16 equ 0
  34. Return16 equ 1
  35. DOSONLY_YES equ 1
  36. FOR_TSR equ 0
  37. FOR_SHELLOUT equ 1
  38. CODERES SEGMENT PUBLIC BYTE ;AC000;
  39. EXTRN EXEC_WAIT:NEAR
  40. CODERES ENDS
  41. DATARES SEGMENT PUBLIC BYTE ;AC000;
  42. EXTRN BATCH:WORD
  43. EXTRN CALL_BATCH_FLAG:byte
  44. EXTRN CALL_FLAG:BYTE
  45. EXTRN ECHOFLAG:BYTE
  46. EXTRN envirseg:word
  47. EXTRN EXTCOM:BYTE
  48. EXTRN FORFLAG:BYTE
  49. EXTRN IFFLAG:BYTE
  50. EXTRN next_batch:word
  51. EXTRN nullflag:byte
  52. EXTRN PIPEFILES:BYTE
  53. EXTRN PIPEFLAG:BYTE
  54. EXTRN RE_OUT_APP:BYTE
  55. EXTRN RE_OUTSTR:BYTE
  56. EXTRN RESTDIR:BYTE
  57. EXTRN SINGLECOM:WORD
  58. EXTRN KSWITCHFLAG:BYTE
  59. EXTRN VERVAL:WORD
  60. EXTRN SCS_Is_First:BYTE
  61. EXTRN SCS_PAUSE:BYTE
  62. EXTRN SCS_REENTERED:BYTE
  63. EXTRN SCS_FIRSTCOM:BYTE
  64. EXTRN SCS_CMDPROMPT:BYTE
  65. EXTRN SCS_DOSONLY:BYTE
  66. EXTRN SCS_PROMPT16:BYTE
  67. EXTRN SCS_FIRSTTSR:BYTE
  68. EXTRN RES_RDRINFO:DWORD
  69. EXTRN RES_BATSTATUS:BYTE
  70. EXTRN crit_msg_off:word ;AC000;
  71. EXTRN crit_msg_seg:word ;AC000;
  72. EXTRN OldTerm:DWORD
  73. EXTRN PARENT:WORD
  74. extrn RetCode:word
  75. extrn Io_Save:word
  76. extrn Io_Stderr:byte
  77. extrn RES_TPA:WORD ; YST
  78. extrn LTPA:WORD ; YST
  79. DATARES ENDS
  80. TRANDATA SEGMENT PUBLIC BYTE ;AC000;
  81. EXTRN BadNam_Ptr:word ;AC000;
  82. EXTRN comspec:byte
  83. EXTRN NT_INTRNL_CMND:byte
  84. TRANDATA ENDS
  85. TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
  86. EXTRN APPEND_EXEC:BYTE ;AN041;
  87. EXTRN ARG1S:WORD
  88. EXTRN ARG2S:WORD
  89. EXTRN ARGTS:WORD
  90. EXTRN BYTCNT:WORD
  91. EXTRN COMBUF:BYTE
  92. EXTRN COMSW:WORD
  93. EXTRN CURDRV:BYTE
  94. EXTRN HEADCALL:DWORD
  95. EXTRN IDLEN:BYTE
  96. EXTRN INTERNATVARS:BYTE
  97. EXTRN PARM1:BYTE
  98. EXTRN PARM2:BYTE
  99. EXTRN RE_INSTR:BYTE
  100. EXTRN RESSEG:WORD
  101. EXTRN SPECDRV:BYTE
  102. EXTRN STACK:WORD
  103. EXTRN SWITCHAR:BYTE
  104. EXTRN TPA:WORD
  105. EXTRN UCOMBUF:BYTE
  106. EXTRN USERDIR1:BYTE
  107. IF IBM
  108. EXTRN ROM_CALL:BYTE
  109. EXTRN ROM_CS:WORD
  110. EXTRN ROM_IP:WORD
  111. ENDIF
  112. EXTRN ENV_PTR_SEG:WORD
  113. EXTRN ENV_SIZE:WORD
  114. EXTRN SCS_TSREXIT:WORD
  115. EXTRN CMD_PTR_SEG:WORD
  116. EXTRN CMD_PTR_OFF:WORD
  117. EXTRN CMD_SIZE:WORD
  118. EXTRN SCS_EXIT_CODE:WORD
  119. EXTRN SCS_RDRINFO:DWORD
  120. EXTRN SCS_BATSTATUS:DWORD
  121. EXTRN SCS_NUM_DRIVES:WORD
  122. EXTRN SCS_CUR_DRIVE:WORD
  123. EXTRN SCS_CODEPAGE:WORD
  124. EXTRN SCS_STD_HANDLE:WORD
  125. EXTRN SCS_STD_BITS:BYTE
  126. EXTRN EXECPATH_SEG:WORD
  127. EXTRN EXECPATH_OFF:WORD
  128. EXTRN EXECPATH_SIZE:WORD
  129. EXTRN EXECPATH:BYTE
  130. EXTRN TRAN_TPA:WORD
  131. extrn transpaceend:byte ; (YST)
  132. TRANSPACE ENDS
  133. ; (YST)
  134. TAIL segment public para
  135. extrn TranStart:word
  136. TAIL ENDS
  137. ; End of (YST)
  138. ; ********************************************************************
  139. ; START OF TRANSIENT PORTION
  140. ; This code is loaded at the end of memory and may be overwritten by
  141. ; memory-intensive user programs.
  142. TRANCODE SEGMENT PUBLIC BYTE ;AC000;
  143. ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
  144. EXTRN $EXIT:NEAR
  145. EXTRN DRVBAD:NEAR
  146. EXTRN EXTERNAL:NEAR
  147. EXTRN FNDCOM:NEAR
  148. EXTRN FORPROC:NEAR
  149. EXTRN PIPEPROC:NEAR
  150. EXTRN PIPEPROCSTRT:NEAR
  151. EXTRN GETENVSIZ:near
  152. PUBLIC COMMAND
  153. PUBLIC DOCOM
  154. PUBLIC DOCOM1
  155. PUBLIC NOPIPEPROC
  156. PUBLIC TCOMMAND
  157. IF IBM
  158. PUBLIC ROM_EXEC
  159. PUBLIC ROM_SCAN
  160. ENDIF
  161. ; NTVDM use diff al value so we don't confuse dos 5.0
  162. ; NTVDM command.com GET_COMMAND_STATE equ 5500h
  163. GET_COMMAND_STATE equ 5501h
  164. NLSFUNC_installed equ 0ffh
  165. KEYB16_installed equ 0ffh ; (YST)
  166. CHECK_KEYB16 equ 0AD80h ; (YST)
  167. set_global_cp equ 2
  168. get_global_cp equ 1
  169. ORG 0
  170. ZERO = $
  171. ORG 100H ; Allow for 100H parameter area
  172. SETDRV:
  173. MOV AH,SET_DEFAULT_DRIVE
  174. INT 21h
  175. ;
  176. ; TCOMMAND is the recycle point in COMMAND. Nothing is known here.
  177. ; No registers (CS:IP) no flags, nothing.
  178. ;
  179. TCOMMAND:
  180. MOV DS,[RESSEG]
  181. ASSUME DS:RESGROUP
  182. MOV AX,-1
  183. XCHG AX,[VERVAL]
  184. CMP AX,-1
  185. JZ NOSETVER2
  186. MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
  187. INT 21h
  188. NOSETVER2:
  189. CALL [HEADCALL] ; Make sure header fixed
  190. XOR BP,BP ; Flag transient not read
  191. CMP [SINGLECOM],-1
  192. JNZ COMMAND
  193. $EXITPREP:
  194. PUSH CS
  195. POP DS
  196. JMP $EXIT ; Have finished the single command
  197. ASSUME DS:NOTHING
  198. ;
  199. ; Main entry point from resident portion.
  200. ;
  201. ; If BP <> 0, then we have just loaded transient portion otherwise we are
  202. ; just beginning the processing of another command.
  203. ;
  204. COMMAND:
  205. ;
  206. ; We are not always sure of the state of the world at this time. We presume
  207. ; worst case and initialize the relevant registers: segments and stack.
  208. ;
  209. ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
  210. CLD
  211. MOV AX,CS
  212. FCLI
  213. MOV SS,AX
  214. ASSUME SS:TRANGROUP
  215. MOV SP,OFFSET TRANGROUP:STACK
  216. FSTI
  217. MOV ES,AX
  218. MOV DS,AX ;AN000; set DS to transient
  219. ASSUME ES:TRANGROUP,DS:TRANGROUP ;AC000;
  220. invoke TSYSLOADMSG ;AN000; preload messages
  221. mov append_exec,0 ;AN041; set internal append state off
  222. MOV DS,[RESSEG]
  223. ASSUME DS:RESGROUP
  224. MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF
  225. MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE)
  226. mov [EXECPATH_SIZE], 0 ; ntvdm execpath extended
  227. ;
  228. ; If we have just loaded the transient, then we do NOT need to initialize the
  229. ; command buffer. ???? DO WE NEED TO RESTORE THE USERS DIRECTORY ???? I
  230. ; guess not: the only circumstances in which we reload the command processor
  231. ; is after a transient program execution. In this case, we let the current
  232. ; directory lie where it may.
  233. ;
  234. OR BP,BP ; See if just read
  235. JZ TESTRDIR ; Not read, check user directory
  236. MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer
  237. JMP SHORT NOSETBUF
  238. TESTRDIR:
  239. CMP [RESTDIR],0
  240. JZ NOSETBUF ; User directory OK
  241. PUSH DS
  242. ;
  243. ; We have an unusual situation to handle. The user *may* have changed his
  244. ; directory as a result of an internal command that got aborted. Restoring it
  245. ; twice may not help us: the problem may never go away. We just attempt it
  246. ; once and give up.
  247. ;
  248. MOV [RESTDIR],0 ; Flag users dirs OK
  249. PUSH CS
  250. POP DS
  251. ASSUME DS:TRANGROUP
  252. MOV DX,OFFSET TRANGROUP:USERDIR1
  253. MOV AH,CHDIR
  254. INT 21h ; Restore users directory
  255. POP DS
  256. ASSUME DS:RESGROUP
  257. NOSETBUF:
  258. CMP [PIPEFILES],0
  259. JZ NOPCLOSE ; Don't bother if they don't exist
  260. CMP [PIPEFLAG],0
  261. JNZ NOPCLOSE ; Don't del if still piping
  262. INVOKE PIPEDEL
  263. NOPCLOSE:
  264. MOV [EXTCOM],0 ; Flag internal command
  265. MOV AX,CS ; Get segment we're in
  266. MOV DS,AX
  267. ASSUME DS:TRANGROUP
  268. PUSH AX
  269. MOV DX,OFFSET TRANGROUP:INTERNATVARS
  270. MOV AX,INTERNATIONAL SHL 8
  271. INT 21H
  272. POP AX
  273. SUB AX,[TPA] ; AX=size of TPA in paragraphs
  274. PUSH BX
  275. MOV BX,16
  276. MUL BX ; DX:AX=size of TPA in bytes
  277. POP BX
  278. OR DX,DX ; See if over 64K
  279. JZ SAVSIZ ; OK if not
  280. MOV AX,-1 ; If so, limit to 65535 bytes
  281. SAVSIZ:
  282. ;
  283. ; AX is the number of bytes free in the buffer between the resident and the
  284. ; transient with a maximum of 64K-1. We round this down to a multiple of 512.
  285. ;
  286. CMP AX,512
  287. JBE GotSize
  288. AND AX,0FE00h ; NOT 511 = NOT 1FF
  289. GotSize:
  290. MOV [BYTCNT],AX ; Max no. of bytes that can be buffered
  291. MOV DS,[RESSEG] ; All batch work must use resident seg.
  292. ASSUME DS:RESGROUP
  293. TEST [ECHOFLAG],1
  294. JZ GETCOM ; Don't do the CRLF
  295. INVOKE SINGLETEST
  296. JB GETCOM
  297. TEST [PIPEFLAG],-1
  298. JNZ GETCOM
  299. TEST [FORFLAG],-1 ; G Don't print prompt in FOR
  300. JNZ GETCOM ; G
  301. TEST [BATCH], -1 ; G Don't print prompt if in batch
  302. JNZ GETCOM ; G
  303. ; INVOKE CRLF2
  304. GETCOM:
  305. MOV CALL_FLAG,0 ; G Reset call flags
  306. MOV CALL_BATCH_FLAG,0 ; G
  307. MOV AH,GET_DEFAULT_DRIVE
  308. INT 21h
  309. MOV [CURDRV],AL
  310. TEST [PIPEFLAG],-1 ; Pipe has highest presedence
  311. JZ NOPIPE
  312. JMP PIPEPROC ; Continue the pipeline
  313. NOPIPE:
  314. TEST [ECHOFLAG],1
  315. JZ NOPDRV ; No prompt if echo off
  316. INVOKE SINGLETEST
  317. JB NOPDRV
  318. TEST [FORFLAG],-1 ; G Don't print prompt in FOR
  319. JNZ NOPDRV ; G
  320. TEST [BATCH], -1 ; G Don't print prompt if in batch
  321. JNZ TESTFORBAT ; G
  322. ; INVOKE PRINT_PROMPT ; Prompt the user
  323. NOPDRV:
  324. TEST [FORFLAG],-1 ; FOR has next highest precedence
  325. JZ TESTFORbat
  326. JMP FORPROC ; Continue the FOR
  327. TESTFORBAT:
  328. MOV [RE_INSTR],0 ; Turn redirection back off
  329. MOV [RE_OUTSTR],0
  330. MOV [RE_OUT_APP],0
  331. MOV IFFlag,0 ; no more ifs...
  332. TEST [BATCH],-1 ; Batch has lowest precedence
  333. JZ ISNOBAT
  334. ; Bugbug: MULT_SHELL_GET no longer used?
  335. push es ;AN000; save ES
  336. push ds ;AN000; save DS
  337. mov ax,mult_shell_get ;AN000; check to see if SHELL has command
  338. mov es,[batch] ;AN000; get batch segment
  339. mov di,batfile ;AN000; get batch file name
  340. push cs ;AN000; get local segment to DS
  341. pop ds ;AN000;
  342. mov dx,offset trangroup:combuf ;AN000; pass communications buffer
  343. int 2fh ;AN000; call the shell
  344. cmp al,shell_action ;AN000; does shell have a commmand?
  345. pop ds ;AN000; restore DS
  346. pop es ;AN000; restore ES
  347. jz jdocom1 ;AN000; yes - go process command
  348. PUSH DS ;G
  349. INVOKE READBAT ; Continue BATCH
  350. POP DS ;G
  351. mov nullflag,0 ;G reset no command flag
  352. TEST [BATCH],-1 ;G
  353. JNZ JDOCOM1 ;G if batch still in progress continue
  354. MOV BX,NEXT_BATCH ;G
  355. CMP BX,0 ;G see if there is a new batch file
  356. JZ JDOCOM1 ;G no - go do command
  357. MOV BATCH,BX ;G get segment of next batch file
  358. MOV NEXT_BATCH,0 ;G reset next batch
  359. JDOCOM1:
  360. PUSH CS ;G
  361. POP DS ;G
  362. JMP DoCom1 ; echoing already done
  363. ISNOBAT:
  364. CMP [SINGLECOM],0
  365. JZ REGCOM
  366. MOV SI,-1
  367. CMP KSWITCHFLAG,0
  368. JE NO_K_SWITCH
  369. INC SI
  370. MOV KSWITCHFLAG,0
  371. NO_K_SWITCH:
  372. XCHG SI,[SINGLECOM]
  373. MOV DI,OFFSET TRANGROUP:COMBUF + 2
  374. XOR CX,CX
  375. SINGLELOOP:
  376. LODSB
  377. STOSB
  378. INC CX
  379. CMP AL,0DH
  380. JNZ SINGLELOOP
  381. DEC CX
  382. PUSH CS
  383. POP DS
  384. ASSUME DS:TRANGROUP
  385. MOV [COMBUF + 1],CL
  386. ;
  387. ; do NOT issue a trailing CRLF...
  388. ;
  389. JMP DOCOM1
  390. ;
  391. ; We have a normal command.
  392. ; Printers are a bizarre quantity. Sometimes they are a stream and
  393. ; sometimes they aren't. At this point, we automatically close all spool
  394. ; files and turn on truncation mode.
  395. ;
  396. REGCOM:
  397. MOV AX,(ServerCall SHL 8) + 9
  398. INT 21h
  399. MOV AX,(ServerCall SHL 8) + 8
  400. MOV DL,1
  401. INT 21h
  402. MOV DS,cs:[RESSEG]
  403. ASSUME DS:RESGROUP
  404. cmp byte ptr [SCS_FIRSTCOM],0
  405. jnz first_inst ;this is the first instance
  406. jmp DoReEnter
  407. DRE_RET:
  408. MOV DS,cs:[RESSEG]
  409. ASSUME DS:RESGROUP
  410. xor ax,ax
  411. jmp short do_again
  412. first_inst:
  413. mov [SCS_PAUSE],0 ; yst 4-5-93
  414. cmp [SCS_Is_First],1
  415. jne cont_scs
  416. mov [SCS_Is_First],0
  417. SAVE <SI,BP>
  418. xor si,si
  419. xor bp,bp
  420. mov al,2
  421. mov ah,setdpb
  422. int 21h ; resets the TSR bit
  423. RESTORE <BP,SI>
  424. xor ax,ax
  425. jmp short do_again
  426. cont_scs:
  427. SAVE <AX,SI,BP>
  428. xor si,si
  429. xor bp,bp
  430. mov al,2
  431. mov ah,setdpb
  432. int 21h ; resets the TSR bit
  433. RESTORE <BP,SI,AX>
  434. jnc cont_scs2
  435. cont_tsr:
  436. jmp tsr_loop
  437. tsr_loop_ret:
  438. jmp short cont_scs1
  439. cont_scs2:
  440. cmp byte ptr [scs_firsttsr],1
  441. je cont_scs1
  442. jmp short cont_tsr
  443. cont_scs1:
  444. ; call free_con
  445. MOV DS,cs:[RESSEG]
  446. ASSUME DS:RESGROUP
  447. mov ax,[retcode]
  448. do_again:
  449. ifdef NEC_98
  450. jmp ClrFky
  451. FKY_OFF DB 1Bh,'[>1h$' ;ESC sequence of FKY off
  452. Clrfky: push ds
  453. push cs
  454. pop ds
  455. push cx
  456. push ax
  457. push dx
  458. mov cl,10H
  459. mov ah,01H
  460. mov dx,offset FKY_OFF
  461. int 0DCH ;FKY off
  462. pop dx
  463. pop ax
  464. pop cx
  465. pop ds
  466. endif ;NEC_98
  467. MOV DS,cs:[RESSEG]
  468. ASSUME DS:RESGROUP
  469. push es
  470. mov es,[envirseg]
  471. mov [ENV_PTR_SEG],es
  472. call GETENVSIZ
  473. pop es
  474. push cs
  475. pop ds
  476. ASSUME DS:TRANGROUP
  477. mov [ENV_SIZE],cx
  478. ;; williamh - Jan 11 1993
  479. ;; nt expects 16bits exit code while DOS has only 8 bits
  480. ;; clear the high byte so that things won't go wrong
  481. xor ah, ah
  482. MOV [SCS_EXIT_CODE],ax
  483. mov ah,19h
  484. int 21h
  485. xor ah,ah
  486. mov [SCS_CUR_DRIVE], ax ; a= 0 , b = 1 etc
  487. mov [CMD_SIZE],COMBUFLEN
  488. MOV DX,OFFSET TRANGROUP:UCOMBUF
  489. if 0
  490. ; Try to read interactive command line via DOSKey.
  491. ; If that fails, use DOS Buffered Keyboard Input.
  492. mov ax,4810h ; AX = DOSKey Read Line function
  493. int 2fh
  494. or ax,ax
  495. jz GotCom ; DOSKey gave us a command line
  496. else
  497. mov [CMD_PTR_SEG],ds
  498. mov [CMD_PTR_OFF],dx
  499. mov dx,OFFSET TRANGROUP:EXECPATH
  500. mov [EXECPATH_SEG], ds
  501. mov [EXECPATH_OFF], dx
  502. mov [EXECPATH_SIZE], EXECPATHLEN
  503. push es
  504. mov es,cs:[RESSEG]
  505. ASSUME es:RESGROUP
  506. mov dx,word ptr es:[RES_RDRINFO]
  507. mov word ptr ds:[SCS_RDRINFO],dx
  508. mov dx,word ptr es:[RES_RDRINFO+2]
  509. mov word ptr ds:[SCS_RDRINFO+2],dx
  510. pop es
  511. ASSUME ES:TRANGROUP
  512. MOV DX,OFFSET TRANGROUP:ENV_PTR_SEG
  513. CMDSVC SVC_CMDGETNEXTCMD ; DS:DX is the buffer
  514. jnc run_cmd
  515. ; If carry is set that means our enviornment buffer was smaller. So get
  516. ; a big enough buffer and get the command again.
  517. cmp ax,32*1024 ; Env size cannot be more than 32k.
  518. jae op_fail
  519. push ax ; the new size in bytes for env in bytes
  520. invoke FREE_TPA
  521. pop bx
  522. MOV CL,4
  523. SHR BX,CL ; Convert back to paragraphs
  524. inc bx ; an extra para
  525. push es
  526. push ds
  527. MOV DS,cs:[RESSEG]
  528. ASSUME DS:RESGROUP
  529. mov es,[envirseg]
  530. pop ds
  531. ASSUME DS:TRANGROUP
  532. MOV CX,ES ;AN056; Get environment segment
  533. ADD CX,BX ;AN056; Add in size of environment
  534. ADD CX,020H ;AN056; Add in some TPA
  535. MOV AX,CS ;AN056; Get the transient segment
  536. CMP CX,AX ;AN056; Are we hitting the transient?
  537. JNB blk_xxx ;AN056; Yes - don't do it!!!
  538. push bx
  539. MOV AH,SETBLOCK
  540. INT 21h
  541. pop bx
  542. jnc blk_xxx
  543. mov ah,ALLOC
  544. int 21h
  545. jc blk_xxx
  546. push ax
  547. mov ah,DEALLOC
  548. int 21h
  549. pop ax
  550. push ds
  551. MOV DS,cs:[RESSEG]
  552. ASSUME DS:RESGROUP
  553. mov [envirseg],ax
  554. pop ds
  555. ASSUME DS:TRANGROUP
  556. clc
  557. blk_xxx:
  558. lahf
  559. push ax
  560. MOV ES,cs:[RESSEG]
  561. invoke ALLOC_TPA
  562. pop ax
  563. sahf
  564. JC op_fail1
  565. pop es
  566. xor ax,ax ; error code zero, its important
  567. jmp do_again
  568. op_fail1:
  569. pop es
  570. op_fail:
  571. mov ax,error_not_enough_memory
  572. jmp do_again
  573. run_cmd:
  574. push es
  575. mov es,cs:[RESSEG]
  576. ASSUME es:RESGROUP
  577. mov ax,word ptr ds:[SCS_RDRINFO]
  578. mov word ptr es:[RES_RDRINFO],ax
  579. mov ax,word ptr ds:[SCS_RDRINFO+2]
  580. mov word ptr es:[RES_RDRINFO+2],ax
  581. mov ax,word ptr ds:[SCS_BATSTATUS]
  582. mov byte ptr es:[RES_BATSTATUS],al
  583. pop es
  584. ASSUME ES:TRANGROUP
  585. test [SCS_STD_HANDLE],ALL_HANDLES
  586. jz no_rdr
  587. test [SCS_STD_HANDLE],MASK_STDIN
  588. jz scs_std_out
  589. xor cx,cx ; CX = HANDLE_STDIN
  590. call alloc_con
  591. jnc scs_std_out
  592. rdr_err:
  593. call free_con
  594. mov ax,error_not_enough_memory
  595. jmp do_again
  596. scs_std_out:
  597. ; Make Sure Stdout is checked before stderr. Its very important.
  598. test [SCS_STD_HANDLE],MASK_STDOUT
  599. jz scs_std_err
  600. mov cx,HANDLE_STDOUT
  601. call alloc_con
  602. jc rdr_err
  603. scs_std_err:
  604. test [SCS_STD_HANDLE],MASK_STDERR
  605. jz no_rdr
  606. mov cx,HANDLE_STDERR
  607. call alloc_con
  608. jc rdr_err
  609. no_rdr:
  610. ifdef NEC_98
  611. push ds
  612. push cx
  613. push ax
  614. push dx
  615. CMDSVC SVC_GETCURSORPOS ;gets bios cursor position
  616. ;now dx=offset on TEXT VRAM
  617. mov ax,dx
  618. mov cl,160
  619. div cl
  620. mov dh,al
  621. xor dl,dl
  622. mov cl,10h
  623. mov ah,03h
  624. int 0DCH ;set cursor position for DOS
  625. jmp DspFky
  626. FKY_ON DB 1Bh,'[>1l$' ;ESC sequence of FKY on
  627. Dspfky: push cs
  628. pop ds
  629. mov cl,10H
  630. mov ah,01H
  631. mov dx,offset FKY_ON
  632. int 0DCH ;FKY on
  633. pop dx
  634. pop ax
  635. pop cx
  636. pop ds
  637. endif ;NEC_98
  638. mov ah,GetSetCdPg
  639. mov al,1
  640. int 21h
  641. jc cdpg_done
  642. cmp bx,[SCS_CODEPAGE]
  643. jz cdpg_done
  644. mov ah,NLSFUNC ; see if NLSFUNC installed
  645. mov al,0 ;
  646. int 2fh ;
  647. cmp al,NLSFUNC_installed ;
  648. jnz no_nlsf_msg ; NO NLSFUNC ; Print message
  649. ; jz got_nls ; Yes - continue
  650. ; mov dx,offset trangroup:NLSFUNC_ptr ; no - set up error message
  651. ; jmp short cp_error ; error exit
  652. mov bx,[SCS_CODEPAGE] ;SCS Code page
  653. mov ah,getsetcdpg ;set global code page function
  654. mov al,set_global_cp ;minor - set
  655. int 21h
  656. jnc cdpg_done ;no error - exit
  657. nlsf_failed:
  658. ; BUGBUG Sudeepb 28-Apr-1992 Putup a message saying NLSFunc failed
  659. no_nlsf_msg:
  660. ; BUGBUG Sudeepb 28-Apr-1992 Putup a message saying NLSFunc not installed
  661. cdpg_done:
  662. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  663. ;; ;;
  664. ;; (YST) 08-Jan-1993 Checking and installing 16-bit KEYB.COM ;;
  665. ;; ;;
  666. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  667. jmp YST_beg
  668. ;; Data for KB16
  669. KEY_LINE db 128 dup (0) ; "d:\nt\system32\kb16.com", 0
  670. YST_ARG db 128 dup (0) ; 32, " XX,,d:\nt\system32\keyboard.sys", 0DH
  671. YPAR dw 0
  672. dd 0
  673. dw 005ch, 0
  674. dw 006ch, 0
  675. KEEP_SS dw 0
  676. KEEP_SP dw 0
  677. YST_beg:
  678. SAVE <BX, ES, DS> ; save all regs for INT 2FH
  679. mov ax, CHECK_KEYB16 ; see if KEYB16 installed
  680. int 2fh
  681. xor dx,dx
  682. cmp al, KEYB16_installed
  683. jne keyb_cont ; KEYB16 not installed, DX == 0
  684. inc dx ; installed DX == 1
  685. keyb_cont:
  686. RESTORE <DS, ES, BX>
  687. push ds
  688. push cs
  689. pop ds
  690. mov si, offset KEY_LINE ; name of KB16.COM
  691. mov cx, offset YST_ARG ; command line
  692. CMDSVC SVC_GETKBDLAYOUT ; Call 32-bit API for checking
  693. ; and installing correct layout
  694. or dx,dx ; if DX != 0 after BOP then we need
  695. pop ds ; to install 16-bit KEYB.COM
  696. jnz run_keyb
  697. jmp End_keyb ; No installation of KB16.COM
  698. run_keyb:
  699. ;; This part run KB16.COM
  700. SAVE <DS, BX>
  701. PUSH ES ; free TPA for running KB16
  702. MOV ES,[TRAN_TPA]
  703. MOV AH,DEALLOC
  704. INT 21h ; Now running in "free" space
  705. push cs
  706. pop ds
  707. push cs
  708. pop es
  709. mov dx, offset KEY_LINE ; file name
  710. mov YPAR+0, 0000H ; keep current enviroment
  711. mov YPAR+2, offset YST_ARG ; arguments (options) for KB16.COM
  712. mov YPAR+4, ds
  713. mov bx, offset YPAR
  714. mov KEEP_SS, ss ; Peter Norton suggests to keep
  715. mov KEEP_SP, sp ; SS and SP
  716. mov ah, 4bh
  717. xor al, al
  718. int 21h ; RUN!
  719. mov ss, cs:KEEP_SS ; Restore SS and SP
  720. mov sp, cs:KEEP_SP
  721. POP ES
  722. SAVE <BP> ; We need to restore TSR bit
  723. xor si,si ; for running next app.
  724. xor bp,bp ; use "undocumented" call.
  725. mov al,2
  726. mov ah,setdpb
  727. int 21h ; resets the TSR bit
  728. RESTORE <BP>
  729. ; Allocate transient again after runnig KB16.
  730. ; Copied from TBATCH.ASM
  731. ; Modify AX,BX,DX,flags
  732. ;
  733. ASSUME DS:TRANGROUP,ES:RESGROUP
  734. PUSH ES
  735. MOV ES,cs:[RESSEG]
  736. MOV BX,0FFFFH ; Re-allocate the transient
  737. MOV AH,ALLOC
  738. INT 21h
  739. PUSH BX ; Save size of block
  740. MOV AH,ALLOC
  741. INT 21h
  742. ;
  743. ; Attempt to align TPA on 64K boundary
  744. ;
  745. POP BX ; Restore size of block
  746. MOV [RES_TPA], AX ; Save segment to beginning of block
  747. MOV [TRAN_TPA], AX
  748. ;
  749. ; Is the segment already aligned on a 64K boundary
  750. ;
  751. MOV DX, AX ; Save segment
  752. AND AX, 0FFFH ; Test if above boundary
  753. JNZ Calc_TPA
  754. MOV AX, DX
  755. AND AX, 0F000H ; Test if multiple of 64K
  756. JNZ NOROUND
  757. Calc_TPA:
  758. MOV AX, DX
  759. AND AX, 0F000H
  760. ADD AX, 01000H ; Round up to next 64K boundary
  761. JC NOROUND ; Memory wrap if carry set
  762. ;
  763. ; Make sure that new boundary is within allocated range
  764. ;
  765. MOV DX, [RES_TPA]
  766. ADD DX, BX ; Compute maximum address
  767. CMP DX, AX ; Is 64K address out of range?
  768. JB NOROUND
  769. ;
  770. ; Make sure that we won't overwrite the transient
  771. ;
  772. MOV BX, CS ; CS is beginning of transient
  773. CMP BX, AX
  774. JB NOROUND
  775. ;
  776. ; The area from the 64K boundary to the beginning of the transient must
  777. ; be at least 64K.
  778. ;
  779. SUB BX, AX
  780. CMP BX, 4096 ; Size greater than 64K?
  781. JAE ROUNDDONE
  782. NOROUND:
  783. MOV AX, [RES_TPA]
  784. ROUNDDONE:
  785. MOV [LTPA],AX ; Re-compute everything
  786. MOV [TPA],AX
  787. MOV BX,AX
  788. MOV AX,CS
  789. SUB AX,BX
  790. PUSH BX
  791. MOV BX,16
  792. MUL BX
  793. POP BX
  794. OR DX,DX
  795. JZ SAVSIZ2
  796. MOV AX,-1
  797. SAVSIZ2:
  798. ;
  799. ; AX is the number of bytes free in the buffer between the resident and the
  800. ; transient with a maximum of 64K-1. We round this down to a multiple of 512.
  801. ;
  802. CMP AX,512
  803. JBE GotSize1
  804. AND AX,0FE00h ; NOT 511 = NOT 1FF
  805. GotSize1:
  806. MOV [BYTCNT],AX
  807. POP ES
  808. ; End Alloc_TPA
  809. RESTORE <BX, DS>
  810. CMDSVC SVC_CMDINITCONSOLE ; make sure console is turned on
  811. End_keyb:
  812. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  813. ;; ;;
  814. ;; End of (YST) 08-Jan-1993 Checking and installing 16-bit KEYB.COM ;;
  815. ;; ;;
  816. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  817. mov dx,[SCS_CUR_DRIVE]
  818. mov [curdrv],dl
  819. mov ah,0eh
  820. int 21h
  821. push cs
  822. pop ds
  823. MOV DX,OFFSET TRANGROUP:UCOMBUF
  824. endif
  825. GotCom:
  826. MOV CL,[UCOMBUF]
  827. XOR CH,CH
  828. ADD CX,3
  829. MOV SI,OFFSET TRANGROUP:UCOMBUF
  830. MOV DI,OFFSET TRANGROUP:COMBUF
  831. REP MOVSB ; Transfer it to the cooked buffer
  832. ;---------------
  833. transpace segment
  834. extrn arg:byte ; the arg structure!
  835. transpace ends
  836. ;---------------
  837. DOCOM:
  838. ; INVOKE CRLF2
  839. DOCOM1:
  840. INVOKE PRESCAN ; Cook the input buffer
  841. JZ NOPIPEPROC
  842. JMP PIPEPROCSTRT ; Fire up the pipe
  843. nullcomj:
  844. jmp nullcom
  845. NOPIPEPROC:
  846. invoke parseline
  847. jnc OkParse ; user error? or maybe we goofed?
  848. BadParse:
  849. PUSH CS
  850. POP DS
  851. MOV DX,OFFSET TRANGROUP:BADNAM_ptr
  852. INVOKE std_eprintf
  853. JMP TCOMMAND
  854. OkParse:
  855. test arg.argv[0].argflags, MASK wildcard
  856. jnz BadParse ; ambiguous commands not allowed
  857. cmp arg.argvcnt, 0 ; there WAS a command, wasn't there?
  858. jz nullcomj
  859. cmp arg.argv[0].arglen, 0 ; probably an unnecessary check...
  860. jz nullcomj ; guarantees argv[0] at least x<NULL>
  861. MOV SI,OFFSET TRANGROUP:COMBUF+2
  862. MOV DI,OFFSET TRANGROUP:IDLEN
  863. MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off
  864. INT 21h
  865. mov BX, arg.argv[0].argpointer
  866. cmp WORD PTR [BX], 05c5ch ; leading "\\" means UNC name
  867. je IsUncName
  868. cmp BYTE PTR [BX+1],':' ; was a drive specified?
  869. jne short drvgd ; no, use default of zero...
  870. mov DL, BYTE PTR [BX] ; pick-up drive letter
  871. and DL, NOT 20H ; uppercase it
  872. sub DL, capital_A ; convert it to a drive number, A=0
  873. CMP AL,-1 ; See what PARSE said about our drive letter.
  874. JZ drvbadj2 ; It was invalid.
  875. IsUncName:
  876. mov DI, arg.argv[0].argstartel
  877. cmp BYTE PTR [DI], 0 ; is there actually a command there?
  878. jnz drvgd ; if not, we have: "d:", "d:\", "d:/"
  879. jmp setdrv ; and set drive to new drive spec
  880. drvbadj2:
  881. jmp drvbad
  882. DRVGD:
  883. MOV AL,[DI]
  884. MOV [SPECDRV],AL
  885. MOV AL,' '
  886. MOV CX,9
  887. INC DI
  888. REPNE SCASB ; Count no. of letters in command name
  889. MOV AL,8
  890. SUB AL,CL
  891. MOV [IDLEN],AL ; IDLEN is truly the length
  892. MOV DI,81H
  893. PUSH SI
  894. mov si, OFFSET TRANGROUP:COMBUF+2 ; Skip over all leading delims
  895. invoke scanoff
  896. ;SR;
  897. ; We are going to skip over the first char always. The logic is that the
  898. ;command tail can never start from the first character. The code below is
  899. ;trying to figure out the command tail and copy it to the command line
  900. ;buffer in the PSP. However, if the first character happens to be a switch
  901. ;character and the user given command line is a full 128 bytes, we try to
  902. ;copy 128 bytes to the PSP while it can take only 127 chars. This extra
  903. ;char overwrites the code and leads to a crash on future commands.
  904. ;
  905. inc si
  906. do_skipcom:
  907. lodsb ; move command line pointer over
  908. invoke delim ; pathname -- have to do it ourselves
  909. jz do_skipped ; 'cause parse_file_descriptor is dumb
  910. cmp AL, 0DH ; can't always depend on argv[0].arglen
  911. jz do_skipped ; to be the same length as the user-
  912. cmp AL, [SWITCHAR] ; specified command string
  913. jnz do_skipcom
  914. do_skipped:
  915. dec SI
  916. ; jarbats 11-20-2000
  917. ; failing to decrease SI results in missing leading space for command tail
  918. ; which upsets many old dos apps which assume there is a space at the beginning and start at the second char
  919. ;do_skipped1:
  920. XOR CX,CX
  921. COMTAIL:
  922. LODSB
  923. STOSB ; Move command tail to 80H
  924. CMP AL,13
  925. LOOPNZ COMTAIL
  926. DEC DI
  927. MOV BP,DI
  928. NOT CL
  929. MOV BYTE PTR DS:[80H],CL
  930. POP SI
  931. ;-----
  932. ; Some of these comments are sadly at odds with this brave new code.
  933. ;-----
  934. ; If the command has 0 parameters must check here for
  935. ; any switches that might be present.
  936. ; SI -> first character after the command.
  937. mov DI, arg.argv[0].argsw_word
  938. mov [COMSW], DI ; ah yes, the old addressing mode problem...
  939. mov SI, arg.argv[1 * SIZE argv_ele].argpointer ; s = argv[1];
  940. OR SI,SI ; if (s == NULL)
  941. JNZ DoParse
  942. MOV SI,BP ; s = bp; (buffer end)
  943. DoParse:
  944. MOV DI,FCB
  945. MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
  946. INT 21h
  947. MOV [PARM1],AL ; Save result of parse
  948. mov DI, arg.argv[1*SIZE argv_ele].argsw_word
  949. mov [ARG1S], DI
  950. mov SI, arg.argv[2*SIZE argv_ele].argpointer ; s = argv[2];
  951. OR SI,SI ; if (s == NULL)
  952. JNZ DoParse2
  953. MOV SI,BP ; s = bp; (bufend)1
  954. DoParse2:
  955. MOV DI,FCB+10H
  956. MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
  957. INT 21h ; Parse file name
  958. MOV [PARM2],AL ; Save result
  959. mov DI, arg.argv[2*SIZE argv_ele].argsw_word
  960. mov [ARG2S], DI
  961. mov DI, arg.argv[0].argsw_word
  962. not DI ; ARGTS doesn't include the flags
  963. and DI, arg.argswinfo ; from COMSW...
  964. mov [ARGTS], DI
  965. MOV AL,[IDLEN]
  966. MOV DL,[SPECDRV]
  967. or DL, DL ; if a drive was specified...
  968. jnz externalj1 ; it MUST be external, by this time
  969. dec al ; (I don't know why -- old code did it)
  970. jmp fndcom ; otherwise, check internal com table
  971. externalj1:
  972. jmp external
  973. nullcom:
  974. mov [EXECPATH_SIZE], 0
  975. MOV DS,cs:[RESSEG]
  976. ASSUME DS:RESGROUP
  977. TEST [BATCH], -1 ;G Are we in a batch file?
  978. JZ nosetflag ;G only set flag if in batch
  979. mov nullflag,nullcommand ;G set flag to indicate no command
  980. nosetflag:
  981. CMP [SINGLECOM],-1
  982. JZ EXITJ
  983. JMP GETCOM
  984. EXITJ:
  985. JMP $EXITPREP
  986. IF IBM
  987. include vector.inc
  988. include pdb.inc
  989. include arena.inc
  990. include mshalo.asm
  991. ENDIF
  992. std_invalid macro
  993. mov ax,0ffffh
  994. push ax
  995. push ax
  996. endm
  997. std_valid macro
  998. push bx
  999. push cx
  1000. endm
  1001. CleanForStd macro
  1002. add sp,12
  1003. endm
  1004. DoReEnter:
  1005. ASSUME DS:RESGROUP
  1006. cmp byte ptr [scs_reentered],3
  1007. jne reent_chk
  1008. ; Control comes here after command /z ran a non-dos binary and
  1009. ; we re-entered. We just make scs_reentered as 2 indicating that on next
  1010. ; time we need to return the exit code to 32bit side.
  1011. mov byte ptr [scs_reentered],2
  1012. jmp reent
  1013. reent_chk:
  1014. cmp byte ptr [scs_reentered],2
  1015. jne reent_cont
  1016. jmp retcode32
  1017. reent_cont:
  1018. cmp byte ptr [scs_reentered],0
  1019. je exec_comspec
  1020. jmp reent_ret
  1021. ; Control comes here when we have to exec either command.com or
  1022. ; cmd.exe. This decision depends on scs_cmdprompt. Here we
  1023. ; mark scs_reentered state as 1 indicating on return to handle
  1024. ; exit code.
  1025. exec_comspec:
  1026. mov byte ptr [scs_reentered],1
  1027. cmp byte ptr [scs_cmdprompt],Prompt32
  1028. je do32bitprompt
  1029. mov al,Start16 ; parameter to put prompt
  1030. mov ah,FOR_SHELLOUT
  1031. call Do16BitPrompt ; ds is resseg here on return its transseg
  1032. or al,al ; return al=0 to run 16bit binary al=1 getnextvdmcommand
  1033. jz dos_only
  1034. jmp reent
  1035. dos_only:
  1036. jmp GotCom ; go run through int21/exec
  1037. do32BitPrompt:
  1038. SAVE <bp,bx,si>
  1039. xor bx,bx
  1040. mov si,bx
  1041. mov bp,bx
  1042. mov ax,5303h
  1043. int 21h
  1044. jnc st_stdin
  1045. std_invalid
  1046. jmp short go_stdout
  1047. st_stdin:
  1048. std_valid
  1049. go_stdout:
  1050. mov bx,1
  1051. mov ax,5303h
  1052. int 21h
  1053. jnc st_stdout
  1054. std_invalid
  1055. jmp short go_stderr
  1056. st_stdout:
  1057. std_valid
  1058. go_stderr:
  1059. mov bx,2
  1060. mov ax,5303h
  1061. int 21h
  1062. jnc st_stderr
  1063. std_invalid
  1064. jmp short std_done
  1065. st_stderr:
  1066. std_valid
  1067. std_done:
  1068. mov bp,sp
  1069. push es
  1070. mov es,[envirseg]
  1071. mov ah,19h
  1072. int 21h
  1073. CMDSVC SVC_EXECCOMSPEC32
  1074. pop es
  1075. mov bp,ax
  1076. lahf
  1077. CleanForStd
  1078. sahf
  1079. mov ax,bp
  1080. RESTORE <si,bx,bp>
  1081. jc reent
  1082. jmp reent_exit
  1083. reent_ret:
  1084. ; ds is already set to RESSEG
  1085. cmp byte ptr [scs_cmdprompt],Prompt32
  1086. je retcode32
  1087. mov al,return16
  1088. mov ah,FOR_SHELLOUT
  1089. call Do16BitPrompt ; ds = resseg , on return its transseg
  1090. or al,al ; return al=0 to run 16bit binary al=1 getnextvdmcommand
  1091. jnz reent
  1092. jmp dos_only
  1093. retcode32:
  1094. mov dx,ds:[retcode]
  1095. mov ah,19h
  1096. int 21h ; al = cur drive
  1097. mov cx,word ptr ds:[RES_RDRINFO]
  1098. mov bx,word ptr ds:[RES_RDRINFO+2] ; bx:cx - rdrinfo
  1099. CMDSVC SVC_RETURNEXITCODE
  1100. mov ds:[retcode],0
  1101. jnc reent_exit
  1102. reent:
  1103. push cs
  1104. pop ds
  1105. assume ds:trangroup
  1106. mov [scs_tsrexit],0
  1107. jmp DRE_RET
  1108. reent_exit:
  1109. ASSUME DS:RESGROUP
  1110. push ax
  1111. mov ax,(multdos shl 8 or message_2f);AN060; reset parse message pointers
  1112. mov dl,set_critical_msg ;AN000; set up critical error message address
  1113. mov di,crit_msg_off ;AN000; old offset of critical messages
  1114. mov es,crit_msg_seg ;AN000; old segment of critical messages
  1115. int 2fh ;AN000; go set it
  1116. push cs
  1117. pop ds
  1118. assume ds:trangroup ;AN000;
  1119. ; Restore user directory if the restore flag is set. RestUDir1 checks for
  1120. ; this, restores user dir if flag is set and resets the flag.
  1121. invoke RestUDir1 ;restore user dir if needed ;M040
  1122. MOV ES,cs:[RESSEG]
  1123. assume es:resgroup
  1124. MOV AX,[PARENT]
  1125. MOV WORD PTR ES:[PDB_Parent_PID],AX
  1126. MOV AX,WORD PTR OldTerm
  1127. MOV WORD PTR ES:[PDB_Exit],AX
  1128. MOV AX,WORD PTR OldTerm+2
  1129. MOV WORD PTR ES:[PDB_Exit+2],AX
  1130. PUSH ES
  1131. MOV ES,[TRAN_TPA]
  1132. MOV AH,DEALLOC
  1133. INT 21h ; Now running in "free" space
  1134. POP ES
  1135. pop ax
  1136. MOV AH,Exit
  1137. INT 21h
  1138. ; Entry al = Start16 means put the command.com prompt, get the command
  1139. ; return16 means return the exit code if needed
  1140. ; ah = FOR_SHELLOUT means came from shellout code (DoReEnter)
  1141. ; ah = FOR_TSR means came from TSR (tsr_loop)
  1142. ;
  1143. ; Exit al = 0 means run 16bit binary
  1144. ; al = 1 means do getnextvdmcommand
  1145. ; if came with FOR_TSR, then additionaly
  1146. ; ah = 1 means returning on exit command
  1147. ; ah = 0 means otherwise
  1148. Do16BitPrompt:
  1149. push es
  1150. push ax
  1151. mov es,cs:[RESSEG] ; es is resident group
  1152. ASSUME ES:resgroup
  1153. PUSH CS
  1154. POP DS ; Need local segment to point to buffer
  1155. assume ds:trangroup
  1156. cmp al,Start16
  1157. ifdef DBCS
  1158. je @F
  1159. jmp d16_ret
  1160. @@:
  1161. else ; !DBCS
  1162. jne d16_ret
  1163. endif ; !DBCS
  1164. d16_loop:
  1165. ifdef DBCS
  1166. ;;; williamh Sept 24 1993, removed it. Not necessary to show two line feed
  1167. ;;; for every command.
  1168. ;;; yasuho 12/9/93 It is necessary. for example, if previous command
  1169. ;;; didn't follow CR+LF before terminate, prompt will show on the strange
  1170. ;;; position.
  1171. endif ; DBCS
  1172. INVOKE CRLF2
  1173. INVOKE PRINT_PROMPT ; put the prompt
  1174. ifdef DBCS ;; this should go to US build also
  1175. ;; reset the title
  1176. xor al, al
  1177. CMDSVC SVC_SETWINTITLE
  1178. endif ; DBCS
  1179. MOV DX,OFFSET TRANGROUP:UCOMBUF
  1180. mov ah,STD_CON_STRING_INPUT ; AH = Buffered Keyboard Input
  1181. int 21h ; call DOS
  1182. ifdef DBCS_NT31J
  1183. ;; special case for CR was added the original source.
  1184. ;; this code doesn't need. 04/07/94 (hiroh)
  1185. ;; #3920: CR+LFs are needed when using 32bit command
  1186. ;; 12/9/93 yasuho
  1187. ;; not necessary CR+LF if nothing to do
  1188. push bx
  1189. mov bx, dx
  1190. cmp byte ptr [bx + 1], 0 ; only CR ?
  1191. pop bx
  1192. je @F ; yes. no neccessary CRLF
  1193. INVOKE CRLF2
  1194. @@:
  1195. endif ; DBCS_NT31J
  1196. push si
  1197. mov si,dx
  1198. inc si
  1199. inc si
  1200. INVOKE SCANOFF ; eat leading delimeters
  1201. cmp byte ptr ds:[si],0dh ; special case CR
  1202. jne d16_gotcom
  1203. pop si
  1204. jmp d16_loop
  1205. d16_gotcom:
  1206. ifdef DBCS ;; this should go to US build also
  1207. ;; update the new command to the title
  1208. mov al, 1
  1209. CMDSVC SVC_SETWINTITLE
  1210. endif ; DBCS
  1211. INVOKE CRLF2
  1212. call check_command ; check for exit and cd
  1213. pop si
  1214. jnc d16_run
  1215. or al,al
  1216. ifdef DBCS
  1217. jnz @F
  1218. jmp d16_exit
  1219. @@:
  1220. else ; !DBCS
  1221. jz d16_exit
  1222. endif ; !DBCS
  1223. d16_dosonly:
  1224. mov byte ptr es:[scs_prompt16],0
  1225. pop ax
  1226. xor ax,ax ; go run the command
  1227. pop es
  1228. ret
  1229. d16_run:
  1230. cmp byte ptr es:[scs_dosonly], DOSONLY_YES
  1231. je d16_dosonly
  1232. push es
  1233. push bp
  1234. push si
  1235. mov ax,0ffffh
  1236. push ax ; no standard handle to pass
  1237. push ax
  1238. push ax
  1239. push ax
  1240. push ax
  1241. push ax
  1242. mov bp,sp ; ss:bp is standard handles
  1243. mov es,es:[envirseg]
  1244. mov si,dx
  1245. add si,2 ; first two bytes are the count, after that real command
  1246. mov ah,19h
  1247. int 21h ; al = cur drive
  1248. ifdef NEC_98
  1249. jmp Clrfky2
  1250. FKY_OFF2 DB 1Bh,'[>1h$' ;ESC sequence of FKY off
  1251. Clrfky2: push ds
  1252. push cs
  1253. pop ds
  1254. push cx
  1255. push ax
  1256. push dx
  1257. mov cl,10H
  1258. mov ah,01H
  1259. mov dx,offset FKY_OFF2
  1260. int 0DCH ;FKY off
  1261. pop dx
  1262. pop ax
  1263. pop cx
  1264. pop ds
  1265. endif ;NEC_98
  1266. mov ah,1 ; do cmd /c
  1267. CMDSVC SVC_CMDEXEC ; Exec through cmd
  1268. ifdef NEC_98
  1269. pushf
  1270. push ds
  1271. push cx
  1272. push ax
  1273. push dx
  1274. CMDSVC SVC_GETCURSORPOS ;gets bios cursor position
  1275. ;now dx=offset on TEXT VRAM
  1276. mov ax,dx
  1277. mov cl,160
  1278. div cl
  1279. mov dh,al
  1280. xor dl,dl
  1281. mov cl,10h
  1282. mov ah,03h
  1283. int 0DCH ;set cursor position for DOS
  1284. jmp Dspfky2
  1285. FKY_ON2 DB 1Bh,'[>1l$' ;ESC sequence of FKY on
  1286. Dspfky2: push cs
  1287. pop ds
  1288. mov cl,10H
  1289. mov ah,01H
  1290. mov dx,offset FKY_ON2
  1291. int 0DCH ;FKY on
  1292. pop dx
  1293. pop ax
  1294. pop cx
  1295. pop ds
  1296. popf
  1297. endif ;NEC_98
  1298. lahf
  1299. add sp,12 ; recover std handle space
  1300. pop si
  1301. pop bp
  1302. pop es
  1303. sahf
  1304. ifndef NEC_98
  1305. jnc d16_loop ; command completed, go put the prompt
  1306. else ;NEC_98
  1307. jc @F
  1308. jmp d16_loop
  1309. @@:
  1310. endif ;NEC_98
  1311. ; carry set means re-entered
  1312. d16_retback:
  1313. mov byte ptr es:[scs_prompt16],1 ; mark that on return we have
  1314. ; to go to 32bit with retcode
  1315. pop ax
  1316. mov ax,1 ; go do getnextvdmcommand
  1317. pop es
  1318. ret
  1319. d16_ret:
  1320. cmp byte ptr es:[scs_prompt16],0 ; mark 0 to mean to come back
  1321. ; and put prompt fro next command
  1322. ifdef DBCS
  1323. jne @F
  1324. jmp d16_loop
  1325. @@:
  1326. else ; !DBCS
  1327. je d16_loop
  1328. endif ; !DBCS
  1329. d16_return32:
  1330. push dx
  1331. mov dx,es:[retcode]
  1332. mov ah,19h
  1333. int 21h ; al = cur drive
  1334. mov cx,word ptr es:[RES_RDRINFO]
  1335. mov bx,word ptr es:[RES_RDRINFO+2] ; bx:cx - rdrinfo
  1336. CMDSVC SVC_RETURNEXITCODE
  1337. pop dx
  1338. mov es:[retcode],0
  1339. jc d16_retback
  1340. mov byte ptr es:[scs_prompt16],0
  1341. jmp d16_loop
  1342. d16_exit:
  1343. ; exit command was given, turn off the lights
  1344. pop ax
  1345. cmp ah,FOR_TSR
  1346. je d16_exittsr
  1347. jmp reent_exit
  1348. d16_exittsr:
  1349. mov ah,1
  1350. pop es
  1351. ret
  1352. ; check if the typed command is one of the commands in NT_INTRL_CMND, if
  1353. ; so return carry set plus al = 0 if the command was "exit".
  1354. ;
  1355. ; input ds:si is the command buffer
  1356. ; si can be trashed.
  1357. check_command:
  1358. SAVE <CX,DI,ES>
  1359. cmp byte ptr ds:[si+1],':' ; special case drive change i.e C:
  1360. jne cc_0
  1361. mov al,byte ptr ds:[si+2]
  1362. cmp al,0dh ; DELIM for some reason does'nt
  1363. je ok_delim ; include 0d
  1364. invoke DELIM
  1365. jnz no_match
  1366. ok_delim:
  1367. mov al,1 ; Not exit command
  1368. ok_xt:
  1369. stc ; Carry means command found
  1370. jmp short cc_ret
  1371. no_match:
  1372. clc ; Carry clear, command not found
  1373. cc_ret:
  1374. RESTORE <ES,DI,CX>
  1375. ret
  1376. cc_0:
  1377. push si
  1378. xor cx,cx
  1379. ; Convert the source string to upper case and get the length
  1380. cc_1:
  1381. mov al,byte ptr ds:[si]
  1382. invoke DELIM
  1383. jz go_look
  1384. invoke MOREDELIM
  1385. jz go_look
  1386. INVOKE UPCONV
  1387. mov byte ptr ds:[si],al
  1388. inc si
  1389. inc cx
  1390. jmp short cc_1
  1391. go_look:
  1392. pop si
  1393. jcxz no_match ; zero length, go fail
  1394. mov di, OFFSET TRANGROUP:NT_INTRNL_CMND
  1395. push cs
  1396. pop es
  1397. ; search through the commands in the table
  1398. cc_5:
  1399. push si
  1400. push di
  1401. push cx
  1402. cmp cl, byte ptr es:[di]
  1403. jne try_next
  1404. inc di
  1405. repz cmpsb
  1406. jnz try_next
  1407. jmp short cc_found
  1408. try_next:
  1409. pop cx
  1410. pop di
  1411. pop si
  1412. mov al,byte ptr es:[di]
  1413. or al,al
  1414. jz no_match
  1415. xor ah,ah
  1416. add ax,di
  1417. mov di,ax
  1418. add di,2
  1419. jmp short cc_5
  1420. cc_found:
  1421. mov al, byte ptr es:[di] ; Is it exit command
  1422. pop cx
  1423. pop di
  1424. pop si
  1425. jmp short ok_xt
  1426. ;
  1427. ; Input: AL is character to classify
  1428. ; Output: Z set if delimiter
  1429. ; NZ set otherwise
  1430. ; Registers modified: none
  1431. ;
  1432. MOREDELIM:
  1433. cmp al,0dh
  1434. retz
  1435. cmp al,'/'
  1436. retz
  1437. cmp al,'\'
  1438. retz
  1439. cmp al,'.'
  1440. retz
  1441. cmp al,'<'
  1442. retz
  1443. cmp al,'>'
  1444. retz
  1445. cmp al,'|'
  1446. retz
  1447. cmp al,'"'
  1448. retz
  1449. cmp al,'+'
  1450. retz
  1451. cmp al,':'
  1452. retz
  1453. cmp al,';'
  1454. retz
  1455. cmp al,'['
  1456. retz
  1457. cmp al,']'
  1458. return
  1459. free_con:
  1460. push ds
  1461. MOV DS,cs:[RESSEG]
  1462. ASSUME DS:RESGROUP
  1463. xor bx,bx ; BX = handle = 0
  1464. mov cx,Io_Save ; CX = original stdin, stdout
  1465. mov dx,word ptr ds:Pdb_Jfn_Table ; DX = current stdin, stdout
  1466. cmp cl,dl
  1467. je Chk1 ; stdin matches
  1468. mov ah,CLOSE
  1469. int 21h ; close stdin
  1470. mov ds:Pdb_Jfn_Table,cl ; restore stdin
  1471. Chk1:
  1472. inc bx ; BX = handle = 1
  1473. cmp ch,dh
  1474. je Chk2 ; stdout matches
  1475. mov ah,CLOSE
  1476. int 21h ; close stdout
  1477. mov ds:Pdb_Jfn_Table+1,ch ; restore stdout
  1478. Chk2:
  1479. inc bx ; BX = handle = 2
  1480. mov dl,byte ptr ds:[Pdb_Jfn_Table+2] ; Dl = current stderr
  1481. mov cl,Io_Stderr ; Cl = original stderr
  1482. cmp dl,cl
  1483. je chk_x ; stderr matches
  1484. mov ah,CLOSE
  1485. int 21h ; close stderr
  1486. mov ds:Pdb_Jfn_Table+2,cl ; restore stderr
  1487. chk_x:
  1488. pop ds
  1489. ret
  1490. alloc_con:
  1491. SAVE <DX,SI,BP,BX,DS>
  1492. MOV DS,cs:[RESSEG]
  1493. ASSUME DS:RESGROUP
  1494. push cx
  1495. pop ax
  1496. mov bx, offset Pdb_Jfn_Table
  1497. add bx,ax
  1498. mov al,byte ptr ds:[bx]
  1499. push ax
  1500. push bx
  1501. mov byte ptr ds:[bx],0ffh
  1502. mov bx,word ptr ds:[RES_RDRINFO]
  1503. mov ax,word ptr ds:[RES_RDRINFO+2]
  1504. CMDSVC SVC_GETSTDHANDLE ; std hanlde in bx:cx
  1505. jc alloc_err
  1506. ;; bx:cx = nt file handle
  1507. ;; dx:ax = file size
  1508. push di
  1509. mov di, ax
  1510. xor si,si
  1511. xor bp,bp
  1512. mov al,0 ; free original console
  1513. mov ah,setdpb
  1514. int 21h
  1515. pop di
  1516. jc alloc_err
  1517. pop bx
  1518. pop ax
  1519. RESTORE <DS,BX,BP,SI,DX>
  1520. ret
  1521. alloc_err:
  1522. pop bx
  1523. pop ax
  1524. mov byte ptr ds:[bx],al
  1525. RESTORE <DS,BX,BP,SI,DX>
  1526. ret
  1527. ; ds for tsr_loop is resseg on entry on exit transseg
  1528. ASSUME DS:RESGROUP
  1529. tsr_loop:
  1530. cmp byte ptr ds:[scs_cmdprompt],Prompt32
  1531. je tsr_ret
  1532. cmp byte ptr ds:[res_batstatus],0
  1533. je short tsr_nobat
  1534. cmp byte ptr ds:[scs_firsttsr],1
  1535. jne short tsr_retcode
  1536. jmp tsr_ret
  1537. tsr_nobat:
  1538. CMDSVC SVC_GETSTARTINFO ; return al = 1, if vdm has to
  1539. ; terminate on app exit.
  1540. or al,al
  1541. jne tsr_ret
  1542. cmp byte ptr [scs_firsttsr],1
  1543. jne tsr_retcode
  1544. cmp word ptr ds:[RES_RDRINFO],0
  1545. je tsr_nordr
  1546. cmp word ptr ds:[RES_RDRINFO+2],0
  1547. jne tsr_ret
  1548. tsr_nordr:
  1549. mov byte ptr ds:[scs_firsttsr],0
  1550. mov al,Start16 ; parameter to put prompt
  1551. mov ah,FOR_TSR
  1552. call Do16BitPrompt ; ds is resseg here on return its transseg
  1553. or ah,ah
  1554. jnz tsr_exit
  1555. or al,al ; return al=0 to run 16bit binary al=1 getnextvdmcommand
  1556. jz tsr_dosonly
  1557. jmp tsr_ret
  1558. tsr_dosonly:
  1559. jmp GotCom ; go run through int21/exec
  1560. tsr_retcode:
  1561. mov al,return16 ; parameter to retun exit code if needed
  1562. mov ah,FOR_TSR
  1563. call Do16BitPrompt ; ds = resseg , on return its transseg
  1564. or ah,ah
  1565. jnz tsr_exit
  1566. or al,al ; return al=0 to run 16bit binary al=1 getnextvdmcommand
  1567. jnz tsr_ret
  1568. jmp GotCom
  1569. tsr_exit:
  1570. push cs
  1571. pop ds
  1572. assume ds:trangroup
  1573. mov [scs_tsrexit],1
  1574. tsr_ret:
  1575. jmp tsr_loop_ret
  1576. TRANCODE ENDS
  1577. END
  1578.