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.
331 lines
8.3 KiB
331 lines
8.3 KiB
;-----------------------------------------------------------------------;
|
|
;
|
|
; WINEXEC.ASM -
|
|
;
|
|
; Windows Exec Function
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
|
|
include kernel.inc
|
|
ifdef WOW
|
|
include wowcmpat.inc
|
|
;The following defines come from winerror.inc, which is new in the
|
|
;win95 source tree, but hasn't been merged into wow
|
|
ERROR_FILE_NOT_FOUND equ 2
|
|
ERROR_BAD_LENGTH equ 24
|
|
endif
|
|
|
|
|
|
ifdef FE_SB
|
|
externFP FarMyIsDBCSLeadByte
|
|
endif
|
|
|
|
ifdef WOW
|
|
externFP MyGetAppWOWCompatFlagsEx
|
|
endif
|
|
|
|
externW WinFlags ; (kdata.asm)
|
|
externD WinAppHooks ; (kdata.asm)
|
|
|
|
sBegin NRESCODE
|
|
|
|
assumes cs,NRESCODE
|
|
|
|
|
|
;-----------------------------------------------------------------------;
|
|
;
|
|
; WinExec() -
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
|
|
; HANDLE PASCAL WinExec(lpszFile,wShow)
|
|
|
|
cProc IWinExec, <FAR,PUBLIC>,<si,di>
|
|
|
|
parmD lpszFile ; Pathname ptr
|
|
parmW wShow ; Mode flag
|
|
;
|
|
; szCmdLine buffer must be big enough for passed in path & parms, plus
|
|
; .EXE, null terminator, and newline terminator.
|
|
; So we add a little room for good measure here.
|
|
;
|
|
LocalV szCmdLine,260+256+8 ; Path and command line (to account for .exe)
|
|
LocalW pszParm ; Ptr to start of parameters
|
|
|
|
LocalB bDotFound ; Non-zero if a period is in the string
|
|
LocalB bDblQFound ; Non-zero if the string starts with "
|
|
|
|
LocalV loadparams, %(SIZE EXECBLOCK)
|
|
LocalD FCB1
|
|
cBegin
|
|
|
|
; Copy first part of line into szCmdLine.
|
|
|
|
lds si,lpszFile
|
|
smov es,ss
|
|
lea di,szCmdLine
|
|
mov cx,260 ; MAX_PATH
|
|
|
|
xor al,al
|
|
mov bDotFound,al
|
|
mov bDblQFound,al
|
|
; The Dbl-quote is used as a delimiter for cmdname as in
|
|
; winexec("\"c:\fldr with spaces\" cmd line", ..);
|
|
mov al, ds:[si] ; get Ist char
|
|
cmp al,'"' ; is it a "
|
|
jne WELoop1 ; N:
|
|
mov bDblQFound,al ; Y: remember that
|
|
lodsb ; skip the dblQ
|
|
|
|
; Loop until a blank or NULL is found.
|
|
WELoop1:
|
|
lodsb
|
|
cmp bDblQFound, 0 ; If str didn't start with dblQ
|
|
je WESpaceCheck ; then SPACE is a delimiter
|
|
; otherwise " is the delimiter
|
|
cmp al,'"' ; look for second DblQ
|
|
jne WESkipSpaceCheck
|
|
and bDblQFound,0 ; reset this, so space is the delimiter
|
|
lodsb ; skip past the dbl Q
|
|
WESpaceCheck:
|
|
cmp al,' ' ; Exit loop if blank or NULL
|
|
je WECont1
|
|
WESkipSpaceCheck:
|
|
cmp al,9
|
|
je WECont1
|
|
or al,al
|
|
je WECont1
|
|
cmp al,'.'
|
|
jne WELoopCont
|
|
mov bDotFound,al
|
|
WELoopCont:
|
|
;** We have to check to see if the dot we found was actually in
|
|
;** a directory name, not in the filename itself.
|
|
cmp al, '\' ; Separator?
|
|
je WE_Separator
|
|
cmp al, '/'
|
|
jne WE_Not_Separator
|
|
WE_Separator:
|
|
mov bDotFound,0 ; No dots count yet
|
|
WE_Not_Separator:
|
|
stosb
|
|
dec cx
|
|
jz WE_filename_too_long
|
|
ifdef FE_SB ;Apr.26,1990 by AkiraK
|
|
push cx
|
|
call FarMyIsDBCSLeadByte
|
|
pop cx
|
|
jc WELoop1
|
|
movsb
|
|
dec cx
|
|
jz WE_filename_too_long
|
|
endif
|
|
jmp short WELoop1
|
|
|
|
WE_filename_too_long:
|
|
krDebugOut DEB_TRACE, "WinExecEnv: filename too long, > 259"
|
|
mov ax,ERROR_FILE_NOT_FOUND
|
|
jmp WinExecEnvExit
|
|
|
|
WECont1:
|
|
mov dx,ax ; Store final char in DX
|
|
|
|
; Does the command have an extention?
|
|
|
|
cmp bDotFound,0
|
|
jne WEHasExt
|
|
|
|
mov ax,0452Eh ;'.E'
|
|
stosw
|
|
mov ax,04558h ;'XE'
|
|
stosw
|
|
|
|
WEHasExt:
|
|
xor ax,ax ; NULL terminate string
|
|
stosb
|
|
|
|
mov pszParm,di ; Store pointer to parm string
|
|
stosb ; length = 0
|
|
mov al,0dh ; line feed terminator
|
|
stosb
|
|
dec di ; back up
|
|
|
|
or dl,dl ; Exec if lpszFile was null terminated
|
|
jz WEExec
|
|
|
|
; Copy everything else into szParm.
|
|
|
|
mov cx,255 ; Max length of cmd tail +1
|
|
WELoop2:
|
|
lodsb
|
|
or al,al
|
|
ifdef WOW
|
|
jz WEDoneParm
|
|
else
|
|
jz WECont2
|
|
endif
|
|
stosb
|
|
dec cx
|
|
jnz WELoop2
|
|
|
|
ifdef WOW
|
|
jmps @F
|
|
|
|
;
|
|
; On NT we have a compatibility flag, WOWCFEX_LONGWINEXECTAIL which is
|
|
; set for applications such as TSSETUP, the setup program for Intergraph's
|
|
; NT-only Transcend app. This app uses a command tail on the order of
|
|
; 143 bytes for a Win32 worker app, and it worked on 3.5 and 3.51,
|
|
; so we need to continue to let at least this app cheat.
|
|
;
|
|
|
|
WEDoneParm:
|
|
sub cx, 128
|
|
ja WECont2
|
|
|
|
; tail was longer than 126 characters
|
|
|
|
call MyGetAppWOWCompatFlagsEx
|
|
test dx, word ptr cs:[WE_GACFEX_LONGWINEXECTAIL+2]
|
|
jz @F
|
|
jmps WECont2
|
|
|
|
WE_GACFEX_LONGWINEXECTAIL:
|
|
DD WOWCFEX_LONGWINEXECTAIL
|
|
|
|
@@:
|
|
endif
|
|
|
|
; Cmd tail too long to fit in PSP !!!
|
|
; Fail the call.
|
|
; We _could_ alloc some memory to hold the cmd tail and make its
|
|
; owner be the new hTask. However InitTask is documented to return
|
|
; es=PSP, es:bx=cmd_tail. So we're in trouble. Could truncate the cmd line.
|
|
; Cleaner to fail the exec.
|
|
; Could grow the PSP and tack the big cmd tail on at the end. Scary!
|
|
; Unfortunately, kernel32.ExecWin16Program maps ERROR_BAD_LENGTH to
|
|
; ERROR_GEN_FAILURE.
|
|
krDebugOut DEB_TRACE, "WinExecEnv: command tail too long, > 126"
|
|
mov ax,ERROR_BAD_LENGTH
|
|
jmps WinExecEnvExit
|
|
|
|
WECont2:
|
|
|
|
; Terminate it with a carriage return.
|
|
|
|
mov al,0Dh
|
|
stosb
|
|
|
|
; Prefix the parameter string with its length.
|
|
|
|
mov bx,pszParm ; ax = length + 2
|
|
mov ax,di
|
|
sub ax,bx
|
|
dec ax ; don't include line feed char or length
|
|
dec ax
|
|
mov ss:[bx],al
|
|
|
|
; Set up the FCBs.
|
|
|
|
WEExec:
|
|
mov word ptr FCB1[0],2 ; FCB1[0] = 2;
|
|
mov ax,wShow ; FCB1[1] = wShow;
|
|
mov word ptr FCB1[2],ax
|
|
xor ax,ax
|
|
mov loadparams.envseg,ax ; loadparms.segEnv = 0;
|
|
mov loadparams.lpfcb2.lo,ax ; loadparms.lpFCB2 = (LPSTR)NULL;
|
|
mov loadparams.lpfcb2.hi,ax
|
|
mov ax,pszParm ; loadparms.lpCmdLine = (LPSTR)pszParm;
|
|
mov loadparams.lpCmdLine.lo,ax
|
|
mov loadparams.lpCmdLine.hi,ss
|
|
lea ax,FCB1 ; loadparms.lpFCB1 = (LPSTR)fcb1buf;
|
|
mov loadparams.lpfcb1.lo,ax
|
|
mov loadparams.lpfcb1.hi,ss
|
|
|
|
; Exec the progam.
|
|
|
|
smov ds,ss
|
|
lea dx,szCmdLine ; ds:ax == ptr to file to exec
|
|
lea bx,loadparams ; es:bx == ptr to param block
|
|
mov ax,4B00h ; dos exec
|
|
int 21h
|
|
|
|
WinExecEnvExit:
|
|
cEnd
|
|
|
|
;**************************************************************************
|
|
; RegisterWinoldapHook(Addr,Opcode):
|
|
;
|
|
; Description: (Opcode == 1) => hook, (Opcode == 0) => unhook.
|
|
; Addr is a ptr to struct of the form WinoldapHookList
|
|
; struct WinoldapHookList { struct WinoldapHookList *ptr; DWORD Hook;};
|
|
;**************************************************************************
|
|
|
|
cProc RegisterWinoldapHook,<FAR,PUBLIC,PASCAL>,<ds,es,di,si,dx>
|
|
parmD Address
|
|
parmB Opcode
|
|
cBegin
|
|
SetKernelDSNRes ; set kernel's DS
|
|
mov ax, WinFlags
|
|
test ax, WF_STANDARD
|
|
mov ax,0
|
|
jz RWH_Call
|
|
lea si,WinAppHooks
|
|
les di,Address
|
|
cmp Opcode,0 ; unhook ?
|
|
jz RWH_Unhook
|
|
RWH_Exchange:
|
|
mov ax,ds:[si] ; old
|
|
mov es:[di],ax ; next of new
|
|
mov ax,ds:[si+2]
|
|
mov es:[di+2],ax ; next set
|
|
mov ds:[si],di
|
|
mov di,es
|
|
mov ds:[si+2],di ; new one becomes first
|
|
mov ax,1
|
|
jmp SHORT RWH_Call
|
|
|
|
RWH_Unhook:
|
|
mov dx,es
|
|
RWH_Compare:
|
|
cmp di,ds:[si]
|
|
jnz RWH_Nexthook
|
|
cmp dx,ds:[si+2]
|
|
jnz RWH_NextHook
|
|
mov ax,es:[di]
|
|
mov ds:[si],ax
|
|
mov ax,es:[di+2]
|
|
mov ds:[si+2],ax
|
|
mov ax,1
|
|
jmp SHORT RWH_Call
|
|
RWH_NextHook:
|
|
lds si,ds:[si]
|
|
mov ax,ds
|
|
or ax,si
|
|
jnz short RWH_Compare
|
|
RWH_Call:
|
|
UnSetKernelDS ; unset it
|
|
cEnd
|
|
|
|
;**********************************************************************
|
|
;
|
|
; GetWinoldapHooks:
|
|
; Description: Called exclusively by winoldap to get a pointer to a list
|
|
; of WinoldapHookList.
|
|
; Entry: None
|
|
; EXIT: DX:AX -> WinoldapHookList...
|
|
; USES: Flags.
|
|
;**********************************************************************
|
|
|
|
cProc GetWinoldapHooks,<FAR,PUBLIC,PASCAL>,<ds,si>
|
|
cBegin
|
|
SetKernelDSNRes ; set kernel DS
|
|
lea si,WinAppHooks
|
|
mov ax, word ptr ds:[si]
|
|
mov dx, word ptr ds:[si+2]
|
|
UnSetKernelDS ; unset it
|
|
cEnd
|
|
|
|
sEnd NRESCODE
|
|
|
|
end
|