⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filename.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	FILENAME - filename scanning routines
;***
; FILENAME - filename scanning routines
;
;	Copyright <C> 1987, Microsoft Corporation
;
; Contains functions:
;	B$IValidatePath
;	B$GET_PATHNAME
;	B$ADD_EXT
;	B$GET_CUR_DRIVE
;	B$GET_CUR_DIR
;	B$GET_DEV_NUM
;
;******************************************************************************
	INCLUDE switch.inc
	INCLUDE rmacros.inc

	USESEG	CONST
	USESEG	_DATA
	USESEG	_BSS
	USESEG	DK_TEXT

	INCLUDE seg.inc
	INCLUDE baslibma.inc
	INCLUDE devdef.inc
	INCLUDE files.inc
	INCLUDE idmac.inc
	INCLUDE rtps.inc	; constants shared with QBI

;	Device Name Generator

DEVMAC	MACRO	ARG
	DB	'&ARG'
	DB	DN_&ARG
	ENDM


	externFP OpenCheckDrive	

sBegin	CONST
	staticB BAD_CHAR_TBL,<34,"+,:;<=>[]|">	; illegal filename chars
	BAD_CHAR_CNT	EQU ($ - BAD_CHAR_TBL)	; table length (w/o space)
	staticB	,<" ">,1	; reject spaces for B$IValidatePath
sEnd	CONST

sBegin	_DATA
	globalB	szWildDefault,<"*"> ; "*.bas" (MUST be before b$BAS_EXT!!!)
	globalB	b$BAS_EXT,<".BAS",0>	
	globalB	b$EXE_EXT,<".EXE",0>	
	EVEN			; sd's must be word-aligned
	staticW	fakeSD,0,2	; phoney SD for B$IValidatePath QB5 code.
sEnd	_DATA

sBegin	_BSS
	globalW b$PN_NAME,,1	; addr of first char in filename.ext
	staticW	FIRST_SLASH,?,1	; address of first "\" in pathname, for
				; underflow checking
	staticW	b$BadCharCnt,,1	; # of bytes of BAD_CHAR_TBL to use
sEnd	_BSS

	; special flag values
SLASH_SEEN		= FILNAML + 1	; last char was a "\"
SLASHDOT_SEEN		= FILNAML + 2	; last chars were "\."
SLASHDOTDOT_SEEN	= FILNAML + 3	; last chars were "\.."


assumes CS,DK_TEXT
sBegin	DK_TEXT

	externNP B$UPCASE
	externNP B$ERR_BFN
	externNP B$ERR_DNA


DEVICE_NAME_TABLE LABEL BYTE
	DEVNAM
	DB	0


;*** 
;B$IValidatePath -- interpreter filename parser (FAR)
;
;Purpose:
;	Interpreter reachable routine to call B$GET_PATHNAME and B$ADD_EXT.
;	Added with revision [9].
;Entry:
;	pSource  = DGROUP offset of filename to be parsed
;	cbSource = length of filename to be parsed
;	pDestBuf = DGROUP offset of destination buffer for parsed filename
;	pExt	 = DGROUP offset of extension to add (if none present)
;Exit:
;	AX = length of parsed filename (NOT including null terminator)
;Uses:
;	per conv.
;Preserves:
;	per conv.
;Exceptions:
;	Invalid file name, Device unavailable 
;******************************************************************************
cProc	B$IValidatePath,<FAR,PUBLIC>,<ES,SI,DI>
ParmW	pSource 			;offset of filename to be parsed
ParmW	cbSource			;length of filename to be parsed
ParmW	pDestBuf			;offset of dest buffer
ParmW	pExt				;offset of extension to add
cBegin

	PUSH	DS			;ES=DS
	POP	ES
	MOV	AX,[pSource]		; AX = ptr to filename string
	MOV	CX,[cbSource]		; CX = length of filename
	MOV	BX,OFFSET DGROUP:fakeSD	; BX = ptr to filename SD
	MOV	[BX],CX			; set up phony SD
	MOV	[BX+2],AX		
	MOV	DI,[pDestBuf]		;[DI] = ptr to destination buffer
	MOV	b$BadCharCnt,BAD_CHAR_CNT+1 ; reject spaces in filenames
	CALL	B$GET_PATHNAME_CORE	; returns CX=length (includes null)
					; and AL = flags
	MOV	SI,[pExt]		;[SI] = ptr to extension
	CALL	B$ADD_EXT		;add extension if one not already there
	XCHG	AX,CX			;[AX] = length of parsed filename
	DEC	AX			; don't include null byte in count
cEnd
ERBFN3:					
	JMP	ERBFN2			


	SUBTTL	General File Name Parser

;*** 
; B$GET_PATHNAME
;
;Purpose:
;
;	Generates the fully-qualified pathname from a filename.
;	Converts name to upper case, and removes "\..\" and "\.\" from the
;	pathname.  Resulting pathname is null-terminated.  Appends the drive
;	letter and a ":" to the front if it doesn't have one already.
;
;	Names within pathname do not have '*'s expanded to '?'s.  No checks
;	are done for too many slashes or length.  These checks are not
;	necessary, since the DOS calls that take as input this processed
;	pathname should perform those checks.  Both forward and backward
;	slashes are accepted as path characters.
;
;	An error is given if a filename has more than one dot.
;	Filenames without extensions that are longer than 8 characters have
;	a "." inserted after the 8th position. 
;	The extension portion is truncated to 3 chars.
;
;Algorithm:
;
;
;Entry:
;	BX    = pointer to filename string descriptor
;	DI    = address to place processed pathname (DGROUP offset)
;
;Exit:
;	AL = FLAGS -- bits FN_HAS_EXT and FN_WILD set appropriately.
;	CX = length of pathname (including the null byte)
;	Upper case, fully-specified pathname filled in.
;
;Uses:
;	none
;
;Preserves:
;	BX,DX
;
;Exceptions:
;	Invalid file name.
;
;******************************************************************************
labelNP	<PUBLIC,B$GET_PATHNAME>			
	mov	b$BadCharCnt,BAD_CHAR_CNT	; use default # of bad chars

cProc	B$GET_PATHNAME_CORE,<NEAR>,<ES,SI,BX,DX>	

cBegin

	PUSH	DS		; ES=DS
	POP	ES		
	MOV	SI,[BX+2]	; DS:SI = pointer to filename
	MOV	CX,[BX]		; CX = length of filename
				; ES:DI = pointer to destination buffer
	PUSH	DI		; save start of processed pathname
	LEA	BX,[DI+FILNAML] ; BX = address for overflow check

; place the drive letter into pathname

	DEC	CX		; filename length < 2?
	JLE	NO_DRIVE_SPEC	; brif so -- no drive specified
	CMP	BYTE PTR [SI+1],':' ; is next filename char a ":"?
	JNE	NO_DRIVE_SPEC	; brif not -- no drive specified
	LODSW			; get first two chars of filename into AX
	DEC	CX		; adjust count
	CALL	B$UPCASE	; convert drive letter to upper case
	JMP	SHORT GOT_DRIVE	; store specified drive in pathname

NO_DRIVE_SPEC:			; no drive specified at start of filename
	INC	CX		; restore filename length
	CALL	B$GET_CUR_DRIVE ; put current DRIVE_LETTER: into AX

GOT_DRIVE:			; AX contains "DRIVE_LETTER:"
	STOSW			; store "DRIVE_LETTER:" into pathname
	MOV	FIRST_SLASH,DI	; save address for underflow check
	cCall	OpenCheckDrive,<ax>	; put up a message box if we are
					; switching logical drives
					; PRESERVES ALL REGISTERS
	SUB	AX,':' SHL 8 + 'A'-1 ; convert AX to drive number (A=1,B=2,etc)
	XCHG	DX,AX		; DX = drive number (DH = 0)
	JCXZ	USE_CURDIR	; brif end of filename -- use current directory
	MOV	AL,[SI]		; get next char into AL
	CALL	CHK_FOR_SLASH	; slash char?
	JE	PROCESS_NAME	; brif so -- don't use current directory

USE_CURDIR:
	CALL	B$GET_CUR_DIR	; get current directory for the proper drive,
				; and store it into the pathname buffer

	XOR	AL,AL		; search for null byte
	PUSH	CX		; save count
	MOV	CX,-1		; search for up to 64K chars
	REPNE	SCASB		; set DI to position past null byte
	DEC	DI		; [DI] = null byte at end of pathname
	CMP	BYTE PTR [DI-1],'\' ; root directory?
	JE	Not_Root_Dir	; brif so -- don't add a "\"
	MOV	AL,'\'		; place a "\" between the current directory
	STOSB			; and the filename
Not_Root_Dir:			
	POP	CX		; restore count

PROCESS_NAME:
	CALL	SLASH_END	; indicate slash char seen, and set b$PN_NAME.
	JCXZ	CheckDir	; brif end of filename -- just return the
				; current directory for the proper drive

	; Register usage:
	;    DS:SI = pointer to next char in filename
	;    ES:DI = pointer to next char in processed pathname
	;	AL = next char in filename
	;	AH = KANJI Flags
	;		0  => not Double Byte Character
	;		1  => Double Byte Character
	;	BX = pathname buffer end address (for overflow check)
	;	CX = number of remaining chars in filename
	;	DH = flags:
	;		FN_WILD -- name portion of pathname contains a wildcard
	;		FN_HAS_EXT -- name portion of pathname has extension
	;	DL = last char(s) flag:
	;		SLASH_SEEN	-- last char in path is "\"
	;		SLASHDOT_SEEN	-- last chars in path are "\."
	;		SLASHDOTDOT_SEEN - last chars in path are "\.."
	;		otherwise	-- number of chars since last "\"
	; On stack:
	;	pathname buffer address


; Now add specified filename to current drive:path, processing "." and ".."

NAME_LOOP:
			; get next filename char
	LODSB			; AL = next filename character

	CALL	B$UPCASE	; convert to upper case
	STOSB			; store char from filename into pathname
	CMP	DI,BX		; are we now past the end of the buffer?
	JA	ERBFN2		;brif so -- illegal pathname

			; process the char

	CMP	AL,'.'		; is char a DOT?
	JNE	CHK_SLASH	; brif not -- check for slash

	CMP	DL,SLASHDOTDOT_SEEN ; seen "\..."?
	JAE	ERBFN2		;brif so -- invalid pathname
	CMP	DL,SLASH_SEEN	; seen "\." or "\.."?
	JAE	INC_COUNT	; brif so -- advance state
	TEST	DH,FN_HAS_EXT	; seen two dots since last "\"? ("x.y.z")
	JNZ	ERBFN2		; brif so -- invalid pathname.
; This handles name of the form "xxxxxxxxy.z" too, since "xxxxxxxxy"
; gets changed to "xxxxxxxx.y" before the ".z" is added.
DOT_EXIT:			
	OR	DH,FN_HAS_EXT	; set extension present flag
	JMP	SHORT ResetCount ; reset count to 1 (just the ".")

CHK_SLASH:
	CALL	CHK_FOR_SLASH	; is it a slash?
DJMP	JNE	CHK_BAD_CHAR	; brif not -- check for invalid char

	CALL	PROCESS_SLASH
	JMP	SHORT END_LOOP	; go to the end of the loop

ERBFN2:				; centrally located
DJMP	JMP	SHORT ERBFN	

VALID_CHAR:			
	CMP	AL,'*'		; is it an asterix?
	JE	IS_WILD_CHAR	; brif so
	CMP	AL,'?'		; is it a question mark?
	JNZ	CHK_DEFAULT	; brif not -- perform default char processing
IS_WILD_CHAR:
	OR	DH,FN_WILD	; flag wild card present

CHK_DEFAULT:
	CMP	DL,SLASHDOT_SEEN ; seen "\.x" (ext w/o name) or "\..x"?
	JAE	ERBFN		; brif so -- illegal pathname
	CMP	DL,SLASH_SEEN	; have we seen "\x"?
	JNE	INC_COUNT	; brif not -- just increment count
ResetCount:			
	XOR	DL,DL		; reset char count/last char flag to 0

INC_COUNT:
	INC	DX		; have seen another char

	CMP	DL,SLASH_SEEN	; processing name portion?
	JAE	END_LOOP	; brif not -- process next char
	CMP	DL,4		; valid length for either extension or name?
	JBE	END_LOOP	; brif so
	TEST	DH,FN_HAS_EXT	; seen a dot already?
	JNZ	BackUpChar	; brif so -- truncate extension to 3 chars

	CMP	DL,9		; 9 characters in name now?
	JB	END_LOOP	; brif < -- process next char
	MOV	AL,'.'		; pretend we now have a '.'
	XCHG	AL,[DI-1]	; turn "xxxxxxxxy" into "xxxxxxxx.y"
	STOSB			
INSERTED_DOT:
	OR	DH, FN_HAS_EXT	; Indicate the presence of the DOT
	MOV	DL, 1		; extenstion has 1 character (the DOT)
	JMP	SHORT INC_COUNT ; Include the new character in the count

				; here if truncating extension
BackUpChar:			; back up 1 char in output fname
	dec	di		; back up over char
	dec	dx		; one less char

END_LOOP:
	LOOP	NAME_LOOP	; process next char, if any

; filename has now been almost completely processed
	CMP	DL,SLASH_SEEN	; does current pathname end with "\." or "\.."?
	JBE	CheckDir	; brif not -- add the null byte
		;Special code to handle directory names

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -