|
|
page ,132 ;/* ; * Microsoft Confidential ; * Copyright (C) Microsoft Corporation 1991 ; * All Rights Reserved. ; */
.xlist .xcref
include comsw.asm include dossym.inc include syscall.inc include sf.inc include comseg.asm include comequ.asm
.list .cref
TRANDATA segment public byte extrn DevWMes_Ptr:word extrn Extend_Buf_Sub:byte extrn LostErr_Ptr:word extrn NoSpace_Ptr:word extrn Overwr_Ptr:word TRANDATA ends
TRANSPACE segment public byte extrn Ascii:byte extrn Binary:byte extrn CFlag:byte extrn Concat:byte extrn DestBuf:byte extrn DestClosed:byte extrn DestHand:word extrn DestIsDev:byte extrn DestSwitch:word extrn Inexact:byte extrn NoWrite:byte extrn NxtAdd:word extrn OCtrlZ:byte extrn OFilePtr_Hi:word extrn OFilePtr_Lo:word extrn Plus_Comma:byte extrn RdEof:byte extrn SrcIsDev:byte extrn String_Ptr_2:word extrn TermRead:byte extrn Tpa:word extrn Written:word TRANSPACE ends
TRANCODE segment public byte
extrn EndCopy:near
public FlshFil public TryFlush
assume cs:TRANGROUP,ds:TRANGROUP,es:TRANGROUP,ss:NOTHING
;*** TryFlush - flush copy buffer, double-check for concatenation ; ; EXIT ZR set if concatenate flag unchanged
TryFlush: mov al,Concat push ax call FlshFil pop ax cmp al,Concat return
;*** Flshfil - write out any data remaining in copy buffer. ; ; Inputs: ; [NXTADD] = No. of bytes to write ; [CFLAG] <> 0 if file has been created ; Outputs: ; [NXTADD] = 0
FlshFil: mov TermRead,0 cmp CFlag,0 je NotExists jmp Exists
NotExists: invoke BuildDest ; find out all about the destination invoke CompName ; source and dest. the same? jne ProcDest ; if not, go ahead
cmp SrcIsDev,0 jne ProcDest ; same name on device ok
cmp Concat,0 ; concatenation? mov dx,offset TRANGROUP:Overwr_Ptr jne No_Concat_Err ; concatenating
jmp CopErr ; not concatenating - overwrite error
No_Concat_Err: mov NoWrite,1 ; flag not writing (just seeking)
ProcDest: mov ax,EXTOPEN shl 8 ; open the file mov si,offset TRANGROUP:DestBuf ; get file name ;M046 ; For writes, we want to deny writes by anyone else at the same time that we ;are writing to it. For instance, on a network, 2 workstations could try ;writing to the same file. Also, because we opened the source file with ;DENY NONE, it is fine if the source and destination files are the same as ;would happen when we append to an existing file. ; mov bx,DENY_WRITE or WRITE_OPEN_MODE;get open mode for copy; M046 xor cx,cx ; no special files mov dx,WRITE_OPEN_FLAG ; set up open flags
cmp NoWrite,0 jne DoDestOpen ; don't actually create if nowrite set mov dx,CREAT_OPEN_FLAG ; set up create flags
DoDestOpen: int 21h
; We assume that the error is normal. ; TriageError will correct the DX value appropriately.
jnc Dest_Open_Okay ;AC030;
Xa_Set_Error: ;AN030; error occurred on XA invoke Set_Ext_Error_Msg ;AN030; get extended error
Ext_Err_Set: ;AN030; mov String_Ptr_2,offset TRANGROUP:DestBuf ;AN000; get address of failed string mov Extend_Buf_Sub,ONE_SUBST ;AN030; put number of subst in control block
CopErrJ2: ;AN030; jmp CopErr ;AN030; go issue message
Dest_Open_Okay: ;AC030 mov DestHand,ax ; save handle mov CFlag,1 ; destination now exists mov bx,ax mov ax,(IOCTL shl 8) int 21h ; get device stuff mov DestIsDev,dl ; set dest info test dl,DEVID_ISDEV jz Exists ;AC030; Dest not a device
; Destination is device.
mov al,byte ptr DestSwitch and al,SWITCHA+SWITCHB jnz TestBoth mov al,Ascii ; neither set, use current setting or al,Binary jz ExSetA ; neither set, default to ascii
TestBoth: jpe Exists ; both are set, ignore test al,SWITCHB jz Exists ; leave in cooked mode mov ax,(IOCTL shl 8) or 1 xor dh,dh or dl,DEVID_RAW mov DestIsDev,dl ; new value int 21h ; set device to raw mode jmp short Exists
CopErrJ: jmp CopErr
ExSetA:
; What we read in may have been in binary mode, flag zapped write OK
mov Ascii,SWITCHA ; set ascii mode or Inexact,SWITCHA ; ascii -> inexact
Exists: cmp NoWrite,0 jne NoChecking ; if nowrite don't bother with name check cmp Plus_Comma,1 ;g don't check if just doing +,, je NoChecking ;g invoke CompName ; source and dest. the same? jne NoChecking ; if not, go ahead cmp SrcIsDev,0 jne NoChecking ; same name on device ok
; At this point we know in append (would have gotten overwrite error ; on first destination create otherwise), and user trying to specify ; destination which has been scribbled already (if dest had been named ; first, NoWrite would be set).
mov dx,offset TRANGROUP:LostErr_Ptr ; tell him he's not going to get it invoke Std_EprintF ;ac022; mov NxtAdd,0 ; set return inc TermRead ; tell read to give up
Ret60: return
NoChecking: mov bx,DestHand ; get handle xor cx,cx xchg cx,NxtAdd jcxz Ret60 ; if nothing to write, forget it inc Written ; flag that we wrote something cmp NoWrite,0 ; if nowrite set, just seek cx bytes jne SeekEnd xor dx,dx push ds mov ds,Tpa assume ds:NOTHING mov ah,WRITE int 21h pop ds assume ds:TRANGROUP mov dx,offset TRANGROUP:NoSpace_Ptr jnc @f jmp Xa_Set_Error ;AC022; failure @@: sub cx,ax retz ; wrote all supposed to test DestIsDev,DEVID_ISDEV jz CopErr ; is a file, error test DestIsDev,DEVID_RAW jnz DevWrtErr ; is a raw device, error cmp Inexact,0 retnz ; inexact so ok dec cx retz ; wrote one byte less (the ^z)
DevWrtErr: mov dx,offset TRANGROUP:DevWMes_Ptr jmp short CopErr
SeekEnd: xor dx,dx ; zero high half of offset xchg dx,cx ; cx:dx is seek location mov ax,(LSEEK shl 8) or 1 int 21h ; seek ahead in the file
; Save the file pointer in DX:AX to restore the file ; with in case the copy should fail.
mov OFilePtr_Lo,ax mov OFilePtr_Hi,dx
cmp RdEof,0 retz ; EOF not read yet
; ^Z has been read - we must set the file size to the current ; file pointer location
mov ah,WRITE int 21h ; cx is zero, truncates file jc Xa_Set_Error_Jmp ;AC022; failure
; Make note that ^Z was removed, in case the ; copy should fail and we need to restore the file.
mov OCtrlZ,1Ah
return
public CopErr CopErr: invoke Std_EPrintF ;AC022;
CopErrP: inc DestClosed cmp CFlag,0 je EndCopyJ ; never actually got it open mov bx,DestHand cmp bx,0 jle NoClose
; Check to see if we should save part of the destination file.
mov cx,OFilePtr_Hi ; CX = hi word of original file ptr mov dx,OFilePtr_Lo ; DX = lo word of original file ptr
mov ax,cx or ax,dx jz ceClose ; null file ptr means nothing to save
; Destination was also the first source. Do the best we can to ; restore it. Truncate it back to the size we took from it (which ; may have been due to a Ctrl-Z, so may not have included the whole ; file). If a Ctrl-Z was originally read, put it back.
mov ax,LSEEK shl 8 int 21h
xor cx,cx ; CX = # bytes to write = 0 mov ah,WRITE int 21h ; truncate file
cmp OCtrlZ,0 je @f ; no ctrl-z removed from original inc cx ; CX = # bytes to write = 1 mov dx,offset TRANGROUP:OCtrlZ ; DS:DX = ptr to original ctrl-z mov ah,WRITE int 21h ; write ctrl-z @@: mov ah,CLOSE int 21h ; close it ;; mov CFlag,0 jmp EndCopy ; and go home
ceClose: mov ah,CLOSE ; close the file int 21h
NoClose: mov dx,offset TRANGROUP:DestBuf mov ah,UNLINK int 21h ; and delete it mov CFlag,0
EndCopyJ: jmp EndCopy
Xa_Set_Error_Jmp: ;AN022; go set up error message jmp Xa_Set_Error ;AN022;
TRANCODE ends end
|