home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1988 / 15 / filecopy.asm < prev    next >
Assembly Source File  |  1988-07-25  |  10KB  |  187 lines

  1. ;FileCopy.ASM - copies a source file to a target file.
  2. ;Written by J. R. Conrad, Baltimore, MD
  3.  
  4. ;----------------------------------------------------------------------
  5. ;   1) Assemble FileCopy.Asm to FileCopy.Obj
  6. ;   2) Use BuildLib to add FileCopy.Obj to UserLib.Exe
  7. ;----------------------------------------------------------------------
  8. ;Basic Syntax:  Call FileCopy(InFile$, OutFile$, Buffer$, ErrCode%).
  9. ;       Where:  InFile$  =      source path and filename,
  10. ;               OutFile$ =      target path and filename,
  11. ;               Buffer$  =      blank string (64 < Len < 32768)
  12. ;               ErrCode% =      1 if source path not found
  13. ;                               2 if source file not found (3 not used)
  14. ;                               4 if source file is a directory
  15. ;                               5 if source file not accessible
  16. ;                               6 if target path not found
  17. ;                               7 if target filename is invalid
  18. ;                               8 if target directory is full
  19. ;                               9 if target file is a directory
  20. ;                              10 if target file is read-only
  21. ;                              11 if target file not accessible
  22. ;                              12 if target disk is full
  23. ;                              13 if length of Buffer$ < 65 bytes
  24. ;
  25. ;       Notes:  1) Critical errors must be captured with On Error,
  26. ;               2) Always reenter with ErrCode% = -1 after critical errors.
  27. ;-----------------------------------------------------------------------
  28. Code            Segment Byte Public 'Code'
  29.                 Assume  CS:Code
  30.                 Public  FileCopy
  31.  
  32. FileCopy        Proc    Far
  33. Begin:          Jmp     Start           ;Local data follows:
  34. Source_Handle   DW      0
  35. Target_Handle   DW      0
  36. Buffer_Size     DW      0
  37. Bytes_Read      DW      0
  38. File_Time       DW      ?
  39. File_Date       DW      ?
  40. Root_Test       DB      ':\',0
  41.  
  42. Start:          Push    BP              ;Save BP.
  43.                 Mov     BP,SP           ;Get stack pointer to parameters.
  44.                 Mov     AX,DS           ;Insure ES = DS.
  45.                 Mov     ES,AX
  46.                 Xor     BX,BX           ;Zero error code.
  47.                 Cld                     ;Forward string primitives.
  48.                 Mov     SI,[BP+6]       ;Recover from critical error?
  49.                 Cmp     Word Ptr [SI],-1  ;If ErrCode% = -1,
  50.                 Jne     Check_Buffer      ;  then close open files from
  51.                 Jmp     Close_Files       ;  previous call.
  52. Check_Buffer:   Mov     SI,[BP+8]         ;Make sure buffer is big enough:
  53.                 Cmp     Word Ptr [SI],64  ;  is it longer than 64 char?
  54.                 Ja      Open_Source       ;If so, then continue.
  55.                 Mov     BX,13             ;Else, set ErrCode% and return.
  56.                 Jmp     Close_Files
  57.  
  58. Open_Source:    Mov     AX,[SI]           ;Save buffer size.
  59.                 Mov     Buffer_Size,AX
  60.                 Mov     DX,[SI+2]         ;DX = offset of Buffer$
  61.                 Mov     SI,[BP+12]        ;Point SI to InFile$.
  62.                 Mov     BX,1              ;Init error code.
  63.                 Call    Load_File         ;Convert to ASCIIZ.
  64.                 Mov     AX,3D00h          ;Request Open File (read-only).
  65.                 Int     21h
  66.                 Jnc     Open_Target       ;Did an error occur?
  67.                 Call    Find_Err          ;If so, run the error analysis.
  68.                 Je      Source_Err        ;   If ZF, error was found.
  69.                 Inc     BX                ;   Else, access denied.
  70. Source_Err:     Jmp     Close_Files
  71.  
  72. Open_Target:    Mov     Source_Handle,AX  ;Save the source file handle.
  73.                 Mov     BX,AX             ;Save file handle in BX
  74.                 Mov     AX,5700h          ;Get time and date from source
  75.                 Push    DX                ;Save buffer$ address in DX
  76.                 Int     21h               ;Get source file's date and time
  77.                 Mov     File_Time,CX      ;  save them
  78.                 Mov     File_Date,DX      ;  internally
  79.                 Pop     DX                ;Retrieve DX
  80.                 Mov     SI,[BP+10]        ;Point SI to OutFile$.
  81.                 Mov     BX,6              ;Init error code.
  82.                 Call    Load_File         ;Convert to ASCIIZ.
  83.                 Mov     AH,3Ch            ;Request Create/Clear File:
  84.                 Mov     CX,0              ;  target is normal file,
  85.                 Int     21h               ;  do it.
  86.                 Jnc     Prep_Copy         ;Did an error occur?
  87.                 Call    Find_Err          ;If so, run the error analysis:
  88.                 Jc      Target_Err        ;  If CF, directory is full.
  89.                 Je      Target_Err        ;  If ZF, error was found.
  90.                 Inc     BX
  91.                 Test    AX,1              ;  Else, if NOT (attribute AND 1),
  92.                 Jz      Target_Err        ;    target is read-only.
  93.                 Inc     BX                ;  Else, access denied.
  94. Target_Err:     Jmp     Close_Files
  95.  
  96. Prep_Copy:      Mov     Target_Handle,AX  ;Save the target file handle.
  97.                 Mov     CX,Buffer_Size    ;Put buffer size in CX.
  98. Do_Copy:        Mov     AH,3Fh            ;Request Read from File service:
  99.                 Mov     BX,Source_Handle  ;  retrieve source handle,
  100.                 Int     21h               ;  do it.
  101.                 Mov     Bytes_Read,AX     ;Store bytes actually read,
  102.                 Mov     CX,AX             ;  store in CX for write.
  103.                 Mov     AH,40h            ;Request Write to File service:
  104.                 Mov     BX,Target_Handle  ;  retrieve handle,
  105.                 Int     21h               ;  do it.
  106.                 Mov     BX,12             ;Test for full disk:
  107.                 Cmp     AX,CX             ;  if bytes written <> read,
  108.                 Jne     Close_Files       ;  then disk is full.
  109.                 Mov     CX,Buffer_Size    ;Retrieve buffer size.
  110.                 Cmp     CX,Bytes_Read     ;Test for EOF.
  111.                 Je      Do_Copy
  112.                 Mov     AX,5701h          ;Set target file date and time
  113.                 Mov     BX,Target_Handle  ;Specify target file handle
  114.                 Mov     CX,File_Time      ;Use the source date and time
  115.                 Mov     DX,File_Date      ;  saved earlier
  116.                 Int     21h
  117.                 Xor     BX,BX             ;Successful copy, error code = 0!
  118.  
  119. Close_Files:    Cmp     Source_Handle,0   ;Is source open?
  120.                 Je      Basic_Return      ;  If no, then no files open.
  121.                 Push    BX                ;Save BX for widow check.
  122.                 Cmp     Target_Handle,0   ;Is target open?
  123.                 Je      Source_Only       ;  If no, then only source open.
  124.                 Mov     AH,3Eh            ;Request file closing service.
  125.                 Mov     BX,Target_Handle  ;Close target file.
  126.                 Int     21h
  127.                 Mov     Target_Handle,0
  128. Source_Only:    Mov     AH,3Eh            ;Request file closing service.
  129.                 Mov     BX,Source_Handle  ;Close source file.
  130.                 Int     21h
  131.                 Mov     Source_Handle,0
  132. Widow_Check:    Pop     BX                ;Check for disk full case.
  133.                 Cmp     BX,12             ;If disk full error, then delete
  134.                 Jne     Basic_Return      ;  partial target file.
  135.                 Mov     SI,[BP+10]        ;Point SI to OutFile$.
  136.                 Call    Load_File         ;Convert to ASCIIZ.
  137.                 Mov     AH,41h            ;Request file deletion service.
  138.                 Int     21h
  139. Basic_Return:   Mov     DI,[BP+6]         ;Set error flag.
  140.                 Mov     [DI],BX
  141.                 Pop     BP                ;Restore BP.
  142.                 Ret     8                 ;Cleanup stack and return.
  143.  
  144.  
  145. Load_File       Proc    Near              ;Convert filename to ASCIIZ format:
  146.                 Mov     CX,[SI]           ;Get length of string,
  147.                 Cmp     CX,64             ;Is the string too long?
  148.                 Jbe     Do_Load           ;If not, continue w/ load.
  149.                 Add     SP,2              ;Else, fix the stack
  150.                 Jmp     Close_Files       ;  and jump to exit.
  151. Do_Load:        Mov     SI,[SI+2]         ;Point SI to filename.
  152.                 Mov     DI,DX             ;Point DI to buffer.
  153.                 Rep     Movsb             ;Transfer pathname
  154.                 Mov     Byte Ptr [DI],0   ;  and make ASCIIZ.
  155.                 Ret
  156. Load_File       Endp
  157.  
  158.  
  159. Find_Err        Proc    Near              ;Determine source of error.
  160.                 Cmp     AX,3              ;If AX = 3,
  161.                 Je      End_Find          ;  then invalid path.
  162.                 Inc     BX
  163.                 Cmp     AX,2              ;Else, if AX = 2,
  164.                 Je      End_Find          ;  then file not found.
  165.                 Inc     BX
  166.                 Mov     AX,4300h          ;Else, retrieve file attribute.
  167.                 Int     21h
  168.                 Jc      End_Find          ;If carry, file does not exist.
  169.                 Inc     BX
  170.                 Mov     AX,CX             ;Save attribute in AX.
  171.                 Xor     AX,0FFFFh         ;Use inverted logic!
  172.                 Test    AX,10h            ;Test for a subdirectory.
  173.                 Je      End_Find          ;If ZF, then subdirectory.
  174.                 Mov     CX,3              ;Else, check for root directory:
  175.                 Mov     SI,Offset Root_Test ;  point SI to root string,
  176.                 Mov     DI,DX               ;  point DI to 2nd character,
  177.                 Inc     DI
  178.                 Repe    Cmps CS:Byte Ptr [SI],[DI]  ;compare strings,
  179.                 Clc                       ; cancel side-effect on carry.
  180. End_Find:       Ret
  181. Find_Err        Endp
  182.  
  183. FileCopy        Endp
  184. Code            Ends
  185. End             Begin
  186.  
  187.