home *** CD-ROM | disk | FTP | other *** search
- ;-----------------------------------------------------------------------;
- ; COPYFILE.ASM ;
- ; ;
- ; This module contains a C-callable low level function that copies ;
- ; one file to another. _copyfile is called by the higher level ;
- ; function fcopy and performs the actual file reads and writes. ;
- ; ;
- ; Parameters passed include file handles for both the source and ;
- ; target files, as well as a FAR pointer to (and size of) a buffer. ;
- ; The _copyfile function thus assumes that both source and target ;
- ; file have been opened and that a FAR buffer has been allocated by ;
- ; farmalloc(). THE POINTER TO THE BUFFER *MUST* BE A FAR POINTER! ;
- ; ;
- ; Note that this function does NOT close the files after the copy ;
- ; operation. It is up to the caller to close the files and free ;
- ; the memory, just as the caller opened the files and allocated the ;
- ; memory prior to calling this function. ;
- ;-----------------------------------------------------------------------;
- ; Usage: ;
- ; ;
- ; #include "fcopy.h" ;
- ; ;
- ; Function prototype: ;
- ; ;
- ; int _copyfile (int source, int target, char far *buf, unsigned bsize) ;
- ; ;
- ; Returns: If successful, returns 0. ;
- ; ;
- ; If copy fails, returns -1 and sets errno ;
- ; and _doserrno to one of the following: ;
- ; ;
- ; EACCES Permission denied (5) ;
- ; EBADF Bad file number (6) ;
- ; DISKFUL Target disk full (-2) ;
- ;-----------------------------------------------------------------------;
- ; Revision history: ;
- ; ;
- ; 1.0 16 MAR 92 Original. Written to match ;
- ; version 2.0 of fcopy(). ;
- ; ;
- ; Uses conditional assembly for all ;
- ; memory models by defining _model. ;
- ; Defaults to the small model if ;
- ; _model is not defined. ;
- ; ;
- ; 1.1 19 APR 92 Uses BP as a scratch register for the ;
- ; buffer size, after retrieving stack ;
- ; variables. This speeds up the copy ;
- ; loop by eliminating a memory access ;
- ; inside the loop. Also defined text ;
- ; equate DISKFUL = -2 as an error code. ;
- ; A similar #define was added to fcopy.h. ;
- ; ;
- ; The jumps in the error handling code ;
- ; were also rearranged so that only one ;
- ; error exit routine is now needed. ;
- ; ;
- ; 1.2 12 MAY 92 Now makes no assumption about setting ;
- ; of DS on entry. For large data models ;
- ; (compact and large), sets DS to the ;
- ; default data segment. For huge model, ;
- ; sets DS to segment containing errno ;
- ; so that errno and _doserrno can be set ;
- ; on error. ;
- ;-----------------------------------------------------------------------;
- ; Copyright (c) 1992 Ray Waters ;
- ; All Rights Reserved ;
- ;-----------------------------------------------------------------------;
-
- EACCES EQU 5 ; equate for permission denied
- EBADF EQU 6 ; equate for bad file number
- DISKFUL EQU -2 ; equate for disk full condition
-
- IFDEF _model ; if a _model was defined,
- .MODEL _model, C ; use it
- ELSE ; else, default to
- .MODEL SMALL, C ; SMALL model
- ENDIF
-
- IFDEF ??version ; if using TASM,
- LOCALS ; enable local labels
- ENDIF
-
- EXTRN C errno:WORD ; global error variable
- EXTRN C _doserrno:WORD ; global DOS error variable
-
- .CODE ; open code segment
-
- PUBLIC _copyfile ; make visible to Linker
-
- _copyfile PROC C USES si di, \
- source:WORD, target:WORD, buf:FAR PTR BYTE, bsize:WORD
-
- push ds ; save original data segment
- lds dx,[buf] ; load far pointer to buffer
- mov si,[source] ; use SI for source handle
- mov di,[target] ; use DI for target handle
- mov bp,[bsize] ; use BP for buffer size - BP is
- ; no longer needed since we have
- ; retrieved our stack variables
-
- @@looptop: ; this is the copy loop
- mov cx,bp ; try to read a buffer full
- mov bx,si ; source file handle
- mov ah,3Fh ; DOS read file function
- int 21h
- jc @@copy_error ; jump on error
- or ax,ax ; were any bytes left to read?
- jz @@done ; if no, finished (end-of-file)
-
- mov cx,ax ; CX = number of bytes to write
- mov bx,di ; target file handle
- mov ah,40h ; DOS write file function
- int 21h
- jc @@copy_error ; jump on error
- cmp ax,cx ; did all bytes get copied?
- je @@looptop ; if yes, loop until finished
- mov ax,DISKFUL ; if not, set error code
- ; and fall through to error exit
-
- @@copy_error:
- IF @DataSize EQ 2 ; if huge data model,
- mov bx,SEG errno ; get segment address
- mov ds,bx ; of errno into DS
- ELSEIF @DataSize EQ 1 ; if large data model,
- mov bx,@data ; get default data segment
- mov ds,bx ; into DS
- ELSE ; if small data model,
- pop ds ; restore original data segment
- ENDIF
- mov [errno],ax ; set errno
- mov [_doserrno],ax ; set _doserrno
- IF @DataSize ; if large data model,
- pop ds ; restore original data segment
- ENDIF
- mov ax,-1 ; return int value of -1
- ret ; return to caller
-
- @@done:
- pop ds ; restore original data segment
- ret ; return to caller (AX = 0)
-
- _copyfile ENDP
-
- END
-