home *** CD-ROM | disk | FTP | other *** search
- (* from MARKET's Turbo archive, 9 Mar 87. Toad Hall
- EXEC.PAS version 1.2
-
- This file contains 2 functions for Turbo Pascal that allow you to
- run other programs from within a Turbo program. The first function,
- subProcess, actually calls up a different program using MS-DOS call
- 4BH, EXEC. The second function, GetComSpec, returns the path name
- of the command interpreter, which is necessary to do certain
- operations. There is also a main program that allows you to test the
- functions.
-
- ----------------------------------------------------------------------
-
- Version 1.1 works with DOS 2.0 and 2.1. Version 1.0 only worked
- with DOS 3.0 due to a subtle bug in DOS 2.x.
-
- - Bela Lubkin
- Borland International Technical Support
- CompuServe 71016,1573
-
- ----------------------------------------------------------------------
-
- Version 1.2 corrects a compiling problem in the INLINE code area of
- subProcess. The line:
- INLINE ($8D/$96/ PathName+1 /
- will always generate a ") required" at the + sign. Apparently
- Turbo only allows displacements on location counter references
- within the INLINE code (i.e. not on variable identifiers).
-
- - James Tuksal
- Burroughs Corporation
- 14115 Farmington Rd.
- Livonia, Michigan
- 48154
-
- ----------------------------------------------------------------------
- *)
- TYPE
- Str66 = STRING [66];
-
- (*
- Pass subProcess a string of the form:
- 'D:\FULL\PATH\NAME\OF\FILE.TYP parameter1 parameter2 ...'
-
- For example,
- 'C:\SYSTEM\CHKDSK.COM'
- 'A:\WS.COM DOCUMENT.1'
- 'C:\DOS\LINK.EXE TEST;'
- 'C:\COMMAND.COM /C COPY *.* B:\BACKUP >FILESCOP.IED'
-
- The fourth example shows several things. To do any of the
- following, you must invoke the command processor and let it do the
- work:
-
- redirection
- piping
- path searching
- searching for the extension of a program (.COM, .EXE, or .BAT)
- batch files;
- internal DOS commands
-
- The name of the command processor file is stored in the DOS
- environment. The function GetComSpec in this file returns the path
- name of the command processor. Also note that you must use the /C
- parameter or COMMAND will not work correctly. You can also call
- COMMAND with no parameters. This will allow the user to use the DOS
- prompt to run anything (as long as there is enough memory). To get
- back to your program, he can type the command EXIT.
-
- Actual example:
- i := subProcess (GetComSpec+' /C COPY *.* B:\BACKUP >FILESCOP.IED');
-
- The value returned is the result returned by DOS after the EXEC
- call. The most common values are:
-
- 0: Success
- 1: Invalid function (should never happen with this routine)
- 2: File/path not found
- 8: Not enough memory to load program
- 10: Bad environment (greater than 32K)
- 11: Illegal .EXE file format
-
- If you get any other result, consult an MS-DOS Technical Reference
- manual.
-
- VERY IMPORTANT NOTE: you MUST use the Options menu of Turbo Pascal
- to restrict the amount of free dynamic memory used by your
- program. Only the memory that is not used by the heap is
- available for use by other programs.
- *)
-
- FUNCTION subProcess (CommandLine : Str255): INTEGER;
- CONST
- ssSave: INTEGER = 0;
- SPSave: INTEGER = 0;
- VAR
- FCB1 : ARRAY [0..36] OF BYTE;
- FCB2 : ARRAY [0..36] OF BYTE;
- PathName : Str66;
- CommandTail : Str255;
- parmTable : RECORD
- envseg : INTEGER;
- comlin : ^INTEGER;
- FCB1Pr : ^INTEGER;
- FCB2Pr : ^INTEGER;
- END;
- BEGIN
- IF POS (' ', CommandLine) = 0 THEN BEGIN
- PathName := CommandLine + #0;
- CommandTail := ^M;
- END
- ELSE BEGIN
- PathName := COPY (CommandLine, 1, POS (' ', CommandLine)-1) + #0;
- CommandTail := COPY (CommandLine, POS (' ', CommandLine), 255) + ^M;
- END;
- CommandTail [0] := PRED(CommandTail[0]);
- WITH Regs Do BEGIN
- FillChar (FCB1, SizeOf(FCB1), 0);
- AX := $2901;
- DS := Seg(CommandTail[1]);
- SI := Ofs(CommandTail[1]);
- ES := Seg(FCB1);
- DI := Ofs(FCB1);
- MSDOS (Regs); { Create FCB 1 }
- FillChar (FCB2, SizeOf(FCB2), 0);
- AX := $2901;
- ES := Seg(FCB2);
- DI := Ofs(FCB2);
- MSDOS (Regs); { Create FCB 2 }
- ES := CSeg;
- BX := SSEG - CSEG + MEMW[CSEG:MEMW[CSEG:$0101] + $112];
- AH := $4A;
- MSDOS (Regs); { Deallocate unused memory }
- WITH parmTable DO BEGIN
- envseg := MEMW[CSEG:$002C];
- comlin := ADDR(CommandTail);
- FCB1Pr := ADDR(FCB1);
- FCB2Pr := ADDR(FCB2);
- END;
- INLINE (
- $BF/$01/$00/ {+MOV DI,0001h }
- $8D/$93/PathName/ {>LEA DX,[BP+DI+DS:PathName] }
- $8D/$9E/parmTable/ { LEA BX,[BP+DS:parmTable] }
- $B8/$00/$4B/ { MOV AX,4B00h }
- $1E/ { PUSH DS }
- $55/ { PUSH BP }
- $16/ { PUSH SS }
- $1F/ { POP DS }
- $16/ { PUSH SS }
- $07/ { POP ES }
- $2E/$8C/$16/SSSave/ { MOV CS:ssSave,SS }
- $2E/$89/$26/SPSave/ { MOV CS:SPSave,SP }
- $FA/ { CLI }
- $CD/$21/ { INT 21h }
- $FA/ { CLI }
- $2E/$8B/$26/SPSave/ { MOV SP,CS:SPSave }
- $2E/$8E/$16/SSSave/ { MOV SS,CS:ssSave }
- $FB/ { STI }
- $9C/ { PUSHF }
- $BF/$12/$00/ {+MOV DI,0012h }
- $3E/$8F/$83/Regs/ {>POP [BP+DI+DS:Regs] }
- $3E/$89/$86/Regs/ { MOV [BP+DS:Regs],AX }
- $5D/ { POP BP }
- $1F); { POP DS }
-
- { + Line added to correct compile problem in 1.1 }
- { > Line modified to correct compile problem in 1.1 }
-
- { The messing around with SS and SP is necessary because under DOS 2.x }
- { after returning from an EXEC call, ALL registers are destroyed }
- { except CS and IP! I wish I'd known that before I released this }
- { package the first time... }
-
- IF (Flags AND 1) <> 0 THEN subProcess := AX
- ELSE subProcess := 0;
- END;
- END; { of subProcess }
-
-
- FUNCTION GetComSpec : Str66;
- TYPE
- Env = ARRAY [0..32767] OF CHAR;
- VAR
- EPtr : ^Env;
- EStr : Str255;
- Done : BOOLEAN;
- i : INTEGER;
- BEGIN
- EPtr := PTR (MEMW [CSEG:$002C],0);
- i := 0;
- Done := FALSE;
- EStr := '';
- REPEAT
- IF EPtr^[i] = #0 THEN BEGIN
- IF EPtr^[SUCC(i)] = #0 THEN Done := TRUE;
- IF COPY (EStr, 1, 8) = 'COMSPEC=' THEN BEGIN
- GetComSpec := COPY (EStr, 9, 100);
- Done := TRUE;
- END;
- EStr := '';
- END
- ELSE EStr := EStr + EPtr^[i];
- i := SUCC(i);
- UNTIL Done;
- END; { of GetComSpec }