📄 macro2.asm
字号:
CMP AL,AH
JNZ CopyBad
CALL PathSep
JNZ CopyBad ; || !pathsep (*s))
NulTerm: ; return -1;
XOR AL,AL ; *d++ = 0;
STOSB
MOV CopySoff,SI
JMP SHORT GoodRet ; }
NormalComp: ; else {
MOV SI,CopySoff
Invoke NameTrans ; s = NameTrans (s, Name1);
CMP SI,CopySOff ; if (s == CopySOff)
JZ CopyBad ; return (-1);
TEST fSharing,-1 ; if (!fSharing) {;smr;SS Override
JNZ DoPack
AND DL,1 ; cMeta += fMeta;
ADD cMeta,DL ; if (cMeta > 0);smr;SS Override
JG CopyBad ; return (-1);
JNZ DoPack ; else
OR DL,DL ; if (cMeta == 0 && fMeta == 0)
JZ CopyBadPath ; return (-1);
DoPack: ; }
MOV CopySoff,SI
Context DS
MOV SI,OFFSET DOSDATA:NAME1
LEA DI,CopyTemp
SAVE <DI>
Invoke PackName ; PackName (Name1, temp);
RESTORE <DI>
Invoke StrLen ; if (strlen(temp)+d > bp)
DEC CX
ADD CX,CopyDoff
CMP CX,CopyBP
JAE CopyBad ; return (-1);
MOV SI,DI ; strcpy (d, temp);
LES DI,CopyD
Invoke FStrCpy
GoodRet: ; }
CLC
JMP SHORT CopyEnd ; return 0;
CopyBad:
STC
CALL ScanPathChar ; check for path chars in rest of string
MOV AL,error_file_not_found ; Set up for bad file error
JNZ CopyEnd
CopyBadPath:
STC
MOV AL,error_path_not_found ; Set bad path error
CopyEnd:
RESTORE <BP,DI,ES,SI,DS>
LAHF
ADD SP,14 ; reclaim temp buffer
Invoke Strlen
DEC CX
SAHF
return
EndProc CopyComponent,NoCheck
Break <Splice - pseudo mount by string substitution>
;
; Splice - take a string and substitute a prefix if one exists. Change
; ThisCDS to point to physical drive CDS.
; Inputs: DS:SI point to string
; NoSetDir = TRUE => exact matches with splice fail
; Outputs: DS:SI points to thisCDS
; ES:DI points to DPB
; String at DS:SI may be reduced in length by removing prefix
; and substituting drive letter.
; CX = 0 If no splice done
; CX <> 0 otherwise
; ThisCDS points to proper CDS if spliced, otherwise it is
; left alone
; ThisDPB points to proper DPB
; Registers modified: DS:SI, ES:DI, BX,AX,CX
Procedure Splice,NEAR
ASSUME CS:DOSCODE,SS:DOSDATA
TEST Splices,-1 ;smr;SS Override
JZ AllDone
SAVE <<WORD PTR ThisCDS>,<WORD PTR ThisCDS+2>> ; TmpCDS = ThisCDS;smr;SS Override
SAVE <DS,SI>
RESTORE <DI,ES>
XOR AX,AX ; for (i=1; s = GetCDSFromDrv (i); i++)
SpliceScan:
invoke GetCDSFromDrv
JC SpliceDone
INC AL
TEST [SI.curdir_flags],curdir_splice
JZ SpliceScan ; if ( Spliced (i) ) {
SAVE <DI>
CALL PathPref ; if (!PathPref (s, d))
JZ SpliceFound ;
SpliceSkip:
RESTORE <DI>
JMP SpliceScan ; continue;
SpliceFound:
CMP BYTE PTR ES:[DI],0 ; if (*s || NoSetDir) {
JNZ SpliceDo
TEST NoSetDir,-1 ;smr;SS Override
JNZ SpliceSkip
SpliceDo:
MOV SI,DI ; p = src + strlen (p);
SAVE <ES>
RESTORE <DS,DI>
CALL TextFromDrive1 ; src = TextFromDrive1(src,i);
MOV AX,Curr_Dir_End ;smr;SS Override
OR AX,AX
JS NoPoke
ADD AX,DI ; curdirend += src-p;
SUB AX,SI
MOV Curr_Dir_End,AX ;smr;SS Override
NoPoke:
CMP BYTE PTR [SI],0 ; if (*p)
JNZ SpliceCopy ; *src++ = '\\';
MOV AL,"\"
STOSB
SpliceCopy: ; strcpy (src, p);
invoke FStrCpy
ADD SP,4 ; throw away saved stuff
OR CL,1 ; signal splice done.
JMP SHORT DoSet ; return;
SpliceDone: ; }
ASSUME DS:NOTHING ; ThisCDS = TmpCDS;
RESTORE <<WORD PTR ThisCDS+2>,<WORD PTR ThisCDS>> ;smr;SS Override
AllDone:
XOR CX,CX
DoSet:
LDS SI,ThisCDS ; ThisDPB = ThisCDS->devptr;;smr;SS Override
LES DI,[SI].curdir_devptr
MOV WORD PTR ThisDPB,DI ;smr;SS Override
MOV WORD PTR ThisDPB+2,ES ;smr;SS Override
return
EndProc Splice, NoCheck
Break <$NameTrans - partially process a name>
;
; $NameTrans - allow users to see what names get mapped to. This call
; performs only string substitution and canonicalization, not splicing. Due
; to Transpath playing games with devices, we need to insure that the output
; has drive letter and : in it.
;
; Inputs: DS:SI - source string for translation
; ES:DI - pointer to buffer
; Outputs:
; Carry Clear
; Buffer at ES:DI is filled in with data
; ES:DI point byte after nul byte at end of dest string in buffer
; Carry Set
; AX = error_path_not_found
; Registers modified: all
Procedure $NameTrans,Near
ASSUME CS:DOSCODE,SS:DOSDATA
SAVE <DS,SI,ES,DI,CX>
; M027 - Start
;
; Sattrib must be set up with default values here. Otherwise, the value from
; a previous DOS call is used for attrib and DevName thinks it is not a
; device if the old call set the volume attribute bit. Note that devname in
; dir2.asm gets ultimately called by Transpath. See also M026. Also save
; and restore CX.
;
mov ch,attr_hidden+attr_system+attr_directory
invoke SetAttrib
; M027 - End
MOV DI,OFFSET DOSDATA:OpenBuf
CALL TransPath ; to translation (everything)
RESTORE <CX,DI,ES,SI,DS>
JNC TransOK
transfer SYS_Ret_Err
TransOK:
MOV SI,OFFSET DOSDATA:OpenBuf
Context DS
GotText:
Invoke FStrCpy
Transfer SYS_Ret_OK
EndProc $NameTrans
Break <DriveFromText - return drive number from a text string>
;
; DriveFromText - examine DS:SI and remove a drive letter, advancing the
; pointer.
;
; Inputs: DS:SI point to a text string
; Outputs: AL has drive number
; DS:SI advanced
; Registers modified: AX,SI.
Procedure DriveFromText,NEAR
ASSUME CS:DOSCODE,SS:NOTHING
XOR AL,AL ; drive = 0;
CMP BYTE PTR [SI],0 ; if (*s &&
retz
CMP BYTE PTR [SI+1],':' ; s[1] == ':') {
retnz
IFDEF DBCS ;AN000;
;--------------------- Start of DBCS 2/18/KK
push ax ;AN000;
mov al,[si] ;AN000;
call TestKanj ;AN000;
pop ax ;AN000;
retnz ;AN000;
;--------------------- End of DBCS 2/18/KK
ENDIF ;AN000;
LODSW ; drive = (*s | 020) - 'a'+1;
OR AL,020h
SUB AL,'a'-1 ; s += 2;
retnz
MOV AL,-1 ; nuke AL...
return ; }
EndProc DriveFromText
Break <TextFromDrive - convert a drive number to a text string>
;
; TextFromDrive - turn AL into a drive letter: and put it at es:di with
; trailing :. TextFromDrive1 takes a 1-based number.
;
; Inputs: AL has 0-based drive number
; Outputs: ES:DI advanced
; Registers modified: AX
Procedure TextFromDrive,NEAR
ASSUME CS:DOSCODE,SS:NOTHING
INC AL
Entry TextFromDrive1
ADD AL,'A'-1 ; *d++ = drive-1+'A';
MOV AH,":" ; strcat (d, ":");
STOSW
return
EndProc TextFromDrive
Break <PathPref - see if one path is a prefix of another>
;
; PathPref - compare DS:SI with ES:DI to see if one is the prefix of the
; other. Remember that only at a pathchar break are we allowed to have a
; prefix: A:\ and A:\FOO
;
; Inputs: DS:SI potential prefix
; ES:DI string
; Outputs: Zero set => prefix found
; DI/SI advanced past matching part
; Zero reset => no prefix, DS/SI garbage
; Registers modified: CX
Procedure PathPref,NEAR
Invoke DStrLen ; get length
DEC CX ; do not include nul byte
IFDEF DBCS ;AN000;
;----------------------- Start of DBCS 2/13/KK
SAVE <AX> ;AN000;; save char register
CmpLp: ;AN000;
MOV AL,[SI] ;AN000;
call TestKanj ;AN000;
jz NotKanj9 ;AN000;
CMPSW ;AN000;
JNZ Prefix ;AN000;
DEC CX ;AN000;
LOOP CmpLp ;AN000;
JMP SHORT NotSep ;AN000;
NotKanj9: ;AN000;
CMPSB ;AN000;
JNZ Prefix ;AN000;
LOOP CmpLp ;AN000;
;----------------------- End of DBCS 2/13/KK
ELSE ;AN000;
REPZ CMPSB ; compare
retnz ; if NZ then return NZ
SAVE <AX> ; save char register
ENDIF ;AN000;
MOV AL,[SI-1] ; get last byte to match
call PathChrCmp ; is it a path char (Root!)
JZ Prefix ; yes, match root (I hope)
NotSep: ; 2/13/KK
MOV AL,ES:[DI] ; get next char to match
CALL PathSepGotCh ; was it a pathchar?
Prefix:
RESTORE <AX> ; get back original
return
EndProc PathPref
Break <ScanPathChar - see if there is a path character in a string>
;
; ScanPathChar - search through the string (pointed to by DS:SI) for
; a path separator.
;
; Input: DS:SI target string (null terminated)
; Output: Zero set => path separator encountered in string
; Zero clear => null encountered
; Registers modified: SI
Procedure ScanPathChar,NEAR
LODSB ; fetch a character
IFDEF DBCS ;AN000;
call TestKanj ;AN000;; 2/13/KK
jz NotKanjr ;AN000;; 2/13/KK
LODSB ;AN000;; 2/13/KK
OR AL,AL ;AN000;; 2/13/KK 3/31/removed
JNZ ScanPathChar ;AN000;; 2/13/KK 3/31/removed
INC AL ;AN000;; 2/13/KK
return ;AN000;; 2/13/KK
;AN000;
NotKanjr: ;AN000;; 2/13/KK
ENDIF ;AN000;
call PathSepGotCh
JNZ ScanPathChar ; not \, / or NUL => go back for more
call PathChrCmp ; path separator?
return
EndProc ScanPathChar
DOSCODE ends
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -