WindowsXP-SP1/base/ntsetup/opktools/oformat/forexec.asm
2020-09-30 16:53:49 +02:00

571 lines
14 KiB
NASM
Raw 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.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
;*****************************************************************************
;*****************************************************************************
;UTILITY NAME: FORMAT.COM
;
;MODULE NAME: FOREXEC.SAL
;
;
;
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ³EXEC_FS_FORMAT³
; ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÙ
; ³
; ³ÚÄÄÄÄÄÄ¿
; ôShrink³
; ³ÀÄÄÄÄÄÄÙ
; ³ÚÄÄÄÄÄÄÄÄÄÄ¿
; ôSetup_EXEC³
; ³ÀÄÄÄÄÄÄÄÄÄÄÙ
; ³ÚÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ôEXEC_ArgVÃÄÄÄÄÄÄÄÄÄÄ´EXEC_Program³
; ³ÀÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ôEXEC_Cur_DirectoryÃÄ´EXEC_Program³
; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
; À´EXEC_RoutineÃÄÄÄÄÄÄÄ´Build_Path_And_EXECÃÄ´EXEC_Program³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
;
; Change List: AN000 - New code DOS 3.3 spec additions
; AC000 - Changed code DOS 3.3 spec additions
;*****************************************************************************
;*****************************************************************************
title DOS 3.30 FORMAT EXEC Module
IF1
%OUT ASSEMBLING: DOS 3.3 FORMAT EXEC LOADER
%OUT
ENDIF
code segment public para 'code'
assume cs:code
code ends
;*****************************************************************************
; Include files
;*****************************************************************************
.xlist
INCLUDE FORCHNG.INC
INCLUDE FORMACRO.INC
INCLUDE SYSCALL.INC
INCLUDE FOREQU.INC
.list
;*****************************************************************************
; Public Data
;*****************************************************************************
Public Drive_Letter_Msg
;*****************************************************************************
; Public Routines
;*****************************************************************************
IF FSExec
Public EXEC_FS_Format
ENDIF ;FSExec ;end /FS: conditional
;***************************************************************************
; External Data Declarations
;***************************************************************************
extrn ExitStatus:Byte
extrn Fatal_Error:Byte
extrn FS_String_Buffer:Byte
extrn msgEXECFailure:Byte
extrn PSP_Segment:Word
extrn DriveToFormat:byte
;**************************************************************************
; Structures
;**************************************************************************
Exec_Block_Parms struc
Segment_Env dw 0
Offset_Command dw 0
Segment_Command dw 0
Offset_FCB1 dw 0
Segment_FCB1 dw 0
Offset_FCB2 dw 0
Segment_FCB2 dw 0
Exec_Block_Parms ends
;**************************************************************************
; Equates
;**************************************************************************
String_Done equ 0
No_Error equ 0
Error equ 1
Stderr equ 2
Stack_Space equ 02eh ; IBM addition ROM paras
;**************************************************************************
; PSP Area
;**************************************************************************
PSP segment public para 'DUMMY'
org 2Ch
PSP_ENV_SEGMENT label word
FCB1 equ 5Ch
FCB2 equ 6Ch
org 80h
Command_Line label byte
PSP ends
;**************************************************************************
; Data Area
;**************************************************************************
data segment public para 'DATA'
assume ds:data,es:nothing
Exec_Block Exec_Block_Parms <>
EXEC_Path db 66 dup(0)
Drive_Letter_Msg db "A:",0 ;Drive for exec fail message
SP_Save dw ?
SS_Save dw ?
;These next two should stay togather
; ---------------------------------------
Path_String db "PATH="
Len_Path_String equ $ - Path_String
;----------------------------------------
;These should stay togather
; ---------------------------------------
Search_FORMAT db "FORMAT"
Len_Search_FORMAT equ $ - Search_FORMAT
Search_Format_End equ $
;----------------------------------------
;These next two should stay togather
; ---------------------------------------
data ends
;**************************************************************************
code segment public para 'code'
assume cs:code,ds:data
;**************************************************************************
; Main Routine
;**************************************************************************
IF FSExec ;if /FS: desired
Procedure Exec_FS_Format
Set_Data_Segment
call Set_FCB1_Drive
call Shrink
mov al,ExitStatus ;Setblock fail?
cmp al,Error
JE $$IF1
call Setup_Exec
call Exec_Argv ;try exec from dir BASIC loaded
mov al,ExitStatus
cmp al,Error
JNE $$IF2
call Exec_Cur_Directory
mov al,ExitStatus ;Try exec from cur directory
cmp al,Error
JNE $$IF2
call EXEC_Routine
mov al,ExitStatus
cmp al,Error
JNE $$IF2
push ds ;save ds
push si ;save si
mov si,PSP_Segment ;get psp
mov ds,si ;put psp in ds
assume ds:PSP
mov si,FCB1 ;ptr to 1st. FCB
mov bl,byte ptr ds:[si] ;get drive ID
pop si ;restore si
pop ds ;restore ds
Set_Data_Segment ;set segments
cmp bl,0 ;Is it default drive?
JNE $$IF3
push ax ;Save exit code
DOS_Call Get_Default_Drive ;Get the default drive
add al,"A" ;Turn into drive letter
mov Drive_Letter_Msg,al ;Save it in message
pop ax ;Get return code back
JMP SHORT $$EN3
$$IF3:
add bl,"A"-1 ;Convert to drive letter
mov Drive_Letter_Msg,bl
$$EN3:
Message msgEXECFailure
JMP SHORT $$EN2
$$IF2:
DOS_Call WaitProcess
mov ExitStatus,al
$$EN2:
$$IF1:
mov Fatal_Error,YES ;Not really, indicates FS used
ret
Exec_FS_Format endp
;****************************************************************************
; Shrink
;****************************************************************************
Procedure Shrink
mov ax,cs ;get code segment
mov bx,ds ;get data segment
sub ax,bx ;data seg size
mov bx,ax ;save paras
mov ax,offset End_Program ;Get the offset of end of loader
mov cl,4 ;Div by 16 to get para's
shr ax,cl
add bx,ax ;add in code space
add bx,Stack_Space ;adjust for stack
add bx,11h ;give PSP space
mov ax,PSP_Segment
mov es,ax
assume es:nothing
DOS_Call SetBlock
JNC $$IF9
Message msgEXECFailure
mov ExitStatus,Error ;Bad stuff, time to quit
$$IF9:
ret
Shrink endp
;**************************************************************************
; Setup_Exec
;**************************************************************************
Procedure Setup_Exec
Set_Data_Segment
mov ax,PSP_Segment ;Get segment of PSP
mov ds,ax
assume ds:PSP
;Setup dword pointer to command line to be passed
mov es:Exec_Block.Segment_Command,ax ;Segment for command line
mov es:Exec_Block.Offset_Command,offset ds:Command_Line
;Setup dword pointer to first FCB to be passed
mov es:Exec_Block.Segment_FCB1,ax ;Segment for FCB1
mov es:Exec_Block.Offset_FCB1,offset ds:FCB1 ;Offset of FCB at 05Ch
;Setup dword pointer to second FCB to be passed ;
mov es:Exec_Block.Segment_FCB2,ax ;Segment for FCB2
mov es:Exec_Block.Offset_FCB2,offset ds:FCB2 ;Offset of FCB at 06Ch
;Setup segment of Environment string, get from PSP ;
mov ax,ds:PSP_Env_Segment
mov es:Exec_Block.Segment_Env,ax
Set_Data_Segment
ret
Setup_EXEC endp
;****************************************************************************
; Exec_Argv
;****************************************************************************
;
; Read the environment to get the Argv(0) string, which contains the drive,
; path and filename that was loaded for FORMAT.COM. This will be used to find
; the xxxxxfmt.exe, assuming that it is in the same location or path as
; FORMAT.COM
;
Procedure EXEC_Argv
Set_Data_Segment ;DS,ES = DATA
cld
mov ax,Exec_Block.Segment_Env ;Get the environment
mov ds,ax ;Get addressability
assume ds:nothing
xor si,si ;Start at beginning
$$DO11:
$$DO12:
inc si ;Get character
cmp byte ptr [si-1],0 ;Find string seperator?
JNE $$DO12
inc si ;Get next char
cmp byte ptr [si-1],0 ;Are we at Argv(0)? (00?)
JNE $$DO11
add si,2 ;Skip the word count
mov di,si ;Save where string starts
$$DO15: ;Find length of Argv(0) string
inc si ;Get char
cmp byte ptr [si-1],0 ;Is it the end?
;End found if 0 found
JNE $$DO15
mov cx,si ;Get number of bytes in string
sub cx,di ;Put in cx reg for rep count
mov si,di ;Point to path
mov di,offset es:EXEC_Path ;Point to where to put it
rep movsb ;Move the string
Set_Data_Segment
dec di ;Point at end of ArgV string
std ;Look backwards
$$DO17: ;Find 'FORMAT' in ARGV string
mov cx,Len_Search_FORMAT ;Get length to compare
mov si,offset Search_FORMAT_End-1 ;Look at comp string from end
repe cmpsb ;See if same string
JNE $$DO17
mov si,offset FS_String_Buffer
inc di ;DI = replacement point-1
cld ;Set direction flag back
mov cx,Len_FS_String_Buffer ;Length of string to move
rep movsb ;Build part of the path
call EXEC_Program
ret
EXEC_ArgV endp
;****************************************************************************
; EXEC_Program
;****************************************************************************
Procedure EXEC_Program
Set_Data_Segment
mov ExitStatus,No_Error ;Setup to Exec the file
mov dx,offset Exec_Path
mov bx,offset Exec_Block
mov al,0
mov word ptr SP_Save,sp ;save sp
mov word ptr SS_Save,ss ;save ss
DOS_Call Exec
cli ;turn off int's
mov sp,word ptr SP_Save ;retrieve sp
mov ss,word ptr SS_Save ;retrieve ss
sti ;turn on int's
; $IF C ;CY means failure
JNC $$IF19
mov ExitStatus,Error ;Set error code
; $ENDIF
$$IF19:
ret
EXEC_Program endp
;****************************************************************************
; EXEC_Routine
;****************************************************************************
Procedure EXEC_Routine
Set_Data_Segment
mov ExitStatus,Error ;Assume the worst
cld
push ds
mov ax,Exec_Block.Segment_Env ;Get the environment
mov ds,ax ;Get addressability
assume ds:nothing
xor si,si ;Start at beginning
; $SEARCH
$$DO21:
cmp word ptr ds:[si],0 ;End of the Evironment?
; $EXITIF E ;Reached end, no more look
JNE $$IF21
; $ORELSE ;Look for 'PATH=' in environment
JMP SHORT $$SR21
$$IF21:
mov di,offset Path_String
mov cx,Len_Path_String
repe cmpsb
; $LEAVE E ;Found if EQ
JE $$EN21
; $ENDLOOP ;Found PATH in environment
JMP SHORT $$DO21
$$EN21:
call Build_Path_And_Exec
; $ENDSRCH
$$SR21:
pop ds
ret
EXEC_Routine endp
;****************************************************************************
; Build_Path_For_EXEC
;****************************************************************************
Procedure Build_Path_And_Exec
$$DO27:
cmp byte ptr ds:[si],0 ;All path entries done?
JE $$IF28
mov di,offset EXEC_Path ;Point at where to put path
mov byte ptr es:[di],0 ;End path just in case
$$DO29:
cmp byte ptr ds:[si],0 ;End of Path?
JE $$EN29
cmp byte ptr ds:[si],';' ;End of entry?
JNE $$IF31
inc si ;point to next character
jmp EXIT_BPE_LOOP ;exit loop
$$IF31:
movsb ;Put char in path string
JMP SHORT $$DO29
$$EN29:
EXIT_BPE_LOOP:
;Path filled in,get backslash
cmp byte ptr ds:[si-1],0 ;Any path there?
JE $$IF34
;Nope
cmp byte ptr ds:[si-1],"\" ;Need a backslash? ;
JE $$IF35
mov byte ptr es:[di],"\" ;Yes, put one in ;
inc di ;Line it up for next stuff
inc si
$$IF35:
push si ;Save place in path
push ds ;Save segment for environment
push es ;Xchange ds/es
pop ds
mov si,offset FS_String_Buffer ;Fill in filename
mov cx, Len_FS_String_Buffer
rep movsb
call Exec_Program
cmp ExitStatus,No_Error ;E if EXEC okay
pop ds ;Get Env segment back
pop si ;Get place in path back
$$IF34:
$$IF28:
JNE $$DO27
ret
Build_Path_And_EXEC Endp
;**************************************************************************
; Exec_Cur_Directory
;**************************************************************************
Procedure Exec_Cur_Directory
Set_Data_Segment
mov si,offset FS_String_Buffer ;Setup path for current dir
mov di,offset EXEC_Path
mov cx,Len_FS_String_Buffer
rep movsb
call EXEC_Program
ret
EXEC_Cur_Directory endp
;=========================================================================
; Set_FCB1_Drive : This routine sets the 1st. byte of the FCB1,
; the drive identifier, to the default drive.
;=========================================================================
Procedure Set_FCB1_Drive ;set drive ID
push ds ;save ds
push si ;save si
mov si,PSP_Segment ;get segment of PSP
mov ds,si ;put it in ds
assume ds:PSP
mov si,FCB1 ;ptr to FCB1
mov byte ptr ds:[si],00h ;set drive ID to
; default drive
pop si ;restore si
pop ds ;restore ds
Set_Data_Segment ;set up segmentation
ret
Set_FCB1_Drive endp
ENDIF ;FSExec ;end /FS: conditional
;assembly
;**************************************************************************
public End_Program
End_Program label byte
;**************************************************************************
code ends
end