2025-04-27 07:49:33 -04:00

345 lines
7.7 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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