home *** CD-ROM | disk | FTP | other *** search
- TITLE 'Copy - RxDOS Command Shell Copy'
- PAGE 59, 132
- .LALL
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; RxDOS Command Shell Copy ;
- ;...............................................................;
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Real Time Dos ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; This material was created as a published version of a DOS ;
- ; equivalent product. This program logically functions in ;
- ; the same way as MSDOS functions and it is internal data ;
- ; structure compliant with MSDOS 5.0 ;
- ; ;
- ; This product is distributed AS IS and contains no warranty ;
- ; whatsoever, including warranty of merchantability or ;
- ; fitness for a particular purpose. ;
- ; ;
- ; ;
- ; (c) Copyright 1990, 1992. Api Software and Mike Podanoffsky ;
- ; All Rights Reserved Worldwide. ;
- ; ;
- ; This product is protected under copyright laws and may not ;
- ; be reproduced in whole or in part, in any form or media, ;
- ; included but not limited to source listing, facimilie, data ;
- ; transmission, cd-rom, or floppy disk without the expressed ;
- ; written consent of the author. ;
- ; ;
- ; Licence for distribution in commercial use: ;
- ; ;
- ; Api Software ;
- ; 12 South Walker Street ;
- ; Lowell, MA 01851 ;
- ; 508/ 454-4961. ;
- ; ;
- ;...............................................................;
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; RxDOS Command Shell ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; Programmer's Notes: ;
- ; ;
- ; Command Shell consists of two parts bound together into a ;
- ; single executable load. There exists a single resident ;
- ; command shell which is accessible by an Int 2Eh. ;
- ; ;
- ;...............................................................;
-
- include rxdosmac.asm
- include rxdosdef.asm
- include rxdoscin.asm
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; RxDOS Command Shell ;
- ;...............................................................;
-
- RxDOSCMD SEGMENT PUBLIC 'CODE'
- assume cs:RxDOSCMD, ds:RxDOSCMD, es:RxDOSCMD, ss:RxDOSCMD
-
- public _Copy
-
- extrn CmndError_BadSwitch : near
- extrn CmndError_CannotCopyUntoSelf : near
- extrn CmndError_CannotCreateFile : near
- extrn CmndError_ContentsLostBeforeCopy : near
- extrn CmndError_FileNotFound : near
- extrn CountArgs : near
- extrn CRLF : near
- extrn deleteArg : near
- extrn DisplayError : near
- extrn DisplayErrorMessage : near
- extrn DisplayLine : near
- extrn RxDOS_DTA : near
- extrn RxDOS_AllFiles : near
-
- extrn _AppendPathName : near
- extrn _CopyString : near
- extrn _Copy_FilesCopied : near
- extrn _CmndParse_Break : near
- extrn _lowerCase : near
- extrn _SwitchChar : near
- extrn _splitpath : near
- extrn _makePath : near
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Copy filenameA+filenameB+filenameC filenameDest ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; Usage: ;
- ; ss:di Arg Array ;
- ; ax Number of arguments in array ;
- ;...............................................................;
-
- _Copy:
-
- Entry
- def __argarray, di ; args array
- def __numArgs, ax ; # args
- def __Mode, 0000 ; non-z if ascii/ z if binary
- def __AddMode ; 0000 not add mode
- def __NextAddMode ; 0000 next is add mode
- def _endoffile
- def _filesCopies, 0000
- def _srcHandle , 0000
- def _destHandle , 0000
- ddef _destCluster
- ddef _srcCluster
-
- defbytes _destFilename , 130
- defbytes _createFilename, 130
- defbytes _copyFilename , 130
- defbytes _buffer, 128
-
- _tempFilename = _copyFilename ; equate temp filename
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; get/test destination filename
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- cmp ax, 2 ; must have at least two args
- ifc _copyError ; any less means error -->
-
- dec ax
- add ax, ax ; args offset in words
- add di, ax ; point to last arg
- push word ptr [ di ] ; get last arg address
- call deleteArg
-
- pop si
- lea di, offset [ _tempFilename ][ bp ]
- call _copyArgument ; copy argument
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; see if dest is just a directory name
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- mov cx, ATTR_DIRECTORY
- lea dx, offset [ _tempFilename ][ bp ]
- Int21 FindFirstFile ; locate file with name
- jc _Copy_18 ; not a directory -->
-
- ; if . or .. handle special
-
- _Copy_08:
- test byte ptr [ RxDOS_DTA. findFileAttribute ], ATTR_DIRECTORY
- jz _Copy_18 ; if not a dir entry -->
-
- cmp byte ptr [ RxDOS_DTA. findFileName ], '.'
- jnz _Copy_24 ; if dir and not . or .. -->
-
- Int21 FindNextFile ; locate next file
- jnc _Copy_08 ; see if also a dir -->
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; scan name for just directory
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_18:
- lea di, offset [ _tempFilename ][ bp ]
-
- _Copy_20:
- cmp byte ptr [ di ], 00 ; null ?
- jz _Copy_26 ; yes, done -->
- inc di
- cmp byte ptr [ di-1 ], ':' ; only drive /colon entered ?
- jnz _Copy_20 ; no -->
- cmp byte ptr [ di ], 00 ;
- jnz _Copy_26
-
- _Copy_24:
- mov si, offset RxDOS_AllFiles ; dummy path
- call _AppendPathName ; append all files
-
- _Copy_26:
- lea si, offset [ _tempFilename ][ bp ]
- lea di, offset [ _destFilename ][ bp ] ; expansion area
- mov byte ptr [ di ], '\' ; (in case no output generated)
- Int21 GetActualFileName ; expand name
- ifc _copyError ; destination doesn't exist -->
-
- xor ax, ax
- mov cx, 4
- lea di, offset [ _destCluster ][ bp ] ; clusters
- rep stosw ; clear clusters
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; main loop through all args
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_30:
- mov word ptr [ __AddMode ][ bp ], 0000 ; not add mode
- mov word ptr [ __NextAddMode ][ bp ], 0000 ; next is not add mode
-
- _Copy_32:
- mov di, word ptr [ __argarray ][ bp ] ; get arg pointer to next arg
- mov si, word ptr [ di ] ; point to text
- or si, si ; null entry ?
- ifz _Copy_Return ; yes, return -->
-
- add word ptr [ __argarray ][ bp ], 2 ; skip this argument next time
-
- mov al, byte ptr [ si ]
- cmp al, byte ptr [ _SwitchChar ] ; switch ?
- ifz _Copy_TestSwitch ; yes, go test switch -->
-
- cmp al, '+'
- ifz _Copy_AddMode ; set add mode -->
-
- lea di, offset [ _copyFilename ][ bp ]
- call _copyArgument
-
- call _scanForwardArgArray ; see if followed by +
- mov word ptr [ __NextAddMode ][ bp ], ax ; next add mode
-
- mov dx, di ; copy filename
- mov cx, ATTR_NORMAL
- Int21 FindFirstFile ; locate file with name
- jnc _Copy_36 ; if file found -->
-
- mov dx, offset CmndError_FileNotFound
- call DisplayLine
- jmp _copyErrorCleanUp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; open source file
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_36:
- lea di, offset [ _copyFilename ][ bp ]
- call _replaceWithRealName
-
- Int21 OpenFile, OPEN_ACCESS_READONLY
- storarg _srcHandle, ax
- ifc _copyError
-
- mov bx, ax
- call GetClusterValue ; src cluster
- mov word ptr [ _srcCluster. _low ][ bp ], ax ; (cluster)
- mov word ptr [ _srcCluster. _high ][ bp ], dx ; (drive )
- jz _Copy_44 ; if not a file -->
-
- call _compareClusters
- jnz _Copy_44 ; no -->
-
- ; error: file destroyed
-
- mov dx, offset CmndError_ContentsLostBeforeCopy
- call DisplayErrorMessage
- jmp _copyErrorCleanUp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; attempt create file
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_44:
- getarg bx, _destHandle
- or bx, bx ; any dest file ?
- jz _Copy_48 ; no, MUST create -->
- cmp word ptr [ __AddMode ][ bp ], 0000 ; add mode ?
- jnz _Copy_56 ; yes, append to existing file -->
-
- _Copy_48:
- lea si, offset [ _destFilename ][ bp ] ; destination filename
- lea di, offset [ _createFilename ][ bp ] ; make destination name
- call _CopyString ; copy string
-
- lea di, offset [ _createFilename ][ bp ] ; make destination name
- call _makeUniqueName ; make unique name
-
- lea dx, offset [ _createFilename ][ bp ] ; destination filename
- Int21 OpenFile, OPEN_ACCESS_READONLY ; we'll try open first
- jc _Copy_52 ; MUST create -->
-
- mov bx, ax
- call GetClusterValue ; cluster of dest
- mov word ptr [ _destCluster. _low ][ bp ], ax ; (cluster)
- mov word ptr [ _destCluster. _high ][ bp ], dx ; (drive )
- Int21 CloseFile ; release file
-
- call _compareClusters
- jnz _Copy_52 ; if not same files -->
-
- mov dx, offset CmndError_CannotCopyUntoSelf
- call DisplayErrorMessage
- jmp _copyErrorCleanUp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; create file
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_52:
- mov cx, ATTR_NORMAL
- lea dx, offset [ _createFilename ][ bp ] ; destination filename
- Int21 CreateFile ; this is wrong (must try open first)
- storarg _destHandle, ax
- ifc _copyError
-
- mov bx, ax
- call GetClusterValue ; cluster of dest
- mov word ptr [ _destCluster. _low ][ bp ], ax ; (cluster)
- mov word ptr [ _destCluster. _high ][ bp ], dx ; (drive )
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; display filename
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_56:
- mov word ptr [ _endoffile ][ bp ], 0000
-
- getarg bx, _srcHandle
- Int21 IoControl, 0000 ; is source a char device ?
- test dx, DEV_CHAR ; test device flag
- jz _Copy_62 ; if file, display filename -->
- storarg __Mode, 01 ; else switch to ascii mode
- jmp short _Copy_66
-
- _Copy_62:
- mov dx, offset [ RxDOS_DTA. findFileName ]
- call DisplayLine ; display line
- call CRLF ; cr/lf
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; copy loop
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_66:
- mov cx, 128
- getarg bx, _srcHandle
- lea dx, offset [ _buffer ][ bp ]
- Int21 ReadFile ; read
- ifc _copyDisplayError ; if error -->
- or ax, ax ; end of file ?
- jz _Copy_78 ; yes, all done -->
-
- mov cx, ax ; how many bytes actually read
- cmp word ptr [ __Mode ][ bp ], 0000 ; ascii mode ?
- jz _Copy_70 ; no -->
-
- push cx
- mov al, 'Z'-40h
- lea di, offset [ _buffer ][ bp ]
- repnz scasb ; scan buffer for ^Z
- pop cx
- jnz _Copy_70 ; if ^z not located ->
-
- mov word ptr [ _endoffile ][ bp ], -1 ; set end of file mode
- dec cx ; don't copy ^Z
-
- _Copy_70:
- or cx, cx ; any more to copy ?
- jz _Copy_78 ; no more -->
-
- getarg bx, _destHandle
- lea dx, offset [ _buffer ][ bp ]
- Int21 WriteFile
-
- cmp word ptr [ _endoffile ][ bp ], 0000 ; end of file ?
- jz _Copy_66 ; not end of file yet -->
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; close source file
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_78:
- getarg bx, _srcHandle
- Int21 CloseFile
- storarg _srcHandle, 0000
-
- cmp word ptr [ __NextAddMode ][ bp ], 0000 ; is next add mode ?
- jnz _Copy_82
-
- getarg bx, _destHandle
- Int21 CloseFile ; if no adds left ...
- storarg _destHandle, 0000
-
- Int21 FindNextFile ; see if more files to copy
- ifnc _Copy_36 ; if file found -->
-
- _Copy_82:
- jmp _Copy_30
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; return
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_Return:
- inc word ptr [ _filesCopies ][ bp ] ; # files copied.
-
- _Copy_ReturnClose:
- getarg bx, _destHandle
- cmp bx, 5
- jle _Copy_ReturnClose_08
- Int21 CloseFile ; close last file
-
- _Copy_ReturnClose_08:
- Return
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; add mode
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_AddMode:
- mov word ptr [ __AddMode ][ bp ], -1 ; set add mode
- jmp _Copy_32
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; test switches
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _Copy_TestSwitch:
- mov al, byte ptr [ si+1 ]
- call _lowerCase ; test switch option
-
- goto 'a', _copyAsciiSwitch
- goto 'b', _copyBinarySwitch
-
- push ax
- mov dx, offset CmndError_BadSwitch
- call DisplayLine ; show error message
-
- pop dx
- call DisplayLine ; show arg
- Return
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; if ascii switch
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _copyAsciiSwitch:
- storarg __Mode, 01 ; ascii mode
- jmp _Copy_32
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; if binary switch
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _copyBinarySwitch:
- storarg __Mode, 00 ; binary mode
- jmp _Copy_32
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ; error in rename command
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- _copyDisplayError:
- call DisplayError
- jmp _copyErrorCleanUp
-
- _copyError:
- mov dx, offset CmndError_CannotCreateFile
- call DisplayErrorMessage
-
- _copyErrorCleanUp:
- getarg bx, _destHandle
- or bx, bx ; if not assigned,
- jz _copyErrorCleanUp_08 ; don't delete -->
- Int21 CloseFile ; close last file
-
- _copyErrorCleanUp_08:
- Return
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Copy Argument ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; Usage: ;
- ; si points to argument start ;
- ; di points to destination ;
- ;...............................................................;
-
- _copyArgument:
-
- push di
-
- _copyArgument_06:
- lodsb ; get character
- stosb
- cmp al, ' '+1 ; space or control character ?
- jc _copyArgument_10 ; yes -->
-
- cmp al, byte ptr [ _SwitchChar ] ; switch character ?
- jz _copyArgument_10 ; yes -->
- call _CmndParse_Break ; parse break ?
- jnz _copyArgument_06 ; no, go to next char -->
-
- _copyArgument_10:
- mov byte ptr [ di-1 ], 0 ; place null terminator
- pop di
- ret
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; LookAhead Add Mode ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; Usage: ;
- ; si points to argument start ;
- ; di points to destination ;
- ;...............................................................;
-
- _scanForwardArgArray:
-
- push di
- mov di, word ptr [ __argarray ][ bp ] ; get arg pointer to next arg
- xor ax, ax ; next is NOT add
-
- _scanForwardArgArray_10:
- mov si, word ptr [ di ] ; point to text
- or si, si ; null entry ?
- jz _scanForwardArgArray_12 ; yes, return -->
-
- add di, 2
- cmp byte ptr [ si ], '/'
- jz _scanForwardArgArray_10
- cmp byte ptr [ si ], '+'
- jnz _scanForwardArgArray_12
- mov ax, -1 ; next IS add
-
- _scanForwardArgArray_12:
- pop di
- ret
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Get Starting Cluster Value for a given Handle ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; Input: ;
- ; bx file handle ;
- ; ;
- ; Output: ;
- ; ax starting cluster value ;
- ;...............................................................;
-
- GetClusterValue:
-
- push es
- push di
- push bx
- Int21 GetPSPAddress ; returns bx with segment
- mov es, bx ; set PSP address
-
- pop si ; restore handle offset
- push si ; (save handle)
- les bx, dword ptr es:[ pspFileHandlePtr ] ; point to file handles
- mov bl, byte ptr es:[ bx + si ] ; get real sft offset
- xor bh, bh
-
- mov ax, 1216h
- int 2fh ; UNDOCUMENTED DOS CALL
- mov ax, word ptr es:[ sftBegCluster ][ di ]
- mov dx, word ptr es:[ sftDevInfo ][ di ]
- and dx, sftDrivemask
-
- pop bx
- pop di
- pop es
- ret
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Compare Drive/Cluster Info ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; NZ if not equal ;
- ;...............................................................;
-
- _compareClusters:
-
- cmp word ptr [ _destCluster. _low ][ bp ], 0000
- jnz _compareClusters_NotEqual
- cmp word ptr [ _srcCluster. _low ][ bp ], 0000
- jnz _compareClusters_NotEqual
-
- mov ax, word ptr [ _destCluster. _low ][ bp ] ; (cluster)
- cmp ax, word ptr [ _srcCluster. _low ][ bp ]
- jnz _compareClusters_NotEqual
-
- mov ax, word ptr [ _destCluster. _high ][ bp ] ; (drive )
- cmp ax, word ptr [ _srcCluster. _high ][ bp ]
- jnz _compareClusters_NotEqual
- ret
-
- _compareClusters_NotEqual:
- mov ax, -1
- or ax, ax
- ret
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Make Unique Name ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; Usage: ;
- ; di name expected with wild characters ;
- ;...............................................................;
-
- _makeUniqueName:
-
- Entry
- def _name, di
- defbytes _expandedname, sizeExpandedName
-
- push di
-
- mov si, di
- lea di, offset [ _expandedname ][ bp ]
- call _splitpath
-
- mov cx, 8
- mov si, offset [ RxDOS_DTA. findFileName ]
- lea di, offset [ _expandedname. expFilename ][ bp ]
- call _makeReplacement
-
- inc si
- mov cx, 3
- lea di, offset [ _expandedname. expExtension + 1 ][ bp ]
- call _makeReplacement
-
- lea si, offset [ _expandedname ][ bp ]
- getarg di, _name
- call _makePath
-
- pop di
- mov dx, di
- Return
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Make Replacement ;
- ;...............................................................;
-
- _makeReplacement:
-
- cmp byte ptr [ di ], '?'
- jnz _makeReplacement_08
-
- mov al, byte ptr [ si ]
- mov byte ptr [ di ], al
-
- _makeReplacement_08:
- inc di
- inc si
- cmp byte ptr [ si ], '.'
- jz _makeReplacement_12
- cmp byte ptr [ si ], 00
- jz _makeReplacement_12
- loop _makeReplacement
-
- _makeReplacement_12:
- mov byte ptr [ di ], 00
- ret
-
- ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
- ; Replace with Real Name ;
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
- ; ;
- ; Usage: ;
- ; di full expanded name expected ;
- ;...............................................................;
-
- _replaceWithRealName:
-
- push di
- mov dx, di
-
- _replaceWithRealName_04:
- cmp byte ptr [ di ], 0 ; find end of string
- jz _replaceWithRealName_08
- inc di
- jmp _replaceWithRealName_04
-
- _replaceWithRealName_08:
- cmp dx, di
- jz _replaceWithRealName_12
-
- mov al, byte ptr [ di-1 ]
- cmp al, ':'
- jz _replaceWithRealName_12
- cmp al, '\'
- jz _replaceWithRealName_12
-
- dec di
- jmp _replaceWithRealName_08
-
- _replaceWithRealName_12:
- mov si, offset [ RxDOS_DTA. findFileName ] ; expanded name
- call _CopyString
-
- pop di
- mov dx, di
- ret
-
- RxDOSCMD ENDS
- END
-