📄 macro2.asm
字号:
LES DI,ThisCDS ; for fatread
EnterCrit critDisk
Invoke FatRead_CDS
LeaveCrit critDisk
NoPath:
MOV AL,error_path_not_found ; Set up for possible bad path error
return ; any errors are in Carry flag
ASSUME DS:NOTHING
;
; Let the network decide if the name is for a spooled device. It will map
; the name if so.
;
CheckUnc:
MOV WORD PTR ThisCDS,-1 ; NULL thisCDS ;smr;SS Override
CallInstall NetSpoolCheck,multNet,35
JNC UNCDone
;
; At this point the name is either a UNC-style name (prefixed with two leading
; \\s) or is a local file/device. Remember that if a net-spooled device was
; input, then the name has been changed to the remote spooler by the above net
; call. Also, there may be a drive in front of the \\.
;
NO_CHECK:
CALL DriveFromText ; eat drive letter
PUSH AX ; save it
MOV AX,WORD PTR [SI] ; get first two bytes of path
call PathChrCmp ; convert to normal form
XCHG AH,AL ; swap for second byte
call PathChrCmp ; convert to normal form
JNZ CheckDevice ; not a path char
CMP AH,AL ; are they same?
JNZ CheckDevice ; nope
;
; We have a UNC request. We must copy the string up to the beginning of the
; local machine root path
;
POP AX
MOVSW ; get the lead \\
UNCCpy: LODSB ; get a byte
IFDEF DBCS ;AN000;
;----------------------------- Start of DBCS 2/23/KK
call TestKanj ;AN000;
jz notkanj1 ;AN000;
STOSB ;AN000;
LODSB ;AN000;
OR AL,AL ;AN000;
JZ UNCTerm ;AN000;; Ignore half kanji error for now
STOSB ;AN000;
jmp UNCCpy ;AN000;
notkanj1: ;AN000;
;----------------------------- End of DBCS 2/23/KK
ENDIF ;AN000;
invoke UCase ;AN000;; convert the char
OR AL,AL
JZ UNCTerm ; end of string. All done.
call PathChrCmp ; is it a path char?
MOV BX,DI ; backup position
STOSB
JNZ UNCCpy ; no, go copy
CALL Canonicalize ; wham (and set cMeta)
UNCDone:
Context DS
IFDEF DBCS
;----------------------------- Start of DBCS 2/23/KK
retc ;AN000; Return if error from Canonicalize
; Although Cononicalize has done lots of good things for us it may also have
; done e5 to 05 conversion on the fisrt char following a path sep char which is
; not wanted on a UNC request as this should be left for the remote station.
; The simplest thing to do is check for such conversions and convert them back
; again.
; This check loop is also called from the DoFile section of TransPath if the
; file is a remote file. Entry point when called is TP_check05 with the
; inputs/outputs as follows;
; Inputs : ES:DI = Buffer to check for re-conversion
; Outputs: None
; Used : DI,AX
MOV DI,WFP_start ;AN000;; ES:DI points to converted string;smr;SS Override
TP_check05: ;AN000;
MOV AL,BYTE PTR ES:[DI] ;AN000;; Get character from path
OR AL,AL ;AN000;; End of null terminated path?
JZ TP_end05 ;AN000;; Finished, CF =0 from OR (ret success)
call TestKanj ;AN000;; Kanji lead character?
JZ TP_notK ;AN000;; Check for path seperator if not
INC DI ;AN000;; Bypass Kanji second byte
JMP TP_nxt05 ;AN000;; Go to check next character
TP_notK: ;AN000;
call PathChrCmp ;AN000;; Is it a path seperator char?
JNZ TP_nxt05 ;AN000;; Check next character if not
CMP BYTE PTR ES:[DI+1],05 ;AN000;; 05 following path sep char?
JNZ TP_nxt05 ;AN000;; Check next character if not
MOV BYTE PTR ES:[DI+1],0E5h ;AN000;; Convert 05 back to E5
TP_nxt05: ;AN000;
INC DI ;AN000;; Point to next char in path
JMP TP_check05 ;AN000;; Test all chars in path
TP_end05:
;----------------------------- End of DBCS 2/23/KK
ENDIF ;AN000;
return ; return error code
ASSUME DS:NOTHING
UNCTerm:
STOSB ;AN000;
JMP UNCDone ;AN000;
CheckDevice:
;
; Check DS:SI for device. First eat any path stuff
;
POP AX ; retrieve drive info
CMP BYTE PTR DS:[SI],0 ; check for null file
JNZ CheckPath
MOV AL,error_file_not_found ; bad file error
STC ; signal error on null input
RETURN ; bye!
CheckPath:
SAVE <AX,BP> ; save drive number
;;;BUGBUG BUG 10-26-1992 scottq
;;;This is a hack for the CDROM extensions (2.1) who scan looking
;;;for the following POP BP == 5Dh (restore <bp,ax>).
;;;The problem is that a direct call to CheckThisDevice can (and did)
;;;end up having a 5D in the opcode's displacement field. The
;;;scanning code would choke on this thinking it was a POP BP instruction.
;;;
;;;What we do here is do a call to a function that is less than 5Dh
;;;bytes away (and assert its not exactly 5D away) that jmps (transfers)
;;;to the correct function. This cannot accidently insert a 5Dh.
;;;
;;;More info:
;;; This particular scan is begun at the UNCdone label for 32 bytes
;;;looking for pop BP, so you cannot put a 5D between here and there.
;;;
call no5Dshere
start5Dhack:
;following is replaced with 5Dhack code--Invoke CheckThisDevice
backfrom5Dhack:
RESTORE <BP,AX> ; get drive letter back
JNC DoFile ; yes we have a file.
;
; We have a device. AX has drive letter. At this point we may fake a CDS ala
; sharing DOS call. We know by getting here that we are NOT in a sharing DOS
; call.
;
MOV fSharing,-1 ; simulate sharing dos call;smr;SS Override
invoke GetThisDrv ; set ThisCDS and init DUMMYCDS
MOV fSharing,0 ; ;smr;SS Override
;
; Now that we have noted that we have a device, we put it into a form that
; getpath can understand. Normally getpath requires d:\ to begin the input
; string. We relax this to state that if the d:\ is present then the path
; may be a file. If D:/ (note the forward slash) is present then we have
; a device.
;
CALL TextFromDrive
MOV AL,'/' ; path sep.
STOSB
invoke StrCpy ; move remainder of string
CLC ; everything OK.
Context DS ; remainder of OK stuff
return
no5Dshere:
Transfer CheckThisDevice ; snoop for device
.erre (no5Dshere - start5Dhack - 5D)
;
; We have a file. Get the raw CDS.
;
DoFile:
ASSUME DS:NOTHING
invoke GetVisDrv ; get proper CDS
MOV AL,error_path_not_found ; Set up for possible bad file error
retc ; CARRY set -> bogus drive/spliced
;
; ThisCDS has correct CDS. DS:SI advanced to point to beginning of path/file.
; Make sure that CDS has valid directory; ValidateCDS requires a temp buffer
; Use the one that we are going to use (ES:DI).
;
SAVE <DS,SI,ES,DI> ; save all string pointers.
invoke ValidateCDS ; poke CDS amd make everything OK
RESTORE <DI,ES,SI,DS> ; get back pointers
MOV AL,error_path_not_found ; Set up for possible bad path error
retc ; someone failed an operation
;
; ThisCDS points to correct CDS. It contains the correct text of the
; current directory. Copy it in.
;
SAVE <DS,SI>
LDS SI,ThisCDS ; point to CDS ;smr;SS Override
MOV BX,DI ; point to destination
ADD BX,[SI].curdir_end ; point to backup limit
; LEA SI,[SI].curdir_text ; point to text
LEA BP,[DI+TEMPLEN] ; regenerate end of buffer
IFDEF DBCS ;AN000;
;------------------------ Start of DBCS 2/13/KK
Kcpylp: ;AN000;
LODSB ;AN000;
call TestKanj ;AN000;
jz Notkanjf ;AN000;
STOSB ;AN000;
MOVSB ;AN000;
CMP BYTE PTR [SI],0 ;AN000;
JNZ Kcpylp ;AN000;
MOV AL, '\' ;AN000;
STOSB ;AN000;
JMP SHORT GetOrig ;AN000;
Notkanjf: ;AN000;
STOSB ;AN000;
OR AL,AL ;AN000;
JNZ Kcpylp ;AN000;
DEC DI ;AN000;; point to NUL byte
;------------------------ End of DBCS 2/13/KK
ELSE ;AN000;
invoke FStrCpy ; copy string. ES:DI point to end
DEC DI ; point to NUL byte
ENDIF ;AN000;
;
; Make sure that there is a path char at end.
;
MOV AL,'\'
CMP ES:[DI-1],AL
JZ GetOrig
STOSB
;
; Now get original string.
;
GetOrig:
DEC DI ; point to path char
RESTORE <SI,DS>
;
; BX points to the end of the root part of the CDS (at where a path char
; should be) . Now, we decide whether we use this root or extend it with the
; current directory. See if the input string begins with a leading \
;
CALL PathSep ; is DS:SI a path sep?
JNZ PathAssure ; no, DI is correct. Assure a path char
OR AL,AL ; end of string?
JZ DoCanon ; yes, skip.
;
; The string does begin with a \. Reset the beginning of the canonicalization
; to this root. Make sure that there is a path char there and advance the
; source string over all leading \'s.
;
MOV DI,BX ; back up to root point.
SkipPath:
LODSB
call PathChrCmp
JZ SkipPath
DEC SI
OR AL,AL
JZ DoCanon
;
; DS:SI start at some file name. ES:DI points at some path char. Drop one in
; for yucks.
;
PathAssure:
MOV AL,'\'
STOSB
;
; ES:DI point to the correct spot for canonicalization to begin.
; BP is the max extent to advance DI
; BX is the backup limit for ..
;
DoCanon:
CALL Canonicalize ; wham.
retc ; badly formatted path.
IFDEF DBCS ;AN000;
;--------------------- Start of DBCS 2/13/KK
; Although Cononicalize has done lots of good things for us it may also have
; done e5 to 05 conversion on the fisrt char following a path sep char which is
; not wanted if this a remote file as this should be left for the remote
; station. Check for a leading \\ in the path buffer and call TP_check05 to
; reconvert if found.
MOV DI,WFP_start ;AN000;; ES:DI points to string;smr;SS Override
MOV AX,WORD PTR ES:[DI] ;AN000;; Get leading 2 chars from path buffer
call PathChrCmp ;AN000;; First char a path char?
JNZ TP_notremote ;AN000;; Not remote if not.
xchg al,ah
call PathChrCmp ;AN000;; Second char a path char?
JNZ TP_notremote ;AN000;; Not remote if not
CALL TP_check05 ;AN000;; Remote so convert 05 back to e5
TP_notremote: ;AN000;
;--------------------- End of DBCS 2/13/KK
ENDIF
;
; The string has been moved to ES:DI. Reset world to DOS context, pointers
; to wfp_start and do string substitution. BP is still the max position in
; buffer.
;
Context DS
MOV DI,wfp_start ; DS:SI point to string
LDS SI,ThisCDS ; point to CDS
ASSUME DS:NOTHING
; LEA SI,[SI].curdir_text ; point to text
CALL PathPref ; is there a prefix?
JNZ DoSplice ; no, do splice
;
; We have a match. Check to see if we ended in a path char.
;
IFDEF DBCS ;AN000;
;---------------------------- Start of DBCS 2/13/KK
PUSH BX ;AN000;
MOV BX,SI ;AN000;
MOV SI,WORD PTR ThisCDS ;AN000;; point to CDS ;smr;SS Override
LOOKDUAL: ;AN000;
MOV AL,BYTE PTR [SI] ;AN000;
call TestKanj ;AN000;
JZ ONEINC ;AN000;
INC SI ;AN000;
INC SI ;AN000;
CMP SI,BX ;AN000;
JB LOOKDUAL ;AN000;
POP BX ;AN000;; Last char was KANJI, don't look back
JMP SHORT Pathline ;AN000;; for path sep, there isn't one.
;AN000;
ONEINC: ;AN000;
INC SI ;AN000;
CMP SI,BX ;AN000;
JB LOOKDUAL ;AN000;
POP BX ;AN000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -