home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* SHELL.PAS *)
- (* Selbstdefinierte Prompts für Shells *)
- (* Turbo Pascal ab 5.0 *)
- (* (c) 1991 Gunnar Blumert & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$A+,B-,D-,E-,F-,I-,L-,N-,O-,R-,S-,V-}
- UNIT Shell;
-
- INTERFACE
- PROCEDURE DosShell;
- IMPLEMENTATION
-
- USES Dos;
-
- FUNCTION ExecShell: BYTE;
- CONST
- PromptBytes = 7;
- Prompt: ARRAY[1..PromptBytes] OF CHAR =
- ('P', 'R', 'O', 'M', 'P', 'T', '=');
- OwnPromptBytes = 32; { Definition des eigenen Prompts }
- MyOwnPrompt: ARRAY[1..OwnPromptBytes] OF CHAR =
- ('R','ü','c','k','k','e', 'h','r',' ','z','u',' ','S','H',
- 'E','L','L','T','S','T', ' ','m','i','t',' ','E','X','I',
- 'T','!','$','_');
- { erzeugt Systemprompt C>, falls kein Prompt gesetzt war }
- NoPromptBytes = 4;
- NoPrompt: ARRAY[1..NoPromptBytes] OF CHAR =
- ('$','n','$','g');
- { Kommandozeile }
- CommandLine: ARRAY[1..2] OF BYTE = (0, 0);
-
- VAR CPU : Registers;
- NewEnv, FillEnvPtr : Pointer;
- EnvBytes, EnvSeg : WORD;
- EnvString : STRING;
- CommandPath : PathStr;
- ExecParameter : ARRAY[0..6] OF WORD;
- ExecError : BYTE;
-
- FUNCTION Make_New_Environment : BOOLEAN;
- VAR PromptBegin, i : BYTE;
- PromptFound : BOOLEAN;
-
- PROCEDURE FillEnviron(SourcePtr : Pointer; Count : WORD);
- BEGIN
- Move(SourcePtr^, FillEnvPtr^, Count);
- Inc(LONGINT(FillEnvPtr), Count)
- END;
-
- PROCEDURE AddZero;
- BEGIN
- BYTE(FillEnvPtr^) := 0;
- Inc(LONGINT(FillEnvPtr))
- END;
-
- BEGIN
- Make_New_Environment := FALSE; PromptFound := FALSE;
- EnvBytes := 0; { Summe der Länge der Strings + Nullbyte }
- FOR i := 1 TO EnvCount DO
- Inc(EnvBytes, Succ(Length(EnvStr(i))));
- { abschließendes zusätzliches Nullbyte }
- Inc(EnvBytes, Succ(OwnPromptBytes));
- { + 1 Paragraph: falls Offset nach GetMem <> 0 }
- Inc(EnvBytes, 16);
- GetMem(NewEnv, EnvBytes);
- EnvSeg := Succ(Seg(NewEnv^));
- { deshalb hier die Segmentadresse erhöhen }
- FillEnvPtr := Ptr(EnvSeg,0);
- { Zeiger auf Beginn des neuen Environments }
- { nun die einzelnen Environmentstrings übertragen }
- { dabei das eigene Prompt einfügen }
- FOR i := 1 TO EnvCount DO BEGIN
- EnvString := EnvStr(i);
- IF Pos('PROMPT', EnvString) = 1 THEN BEGIN
- PromptFound := TRUE;
- PromptBegin := Pos('=', EnvString);
- FillEnviron(@EnvString[1], PromptBegin);
- FillEnviron(@MyOwnPrompt, OwnPromptBytes);
- FillEnviron(@EnvString[Succ(PromptBegin)],
- Length(EnvString) - PromptBegin);
- END ELSE
- FillEnviron(@EnvString[1], Length(EnvString));
- AddZero; { Nullbyte zum Trennen der Strings }
- END; { falls kein Prompt definiert war, dann anhängen }
- IF NOT PromptFound THEN BEGIN
- FillEnviron(@Prompt, PromptBytes);
- FillEnviron(@MyOwnPrompt, OwnPromptBytes);
- FillEnviron(@NoPrompt, NoPromptBytes);
- AddZero;
- END;
- AddZero;
- Make_New_Environment := TRUE;
- END;
-
- BEGIN { von SHELL }
- ExecError := 8;
- IF NOT Make_New_Environment THEN Exit;
- WITH CPU DO BEGIN
- AH := $4A; { Speicher freigeben }
- ES := PrefixSeg;
- BX := Succ(Seg(HeapPtr^)-PrefixSeg)
- END;
- MsDos(CPU);
- CommandPath := GetEnv('COMSPEC') + #0;
- FillChar(ExecParameter, SizeOf(ExecParameter), #0);
- ExecParameter[0] := EnvSeg;
- ExecParameter[1] := Ofs(CommandLine);
- ExecParameter[2] := Seg(CommandLine);
- WITH CPU DO BEGIN
- AX := $4B00;
- DS := Seg(CommandPath[1]);
- DX := Ofs(CommandPath[1]);
- ES := Seg(ExecParameter);
- BX := Ofs(ExecParameter)
- END;
- SwapVectors;
- MsDos(CPU); { evtl. Fehlermeldung }
- SwapVectors;
- IF (CPU.Flags AND 1) <> 0 THEN
- ExecError := CPU.AL
- ELSE
- ExecError := 0;
- WITH CPU DO BEGIN { Speicher wieder belegen }
- AH := $4A;
- ES := PrefixSeg;
- BX := $FFFF; { ermittelt maximal }
- MsDos(CPU); { verfügbaren Speicherplatz }
- AH := $4A; { diesen dann anfordern }
- ES := PrefixSeg;
- MsDos(CPU);
- END;
- FreeMem(NewEnv, EnvBytes);
- ExecShell := ExecError;
- END;
-
- PROCEDURE DosShell;
- VAR s : STRING;
- e : BYTE;
- BEGIN
- e := ExecShell;
- IF e <> 0 THEN BEGIN
- s := '';
- CASE e OF
- 1: s := 'Falsche Funktionsnummer übergeben!';
- 2: s := 'COMMAND.COM nicht gefunden!';
- 8: s := 'Zuwenig Speicherplatz!';
- 10: s := 'Environment ungültig!';
- 11: s := 'Parameterblock ungültig!';
- ELSE s := 'Erstaunlicher Fehler!';
- END;
- WriteLn('Fehler: ',s)
- END
- END;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von SHELL.PAS *)