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.
 
 
 
 
 
 

571 lines
14 KiB

;/*
; * 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