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.
511 lines
13 KiB
511 lines
13 KiB
page ,132
|
|
; SCCSID = @(#)tmisc2.asm 4.3 85/06/25
|
|
; SCCSID = @(#)tmisc2.asm 4.3 85/06/25
|
|
TITLE Part7 COMMAND Transient Routines
|
|
;/*
|
|
; * Microsoft Confidential
|
|
; * Copyright (C) Microsoft Corporation 1991
|
|
; * All Rights Reserved.
|
|
; */
|
|
|
|
; More misc routines
|
|
|
|
|
|
.xlist
|
|
.xcref
|
|
include comsw.asm
|
|
include dossym.inc
|
|
include syscall.inc
|
|
include pdb.inc
|
|
include bpb.inc
|
|
include sf.inc
|
|
include comseg.asm
|
|
include comequ.asm
|
|
include ioctl.inc
|
|
.list
|
|
.cref
|
|
|
|
|
|
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
|
CodeRes ENDS
|
|
|
|
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
|
EXTRN IFFlag:BYTE
|
|
EXTRN PIPEFLAG:BYTE
|
|
EXTRN RE_OUTSTR:BYTE
|
|
EXTRN RE_OUT_APP:BYTE
|
|
DATARES ENDS
|
|
|
|
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
|
EXTRN AccDen_PTR:WORD
|
|
EXTRN Extend_buf_ptr:word ;AN000;
|
|
EXTRN FULDIR_PTR:WORD
|
|
EXTRN msg_disp_class:byte ;AN000;
|
|
TRANDATA ENDS
|
|
|
|
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
|
EXTRN DESTINFO:BYTE
|
|
EXTRN DESTISDIR:BYTE
|
|
EXTRN KPARSE:BYTE ;AC000;
|
|
EXTRN ONE_CHAR_VAL:BYTE ;AN011;
|
|
EXTRN PATHCNT:WORD
|
|
EXTRN PATHPOS:WORD
|
|
EXTRN PATHSW:WORD
|
|
EXTRN RE_INSTR:BYTE
|
|
EXTRN RESSEG:WORD
|
|
EXTRN SRCBUF:BYTE
|
|
EXTRN SWITCHAR:BYTE
|
|
|
|
IF IBM
|
|
EXTRN ROM_CALL:BYTE
|
|
EXTRN ROM_CS:WORD
|
|
EXTRN ROM_IP:WORD
|
|
ENDIF
|
|
|
|
TRANSPACE ENDS
|
|
|
|
TRANCODE SEGMENT PUBLIC byte
|
|
|
|
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
|
|
|
EXTRN CERROR:NEAR
|
|
|
|
IF IBM
|
|
EXTRN ROM_EXEC:NEAR
|
|
EXTRN ROM_SCAN:NEAR
|
|
ENDIF
|
|
|
|
PUBLIC IOSET
|
|
PUBLIC MOVE_TO_SRCBUF ;AN000;
|
|
PUBLIC PGETARG
|
|
PUBLIC SETPATH
|
|
PUBLIC TESTDOREIN
|
|
PUBLIC TESTDOREOUT
|
|
|
|
|
|
ASSUME DS:TRANGROUP
|
|
|
|
SETPATH:
|
|
;
|
|
; ENTRY PathPos = ptr to string
|
|
; PathCnt = length of string
|
|
;
|
|
; EXIT PathPos = ptr to string after pathname
|
|
; PathCnt = length of rest of string
|
|
; DX = ptr to pathname in string, made ASCIIZ
|
|
; DestIsDir = 1 if pathname delimiters appeared in pathname, 0 otherwise
|
|
; DestInfo = 2 if wildcards (?, *) appeared in pathname, 0 otherwise
|
|
;
|
|
; A null character is dropped at the end of the pathname. If the
|
|
; character in that spot previously was CR, it is copied into the
|
|
; following byte. So there must be at least two two character
|
|
; positions in the buffer following the pathname.
|
|
;
|
|
MOV AX,[PATHCNT] ;AC000; get length of string
|
|
MOV SI,[PATHPOS] ;AC000; get start of source buffer
|
|
|
|
GETPATH:
|
|
MOV [DESTINFO],0
|
|
MOV [DESTISDIR],0
|
|
MOV SI,[PATHPOS] ; SI = ptr to string
|
|
MOV CX,[PATHCNT] ; CX = string length
|
|
MOV DX,SI ; DX = ptr to string
|
|
JCXZ PATHDONE ; string length is zero, we're done
|
|
PUSH CX ; save string length
|
|
PUSH SI ; save ptr to string
|
|
INVOKE SWITCH
|
|
|
|
; After Switch, SI has been scanned past any switches, and
|
|
; switches that COMMAND intrinsically recognizes are recorded in AX.
|
|
|
|
MOV [PATHSW],AX ; PathSw = switch occurrence mask
|
|
POP BX ; BX = ptr to original string
|
|
SUB BX,SI ; BX = -(# chars scanned by Switch)
|
|
POP CX ; CX = string length
|
|
ADD CX,BX ; CX = string length from current SI
|
|
MOV DX,SI ; DX = ptr to current string
|
|
|
|
SKIPPATH:
|
|
|
|
;;;; IFDEF DBCS 3/3/KK
|
|
MOV [KPARSE],0
|
|
|
|
SKIPPATH2:
|
|
;;;; ENDIF 3/3/KK
|
|
|
|
JCXZ PATHDONE ; string length is zero, we're done
|
|
DEC CX ; CX = length left after next char
|
|
LODSB ; AL = next char of string
|
|
; SI = ptr to char after this one
|
|
|
|
;;;; IFDEF DBCS 3/3/KK
|
|
INVOKE TESTKANJ
|
|
JZ TESTPPSEP ; no Kanji, move along
|
|
DEC CX
|
|
INC SI
|
|
INC [KPARSE]
|
|
JMP SKIPPATH2
|
|
|
|
TESTPPSEP:
|
|
;;;; ENDIF 3/3/KK
|
|
|
|
INVOKE PATHCHRCMP ; compare AL to path delimiter char
|
|
JNZ TESTPMETA ; it's not a path delim
|
|
INC [DESTISDIR] ; DestIsDir = 1, signalling path char
|
|
|
|
TESTPMETA:
|
|
CMP AL,'?'
|
|
JNZ TESTPSTAR ; char is not '?'
|
|
OR [DESTINFO],2 ; DestInfo = 2, signalling wildcard
|
|
|
|
TESTPSTAR:
|
|
CMP AL,star
|
|
JNZ TESTPDELIM ; char is not '*'
|
|
OR [DESTINFO],2 ; DestInfo = 2, signalling wildcard
|
|
|
|
TESTPDELIM:
|
|
INVOKE DELIM ; compare AL to all delimiters
|
|
JZ PATHDONEDEC ; delimiter found, back up & leave
|
|
CMP AL,[SWITCHAR]
|
|
JNZ SKIPPATH ; char isn't switch, go get next char
|
|
|
|
PATHDONEDEC:
|
|
DEC SI ; SI = ptr to char after pathname
|
|
|
|
PATHDONE:
|
|
XOR AL,AL ; AL = NULL
|
|
XCHG AL,[SI] ; place NULL after pathname
|
|
INC SI ; SI = ptr to byte after NULL
|
|
CMP AL,0DH ; were we at end of line?
|
|
JNZ NOPSTORE ; not EOL, finish up
|
|
MOV [SI],AL ; save EOL after NULL
|
|
|
|
NOPSTORE:
|
|
MOV [PATHPOS],SI ; PathPos = ptr to char after NULL
|
|
MOV [PATHCNT],CX ; PathCnt = length of string left
|
|
return
|
|
|
|
PGETARG:
|
|
MOV SI,80H
|
|
LODSB
|
|
OR AL,AL
|
|
retz
|
|
CALL PSCANOFF
|
|
CMP AL,13
|
|
return
|
|
|
|
PSCANOFF:
|
|
LODSB
|
|
INVOKE DELIM
|
|
JNZ PSCANOFFD
|
|
CMP AL,';'
|
|
JNZ PSCANOFF ; ';' is not a delimiter
|
|
|
|
PSCANOFFD:
|
|
DEC SI ; Point to first non-delimiter
|
|
return
|
|
|
|
IOSET:
|
|
;
|
|
; ALL REGISTERS PRESERVED
|
|
;
|
|
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
|
|
|
PUSH DS
|
|
PUSH DX
|
|
PUSH AX
|
|
PUSH BX
|
|
PUSH CX
|
|
MOV DS,[RESSEG]
|
|
ASSUME DS:RESGROUP
|
|
|
|
CMP [PIPEFLAG],0
|
|
JNZ NOREDIR ; Don't muck up the pipe
|
|
TEST IFFlag,-1
|
|
JNZ NoRedir
|
|
CALL TESTDOREIN
|
|
CALL TESTDOREOUT
|
|
|
|
NOREDIR:
|
|
POP CX
|
|
POP BX
|
|
POP AX
|
|
POP DX
|
|
POP DS
|
|
ASSUME DS:NOTHING
|
|
return
|
|
|
|
TESTDOREIN:
|
|
|
|
ASSUME DS:RESGROUP
|
|
|
|
CMP [RE_INSTR],0
|
|
retz
|
|
PUSH DS
|
|
PUSH CS
|
|
POP DS
|
|
MOV DX,OFFSET tranGROUP:RE_INSTR
|
|
MOV AX,(OPEN SHL 8)
|
|
MOV BX,AX
|
|
INT 21h
|
|
POP DS
|
|
JC REDIRERR
|
|
MOV BX,AX
|
|
MOV AL,0FFH
|
|
;
|
|
; Mega sleaze!! We move the SFN from the new handle spot into the old stdin
|
|
; spot. We invalidate the new JFN we got.
|
|
;
|
|
XCHG AL,[BX.PDB_JFN_Table]
|
|
MOV DS:[PDB_JFN_Table],AL
|
|
|
|
return
|
|
;
|
|
; We had some kind of error on the redirection. Figure out what the
|
|
; appropriate message should be; BX has the system call that failed
|
|
;
|
|
REDIRERR:
|
|
PUSH CS
|
|
POP DS
|
|
Call TriageError
|
|
;
|
|
; At this point, we have recognized the network-generated access denied error.
|
|
; The correct message is in DX
|
|
;
|
|
CMP AX,65
|
|
JZ CERRORJ ;AC000; just issue message returned
|
|
CMP BH,OPEN
|
|
JZ OpenError
|
|
;
|
|
; The error was for a create operation. Report the error as a creation error.
|
|
;
|
|
MOV DX,OFFSET TranGroup:FULDIR_PTR
|
|
|
|
CERRORJ:
|
|
JMP CERROR
|
|
;
|
|
; The system call was an OPEN. Report either file not found or path not found.
|
|
;
|
|
|
|
OpenError:
|
|
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
|
|
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
|
mov Extend_Buf_ptr,ax ;AN000; get message number in control block
|
|
JMP CERROR
|
|
|
|
TESTDOREOUT:
|
|
|
|
ASSUME DS:RESGROUP
|
|
|
|
CMP [RE_OUTSTR],0
|
|
JNZ REOUTEXISTS ;AN017; need long jump
|
|
JMP NOREOUT ;AN017;
|
|
|
|
REOUTEXISTS:
|
|
CMP [RE_OUT_APP],0
|
|
JZ REOUTCRT
|
|
;
|
|
; The output redirection was for append. We open for write and seek to the
|
|
; end.
|
|
;
|
|
MOV DX,OFFSET RESGROUP:RE_OUTSTR
|
|
MOV AX,(OPEN SHL 8) OR 2 ;AC011; Open for read/write
|
|
PUSH AX
|
|
INT 21h
|
|
POP BX
|
|
JC OpenWriteError
|
|
|
|
MOV BX,AX
|
|
MOV AX,IOCTL SHL 8 ;AN035; Get attributes of handle
|
|
INT 21h ;AN035;
|
|
TEST DL,devid_ISDEV ;AN035; Is it a device?
|
|
JNZ SET_REOUT ;AN035; Yes, don't read from it
|
|
|
|
MOV AX,(LSEEK SHL 8) OR 2
|
|
MOV CX,-1 ;AC011; MOVE TO EOF -1
|
|
MOV DX,CX ;AC011;
|
|
INT 21h
|
|
PUSH CS ;AN011; Get transient seg to DS
|
|
POP DS ;AN011;
|
|
assume DS:Trangroup ;AN011;
|
|
MOV AX,(READ SHL 8) ;AN011; Read one byte from the
|
|
MOV CX,1 ;AN011; file into one_char_val
|
|
MOV DX,OFFSET Trangroup:ONE_CHAR_VAL;AN011;
|
|
INT 21h ;AN011;
|
|
JC OpenWriteError ;AN011; If error, exit
|
|
cmp ax,cx ;AN017; Did we read 1 byte?
|
|
jnz reout_0_length ;AN017; No - file must be 0 length
|
|
|
|
cmp one_char_val,01ah ;AN011; Was char an eof mark?
|
|
mov DS,[resseg] ;AN011; Get resident segment back
|
|
assume DS:Resgroup ;AN011;
|
|
JNZ SET_REOUT ;AN011; No, just continue
|
|
MOV AX,(LSEEK SHL 8) OR 1 ;AN011; EOF mark found
|
|
MOV CX,-1 ;AN011; LSEEK back one byte
|
|
MOV DX,CX ;AN011;
|
|
INT 21h ;AN011;
|
|
JMP SHORT SET_REOUT
|
|
|
|
reout_0_length: ;AN017; We have a 0 length file
|
|
mov DS,[resseg] ;AN017; Get resident segment back
|
|
assume DS:Resgroup ;AN017;
|
|
MOV AX,(LSEEK SHL 8) ;AN017; Move to beginning of file
|
|
XOR CX,CX ;AN017; Offset is 0
|
|
MOV DX,CX ;AN017;
|
|
INT 21h ;AN017;
|
|
JMP SHORT SET_REOUT ;AN017; now finish setting up redirection
|
|
|
|
OpenWriteError:
|
|
CMP AX,error_access_denied
|
|
STC ; preserve error
|
|
JNZ REOUTCRT ;AN017; need long jump
|
|
JMP REDIRERR ;AN017;
|
|
|
|
REOUTCRT:
|
|
MOV DX,OFFSET RESGROUP:RE_OUTSTR
|
|
XOR CX,CX
|
|
MOV AH,CREAT
|
|
PUSH AX
|
|
INT 21h
|
|
POP BX
|
|
JNC NOREDIRERR ;AC011;
|
|
JMP REDIRERR ;AC011;
|
|
|
|
NOREDIRERR: ;AN011;
|
|
MOV BX,AX
|
|
|
|
SET_REOUT:
|
|
;
|
|
; Mega sleaze!! We move the SFN from the new handle spot into the old stdout
|
|
; spot. We invalidate the new JFN we got.
|
|
;
|
|
MOV AL,0FFH
|
|
XCHG AL,[BX.PDB_JFN_Table]
|
|
MOV DS:[PDB_JFN_Table+1],AL
|
|
|
|
NOREOUT:
|
|
return
|
|
|
|
;
|
|
; Compute length of string (including NUL) in DS:SI into CX. Change no other
|
|
; registers
|
|
;
|
|
Procedure DSTRLEN,NEAR
|
|
|
|
SaveReg <AX>
|
|
XOR CX,CX
|
|
CLD
|
|
|
|
DLoop: LODSB
|
|
INC CX
|
|
OR AL,AL
|
|
JNZ DLoop
|
|
SUB SI,CX
|
|
RestoreReg <AX>
|
|
return
|
|
|
|
EndProc DSTRLEN
|
|
|
|
Break <Extended error support>
|
|
|
|
;
|
|
; TriageError will examine the return from a carry-set system call and
|
|
; return the correct error if applicable.
|
|
;
|
|
; Inputs: outputs from a carry-settable system call
|
|
; No system calls may be done in the interrim
|
|
; Outputs: If carry was set on input
|
|
; carry set on output
|
|
; DX contains trangroup offset to printf message
|
|
; else
|
|
; No registers changed
|
|
;
|
|
|
|
Procedure TriageError,NEAR
|
|
|
|
retnc ; no carry => do nothing...
|
|
PUSHF
|
|
SaveReg <BX,CX,SI,DI,BP,ES,DS,AX,DX>
|
|
MOV AH,GetExtendedError
|
|
INT 21h
|
|
RestoreReg <CX,BX> ; restore original AX
|
|
MOV DX,OFFSET TranGroup:AccDen_PTR
|
|
CMP AX,65 ; network access denied?
|
|
JZ NoMove ; Yes, return it.
|
|
MOV AX,BX
|
|
MOV DX,CX
|
|
|
|
NoMove:
|
|
RestoreReg <DS,ES,BP,DI,SI,CX,BX>
|
|
popf
|
|
return
|
|
|
|
EndProc TriageError
|
|
|
|
PUBLIC Triage_Init
|
|
Triage_Init proc FAR
|
|
call TriageError
|
|
ret
|
|
Triage_Init endp
|
|
|
|
|
|
; ****************************************************************
|
|
; *
|
|
; * ROUTINE: MOVE_TO_SRCBUF
|
|
; *
|
|
; * FUNCTION: Move ASCIIZ string from DS:SI to SRCBUF. Change
|
|
; * terminating 0 to 0dH. Set PATHCNT to length of
|
|
; * string. Set PATHPOS to start of SRCBUF.
|
|
; *
|
|
; * INPUT: DS:SI points to ASCIIZ string
|
|
; * ES points to TRANGROUP
|
|
; *
|
|
; * OUTPUT: SRCBUF filled in with string terminated by 0dH
|
|
; * PATHCNT set to length of string
|
|
; * PATHPOS set to start of SRCBUF
|
|
; * CX,AX changed
|
|
; *
|
|
; ****************************************************************
|
|
|
|
assume es:trangroup,ds:nothing ;AN000;
|
|
|
|
MOVE_TO_SRCBUF PROC NEAR ;AN000;
|
|
|
|
push si ;AN000; save si,di
|
|
push di ;AN000;
|
|
push cx ;AN000;
|
|
mov di,offset TRANGROUP:srcbuf ;AN000; set ES:DI to srcbuf
|
|
xor cx,cx ;AN000; clear cx for counint
|
|
mov ax,cx ;AN000; clear ax
|
|
push di ;AN000; save start of srcbuf
|
|
lodsb ;AN000; get a character from DS:SI
|
|
|
|
mts_get_chars: ;AN000;
|
|
cmp al,0 ;AN000; was it a null char?
|
|
jz mts_end_string ;AN000; yes - exit
|
|
stosb ;AN000; no - store it in srcbuf
|
|
inc cx ;AN000; increment length count
|
|
lodsb ;AN000; get a character from DS:SI
|
|
jmp short mts_get_chars ;AN000; go check it
|
|
|
|
mts_end_string: ;AN000; we've reached the end of line
|
|
mov al,end_of_line_in ;AN000; store 0dH in srcbuf
|
|
stosb ;AN000;
|
|
pop di ;AN000; restore start of srcbuf
|
|
|
|
push cs ;AN000; set DS to local segment
|
|
pop ds ;AN000;
|
|
assume ds:trangroup ;AN000;
|
|
mov [pathcnt],cx ;AN000; set patchcnt to length count
|
|
mov [pathpos],di ;AN000; set pathpos to start of srcbuf
|
|
pop cx ;AN000; restore cx,di,si
|
|
pop di ;AN000;
|
|
pop si ;AN000;
|
|
|
|
RET ;AN000; exit
|
|
|
|
MOVE_TO_SRCBUF ENDP ;AN000;
|
|
|
|
TRANCODE ENDS
|
|
END
|
|
|