Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1249 lines
29 KiB

;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
;===========================================================================
;
; FILE: .ASM
;
;===========================================================================
;===========================================================================
;Declaration of include files
;===========================================================================
debug equ 0
.xlist
INCLUDE DOSEQUS.INC
INCLUDE DOSMAC.INC
INCLUDE SYSCALL.INC
INCLUDE ERROR.INC
INCLUDE DIRENT.INC
INCLUDE BPB.INC
INCLUDE FOREQU.INC
INCLUDE FORMACRO.INC
.list
;
;---------------------------------------------------------------------------
;
; M029 : Remove the assumption that COMSPEC= has an absolute path name.
; and build the file name (COMMAND.COM) in a different buffer
; other than the buffer in which COMSPEC was stored.
;
;---------------------------------------------------------------------------
;
;===========================================================================
; Data segment
;===========================================================================
DATA SEGMENT PUBLIC PARA 'DATA'
;===========================================================================
; Declarations for all publics in other modules used by this module
;===========================================================================
;Bytes
EXTRN DriveLetter :BYTE
EXTRN SystemDriveLetter :BYTE
EXTRN Extended_Error_Msg :BYTE
EXTRN BiosFile :BYTE
EXTRN AltBiosFile :BYTE
EXTRN AltBiosLen :ABS
EXTRN MsdosFile :BYTE
EXTRN MsdosRemark :BYTE
EXTRN MsdosRemarkLen :ABS
IFDEF DBLSPACE_HOOKS
EXTRN fDblSpace :BYTE
ENDIF
;Words
EXTRN mStart :WORD
EXTRN mSize :WORD
EXTRN Environ_Segment :WORD
EXTRN PSP_Segment :WORD
;Pointers
;Structures
EXTRN Bios :BYTE
EXTRN dos :BYTE
EXTRN command :BYTE
IFDEF DBLSPACE_HOOKS
EXTRN DblSpaceBin :BYTE
ENDIF
BiosAttributes equ attr_hidden + attr_system + attr_read_only
DosAttributes equ attr_hidden + attr_system + attr_read_only
IFDEF DBLSPACE_HOOKS
DblSpaceAttributes equ attr_hidden + attr_system + attr_read_only
ENDIF
CommandAttributes equ 0
CommandFile db "X:\COMMAND.COM",0
db (128 - 15) DUP (0) ; M012
Comspec_ID db "COMSPEC=",00 ; Comspec target
; DOS status bits in FileStat are unused.
; Starting with Chicago, IO.SYS and MSDOS.SYS have been combined.
; For our purposes, the single file will be referred to as BIOS.
FileStat db ? ; In memory Status of files
; XXXXXX00B BIOS not in
; XXXXXX01B BIOS partly in
; XXXXXX10B BIOS all in
; XXXX00XXB DOS not in
; XXXX01XXB DOS partly in
; XXXX10XXB DOS all in
; XX00XXXXB COMMAND not in
; XX01XXXXB COMMAND partly in
; XX10XXXXB COMMAND all in
Command_Com DB "X:\COMMAND.COM",0 ; M029
IFDEF DBLSPACE_HOOKS
DblSpaceFile db "X:\DRVSPACE.BIN",0 ;full path to source copy
db 64 DUP (0) ; of DRVSPACE.bin
DblSpaceTargetName db "X:\" ;target DRVSPACE.bin name
DblSpaceBase db "DRVSPACE.BIN",0 ;base name used to srch PATH
ENDIF
DOS_BUFFER db 45 dup (?) ; Find First/Next buffer
TempHandle dw ?
IOCNT dd ?
DATA ENDS
;===========================================================================
; Executable code segment
;===========================================================================
CODE SEGMENT PUBLIC PARA 'CODE'
ASSUME CS:CODE, DS:DATA, ES:DATA
;===========================================================================
; Declarations for all publics in other modules used by this module
;===========================================================================
;Functions
EXTRN SysPrm :NEAR
EXTRN TargPrm :NEAR
EXTRN Get_PSP_Parms :NEAR
EXTRN Cap_Char :NEAR
;Labels
EXTRN FatalExit :NEAR
EXTRN Find_Path_In_Environment:NEAR
EXTRN Path_Crunch :NEAR
EXTRN Search :NEAR
;===========================================================================
; Declarations for all publics in this module
;===========================================================================
PUBLIC ReadDos
PUBLIC WriteDos
PUBLIC CommandFile
IFDEF DBLSPACE_HOOKS
PUBLIC DblSpaceFile
ENDIF
PUBLIC FileStat
; ==========================================================================
; Copy WINBOOT.SYS, COMMAND.COM, and DRVSPACE.BIN (if present) into
; data area.
; Carry set if problems
; M011; SystemDriveLetter=Drive to Try
; ==========================================================================
ReadDos:
;M011 - begin
xor ax, ax
mov Bios.FileSizeInParagraphs, ax ; Initialize file sizes
mov Command.FileSizeInParagraphs, ax
IFDEF DBLSPACE_HOOKS
mov DblSpaceBin.FileSizeInParagraphs, ax
ENDIF
mov AL,SystemDriveLetter
mov [BiosFile],AL ; Stuff it in file specs.
mov [CommandFile],AL
IFDEF DBLSPACE_HOOKS
mov [DblSpaceFile], al
ENDIF
call Get_Bios
jnc RdFils
;M011 - end
return
RdFils:
mov BYTE PTR [FileStat],0
mov BX,[Bios.fileHandle]
mov AX,[mStart]
mov DX,AX
add DX,[mSize] ; CX first bad para
mov [Bios.fileStartSegment],AX
mov CX,[Bios.fileSizeInParagraphs]
add AX,CX
cmp AX,DX
jbe GotBios
mov BYTE PTR [FileStat],00000001B ; Got part of Bios
mov SI,[mSize]
xor DI,DI
call DISIX4
push DS
mov DS,[Bios.fileStartSegment]
assume DS:NOTHING
call ReadFile
pop DS
assume DS:data
jc ClsAll
xor DX,DX
mov CX,DX
mov AX,(LSEEK shl 8) OR 1
int 21H
mov WORD PTR [Bios.fileOffset],AX
mov WORD PTR [Bios.fileOffset+2],DX
FilesDone:
clc
ClsAll:
pushF
call FILE_CLS
popF
return
; ==========================================================================
GotBios:
mov BYTE PTR [FileStat],00000010B ; Got all of Bios
push ES
les SI,[Bios.fileSizeInBytes]
mov DI,ES
pop ES
push DS
mov DS,[Bios.fileStartSegment]
assume DS:nothing
call ReadFile
pop DS
assume DS:data
jc ClsAll
push AX
push DX
call File_Cls
call Get_DOS
pop DX
pop AX
ClsAllJ:
jnc notClsAll
jmp ClsAll
NotClsAll:
push AX
push DX
call Get_Command_Path ; get path of COMMAND.COM
call Get_Command ; Point to COMMAND and read it
pop DX
pop AX
jnc Found_Command
return
; ==========================================================================
Found_COMMAND:
mov BX,[command.fileHandle]
mov [command.fileStartSegment],AX
cmp AX,DX ; No room left?
jz ClsAllJ ; Yes
mov CX,[command.fileSizeInParagraphs]
add AX,CX
cmp AX,DX
jbe GotCom
or BYTE PTR [FileStat],00010000B ; Got part of COMMAND
sub DX,[command.fileStartSegment]
mov SI,DX
xor DI,DI
call DISIX4
push DS
mov DS,[command.fileStartSegment]
assume DS:nothing
call ReadFile
pop DS
assume DS:data
jc ClsAllJ
xor DX,DX
mov CX,DX
mov AX,(LSEEK shl 8) OR 1
int 21h
mov WORD PTR [command.fileOffset],AX
mov WORD PTR [command.fileOffset+2],DX
jmp FilesDone
GotCom:
or BYTE PTR [FileStat],00100000B ; Got all of COMMAND
push ES
les SI,[command.fileSizeInBytes]
mov DI,ES
pop ES
push DS
mov DS,[command.fileStartSegment]
assume DS:nothing
call ReadFile
pop DS
assume DS:data
jc ClsAllJ
IFDEF DBLSPACE_HOOKS
; Attempt to locate dblspace.bin
push ax
push dx
call File_cls ; close COMMAND.COM
call Get_DblSpace
pop dx
pop ax
jnc Found_DblSpace
; DblSpace.bin is nowhere to be found! This isn't fatal, clear
; carry and return.
clc
return
; ==========================================================================
; DblSpace.bin has been located, will it fit in memory?
; AX has next free location in memory buffer, DX has
; (just past) end of buffer address.
Found_DblSpace:
mov bx, [DblSpaceBin.fileHandle]
mov [DblSpaceBin.fileStartSegment], ax
cmp ax, dx ; any room left?
jz ClsAllJ2 ; no!
mov cx, [DblSpaceBin.fileSizeInParagraphs]
add ax, cx
cmp ax, dx
jbe GotDblSpace
;
; No mem for dblspace driver. Lets not count its size towards SysSiz
;
mov word ptr [DblSpaceBin.fileSizeInBytes], 0
mov word ptr [DblSpaceBin.fileSizeInBytes].2, 0
;
; BUGBUG :: Display a warning message
;
ClsAllJ2: ; insufficient memory, skip
jmp ClsAll ; DRVSPACE.bin (CY is clear)
GotDblSpace:
mov [fDblSpace], TRUE ; got it!
mov si, word ptr [DblSpaceBin.fileSizeInBytes]
mov di, word ptr [DblSpaceBin.fileSizeInBytes+2] ; di:si = size
push ds
mov ds, [DblSpaceBin.fileStartSegment] ; ds:0 = addr
assume ds:nothing
call ReadFile ; load it
pop ds
assume ds:data
ENDIF
jmp ClsAll
; ==========================================================================
; Write Bios DOS COMMAND to the newly formatted disk.
; ==========================================================================
ASSUME DS:DATA
WriteDos:
mov CX,BiosAttributes
mov DX,OFFSET BiosFile ; DS:DX --> ASCIIZ pathname
push ES
les SI,[Bios.fileSizeInBytes]
mov DI,ES ; DI:SI is file size
pop ES
call MakeFil ; create & open file in dest. drive
retc
mov [TempHandle],BX ; save file handle
test BYTE PTR FileStat,00000010B ; is BIOS all in already?
jnz GotAllBio ; yes, write it out
call Get_Bios ; no, read it in
jnc Got_WBios ; check for error
ret
; ==========================================================================
Got_WBios:
push ES
LES SI,[Bios.fileOffset]
mov DI,ES ; DI:SI is file pointer
pop ES
mov WORD PTR [IOCNT],SI
mov WORD PTR [IOCNT+2],DI
mov BP,OFFSET Bios ; BP --> parameter block for BIOS file
call GotTArg
retc
jmp SHORT BiosDone
GotAllBio:
push ES
LES SI,[Bios.fileSizeInBytes]
mov DI,ES ; DI:SI is BIOS file size
pop ES
push DS
mov DS,[Bios.fileStartSegment] ; DS:0 --> start of BIOS in memory
assume DS:nothing
call WriteFile ; write BIOS to disk
pop DS
assume DS:data
BiosDone:
mov BX,[TempHandle]
mov CX,Bios.fileTime
mov DX,Bios.fileDate
call CloseTarg ; close BIOS file on target disk
cmp [MsdosFile],0
je skip_msdos
mov CX,DosAttributes
mov DX,OFFSET MsdosFile ; DS:DX --> ASCIIZ pathname
sub si,si
sub di,di ; DI:SI is file size
call MakeFil ; create & open file in dest. drive
jc skip_msdos
call Get_Dos
mov dx,offset MsdosRemark
mov cx,word ptr [dos.fileSizeInBytes]
mov ah,WRITE
int 21h
mov CX,Bios.fileTime
mov DX,Bios.fileDate
call CloseTarg ; close dummy MSDOS file on target disk
skip_msdos:
mov CX,CommandAttributes
;M029 call Command_Root ;adjust path for
;M029 ;COMMAND.COM creation
mov DX,OFFSET Command_Com ; M029
push ES
les SI,[command.fileSizeInBytes]
mov DI,ES
pop ES
call MakeFil
retc
mov [TempHandle],BX
test BYTE PTR FileStat,00100000B
jnz GotAllCom
call Get_COMMAND
jnc Got_WCOM
ret
Got_WCOM:
mov BP,OFFSET command ; BP --> parameter block for COMMAND file
test BYTE PTR FileStat,00010000B
jnz PartCom
mov WORD PTR [command.fileOffset],0
mov WORD PTR [command.fileOffset+2],0
call GETSYS3
retc
jmp SHORT ComDone
PartCom:
push ES
LES SI,[command.fileOffset]
mov DI,ES
pop ES
mov WORD PTR [IOCNT],SI
mov WORD PTR [IOCNT+2],DI
call GotTArg
retc
jmp SHORT ComDone
GotAllCom:
push ES
les SI,[command.fileSizeInBytes]
mov DI,ES
pop ES
push DS
mov DS,[command.fileStartSegment]
assume DS:nothing
call WriteFile
pop DS
assume DS:data
ComDone:
mov BX,[TempHandle]
mov CX,command.fileTime
mov DX,command.fileDate
call CloseTarg
IFDEF DBLSPACE_HOOKS
; Write dblspace.bin to target disk if it was located and loaded
; into memory.
cmp [fDblSpace], TRUE ;Have it?
jne WriteDosDone ; no...
mov cx, DblSpaceAttributes ;Create file on
mov dx, offset DblSpaceTargetName ; target disk
mov si, word ptr [DblSpaceBin.fileSizeInBytes]
mov di, word ptr [DblSpaceBin.fileSizeInBytes+2]
call MakeFil
retc
mov [TempHandle], bx
mov si, word ptr [DblSpaceBin.fileSizeInBytes]
mov di, word ptr [DblSpaceBin.fileSizeInBytes+2]
push ds
mov ds, [DblSpaceBin.fileStartSegment]
assume ds:nothing
call WriteFile ;Write dblspace.bin image
pop ds
assume ds:data
mov bx, [TempHandle] ;Set time/date, close
mov cx, [DblSpaceBin.fileTime] ; DblSpace.bin
mov dx, [DblSpaceBin.fileDate]
call ClosetArg
WriteDosDone:
ENDIF
clc
return
; ==========================================================================
; Create a file on target disk
; CX = attributes, DX points to name
; DI:SI is size file is to have
;
; There is a bug in DOS 2.00 and 2.01 having to do with writes
; from the end of memory. In order to circumvent it this routine
; must create files with the length in DI:SI
;
; On return BX is handle, carry set if problem
; ==========================================================================
MakeFil:
mov BX,DX ; BX --> ASCIIZ pathname
push WORD PTR [BX] ; save drive letter in pathname
mov AL,DriveLetter
mov [BX],AL ; set new drive letter in pathname
mov AH,CREAT
int 21H ; create the file on disk
pop WORD PTR [BX] ; restore original drive letter in pathname
mov BX,AX ; save handle in BX
jc CheckMany
mov CX,DI
mov DX,SI ; CX:DX is size of file
mov AX,LSEEK shl 8
int 21H ; Seek to eventual EOF
xor CX,CX
mov AH,WRITE
int 21H ; Set size of file to position
xor CX,CX
mov DX,CX
mov AX,LSEEK shl 8
int 21H ; Seek back to start
return
; ==========================================================================
; Examine error code in AX to see if it is too-many-open-files.
; If it is, we abort right here. Otherwise we return.
; ==========================================================================
CheckMany:
cmp AX,error_too_many_open_files
retnz
Extended_Message
jmp FatalExit
;*********************************************
; Close a file on the target disk
; CX/DX is time/date, BX is handle
CloseTarg:
mov AX,(FILE_TIMES shl 8) OR 1
int 21H
mov AH,CLOSE
int 21H
return
;****************************************
; Transfer system files
; BP points to data structure for file involved
; offset is set to current amount read in
; Start set to start of file in buffer
; TempHandle is handle to write to on target
IoLoop:
mov AL,[SystemDriveLetter]
cmp AL,[DriveLetter]
jnz GotTArg
mov AH,DISK_RESET
int 21H
call TargPrm ;Get target disk
; ==========================================================================
; Enter here if some of file is already in buffer, IOCNT must be set
; to size already in buffer.
; ==========================================================================
ASSUME DS:DATA
GotTArg:
mov BX,[TempHandle]
mov SI,WORD PTR [IOCNT]
mov DI,WORD PTR [IOCNT+2]
push DS
mov DS,DS:[BP.fileStartSegment]
assume DS:nothing
call WriteFile ; Write next part
pop DS
assume DS:data
retc
push ES
LES AX,DS:[BP.fileOffset]
cmp AX,WORD PTR DS:[BP.fileSizeInBytes] ; has all the file been written?
jnz GETSYS3 ; no, read rest in
mov AX,ES
cmp AX,WORD PTR DS:[BP.fileSizeInBytes+2]
jnz GETSYS3
pop ES
return ; Carry clear from cmp
GETSYS3:
; ==========================================================================
; Enter here if none of file is in buffer
; (or none of what remains to be written is in buffer)
; ==========================================================================
pop ES
mov AH,DISK_RESET
int 21H
mov AX,[mStart] ; Furthur IO done start here
mov DS:[BP.fileStartSegment],AX ; point to start of buffer
mov AL,[SystemDriveLetter] ; see if we have system disk
cmp AL,[DriveLetter]
jnz TestSys
gSys:
; Need to prompt for system disk
; call File_Cls ;SA; close file that was opened
mov AH,DISK_RESET
int 21H
call SysPrm ; Prompt for system disk
; inc NeedSysDisk ;SA;signal need for sys disk
; stc ;SA;force return to caller
; ret ;SA;handle SysPrm in WriteSysFiles
TestSys:
; call TestSysDISK
jc gSys ; repeat prompt if needed
mov BX,WORD PTR DS:[BP.fileHandle] ; CS over ARR 2.30
push ES
LES DX,dWORD PTR DS:[BP.fileOffset] ; CS over ARR 2.30
mov CX,ES ; CX:DX = required offset in file
pop ES
push DX
mov AX,LSEEK shl 8
int 21H
pop DX
push ES
LES SI,dWORD PTR DS:[BP.fileSizeInBytes] ; CS over
mov DI,ES ; put high word in di
pop ES
SUB SI,DX ; get low word value
SBB DI,CX ; DI:SI is #bytes to go
push DI
push SI
add SI,15 ; round up 1 para
ADC DI,0 ; pick up carry
call DISID4 ; div 16 to get para count
mov AX,SI ; put para count in AX
pop SI ; restore bytes remaining
pop DI ; restore bytes remaining
cmp AX,[mSize] ; enough memory for remainder?
jbe GOTSIZ2 ; yes
mov SI,[mSize]
xor DI,DI
call DISIX4
GOTSIZ2:
mov WORD PTR [IOCNT],SI ; save byte count for read
mov WORD PTR [IOCNT+2],DI
push DS
mov DS,[mStart]
assume DS:nothing
call ReadFile
pop DS
assume DS:data
jnc GetOffs
call ClsAll
jmp gSys
GetOffs:
xor DX,DX ; clear DX
mov CX,DX ; clear CX
mov AX,(LSEEK shl 8) OR 1
int 21H
mov WORD PTR DS:[BP.fileOffset],AX
mov WORD PTR DS:[BP.fileOffset+2],DX
jmp IoLoop
; ==========================================================================
; Test to see if correct system disk. Open handles
; ==========================================================================
CRET12:
stc
return
; ==========================================================================
; TestSysDISK:
; ==========================================================================
Get_Bios:
mov AX,OPEN shl 8
mov DX,OFFSET BiosFile ; DS:DX --> ASCIIZ pathname
int 21H
jnc SetBios
push es
push ds
pop es
mov cx,AltBiosLen
lea si,AltBiosFile
mov di,dx
mov al,[di]
mov [MsdosFile],al
add di,3
cld
rep movsb
pop es
mov AX,OPEN shl 8
int 21H
jnc SetBios
jmp CheckMany
SetBios:
mov [Bios.fileHandle],AX ; save file handle
mov BX,AX ; BX = file handle
call GetFsiz
cmp [Bios.fileSizeInParagraphs],0
jz SetBioSize
cmp [Bios.fileSizeInParagraphs],AX
jz SetBioSize
BiosCls:
mov AH,CLOSE
mov BX,[Bios.fileHandle]
int 21h
ret
; ==========================================================================
SetBioSize:
mov [Bios.fileSizeInParagraphs],AX
mov WORD PTR [Bios.fileSizeInBytes],SI
mov WORD PTR [Bios.fileSizeInBytes+2],DI
mov [Bios.fileDate],DX
mov [Bios.fileTime],CX
clc
ret
; ==========================================================================
Get_COMMAND:
mov AX,OPEN shl 8
mov DX,OFFSET CommandFile
int 21H
jnc GotComHand
jmp CheckMany
Get_DOS:
mov WORD PTR [dos.fileSizeInBytes],MsdosRemarkLen
mov WORD PTR [dos.fileSizeInBytes+2],0
ret
GotComHand:
mov [command.fileHandle],AX
mov BX,AX
call GetFsiz
cmp [command.fileSizeInParagraphs],0
jz SetComSize
cmp [command.fileSizeInParagraphs],AX
jz SetComSize
ComCls:
mov AH,CLOSE
mov BX,[command.fileHandle]
int 21H
ret
; ==========================================================================
SetComSize:
mov [command.fileSizeInParagraphs],AX
mov WORD PTR [command.fileSizeInBytes],SI
mov WORD PTR [command.fileSizeInBytes+2],DI
mov [command.fileDate],DX
mov [command.fileTime],CX
CLC
return
IFDEF DBLSPACE_HOOKS
; ==========================================================================
Get_DblSpace:
mov AX,OPEN shl 8
mov DX,OFFSET DblSpaceFile
int 21H
jnc GotDblHand
; We didn't locate DblSpace.bin in the root directory, look for
; it along the PATH
call Find_DblSpace_on_Path ; sets CY if not found
retc
mov AX,OPEN shl 8 ; open the copy found
mov DX,OFFSET DblSpaceFile
int 21H
retc
GotDblHand:
mov [DblSpaceBin.fileHandle],AX
mov BX,AX
call GetFsiz
mov [DblSpaceBin.fileSizeInParagraphs],AX
mov WORD PTR [DblSpaceBin.fileSizeInBytes],SI
mov WORD PTR [DblSpaceBin.fileSizeInBytes+2],DI
mov [DblSpaceBin.fileDate],DX
mov [DblSpaceBin.fileTime],CX
CLC
return
ENDIF
; ==========================================================================
FILE_CLS:
mov AH,CLOSE
int 21H
ret
; ==========================================================================
; Handle in BX, return file size in para in AX
; File size in bytes DI:SI, file date in DX, file
; time in CX.
; ==========================================================================
GetFsiz:
mov AX,(LSEEK shl 8) OR 2
xor CX,CX
mov DX,CX
int 21h
mov SI,AX
mov DI,DX
add AX,15 ; Para round up
adc DX,0
and DX,0fH ; If file is larger than this
; it is bigger than the 8086
; address space!
mov CL,12
shl DX,CL
mov CL,4
shr AX,CL
or AX,DX
push AX
mov AX,LSEEK shl 8
xor CX,CX
mov DX,CX
int 21H
mov AX,FILE_TIMES shl 8
int 21H
pop AX
return
; ==========================================================================
; Read/Write file
; DS:0 is Xaddr
; DI:SI is byte count to I/O
; BX is handle
; Carry set if screw up
;
; I/O SI bytes
; I/O 64K - 1 bytes DI times
; I/O DI bytes
; ==========================================================================
ReadFile: ; Must preserve AX,DX
push AX
push DX
push BP
mov BP,READ shl 8
call FilIo
pop BP
pop DX
pop AX
return
WriteFile:
push BP
mov BP,WRITE shl 8
call FilIo
pop BP
return
FilIo:
xor DX,DX
mov CX,SI
jCXZ K64IO
mov AX,BP
int 21H
retc
add DX,AX
cmp AX,CX ; If not =, AX<CX, carry set.
retnz
call Normalize
K64IO:
CLC
mov CX,DI
jCXZ IoRet
mov AX,BP
int 21H
retc
add DX,AX
cmp AX,CX ; If not =, AX<CX, carry set.
retnz
call Normalize
mov CX,DI
K64M1:
push CX
xor AX,AX
OR DX,DX
jz NormIo
mov CX,10H
SUB CX,DX
mov AX,BP
int 21H
jc IoRetP
add DX,AX
cmp AX,CX ; If not =, AX<CX, carry set.
jnz IoRetP
call Normalize
NormIo:
mov CX,0FFFFH
SUB CX,AX
mov AX,BP
int 21H
jc IoRetP
add DX,AX
cmp AX,CX ; If not =, AX<CX, carry set.
jnz IoRetP
call Normalize ; Clears carry
pop CX
LOOP K64M1
push CX
IoRetP:
pop CX
IoRet:
return
; ==========================================================================
; Shift DI:SI left 4 bits
; ==========================================================================
DISIX4:
mov CX,4
@@:
shl SI,1
rcl DI,1
loop @B
return
; ==========================================================================
; Shift DI:SI right 4 bits
; ==========================================================================
DISID4:
mov CX,4
@@:
shr DI,1
rcr SI,1
loop @B
return
; ==========================================================================
; Normalize DS:DX
; ==========================================================================
Normalize:
push DX
push AX
SHR DX,1
SHR DX,1
SHR DX,1
SHR DX,1
mov AX,DS
add AX,DX
mov DS,AX
pop AX
pop DX
and DX,0FH ; Clears carry
return
;=========================================================================
; Get_Command_Path : This routine finds the path where
; COMMAND.COM resides based on the
; environmental vector. Once the
; path is found it is copied to
; CommandFile.
;
; Inputs : Exec_Block.Segment_Env - Segment of environmental vector
; Comspec_ID - "COMSPEC="
;
; Outputs : CommandFile - Holds path to COMMAND.COM
;=========================================================================
Procedure Get_Command_Path
push DS
push ES
Set_Data_Segment ; DS,ES = Data
call Get_PSP_Parms ; Gets PSP info.
cld ; Clear direction
mov AX,ES:Environ_Segment ; Get seg. of
; Environ. vector
mov DS,AX ; Put it in DS
assume DS:nothing
xor SI,SI ; Clear SI
;M012 - begin
GCP_WhileNotFound:
mov BX,SI ; Save SI
cmp byte ptr DS:[SI],0
jz GCP_NotFound
mov DI,offset Comspec_ID
mov CX,8 ; Loop 8 times
repe cmpsb ; "COMSPEC=" ?
jnz GCP_NotThisLine ; "COMSPEC=" not found
; "COMSPEC=" found
mov DI,offset ES:CommandFile
lodsb ; Priming read
; Copy COMSPEC even if COMSPEC drive != boot drive
; mov DL,AL ; Prepare for capitalization
; call Cap_Char ; Capitalize character in DL
; cmp DL,ES:CommandFile ; COMSPEC same as boot Drive?
; jne GCP_NotFound ; COMSPEC drive != boot drive
GCP_GetPath: ; While AL not = 0
stosb ; Save it
or al,al ; At end?
je GCP_Done ; Yes
lodsb ; Get character
jmp SHORT GCP_GetPath
GCP_NotThisLine:
mov SI,BX ; Restore SI
GCP_Find0Terminator:
lodsb ; Loop until past the first 0.
or al,al
jnz GCP_Find0Terminator
jmp GCP_WhileNotFound
GCP_NotFound:
; Nothing to do
; since commandfile is
; already patched to try
; in the root of the
; default or boot drive
GCP_Done:
;M012 - end
pop ES
pop DS
ret
Get_Command_Path ENDP
comment ^ ; M029
;
; This routine is no longer required ; M029
;
;=========================================================================
; Command_Root : This routine sets up CommandFile so that the
; COMMAND.COM will be written to the root.
; It does this by copying at offset 3 of CommandFile
; the literal COMMAND.COM. This effectively
; overrides the original path, but maintains the
; Drive letter that is to be written to.
;
; Inputs : CommandFile - Holds full path to default COMMAND.COM
; Outputs : CommandFile - Holds modified path to new COMMAND.COM
; on target Drive.
;=========================================================================
Procedure Command_Root
push DS
push ES
push DI
push SI
push CX
Set_Data_Segment
mov DI,offset CommandFile+3 ; Point to path past drive spec
mov SI,offset Command_Com ; Holds the literal COMMAND.COM
mov CX,000ch ; Len. of literal
rep movsb ; Move it
pop CX
pop SI
pop DI
pop ES
pop DS
ret
Command_Root ENDP
endcomment ^ ; M029
IFDEF DBLSPACE_HOOKS
;******************* START OF SPECIFICATIONS ***********************************
;Routine name: Find_DblSpace_on_Path
;*******************************************************************************
;
;Description: Search Path for DRVSPACE.bin
;
;Output: no error - CF = 0 DblSpaceFile filled in with
; full path to DRVSPACE.bin
; error - CF = 1 Dblspace.bin not found
;
; Cut and pasted from SYS command code: 12/07/92 JEM
;
;******************* END OF SPECIFICATIONS *************************************
Find_DblSpace_on_Path PROC NEAR
push es
push ds ; save our segments
push si ; save DTA address
mov ax, PSP_Segment
mov es, ax ; get our PSP to ES
call Find_Path_In_Environment ; returns ptr to path string in ES:DI
jc fdp_exit ; no path, can't find DRVSPACE.bin
assume es:nothing
mov ax,ds ; swap DS and ES
push es
pop ds
assume ds:nothing
mov si,di ; DS:SI ==> Path string
mov es,ax
assume es:data
fdp_path_loop:
mov bh,';' ; path separator character
mov dx,offset DblSpaceBase ; base file name
mov di,offset DblSpaceFile ; buffer to stick full path in
call Path_Crunch ; concatenate name and path
pushf ; save result
push ds ; save segment of Path
push es
pop ds
assume ds:data
mov dx,offset DblSpaceFile ; buffer with full path name
mov bx,offset DOS_BUFFER ; DMA buffer for finds
mov al,1 ; extension is specified
call Search
or al,al ; found the file?
pop ds ; recover path segment
assume ds:nothing
pop ax ; recover flags in AX
jnz fdp_exit ; found it!
xchg ah,al
sahf ; check Path_Crunch result
jnc fdp_path_loop
fdp_exit:
pop si
pop ds
pop es
assume ds:data
ret
Find_DblSpace_on_Path ENDP
ENDIF
CODE ENDS
END