[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]