Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

375 lines
6.0 KiB

FindStruc struc
db 21 dup (?) ;reserved area
Attr db ? ;attribute of file
Time dw ? ;time of last write
Date dw ? ;date of last write
Fsize dd ? ;filesize
Fname db 13 dup (?) ;filename
FindStruc ends
CMDSIZE equ 94h ;current resident size of
;command.com is 94h paras
code segment byte public 'CODE'
assume cs:code, ds:code, es:code
org 100h
public start
start:
mov sp,offset MyStack ;set ss:sp to our stack
mov ax,offset EndProg
add ax,15
mov cl,4
shr ax,cl ;para size of this program
mov bx,ax ;bx = this program's size
mov cx,es
add ax,cx ;ax = top of this program
sub ax,1000h - CMDSIZE ;are we below the first 64K?
jae no_mem ;no, dont reserve memory
neg ax ;additional memory to be reserved
add bx,ax
no_mem: ;bx = #paras needed
mov ah,4ah
int 21h ;resize to desired size
;
;Prepare to execute the desired program
;
call Exec_prepare
jnc do_exec
mov al,1 ;return error
jmp short exit
do_exec:
cmp helpflg,1
je do_help
mov ah,4bh
mov dx,offset ExecPath
mov bx,offset ExecBlk
int 21h ;do the Exec
jc exec_err ;error while executing
;
;No error on execution. Get the return code of the program we executed and
;return that as our return code.
;
mov ah,4dh
int 21h ;al = return code now
exit:
mov ah,4ch
int 21h ;terminate ourselves
exec_err:
mov dx,offset ErrMsg ;Error executing command.com
mov al,1
call dispmsg
jmp short exit
do_help:
mov dx,offset HelpMsg ;Display help for loadfix
call dispmsg
xor al,al
jmp short exit
;***
;Dispmsg -- Displays messages that are terminated by '$'
;
;Input: ds:dx = pointer to message
;
;Output: None
;
;Registers: ax
;***
dispmsg proc near
mov ah,9
int 21h
ret
dispmsg endp
;***
;Exec_prepare -- Searches the environment for the COMSPEC and sets up the
;command line and FCBs for the Exec call
;
;Input: None
;
;Output: Carry set => error. Error message is displayed here
; Carry clear => all parameters set successfully
;
;Registers: ax, cx, dx, si, di
;***
Exec_prepare proc near
push ds
push es
mov si,81h ;ds:si points at our command line
call skip_white ;skip all leading whitespace
cmp byte ptr [si],0dh ;Did we hit a CR?
je no_parms ;yes, no parameters given
;
;Check if we have a /? here
;
cmp byte ptr [si],'/'
jne no_help
cmp byte ptr [si+1],'?'
jne no_help
inc helpflg ;/? given -- print help
jmp short exefnd
no_help:
mov dx,si ;ds:dx now points at the program
mov si,offset CmdOpt
mov di,offset CmdParms
inc di
mov cl,CmdOptLen
xor ch,ch
rep movsb
mov si,dx
xor cx,cx
st_lp:
lodsb
stosb
inc cx
cmp al,0dh
jne st_lp
dec cx
add cl,CmdOptLen ;command line cannot be >128
mov CmdParms,cl
mov si,offset CmdParms
mov word ptr CmdPtr,si
mov word ptr CmdPtr+2,cs ;store command line pointer
mov word ptr Fcb1+2,cs
mov word ptr Fcb2+2,cs
call find_comspec
jc no_comspec
mov si,offset ExecPath
xchg si,di
push ds
push es
pop ds
pop es
comspec_lp:
lodsb
stosb
or al,al
jnz comspec_lp
exefnd:
clc
execp_ret:
pop es
pop ds
ret
no_parms:
mov dx,offset NoParms
call dispmsg
stc
jmp short execp_ret
no_comspec:
mov dx,offset NoComspec
call dispmsg
stc
jmp short execp_ret
Exec_prepare endp
;***
;skip_white -- Skips all whitespace characters until it hits a non-whitespace
;
;Input: ds:si = string to be looked at
;
;Output: ds:si points at the first non-whitespace char in the string
;
;Registers: ax, si
;***
skip_white proc near
lodsb
cmp al,20h ;Blank?
je skip_white ;yes, skip
cmp al,9 ;Tab?
je skip_white ;yes, skip
dec si ;point at the first non-white
ret
skip_white endp
;***
;find_comspec -- searches in the environment for the COMSPEC variable
;
;Input: None
;
;Output: es:di points at the arguments of the COMSPEC= variable
;
;Registers: si
;***
find_comspec proc near
mov si,offset Comspec_Text
;
; input: ds:si points to a "=" terminated string
; output: es:di points to the arguments in the environment
; zero is set if name not found
; carry flag is set if name not valid format
;
call find ; find the name
jc done_findp ; carry means not found
call scasb1 ; scan for = sign
done_findp:
ret
find_comspec endp
;***
;find -- scans the environment for the variable whose name is passed in
;
;Input: ds:si points at the environment variable to be scanned for
;
;Output: es:di points at the environment variable
;
;Registers: ax, di
;***
find proc near
cld
call count0 ; cx = length of name
mov es,es:[2ch] ; get environment segment
;
;Bugbug: What if the environment segment here is 0?
;
xor di,di
find1:
push cx
push si
push di
find11:
lodsb
inc di
cmp al,es:[di-1]
jnz find12
loop find11
find12:
pop di
pop si
pop cx
jz end_find
push cx
call scasb2 ; scan for a nul
pop cx
cmp byte ptr es:[di],0
jnz find1
stc ; indicate not found
end_find:
ret
find endp
;***
;count0 -- returns length of string until the first '=' char
;
;Input: ds:si points at the string
;
;Output: cx = length until '='
;
;Registers: di
;***
count0 proc near
mov di,si ;ds = es = cs
push di ; count number of chars until "="
call scasb1
pop cx
sub di,cx
xchg di,cx
ret
count0 endp
;***
;scasb1 -- scans string for the first '='
;scasb2 -- scans string for the first null
;
;Input: es:di = string
;
;Output: es:di points after the desired char
;
;Registers: ax, cx
;***
scasb1 proc near
mov al,'=' ; scan for an =
jmp short scasbx
scasb2:
xor al,al ; scan for a nul
scasbx:
mov cx,100h
repnz scasb
ret
scasb1 endp
;**************************
;Data
;**************************
ExecBlk label word
dw 0
CmdPtr dd ?
Fcb1 dw offset MyFcb1
dw ?
Fcb2 dw offset MyFcb2
dw ?
dw 128 dup (1)
MyStack label word
CmdOpt db '/C '
CmdOptLen db $ - CmdOpt
CmdParms db 128 dup (?) ;buffer to hold prog to be Exec'ed
ExecPath db 67 dup (?) ;holds path to COMMAND.COM
ComSpec_Text db 'COMSPEC=',0
MyFcb1 db 0
db 11 dup (' ')
MyFcb2 db 0
db 11 dup (' ')
Helpflg db 0 ;default is no help
include loadmsg.msg
EndProg label byte
code ends
end start