345 lines
7.7 KiB
NASM
345 lines
7.7 KiB
NASM
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
|
||
|