page    60,132
title   Exec

;----------------------------------------------------------------------------

COMMENT %

This is a function to let a Windows application start up another application.
The second application can be either a Windows app or an "old" app.
In the terminology of the C runtime library, this would fall into the
"spawnxxx" category instead of the "execxxx" category, that is, it starts up
the second app and keeps the original app running.

This function should work with any memory model; just be sure to declare it
correctly.  In your C code, it should be declared as:

int FAR PASCAL Exec( LPSTR szProgName, LPSTR szCmdTail, int cmdShow );

szProgName is the name of the .EXE file to be run.

szCmdTail is the command line to be passed.  The command line must be in the
strange DOS command line format: A length byte, followed by the line itself,
followed by a CR (which is not included in the length).

For example, to start up an additional copy of the MS-DOS Executive, you
could use:

    Exec( "msdos.exe", "\x00\r" );

The command line in this case is empty - a length byte of 0, and the CR
to terminate.

Or, to run a DIR command in a COMMAND.COM window:

    Exec( "command.com", "\x03dir\r" );

cmdShow is a ShowWindow option (SW_xxxxxx) from windows.h.  This option is
passed to the called program's WinMain, and normally controls how its main
window is displayed.  The usual values used here are:

    SW_SHOW for an open window.
    SW_SHOWMINIMIZED for an iconic window.
    SW_SHOWMAXIMIZED for a maximized window.

Although there is no code in this function to search the PATH, Windows does
that for you automatically, as long as you don't specify a directory path
in the Exec call itself.

To include Exec in your WinApp, just assemble it and link it in.

%

;----------------------------------------------------------------------------

;memM	 equ	 1
memS	equ	1

.xlist
include cmacros.inc
.list

;----------------------------------------------------------------------------

ParamStruc      STRUC
    ExecEnvSeg      dw      ?
    CmdLineOff      dw      ?
    CmdLineSeg      dw      ?
    FCB1Off         dw      ?
    FCB1Seg         dw      ?
    FCB2Off         dw      ?
    FCB2Seg         dw      ?
    FCB1            dw      10 dup (?)
    FCB2            dw      10 dup (?)
ParamStruc      ENDS

;----------------------------------------------------------------------------

sBegin  CODE

assumes CS,CODE
assumes DS,DATA

;----------------------------------------------------------------------------
; int FAR PASCAL Exec( LPSTR lpszProgName, LPSTR lpszCmdTail, int cmdShow );
;
;     Runs a program.
;
;     *lpszProgName must be zero-terminated and must include the extension.
;     *lpCmdTail must be in the strange DOS command line format
;     (CR-terminated string with length byte, e.g.
;     a DIR command would be hex 03 44 49 52 0D or "\x03DIR\r")
;     cmdShow is the ShowWindow SW_xxxxxx code to be passed to the program's
;     WinMain function.
;
;     Exec returns the EXEC error code or 0 if successful.
;----------------------------------------------------------------------------

cProc   Exec, <PUBLIC,FAR>,<di,ds>
        parmD   lpszProgName
        parmD   lpszCmdTail
        parmW   cmdShow
        localV  ExecParams,%(size ParamStruc)
cBegin
        ; Clear out the parameter block
        push    ss
        pop     es
        lea     di, ExecParams
        xor     ax, ax
        mov     cx, (size ParamStruc) / 2
        cld
        rep stosw

        ; Set up command line pointer
        les     ax, lpszCmdTail
        mov     ExecParams.CmdLineOff, ax
        mov     ExecParams.CmdLineSeg, es

        ; Set up cmdShow parameter
        mov     ExecParams.FCB1+0, 2
        mov     ax, cmdShow
        mov     ExecParams.FCB1+2, ax

        ; Set up FCB pointers
        lea     di, ExecParams.FCB1
        mov     ExecParams.FCB1Off, di
        mov     ExecParams.FCB1Seg, ss
        lea     di, ExecParams.FCB2
        mov     ExecParams.FCB2Off, di
        mov     ExecParams.FCB2Seg, ss

        ; Run the program
        lds     dx, lpszProgName
        lea     bx, ExecParams
        mov     ax, 4B00h                   ; Load and Execute Program
        int     21h
        jc      exDone
        xor     ax, ax
    exDone:

cEnd

;----------------------------------------------------------------------------

sEnd    CODE

;----------------------------------------------------------------------------

END

;----------------------------------------------------------------------------
