555 lines
15 KiB
NASM
555 lines
15 KiB
NASM
TITLE doslib - DOS access library routines
|
||
|
||
; Windows Write, Copyright 1985-1992 Microsoft Corporation
|
||
; =====================================================================
|
||
; This file contains DOS access routines.
|
||
; These routines are general, simple calls to DOS and
|
||
; are likely to be generally useful. They assume /PLM calling
|
||
; is used.
|
||
; FAR calls are used throughout
|
||
;
|
||
;
|
||
; NOTE: DOSLIB.H CONTAINS A C HEADER DEFINING THE FUNCTIONS IN THIS
|
||
; MODULE. IT MUST BE UPDATED WHENEVER A FUNCTION IS ADDED OR AN INTERFACE
|
||
; CHANGES
|
||
; =====================================================================
|
||
|
||
|
||
; =====================================================================
|
||
; cmacros2.inc is a special version of cmacros.inc in which the only
|
||
; difference is that it defines the segment for assembly code to
|
||
; be FILE_TEXT instead of _TEXT.
|
||
; This is done so that functions in FILE.C will
|
||
; not call intermodule and subject themselves to possible file closure
|
||
; when calling DOS functions.
|
||
; =====================================================================
|
||
include cmacros2.inc
|
||
|
||
sBegin DATA
|
||
ifdef DEBUG
|
||
EXTRN vfCommDebug:WORD
|
||
endif
|
||
sEnd DATA
|
||
|
||
|
||
cchMaxFile EQU 128
|
||
EXTRN ANSITOOEM:FAR
|
||
|
||
sBegin CODE
|
||
assumes CS,CODE
|
||
|
||
; ---------------------------------------------------------------------
|
||
; int FAR CchCurSzPath( szPath, bDrive )
|
||
; PSTR szPath;
|
||
; int bDrive;
|
||
;
|
||
; Copy the current path name for the current drive into szPath
|
||
; szPath must have 67 bytes of storage
|
||
;
|
||
; bDrive is 0=default, 1=A, 2=B,...
|
||
;
|
||
; Returned cch includes the terminating '\0'
|
||
; Form of returned string is e.g. "C:\WINDOWS\BIN\" (0-terminated)
|
||
; String is guaranteed to: (1) Include the drive letter, colon, and leading "\"
|
||
; (2) End with a backslash
|
||
;
|
||
; 0 = an error occurred, nonzero = success
|
||
; the path string will be NULL if an error occurred
|
||
; An error should really not be possible, since the default drive ought to be
|
||
; valid
|
||
; ---------------------------------------------------------------------
|
||
|
||
cProc CchCurSzPath, <FAR, PUBLIC>, <SI>
|
||
parmDP <szPath>
|
||
parmB <bDrive>
|
||
cBegin CchCurSzPath
|
||
|
||
mov al,bDrive
|
||
mov dl,al
|
||
cmp al,0
|
||
jz cspDFLTDRV ; default drive
|
||
dec al
|
||
jmp cspGOTDRV ; not default drive
|
||
|
||
cspDFLTDRV:
|
||
mov ah,19h ; Get current drive
|
||
int 21h
|
||
|
||
; now we have al: 0=A, 1=B, ....
|
||
; dl: 0=default, 1=A, 2=B
|
||
|
||
cspGOTDRV: ; Put "X:\" at front of szPath
|
||
add al,'A'
|
||
mov si,szPath
|
||
mov [si],al
|
||
mov BYTE PTR [si+1],':'
|
||
mov BYTE PTR [si+2],'\' ; Leave si pointing at szPath
|
||
|
||
add si,3 ; Rest of path goes at SzPath+3
|
||
mov ah,47h
|
||
int 21h
|
||
mov si,szPath
|
||
jc cspERR ; error -- return negative of err code in AX
|
||
|
||
dec si ; Path was OK - find null terminator
|
||
cspLOOP: inc si
|
||
cmp al,[si]
|
||
jnz cspLOOP
|
||
|
||
cmp BYTE PTR [si-1],'\' ; Append backslash if needed
|
||
jz cspSTROK ; not needed, string is already OK
|
||
mov BYTE PTR [si],'\'
|
||
inc si
|
||
mov BYTE PTR [si],0
|
||
cspSTROK: ; now we are guaranteed a good string
|
||
mov ax,si ; determine string length
|
||
sub ax,szPath
|
||
inc ax
|
||
jmp cspRET
|
||
|
||
cspERR: mov BYTE PTR [si],0 ; error -- NULL path string
|
||
neg ax
|
||
cspRET:
|
||
cEnd CchCurSzPath
|
||
|
||
|
||
ifdef ENABLE
|
||
;-----------------------------------------------------------------------------
|
||
; DOSHND FAR WCreateNewSzFfname( szFfname, attrib )
|
||
;
|
||
; Create specified file, leave open for read/write, return handle
|
||
; filename is an ffname, with drive and path. Uses the NEW
|
||
; DOS 3.0 CREATE call which fails if the file exists. Caller has
|
||
; responsibility for assuring DOS version number sufficiently high
|
||
;
|
||
; returned handle is negative if there was an error
|
||
; the value will be the negative of the error code returned in AX
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc WCreateNewSzFfname, <FAR, PUBLIC>
|
||
parmDP <szFfname>
|
||
parmW <attrib>
|
||
cBegin WCreateNewSzFfname
|
||
|
||
mov dx,szFfname
|
||
mov cx,attrib
|
||
mov ah,5bh
|
||
int 21h
|
||
jnc cnsfdone
|
||
neg ax ; error - return the negative of the error code
|
||
cnsfdone:
|
||
cEnd WCreateNewSzFfname
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; DOSHND FAR WCreateSzFfname( szFfname, attrib )
|
||
;
|
||
; Create specified file, leave open for read/write, return handle
|
||
; filename is an ffname, with drive and path
|
||
;
|
||
; returned handle is negative if there was an error
|
||
; the value will be the negative of the error code returned in AX
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc WCreateSzFfname, <FAR, PUBLIC>
|
||
parmDP <szFfname>
|
||
parmW <attrib>
|
||
cBegin WCreateSzFfname
|
||
|
||
mov dx,szFfname
|
||
mov cx,attrib
|
||
mov ah,3ch
|
||
int 21h
|
||
jnc csfdone
|
||
neg ax ; error - return the negative of the error code
|
||
csfdone:
|
||
cEnd WCreateSzFfname
|
||
endif
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; int DosxError()
|
||
;
|
||
; Return a DOS extended error code
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc DosxError, <FAR, PUBLIC>
|
||
cBegin DosxError
|
||
mov ah,59h
|
||
mov bx,0 ; bug fix, 10/2/86, BryanL
|
||
int 21h
|
||
cEnd DosxError
|
||
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; WORD WDosVersion()
|
||
;
|
||
; Return a word indicating DOS version, major in low 8 bits, minor in high 8
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc WDosVersion, <FAR, PUBLIC>
|
||
cBegin WDosVersion
|
||
mov ah,30h
|
||
int 21h
|
||
cEnd WDosVersion
|
||
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; WORD DaGetFileModeSz(sz)
|
||
;
|
||
; Return a word indicating attributes of file sz (EXPECTED IN ANSI);
|
||
; 0xFFFF if it fails.
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc DaGetFileModeSz, <FAR, PUBLIC>
|
||
parmDP <sz>
|
||
localV <szOem>,cchMaxFile
|
||
|
||
cBegin DaGetFileModeSz
|
||
; Convert filename from ANSI set to OEM Set
|
||
|
||
push ds
|
||
push sz
|
||
push ds
|
||
lea ax,szOem
|
||
push ax
|
||
call ANSITOOEM
|
||
|
||
lea dx,szOem
|
||
mov ax,4300h
|
||
|
||
int 21h
|
||
mov ax, cx
|
||
jnc daNoErr
|
||
mov ax, 0ffffh ; error -- return 0xFFFF
|
||
daNoErr:
|
||
cEnd DaGetFileModeSz
|
||
|
||
; WRITE uses OpenFile instead
|
||
ifdef ENABLE
|
||
;-----------------------------------------------------------------------------
|
||
; DOSHND FAR WOpenSzFfname( szFfname, openmode )
|
||
;
|
||
; Open specified file in specified mode, return a handle or
|
||
; the negative of an error code if the open failed
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc WOpenSzFfname, <FAR, PUBLIC>
|
||
parmDP <szFfname>
|
||
parmB <openmode>
|
||
cBegin WOpenSzFfname
|
||
|
||
mov dx,szFfname
|
||
mov al,openmode
|
||
mov ah,3dh
|
||
|
||
int 21h
|
||
jnc osfdone
|
||
neg ax ; error - return the negative of the error code
|
||
osfdone:
|
||
cEnd WOpenSzFfname
|
||
|
||
endif
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; int FAR FCloseDoshnd( doshnd )
|
||
;
|
||
; Close file given DOS handle, return 0 = error, nonzero = no error
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc FCloseDoshnd, <FAR, PUBLIC>
|
||
parmW <doshnd>
|
||
cBegin FCloseDoshnd
|
||
|
||
mov bx,doshnd
|
||
mov ah,3eh
|
||
|
||
int 21h
|
||
mov ax,0000
|
||
jc cdhskip ; error, leave a zero in ax
|
||
inc ax
|
||
cdhskip:
|
||
cEnd FCloseDoshnd
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; int FAR FpeDeleteSzFfname( szFfname )
|
||
;
|
||
; Delete specified file, return < 0=failure, 0=success
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc FpeDeleteSzFfname, <FAR, PUBLIC>
|
||
parmDP <szFfname>
|
||
|
||
localV <szOem>,cchMaxFile
|
||
|
||
cBegin FpeDeleteSzFfname
|
||
|
||
; Convert filename from ANSI set to OEM Set
|
||
|
||
push ds
|
||
push szFfname
|
||
push ds
|
||
lea ax,szOem
|
||
push ax
|
||
call ANSITOOEM
|
||
|
||
lea dx,szOem
|
||
mov ah,41h
|
||
|
||
int 21h
|
||
jc dsfskip ; error - return the negative of the error code
|
||
mov ax,0ffffh
|
||
dsfskip:
|
||
neg ax
|
||
cEnd FpeDeleteSzFfname
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; int FAR FpeRenameSzFfname( szCur, szNew )
|
||
;
|
||
; Rename file szCur to szNew, return < 0=failure, 0=success
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc FpeRenameSzFfname, <FAR, PUBLIC>, <ES,DI>
|
||
parmDP <szCur>
|
||
parmDP <szNew>
|
||
|
||
localV <szCurOem>,cchMaxFile
|
||
localV <szNewOem>,cchMaxFile
|
||
|
||
cBegin FpeRenameSzFfname
|
||
|
||
; Convert filenames to Oem char set
|
||
|
||
push ds
|
||
push szCur
|
||
push ds
|
||
lea ax,szCurOem
|
||
push ax
|
||
call ANSITOOEM
|
||
push ds
|
||
push szNew
|
||
push ds
|
||
lea ax, szNewOem
|
||
push ax
|
||
call ANSITOOEM
|
||
|
||
lea dx,szCurOem ; old filename in ds:dx
|
||
push ds ; new filename in es:di
|
||
pop es
|
||
lea di,szNewOem
|
||
mov ah,56h
|
||
|
||
int 21h
|
||
jc rnfskip ; error - return the negative of the error code
|
||
mov ax,0ffffh
|
||
rnfskip:
|
||
neg ax
|
||
cEnd FpeRenameSzFfname
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; int CchReadDoshnd ( doshnd, lpchBuffer, bytes )
|
||
;
|
||
; Read bytes from an open file, place into buffer
|
||
; Returns # of bytes read (should be == bytes unless EOF or error)
|
||
; If an error occurs, returns the negative of the error code
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc CchReadDoshnd, <FAR, PUBLIC>, <DS>
|
||
parmW <doshnd>
|
||
parmD <lpchBuffer>
|
||
parmW <bytes>
|
||
cBegin CchReadDoshnd
|
||
|
||
mov bx,doshnd
|
||
lds dx,lpchBuffer
|
||
mov cx,bytes
|
||
mov ah,3fh
|
||
|
||
int 21h
|
||
jnc crdone
|
||
|
||
neg ax ; error - return value is the negative of the error code
|
||
crdone:
|
||
cEnd CchReadDoshnd
|
||
|
||
|
||
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; int CchWriteDoshnd ( doshnd, lpchBuffer, bytes )
|
||
;
|
||
; Write bytes from an open file, place into buffer
|
||
; Returns # of bytes read (should be == bytes unless EOF or error)
|
||
; If an error occurs, returns the negative of the error code
|
||
; Disk full is not an "error"; detect it by return code != bytes
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc CchWriteDoshnd, <FAR, PUBLIC>,<DS>
|
||
parmW <doshnd>
|
||
parmD <lpchBuffer>
|
||
parmW <bytes>
|
||
cBegin CchWriteDoshnd
|
||
|
||
mov bx,doshnd
|
||
lds dx,lpchBuffer
|
||
mov cx,bytes
|
||
mov ah,40h
|
||
|
||
int 21h
|
||
jnc cwdone
|
||
|
||
neg ax ; error: return the negative of the error code
|
||
cwdone:
|
||
|
||
cEnd CchWriteDoshnd
|
||
|
||
|
||
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; long DwSeekDw ( doshnd, dwSeekpos, bSeekfrom )
|
||
;
|
||
; Seek to requested position in file
|
||
; bSeekfrom is: 0 = seek relative to beginning of file
|
||
; 1 = seek relative to current pointer location
|
||
; 2 = seek relative to end of file
|
||
;
|
||
; Returns the new location of the read/write pointer (a long)
|
||
; If an error occurs, returns the negative of the error code (long)
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc DwSeekDw, <FAR, PUBLIC>
|
||
parmW <doshnd>
|
||
parmD <dwSeekpos>
|
||
parmB <bSeekfrom>
|
||
cBegin DwSeekDw
|
||
|
||
mov bx,doshnd
|
||
mov cx,SEG_dwSeekpos
|
||
mov dx,OFF_dwSeekpos
|
||
mov al,bSeekfrom
|
||
mov ah,42h
|
||
|
||
int 21h
|
||
jnc seekdone
|
||
|
||
neg ax ; Error: return the negative of the error code
|
||
mov dx,0ffffH
|
||
|
||
seekdone:
|
||
|
||
cEnd DwSeekDw
|
||
|
||
|
||
; WRITE does not use these currently
|
||
|
||
ifdef ENABLE
|
||
;-----------------------------------------------------------------------------
|
||
; int FAR FFirst(pb, szFileSpec, attrib)
|
||
; Get first directory entry, place in buffer at pb. (buffer must contain
|
||
; 43 bytes of storage)
|
||
; attrib specifies attribute per MSDOS spec.
|
||
; szFileSpec is filename specification
|
||
; Returns 0=no error, nonzero = error
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc FFirst, <FAR, PUBLIC>, <SI, DI>
|
||
parmDP <pb, szFileSpec>
|
||
parmW <attrib>
|
||
cBegin FFirst
|
||
|
||
mov dx,pb ; set dta to pb
|
||
mov ah,1ah
|
||
int 21h
|
||
|
||
mov cx,attrib ; get first directory record, place in *pb
|
||
mov dx,szFileSpec
|
||
mov ah,4eh
|
||
int 21h
|
||
jc ffdone
|
||
xor ax,ax
|
||
|
||
ffdone:
|
||
cEnd FFirst
|
||
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; int FAR FNext(pb)
|
||
; Get next directory entry, place in buffer at pb.
|
||
; Return 0= found match OK, nonzero = error or no more matches
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc FNext, <FAR, PUBLIC>, <SI, DI>
|
||
parmDP <pb>
|
||
cBegin FFirst
|
||
|
||
mov dx,pb ; set dta to pb
|
||
mov ah,1ah
|
||
int 21h
|
||
|
||
mov ah,4fh
|
||
int 21h
|
||
jc fndone
|
||
xor ax,ax
|
||
|
||
fndone:
|
||
cEnd FNext
|
||
|
||
endif
|
||
|
||
ifdef OLDDEBUG
|
||
/* This method isn't quite working under Win 3.0 ..pault */
|
||
;-----------------------------------------------------------------------------
|
||
; void CommSz( sz ) - put out string to AUX device
|
||
;
|
||
; For debugging
|
||
;-----------------------------------------------------------------------------
|
||
|
||
cProc CommSz, <FAR, PUBLIC>
|
||
parmDP <sz>
|
||
cBegin CommSz
|
||
|
||
CommSz1:
|
||
mov bx, sz ; if ((dl = *(sz++)) == 0) goto CommSz2
|
||
inc sz
|
||
mov dl, [bx]
|
||
cmp dl, 0
|
||
jz CommSz2
|
||
|
||
call DebugOutput ; Output dl to AUX or LPT device
|
||
|
||
jmp CommSz1
|
||
|
||
CommSz2:
|
||
|
||
cEnd CommSz
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; static void DebugOutput - put character to AUX or LPT device
|
||
; if (vfCommDebug)
|
||
; output to AUX port
|
||
; else output to LPT port
|
||
; input: dl = character
|
||
; output: none. Uses ah
|
||
;
|
||
;-----------------------------------------------------------------------------
|
||
|
||
assumes ds,DATA
|
||
DebugOutput PROC NEAR
|
||
|
||
mov ah,4 ; Assume AUX device
|
||
test vfCommDebug,0ffh
|
||
jnz DebugOut1
|
||
inc ah ; Change to LPT device
|
||
DebugOut1:
|
||
int 21h ; Output character
|
||
ret
|
||
|
||
DebugOutput ENDP
|
||
|
||
endif ;DEBUG
|
||
|
||
sEnd CODE
|
||
|
||
|
||
|
||
END
|
||
|