[Back to DOS SWAG index]  [Back to Main SWAG index]  [Original]

{
Ever been in a situation where you want to secure a PC (for example in a
network environment) by using menus from which you can't exit and
user/software companies keep coming with software with the Shell to DOS
option?

Here's a simple solution which works with a lot of programs which shell
by using COMSPEC.

This program called execute patches it's own environment with a
replacement COMSPEC, Does an EXEC and restores the original environment.
It's done by making fetching all environment strings, replace comspec
with the first commandline parameter (which should be shorter than the
original comspec, so I use the program called EXIT located in the
same directory as COMMAND.COM). Than it does an plain TP Exec (without
swapping to EMS/XMS/DISK etc) of the second commandline parameter with
the rest of the commandline as it's parameters.

I used patching the original environment of EXECUTE because the program
executed inherits it and EXECUTE needs comspec only to exit itself (and
return to a menu for example). Because of this construction it's
possible to exit the program started normally and return to a menu but
you'll be unable to shell to dos and type something like FORMAT C:.

An example EXIT.PAS is also supplied. Pressing CTRL-BREAK etc doesn't
matter, you'll always return to the application from which you tried to
shell. Beware that some programs like SPSS and VP-Planner have
difficulties with R/O attributes on EXIT.EXE (and COMMAND.COM), so keep
it R/W.

So to for example disable the Turbo Pascal File/Dos use :

EXECUTE C:\DOS\EXIT.EXE C:\TURBO55\TURBO.EXE TEST.PAS

instead of

C:\TURBO55\TURBO TEST.PAS

If COMSPEC was C:\DOS\COMMAND.COM and Turbo Pascal was located in
the C:\TURBO55 directory.


Remember the extensions .EXE or .COM are necessary!

------------------------<cut here

{---------------------------------------------------------}
{  Project : Exec with Temporaryly changed 'COMSPEC'      }
{          : the exec routine itself                      }
{  Auteur  : Ir. G.W. van der Vegt                        }
{---------------------------------------------------------}
{  Datum .tijd  Revisie                                   }
{  921118.0930  Creatie.                                  }
{---------------------------------------------------------}
{ This program patches the COMSPEC environment variable   }
{ with a new value (ie EXIT.EXE) and executes the         }
{ program. After execution it restores the environment    }
{                                                         }
{ Syntax :                                                }
{                                                         }
{ EXECUTE temporary_comspec program_name [paramaters]     }
{                                                         }
{ Limits :-Only maxenv environments strings can be stored,}
{          each with a maximum length of 128 characters.  }
{         -The temporary comspec must be shorter than the }
{          original one.                                  }
{         -Environment must be smaller than 32k           }
{---------------------------------------------------------}

{$M 4096,0,0}

Program Execute;

Uses
  Crt,
  Dos;


Const
  Maxenv = 64;

Type
  psp = Record
          int20adr : Word;
          endofmem : Word;
          res1     : Byte;
          callfar  : Array[1..5] OF Byte;
          int22    : Pointer;
          Int23    : Pointer;
          Int24    : Pointer;
          parentpsp: Word;
          handles  : Array[1..20] OF Byte;
          envseg   : Word;
        {----More follows}
        End;

  env = array[1..32678] OF Char;

Var
  e      : ^env;
  p      : ^psp;
  addcnt : Word;                           {----no of additional strings}
  i      : Integer;                        {----loop counter}
  envar  : Array[1..maxenv] of String[128];{----environment string storage}
  noenv  : Integer;                        {----no strings in environment}
  cmdline: STRING;                         {----command line of program to start}
  comspec: STRING;                         {----original comspec storage}
  ch     : CHAR;

{---------------------------------------------------------}

Procedure Read_env;

Var
  i,k : Integer;

begin
  p:=Ptr(prefixseg,0);
  noenv:=0;

{----Show environment strings}
  e:=Ptr(p^.envseg,0);
  i:=1;
  Inc(noenv);
  envar[noenv]:='';
  Repeat
    If (e^[i]<>#0)
      Then envar[noenv]:=envar[noenv]+e^[i]
      Else
        Begin
          Inc(noenv);
          If (noenv>=maxenv)
            THEN
              BEGIN
                Writeln('Only ',maxenv:0,' environment strings can be stored.');
                Halt;
              END;

          envar[noenv]:='';
        End;
    Inc(i);
  Until (e^[i]=#00) AND (e^[i]=e^[i-1]);

{----Show Additional environment strings}
  Inc(i);
  addcnt:=Word(Ord(e^[i])+256*Ord(e^[i+1]));
  Inc(i);
  Inc(i); {----eerste character additional strings}
  k:=addcnt;

  If (noenv+addcnt>=maxenv)
    THEN
      BEGIN
        Writeln('Only ',maxenv:0,' (additional)environment strings can be stored');
        Halt;
      END;

  Repeat
    If (e^[i]<>#0)
      Then envar[noenv]:=envar[noenv]+e^[i]
      Else
        Begin
          Inc(noenv);
          envar[noenv]:='';
          Dec(k);
        End;
    Inc(i);
  Until (k<=0);

  dec(noenv);

 {Writeln(' Environment Strings : ',noenv-addcnt);
  for j:=1 to noenv-addcnt do
    writeln('e ',envar[j]);
  Writeln(' Additional Strings : ',addcnt);
  for j:=noenv-addcnt+1 to noenv do
    writeln('a ',envar[j]);
  writeln;}
end; {of Read_env}

{---------------------------------------------------------}

Procedure Patch_env(envst,newval : STRING);

Var
  i,j,k : Integer;

BEGIN
{----change an envronment string}
  for i:=1 to noenv do
    begin
      if (pos(envst+'=',envar[i])=1)
        THEN
          begin
            Delete(envar[i],Pos('=',envar[i])+1,Length(envar[i])-Pos('=',envar[i]));
            envar[i]:=envar[i]+newval;
          end;
    end;

{----patch environment strings}
  i:=1;
  for j:=1 to noenv-addcnt do
    begin
      for k:=1 to Length(envar[j]) do
        begin
          e^[i]:=envar[j][k];
          inc(i);
        end;
      e^[i]:=#0;
      inc(i);
    end;

{----patch environment string end}
  e^[i]:=#0;                  inc(i);
{----patch additional string count}
  e^[i]:=Chr(addcnt mod 256); inc(i);
  e^[i]:=Chr(addcnt div 256); inc(i);

{----patch additional strings}
  for j:=noenv-addcnt+1 to noenv do
    begin
      for k:=1 to Length(envar[j]) do
        begin
          e^[i]:=envar[j][k];
          inc(i);
        end;
      e^[i]:=#0;
      inc(i);
    end;
end; {of Patch_env}

{---------------------------------------------------------}

Begin
  If (Paramcount<2)
    THEN
      BEGIN
        Writeln('Syntax : EXECUTE temporary_comspec program_name [program_param]');
        Halt;
      END;

  checkbreak:=false;

  comspec:=Getenv('COMSPEC');

  If (Length(Paramstr(1))>Length(comspec))
    THEN
      BEGIN
        Writeln('Path&name of temporary COMSPEC should be shorter than the original');
        Halt;
      END;

  Read_env;

  Patch_env('COMSPEC',Paramstr(1));

  cmdline:='';
  FOR i:=3 to Paramcount DO
    cmdline:=cmdline+' '+Paramstr(i);

  Swapvectors;
  Exec(Paramstr(2),cmdline);
  Swapvectors;

  WHILE Keypressed DO ch:=Readkey;

  Patch_env('COMSPEC','C:\COMMAND.COM');
end.


------------------------<cut here


Program Exit;

Uses
  CRT;

Begin
 Clrscr;
 GotoXY(20,12);
 Write('Sorry, SHELLing to DOS not Possible.');
End.

[Back to DOS SWAG index]  [Back to Main SWAG index]  [Original]