home *** CD-ROM | disk | FTP | other *** search
- Type
- Exec_Str66=String[66]; {Used for paths, filenames, etc}
- Exec_Str255=String[255]; {Main command string type}
-
- Var
- Exec_Regs: Record Case Integer Of
- 1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
- 2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
- End;
- { NOTE: the above variable is referenced in an Inline statement. It MUST
- be a global variable (not a local variable or a typed constant)!! Ignore
- this and you'll find yourself in Wonderland faster than you can reach
- for the off switch}
-
- Function GetEnvStr(SearchString: Exec_Str255): Exec_Str255;
- Type
- Env=Array [0..32767] Of Char;
- Var
- EPtr: ^Env;
- EStr: Exec_Str255;
- Done: Boolean;
- I: Integer;
-
- Begin
- GetEnvStr:='';
- If SearchString<>'' Then
- Begin
- EPtr:=Ptr(MemW[CSeg:$002C],0);
- I:=0;
- SearchString:=SearchString+'=';
- Done:=False;
- EStr:='';
- Repeat
- If EPtr^[I]=#0 Then
- Begin
- If EPtr^[Succ(I)]=#0 Then
- Begin
- Done:=True;
- If SearchString='==' Then
- Begin
- EStr:='';
- I:=I+4;
- While EPtr^[I]<>#0 Do
- Begin
- EStr:=EStr+EPtr^[I];
- I:=Succ(I);
- End;
- GetEnvStr:=EStr;
- End;
- End;
- If Copy(EStr,1,Length(SearchString))=SearchString Then
- Begin
- GetEnvStr:=Copy(EStr,Succ(Length(SearchString)),255);
- Done:=True;
- End;
- EStr:='';
- End
- Else EStr:=EStr+EPtr^[I];
- I:=Succ(I);
- Until Done;
- End;
- End;
-
- Function ComSpec: Exec_Str66;
- Begin
- ComSpec:=GetEnvStr('COMSPEC');
- End;
-
- Function Exec(CommandLine: Exec_Str255): Integer;
- Const
- SSSave: Integer=0;
- SPSave: Integer=0;
-
- Var
- FCB1,FCB2: Array [0..36] Of Byte; {*}
- PathName: Exec_Str66; {*}
- CommandTail: Exec_Str255;
- ParmTable: Record {*}
- EnvSeg: Integer;
- ComLin: ^Integer;
- FCB1Pr: ^Integer;
- FCB2Pr: ^Integer;
- End;
- RegsFlags: Integer; {*}
- {*: these variables are accessed in an Inline statement; their
- declarations must not be changed }
-
- Begin
- (* Process the command, making sure that its in proper format *)
- If Pos(' ',CommandLine)=0 Then
- Begin
- PathName:=CommandLine+#0;
- CommandTail:=^M;
- End
- Else
- Begin
- PathName:=Copy(CommandLine,1,Pred(Pos(' ',CommandLine)))+#0;
- CommandTail:=Copy(CommandLine,Pos(' ',CommandLine),255)+^M;
- End;
- CommandTail[0]:=Pred(CommandTail[0]);
- (* Now set up the Function 4B data block *)
- With Exec_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(Exec_Regs); { Create FCB 1 }
- FillChar(FCB2,Sizeof(FCB2),0);
- AX:=$2901;
- ES:=Seg(FCB2);
- DI:=Ofs(FCB2);
- MsDos(Exec_Regs); { Create FCB 2 }
- With ParmTable Do
- Begin
- EnvSeg:=MemW[CSeg:$002C]; { Makes sure valid environ is passed }
- ComLin:=Addr(CommandTail);
- FCB1Pr:=Addr(FCB1);
- FCB2Pr:=Addr(FCB2);
- End;
- (* Now this inline does the actual work. It could be done without
- inline code, but with so much stack manipulation I felt more
- comfortable doing it in this manner. Not that no allocation of
- memory is necessary since Turbo automatically does that. (Isn't
- that nice of them!) *)
-
- InLine($8D/$96/ PathName /$42/ { <DX>:=Ofs(PathName[1]); }
- $8D/$9E/ ParmTable / { <BX>:=Ofs(ParmTable); }
- $B8/$00/$4B/ { <AX>:=$4B00; }
- $1E/$55/ { Save <DS>, <BP> }
- $16/$1F/ { <DS>:=Seg(PathName[1]); }
- $16/$07/ { <ES>:=Seg(ParmTable); }
- $2E/$8C/$16/ SSSave / { Save <SS> in SSSave }
- $2E/$89/$26/ SPSave / { Save <SP> in SPSave }
- $FA/ { Disable interrupts }
- $CD/$21/ { Call PC-DOS }
- $FA/ { Disable interrupts }
- $2E/$8B/$26/ SPSave / { Restore <SP> }
- $2E/$8E/$16/ SSSave / { Restore <SS> }
- $FB/ { Enable interrupts }
- $5D/$1F/ { Restore <BP>,<DS> }
- $9C/$8F/$86/ RegsFlags / { Flags:=<CPU flags> }
- $A3/ Exec_Regs ); { Exec_Regs.AX:=<AX>; }
-
- If (RegsFlags And 1)<>0 Then Exec:=AX
- Else Exec:=0;
- End;
- End;
-
- Function ExecCommand(CommandLine: Exec_Str255): Integer;
- Begin
- ExecCommand := Exec(ComSpec +' /C '+CommandLine);
- End;
-
- Function Shell: Integer;
- Begin
- Shell:=Exec(ComSpec);
- End;
-
-
-