?? checkpat.asm
字號:
;
; --- Version 3.3 92-08-23 12:09 ---
;
; CHECKPAT.ASM - Utility function to check a given file/path,
; and to resolve an incomplete path.
; (Does not use any undocumented DOS functions.)
;
; Public Domain Software written by
; Thomas Wagner
; Ferrari electronic GmbH
; Beusselstrasse 27
; D-1000 Berlin 21
; Germany
;
;>e
; Assemble with
;
; tasm /DPASCAL checkpat,checkpap - Turbo Pascal (Tasm only), near
; tasm /DPASCAL /DFARCALL checkpat,checkpap - Turbo Pascal (Tasm only), far
; ?asm checkpat; - C, default model (small)
; ?asm /DMODL=large checkpat - C, large model
;
; NOTE: For C, change the 'model' directive below according to your
; memory model, or define MODL=xxx on the command line.
;
; For Turbo C Huge model, you must give /DTC_HUGE on the
; command line, or define it here.
;
;
; This routine accepts a file name and/or path, checks and resolves the
; path, and splits the name into its components.
;
; A relative path, or no path at all, is resolved to a full path
; specification. An invalid disk drive will not cause the routine
; to fail.
;
; PASCAL:
; function checkpath (name : string,
; inflags : integer,
; drive : string,
; dir : string,
; fname : string,
; ext : string,
; fullpath: string)
; : integer;
; C:
; int checkpath (char *name,
; int inflags,
; char *drive,
; char *dir,
; char *fname,
; char *ext,
; char *fullpath);
;
; Parameters:
;
; name - Input: file name and/or path string
; inflags - Input: parameters for analysis
; INF_NODIR: do no interpret name as directory
; drive - Output: drive letter, with trailing colon
; dir - Output: directory, with leading and trailing bakslash
; fname - Output: file name
; ext - Output: file extension, with leading dot
; fullpath - Output: combined path
;
; NOTE: The input 'name' and the output 'fullpath' parameters may
; both point to the same string. The 'fullpath' pointer will
; only be used after completion of input parsing.
;
; NOTE: For Pascal, reserve one character in addition to the
; standard maximum length for all strings, including the
; input parameter. All strings will be zero-terminated
; during internal processing. DO NOT pass a constant as
; input parameter string.
;
; Returns:
;
; A negative value on error:
;
; ERR_DRIVE -1 Invalid drive
; ERR_PATH -2 Invalid path
; ERR_FNAME -3 Malformed filename
; ERR_DRIVECHAR -4 Illegal drive letter
; ERR_PATHLEN -5 Path too long
; ERR_CRITICAL -6 Critical error (invalid drive, drive not ready)
;
; On error, all output strings except the drive string will be empty.
;
; If no error occured, a positive value consisting of the bitwise OR
; of the following flags:
;
; HAS_WILD 1 Filename/ext has wildcard characters
; HAS_EXT 2 Extension specified
; HAS_FNAME 4 Filename specified
; HAS_PATH 8 Path specified
; HAS_DRIVE 0x10 Drive specified
;
; Those flags are set only if the corresponding
; component was given in the input string. The
; 'drive' and 'dir' strings will always contain
; the resolved drive and path.
;
; FILE_EXISTS 0x20 File exists, upper byte has attributes
; IS_DIR 0x1000 Directory, upper byte has attributes
;
; The file attributes returned if FILE_EXISTS or IS_DIR
; is set are
; 0x0100 - Read only
; 0x0200 - Hidden
; 0x0400 - System
; 0x2000 - Archive
; 0x4000 - Device
;
;<
;>d
; Assemblierung mit
;
; tasm /DPASCAL checkpat,checkpatp - Turbo Pascal (nur Tasm), near
; tasm /DPASCAL /DFARCALL checkpat,checkpatp - Turbo Pascal (nur Tasm), far
; ?asm checkpat; - C, default model (small)
; ?asm /DMODL=large checkpat - C, large model
;
; HINWEIS: F乺 C k攏nen Sie entweder die folgende 'model'-Direktive
; Ihrem Speichermodell entsprechend 刵dern, oder beim
; Assemblieren MODL=xxx in der Kommandozeile definieren.
;
; F乺 Turbo C Huge model m乻sen Sie /DTC_HUGE beim Assemblieren
; angeben, oder das Symbol in dieser Quelle definieren.
;
; Diese Routine erwartet einen Dateinamen und/oder Pfad, pr乫t ihn
; und l攕t den Pfad auf, und teilt den Namen in seine Komponenten.
;
; Ein relativer Pfad, oder eine fehlende Pfadangabe, wird in eine
; absolute Pfadangabe konvertiert. Ein ung乴tiger Laufwerksbuchstabe
; f乭rt nicht zum Abbruch.
;
; PASCAL:
; function checkpath (name : string,
; inflags : integer,
; drive : string,
; dir : string,
; fname : string,
; ext : string,
; fullpath: string)
; : integer;
; C:
; int checkpath (char *name,
; int inflags,
; char *drive,
; char *dir,
; char *fname,
; char *ext,
; char *fullpath);
;
; Parameter:
;
; name - Input: Filename und/oder Pfad
; inflags - Input: Analyse-Parameter
; INF_NODIR: Name nicht als Directory interpretieren
; drive - Output: Laufwerksbuchstabe, mit abschlie醗ndem Doppelpunkt
; dir - Output: Directory, mit f乭rendem und abschlie醗ndem '\'
; fname - Output: Filename
; ext - Output: File extension, mit f乭rendem Punkt
; fullpath - Output: Kombinierter Pfad
;
; Liefert:
;
; Einen negativen Wert bei Fehler:
;
; ERR_DRIVE -1 Ung乴tiges Laufwerk
; ERR_PATH -2 Ung乴tiger Pfad
; ERR_FNAME -3 Fehlerhafter Dateiname
; ERR_DRIVECHAR -4 Illegaler Laufwerksbuchstabe
; ERR_PATHLEN -5 Pfad zu lang
; ERR_CRITICAL -6 Critical error (Illegales Laufwerk,
; Laufwerk nicht bereit)
;
; Bei Fehler sind alle Ausgabestrings au醗r 'drive' leer.
;
; Wenn kein Fehler auftrat einen positiven Wert der aus dem
; bitweisen OR der folgenden Flags besteht:
;
; HAS_WILD 1 Filename/ext enth刲t Wildcard-Zeichen
; HAS_EXT 2 Extension angegeben
; HAS_FNAME 4 Filename angegeben
; HAS_PATH 8 Pfad angegeben
; HAS_DRIVE 0x10 Laufwerk angegeben
;
; Diese Flags sind nur gesetzt wenn die entsprechende
; Komponente im Eingabestring enthalten war. Die
; 'drive' und 'dir' Ausgabestrings enthalten stets
; den aufgel攕ten Laufwerks- und Pfadstring.
;
; FILE_EXISTS 0x20 Datei existiert, Attribute im oberen Byte
; IS_DIR 0x1000 Directory, Attribute im oberen Byte
;
; Die Dateiattribute die geliefert werden wenn FILE_EXISTS
; oder IS_DIR gesetzt ist sind:
;
; 0x0100 - Read only
; 0x0200 - Hidden
; 0x0400 - System
; 0x2000 - Archive
; 0x4000 - Device
;
;<
;
IFDEF PASCAL
.model tpascal
IFDEF FARCALL
%out Pascal, far calls
ELSE
%out Pascal, near calls
ENDIF
ptrsize = 1
ELSE
IFNDEF MODL
.model small,c
%out small model
ELSE
% .model MODL,c
% %out MODL model
ENDIF
ptrsize = @DataSize
ENDIF
;
ldds macro reg,var
IF ptrsize
lds reg,var
ELSE
mov reg,var
ENDIF
endm
;
lddsf macro reg,var
IF ptrsize
lds reg,var
ELSE
mov ds,dseg
mov reg,var
ENDIF
endm
;
ldes macro reg,var
IF ptrsize
les reg,var
ELSE
mov reg,var
ENDIF
endm
;
ldesf macro reg,var
IF ptrsize
les reg,var
ELSE
mov es,dseg
mov reg,var
ENDIF
endm
;
public checkpath
public exists
;
ERR_DRIVE = -1
ERR_PATH = -2
ERR_FNAME = -3
ERR_DRIVECHAR = -4
ERR_PATHLEN = -5
ERR_CRITICAL = -6
;
HAS_WILD = 1
HAS_EXT = 2
HAS_FNAME = 4
HAS_PATH = 8
HAS_DRIVE = 10h
FILE_EXISTS = 20h
IS_DIR = 1000h
;
MAXPATH = 66
;
INF_NODIR = 1
;
IFDEF PASCAL
.data
ELSE
IFDEF TC_HUGE
.fardata? checkpat_data
ELSE
.data?
ENDIF
ENDIF
;
save24 label dword
sav24_off dw ?
sav24_seg dw ?
fail dw ?
dfltpath db 68 dup(?)
;
.code
;
@strcpy proc near
lodsb
stosb
or al,al
jnz @strcpy
dec di
ret
@strcpy endp
;
IFDEF PASCAL
@strlen proc near
push di
inc di
xor ax,ax
mov cx,-1
repne scasb
not cx
dec cx
pop di
mov es:[di],cl
ret
@strlen endp
ENDIF
;
@int24_handler proc far
push ds
IFDEF TC_HUGE
mov ax,SEG checkpat_data
ELSE
IFDEF PASCAL
mov ax,SEG fail
ELSE
mov ax,SEG DGROUP
ENDIF
ENDIF
mov ds,ax
mov fail,1
pop ds
xor ax,ax ; ignore (for compatibility with DOS < 3.1)
iret
@int24_handler endp
;
;
IFDEF PASCAL
IFDEF FARCALL
checkpath PROC far uses ds, string: dword, inflags: word, drive: dword, path: dword, fname: dword, ext: dword, fullpath: dword
ELSE
checkpath PROC near uses ds, string: dword, inflags: word, drive: dword, path: dword, fname: dword, ext: dword, fullpath: dword
ENDIF
ELSE
checkpath PROC uses ds si di, string: ptr byte, inflags: word, drive: ptr byte, path: ptr byte, fname: ptr byte, ext: ptr byte, fullpath: ptr byte
ENDIF
local drv: word,flags:word,dseg: word
;
IFDEF TC_HUGE
mov ax,SEG my_data
mov ds,ax
ENDIF
mov dseg,ds
IFDEF PASCAL
cld
ENDIF
;
; save old critical error handler, install own
;
mov ax,3524h
int 21h
mov sav24_off,bx
mov sav24_seg,es
mov fail,0
mov ax,cs
mov ds,ax
mov dx,offset @int24_handler
mov ax,2524h
int 21h
mov ds,dseg
;
; Init output strings & flags
;
xor ax,ax
mov flags,ax
ldesf di,path
IFDEF PASCAL
stosw
ELSE
stosb
ENDIF
ldes di,fname
IFDEF PASCAL
stosw
ELSE
stosb
ENDIF
ldes di,ext
IFDEF PASCAL
stosw
ELSE
stosb
ENDIF
;
;------ Check the drive. If none was given, use current drive.
;
ldes di,drive
IFDEF PASCAL
inc di
ENDIF
ldds si,string
IFDEF PASCAL
; for pascal, zero-terminate input string
lodsb
mov bl,al
xor ah,ah
mov [si+bx],ah
ENDIF
;
; skip leading whitespace
;
skip_space:
lodsb
cmp al,' '
je skip_space
cmp al,09h
je skip_space
dec si
;
or al,al
jz no_drive
cmp byte ptr 1[si],':'
je drive_there
;
no_drive:
mov ah,19h ; get default drive
int 21h
add al,'A'
stosb
mov bl,al
mov al,':'
stosb
jmp short check_drive
;
badchar:
mov ax,ERR_DRIVECHAR
jmp error_exit
;
drive_there:
inc si
and al,NOT 20h ; convert to uppercase
cmp al,'A'
jb badchar
cmp al,'A'+1fh ; Novell allows some strange chars
ja badchar
stosb
or flags,HAS_DRIVE
mov bl,al
movsb
;
; Now check the drive for validity by getting the current directory
; of this drive (we need it anyway later on)
;
check_drive:
and bx,1fh
mov drv,bx
xor al,al
stosb
;
push ds
push si
;
mov ax,dseg
mov ds,ax
mov es,ax
mov si,offset dfltpath+3
mov ah,47h ; get current directory
mov dx,drv ; drive number
int 21h
jc cpath_bad
cmp fail,0
je cpath_good
;
; Get dir returned an error -> the drive is invalid.
;
cpath_bad:
add sp,4
mov ax,ERR_DRIVE
jmp error_exit ; can't continue with invalid drive
;
; The drive is valid, edit the current path to include
; leading drive letter, colon, and backslash.
; Also, copy the path into the path output string, in case no
; path is given in the input, and append trailing backslash to it.
;
cpath_good:
mov di,offset dfltpath
mov ax,drv
add al,'A'-1
stosb
mov al,':'
stosb
mov si,di ; point to start of path
mov al,'\'
stosb
ldes di,path
IFDEF PASCAL
inc di
ENDIF
call @strcpy
mov al,'\'
cmp byte ptr es:[di-1],al ; root dir?
je drive_ok ; then no second backslash
cmp byte ptr es:[di-1],'/' ; forward slash also legal
je drive_ok
stosb ; else append backslash
;
;
;------ Drive checked, is valid. Now separate path and filename.
;
drive_ok:
pop si
pop ds
push si
push di
push es
mov di,si
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -