Command.com Eingabe vor der Verarbeitung abfangen

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Antworten
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Command.com Eingabe vor der Verarbeitung abfangen

Beitrag von Dosenware »

Gruß,

weiß jemand wie ich in der Command.com beim Druck auf Enter (bzw. die jeweiligen entsprechungen (batch)) die Eingabe abfangen kann bevor die command.com diese Verarbeitet.

Ich wuerde gerne zwischen Eingabe und Verarbeitung noch etwas dazwischenschalten um der Command.com noch ein paar zusaetzliche Befehle beizubringen -> Quasi ein Command.com Extender.

dazu muesste ich jedoch sowohl an die Eingabe, sowie die Sprungadresse der verarbeitenden Routine herankommen (hoffe das dies per Int realisiert wurde, sonst wirds schwierig)

http://www.ctyme.com/intr/rb-5189.htm#Table2978
deutet darauf hin, das dies Moeglich ist - jedoch finde ich keine Routine mit der ich da eine eigene Routine installieren kann (TSR)...

/Gruß
elianda
DOS-Übermensch
Beiträge: 1150
Registriert: Mi 31. Jan 2007, 19:04
Wohnort: Halle
Kontaktdaten:

Beitrag von elianda »

Hmm na wie realisiert es denn Append?
Diverse Retro-Computer vorhanden.
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Beitrag von Dosenware »

http://support.microsoft.com/kb/28473

http://www.ctyme.com/intr/rb-2939.htm sieht noch am erfolgversprechensten aus, aber um es mit den Worten meiner Generation zu Formulieren: Hae?
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Beitrag von DOSferatu »

Ne einfache Möglichkeit wäre jetzt, die Command.Com nochmal auszuführen, mit der entsprechenden Funktion als Parameter.
Außerdem mal bei INT 21h (die gazen DOS-Ints) in "Ralph Brown's Interrupt List" angucken. Die ganze ersten INTs sind dafür da, um Zeichen von der Tastatur einzulesen.
(Also einfach mal diese INTs hooken, selber einlesen bis zum Enter. Wenn normaler Befehl, dann Command.Com mit dem Befehl als Parameter ausführen. Wenn eigener Befehl, dann den ausführen.)
Wenn der Befehl ein Programm (also EXE oder COM) starten soll, also keine BAT, dann kann man auch den INT21h für "EXEC" (execute) benutzen. Funktion 4Bh. Läßt sich leicht merken. Weil INT21h, Funktion 4Ch nämlich n DOS-Programm beendet.
Also die Funktionen für Tastatur einlesen sind gleich die allerersten (da gibts mehrere, welche, die "allgemein alles" einlesen und welche, die eben speziell für Tastatur. Nehm an, daß die speziellen dann alle die allgemeine aufrufen.
Ich hab übrigens mal sowas gecodet - ein "DOS im DOS" - das war dazu gedacht, bestimmte Befehle mit Paßwort zu schützen. (Wollte mal einer bei "wer-weiss-was" haben.
Ich hatte es damals nur nicht hingekriegt, daß das Ding quasi so startet, daß es schon direct vor command.com startet, dann immer nur die command.com aufruft.
Falls es sowas sein soll, wie, daß man z.B. die CTRL-ALT-DEL oder CTRL-C Dinge gleich mit sperrt, dafür gibts auch INTs, müßt ich nachsehn.

Anmerkung: In meinem Game benutze ich sozusagen n "eigenen Keyboardtreiber". Weil man bei sowas ja mehere Tasten gleichzeitig abfragen können muß - und es ja ohne diese "Verzögerung nach Tastendruch" gehen muß - mußte das sein.
Damt man auch "normale Eingabe" machen kann, hab ich dann noch eigene Tabelle gemacht, die die Umsetzung in ASCII enthält. (Bzw mehrere, weil ichs gleich mehrsprachig gemacht hab.)

Eine andere Möglichkeit wäre die:
Man checkt immer den Tastaturpuffer und liest das, was da reingeschrieben wird, einzeln aus. Gleichzeitig hookt man den Keyboard-INT, läßt aber alle Zeichen durch. Nur wenns ein ENTER ist (Scancode 28dez für Enter, bzw 224 und 28 für das 2. Enter, es reicht die 28 abzufangen), und dann halt das Enter entweder an's System übergeben lassen, wenn's kein eigener Befehl ist.
Und wenns ein eigener Befehl ist, dann eben den Keyboard INT gleich beenden, ohne daß das Enter übergeben wird und den eigenen Befehl ausführen.

Anfrage: Auf welche Art willst Du die eigenen Befehle denn einbinden? Willst Du in DOS ein Programm starten, das dann sozusagen ein "DOS vor dem DOS" ist oder willst Du es eher wie eine TSR machen?

(Achso: Interrupt-Vector setzen/holen mit INT21h, Funktion 25h/35h (in AH).)

Hm... Ja.
Leider muß ich sagen, daß ich jetzt mal kurz die "RBIL" durchsucht hab und erstmal auf die schnelle keinen INT bzw Funktion gefunden hab, wo Command.Com einen Befehl scannt und ausführt. Vielleicht braucht man einfach eine Einsprung-Adresse, aber die ist möglicherweise in jeder DOS-Version ne andere.
Kann nochmal bissel nachforschen, falls Interesse.
Aber vielleicht tun es ja auch schon die o.g. Möglichkeiten.

Falls das Programm in Pascal werden soll (was ich zwar nicht vermute, kann aber sein), dann könnt ich n kurzes Stück Code als Beispiel liefern, wie ich sowas anstellen würde.
Ich könnts auch in Assembler machen, das tät n bißchen länger dauern.

Hoffe, ein wenig geholfen zu haben.

Bis bald.
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Beitrag von DOSferatu »

Achso, mir ist grad noch was eingefallen, wie mans noch einfacher machen könnte:
Man macht einfach aus jedem neuen Befehl eine EXE-Datei und legt die in den DOS-Pfad. Dann wird die von überall aus ausgeführt, auch von Batches aus.
Wenn man nicht für jeden Befehl n eigene EXE anlegen will, sondern nur eine als ganzes, könnte man mehrere BATs schreiben die alle diese EXE aufrufen.
Die BATs oder die EXEn legt man in den Pfad am besten noch VOR den Pfad, wo die Command.Com drinliegt. Dann wird immer erst der eigene Befehl gesucht, bevor in DOS gesucht wird, es sei denn, es ist ein DOS-Befehl, der direkt in der COMMAND drinliegt (wie cd oder sowas), aber die willst Du wohl nicht ändern.
(Oder es sei denn, man ist zufällig in dem Verzeichnis, wo die Command.com liegt.)

Hoffe, das hat jetzt nicht zusehr verwirrt, aber ich denke, es müßte vielleicht auch so gehen.

Bis bald.
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Beitrag von Dosenware »

Vielleicht braucht man einfach eine Einsprung-Adresse, aber die ist möglicherweise in jeder DOS-Version ne andere.
wuerde sehr wahrscheinlich schiefgehen, da der residente Teil der Command.com moeglicherweise dazwischenfunkt.
Wenn man nicht für jeden Befehl n eigene EXE anlegen will, sondern nur eine als ganzes, könnte man mehrere BATs schreiben die alle diese EXE aufrufen.
scheidet aus wegen der Parameteruebergabe (Leerzeichen, nur 9 Parameter, max 255 Zeichen - fuer meine Zwecke unbrauchbar) und wenn man der command den umgang mit verschiedenen Dateitypen beibringen will, ist die Variante untauglich...
(Also einfach mal diese INTs hooken, selber einlesen bis zum Enter. Wenn normaler Befehl, dann Command.Com mit dem Befehl als Parameter ausführen. Wenn eigener Befehl, dann den ausführen.)
Die Variante wollte ich eigentlich Vermeiden, weil ich mich dann um die Kommandozeile kuemmern muesste...
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re:

Beitrag von freecrac »

DOSferatu hat geschrieben: (...Wenn normaler Befehl, dann Command.Com mit dem Befehl als Parameter ausführen...)
Internen COMMAND.COM-Befehl ausführen ohne eine neue Instanz von Command.Com zu starten:
RBIL->inter61c.zip->INTERRUP.K
--------l-2E---------------------------------
INT 2E U - DOS 2+ - PASS COMMAND TO COMMAND INTERPRETER FOR EXECUTION
DS:SI -> commandline to execute (see #02585)
Return: all registers except CS:IP destroyed
AX = status (4DOS v4.0)
0000h successful
FFFFh error before processing command (not enough memory, etc)
other error number returned by command
Notes: this call allows execution of arbitrary commands (including COMMAND.COM
internal commands) without loading another copy of COMMAND.COM
if COMMAND.COM is the user's command interpreter, the primary copy
executes the command; this allows the master environment to be
modified by issuing a "SET" command, but changes in the master
environment will not become effective until all programs descended
from the primary COMMAND.COM terminate
since COMMAND.COM processes the string as if typed from the keyboard,
the transient portion needs to be present, and the calling program
must ensure that sufficient memory to load the transient portion can
be allocated by DOS if necessary
results are unpredictable if invoked by a program run from a batch file
because this call is not reentrant and COMMAND.COM uses the same
internal variables when processing a batch file
hooked but ignored by 4DOS v3.0 COMMAND.COM replacement unless SHELL2E
has been loaded
the MS-DOS 5 Programmer's Reference calls this "Reload Transient"

Format of DOS commandline:
Offset Size Description (Table 02585)
00h BYTE length of command string, not counting trailing CR
01h var command string
N BYTE 0Dh (CR)
-----------------------------------------------------------------------------------
Hinweis: Das funktioniert auch mit allen Batch-Befehlen wie etwa ein: "call xy.bat"!
Wenn der Befehl ein Programm (also EXE oder COM) starten soll, also keine BAT, dann kann man auch den INT21h für "EXEC" (execute) benutzen. Funktion 4Bh.
Aus einer Anwendung heraus eine andere Child-Anwendung ausführen:
RBIL->inter61b.zip->INTERRUP.G
--------D-214B-------------------------------
INT 21 - DOS 2+ - "EXEC" - LOAD AND/OR EXECUTE PROGRAM
AH = 4Bh
AL = type of load
00h load and execute
01h load but do not execute
03h load overlay (see #01591)
04h load and execute in background (European MS-DOS 4.0 only)
"Exec & Go" (see also AH=80h)
DS:DX -> ASCIZ program name (must include extension)
ES:BX -> parameter block (see #01590,#01591,#01592)
CX = mode (subfunction 04h only)
0000h child placed in zombie mode after termination
0001h child's return code discarded on termination
Return: ......
----------------------------------------------------------------------------------------

Beispiel für einen "parameter block" im Code-Segment:

Code: Alles auswählen

;----------
PARBLOCK  equ THIS WORD       ; Parameter-Block für die EXEC-Funktion
          DW 0                ; gleicher Environment-Block
          DW OFFSET COMLINE   ; Offset- und Segmentadresse der
          DW SEG CODE         ;      Kommandozeile
          DD 0                ; keine Daten in PSP #1
          DD 0                ; keine Daten in PSP #2
COMLINE   DB 80h dup (0)      ; Kommandozeile
;----------

RETT_SS   DW ?
RETT_SP   DW ?
Anmerkungen:
a) Bevor die zweite Anwendung(child process) damit gestartet wird müssen die Register "SS" und "SP" in einen dafür reservierten Speicherbereich gerettet werden und nach dem Beenden der zweiten Anwendung wieder damit geladen werden.
b) Oft werden angehängte Parameter einer Anwendung einfach nur aus dem PSP ab Adresse 80h herausgelesen. Besser wäre es jedoch vorher die jeweilige Adresse des PSPs erstmal zu ermitteln bevor das geschieht, denn die zweite Anwendung bringt ja ggf. ihre eigene Kommandozeile im übergebenen Parameter-Block mit.

RBIL->inter61b.zip->INTERRUP.H
--------D-2162-------------------------------
INT 21 - DOS 3.0+ - GET CURRENT PSP ADDRESS
AH = 62h
Return: BX = segment of PSP for current process
Notes: this function does not use any of the DOS-internal stacks and may
thus be called at any time, even during another INT 21h call
the current PSP is not necessarily the caller's PSP
identical to the undocumented AH=51h
-----------------------------------------------

Dirk
Antworten