home *** CD-ROM | disk | FTP | other *** search
- ;FileCopy.ASM - copies a source file to a target file.
- ;Written by J. R. Conrad, Baltimore, MD
-
- ;----------------------------------------------------------------------
- ; 1) Assemble FileCopy.Asm to FileCopy.Obj
- ; 2) Use BuildLib to add FileCopy.Obj to UserLib.Exe
- ;----------------------------------------------------------------------
- ;Basic Syntax: Call FileCopy(InFile$, OutFile$, Buffer$, ErrCode%).
- ; Where: InFile$ = source path and filename,
- ; OutFile$ = target path and filename,
- ; Buffer$ = blank string (64 < Len < 32768)
- ; ErrCode% = 1 if source path not found
- ; 2 if source file not found (3 not used)
- ; 4 if source file is a directory
- ; 5 if source file not accessible
- ; 6 if target path not found
- ; 7 if target filename is invalid
- ; 8 if target directory is full
- ; 9 if target file is a directory
- ; 10 if target file is read-only
- ; 11 if target file not accessible
- ; 12 if target disk is full
- ; 13 if length of Buffer$ < 65 bytes
- ;
- ; Notes: 1) Critical errors must be captured with On Error,
- ; 2) Always reenter with ErrCode% = -1 after critical errors.
- ;-----------------------------------------------------------------------
- Code Segment Byte Public 'Code'
- Assume CS:Code
- Public FileCopy
-
- FileCopy Proc Far
- Begin: Jmp Start ;Local data follows:
- Source_Handle DW 0
- Target_Handle DW 0
- Buffer_Size DW 0
- Bytes_Read DW 0
- File_Time DW ?
- File_Date DW ?
- Root_Test DB ':\',0
-
- Start: Push BP ;Save BP.
- Mov BP,SP ;Get stack pointer to parameters.
- Mov AX,DS ;Insure ES = DS.
- Mov ES,AX
- Xor BX,BX ;Zero error code.
- Cld ;Forward string primitives.
- Mov SI,[BP+6] ;Recover from critical error?
- Cmp Word Ptr [SI],-1 ;If ErrCode% = -1,
- Jne Check_Buffer ; then close open files from
- Jmp Close_Files ; previous call.
- Check_Buffer: Mov SI,[BP+8] ;Make sure buffer is big enough:
- Cmp Word Ptr [SI],64 ; is it longer than 64 char?
- Ja Open_Source ;If so, then continue.
- Mov BX,13 ;Else, set ErrCode% and return.
- Jmp Close_Files
-
- Open_Source: Mov AX,[SI] ;Save buffer size.
- Mov Buffer_Size,AX
- Mov DX,[SI+2] ;DX = offset of Buffer$
- Mov SI,[BP+12] ;Point SI to InFile$.
- Mov BX,1 ;Init error code.
- Call Load_File ;Convert to ASCIIZ.
- Mov AX,3D00h ;Request Open File (read-only).
- Int 21h
- Jnc Open_Target ;Did an error occur?
- Call Find_Err ;If so, run the error analysis.
- Je Source_Err ; If ZF, error was found.
- Inc BX ; Else, access denied.
- Source_Err: Jmp Close_Files
-
- Open_Target: Mov Source_Handle,AX ;Save the source file handle.
- Mov BX,AX ;Save file handle in BX
- Mov AX,5700h ;Get time and date from source
- Push DX ;Save buffer$ address in DX
- Int 21h ;Get source file's date and time
- Mov File_Time,CX ; save them
- Mov File_Date,DX ; internally
- Pop DX ;Retrieve DX
- Mov SI,[BP+10] ;Point SI to OutFile$.
- Mov BX,6 ;Init error code.
- Call Load_File ;Convert to ASCIIZ.
- Mov AH,3Ch ;Request Create/Clear File:
- Mov CX,0 ; target is normal file,
- Int 21h ; do it.
- Jnc Prep_Copy ;Did an error occur?
- Call Find_Err ;If so, run the error analysis:
- Jc Target_Err ; If CF, directory is full.
- Je Target_Err ; If ZF, error was found.
- Inc BX
- Test AX,1 ; Else, if NOT (attribute AND 1),
- Jz Target_Err ; target is read-only.
- Inc BX ; Else, access denied.
- Target_Err: Jmp Close_Files
-
- Prep_Copy: Mov Target_Handle,AX ;Save the target file handle.
- Mov CX,Buffer_Size ;Put buffer size in CX.
- Do_Copy: Mov AH,3Fh ;Request Read from File service:
- Mov BX,Source_Handle ; retrieve source handle,
- Int 21h ; do it.
- Mov Bytes_Read,AX ;Store bytes actually read,
- Mov CX,AX ; store in CX for write.
- Mov AH,40h ;Request Write to File service:
- Mov BX,Target_Handle ; retrieve handle,
- Int 21h ; do it.
- Mov BX,12 ;Test for full disk:
- Cmp AX,CX ; if bytes written <> read,
- Jne Close_Files ; then disk is full.
- Mov CX,Buffer_Size ;Retrieve buffer size.
- Cmp CX,Bytes_Read ;Test for EOF.
- Je Do_Copy
- Mov AX,5701h ;Set target file date and time
- Mov BX,Target_Handle ;Specify target file handle
- Mov CX,File_Time ;Use the source date and time
- Mov DX,File_Date ; saved earlier
- Int 21h
- Xor BX,BX ;Successful copy, error code = 0!
-
- Close_Files: Cmp Source_Handle,0 ;Is source open?
- Je Basic_Return ; If no, then no files open.
- Push BX ;Save BX for widow check.
- Cmp Target_Handle,0 ;Is target open?
- Je Source_Only ; If no, then only source open.
- Mov AH,3Eh ;Request file closing service.
- Mov BX,Target_Handle ;Close target file.
- Int 21h
- Mov Target_Handle,0
- Source_Only: Mov AH,3Eh ;Request file closing service.
- Mov BX,Source_Handle ;Close source file.
- Int 21h
- Mov Source_Handle,0
- Widow_Check: Pop BX ;Check for disk full case.
- Cmp BX,12 ;If disk full error, then delete
- Jne Basic_Return ; partial target file.
- Mov SI,[BP+10] ;Point SI to OutFile$.
- Call Load_File ;Convert to ASCIIZ.
- Mov AH,41h ;Request file deletion service.
- Int 21h
- Basic_Return: Mov DI,[BP+6] ;Set error flag.
- Mov [DI],BX
- Pop BP ;Restore BP.
- Ret 8 ;Cleanup stack and return.
-
-
- Load_File Proc Near ;Convert filename to ASCIIZ format:
- Mov CX,[SI] ;Get length of string,
- Cmp CX,64 ;Is the string too long?
- Jbe Do_Load ;If not, continue w/ load.
- Add SP,2 ;Else, fix the stack
- Jmp Close_Files ; and jump to exit.
- Do_Load: Mov SI,[SI+2] ;Point SI to filename.
- Mov DI,DX ;Point DI to buffer.
- Rep Movsb ;Transfer pathname
- Mov Byte Ptr [DI],0 ; and make ASCIIZ.
- Ret
- Load_File Endp
-
-
- Find_Err Proc Near ;Determine source of error.
- Cmp AX,3 ;If AX = 3,
- Je End_Find ; then invalid path.
- Inc BX
- Cmp AX,2 ;Else, if AX = 2,
- Je End_Find ; then file not found.
- Inc BX
- Mov AX,4300h ;Else, retrieve file attribute.
- Int 21h
- Jc End_Find ;If carry, file does not exist.
- Inc BX
- Mov AX,CX ;Save attribute in AX.
- Xor AX,0FFFFh ;Use inverted logic!
- Test AX,10h ;Test for a subdirectory.
- Je End_Find ;If ZF, then subdirectory.
- Mov CX,3 ;Else, check for root directory:
- Mov SI,Offset Root_Test ; point SI to root string,
- Mov DI,DX ; point DI to 2nd character,
- Inc DI
- Repe Cmps CS:Byte Ptr [SI],[DI] ;compare strings,
- Clc ; cancel side-effect on carry.
- End_Find: Ret
- Find_Err Endp
-
- FileCopy Endp
- Code Ends
- End Begin
-
-