$if 0 DOSKEY-Macros zu ausfhrbaren Dateien expandieren ------------------------------------------------- --------------------------------------------------------------------------- Programm: MAC2BAT.BAS Funktion: Expandiert DOSKEY-Makros zu Batchdateien Compiler: PowerBasic, Version 3.0 Pr-Autor: Gerhard Frey, Oberthal --------------------------------------------------------------------------- Der DOS-Multiplexinterrupt INT 2Fh ist ein intern durch das Betriebssystem benutzter Interrupt, der nur teilweise offiziell dokumentiert ist. Er er- laubt die Kommunikation zwischen zwei laufenden Prozessen und besitzt genau wie der INT 21h einen Funktionsdispatcher, der ber Register AH die jewei- lige Unterfunktion aufruft. Der Multiplex wird beispielsweise benutzt, um bei der Installation residenter Programme zu prfen, ob ein Programm nicht bereits installiert ist. COMMAND.COM benutzt den INT 2F u. a., um ber die Funktion 48h, Unterfunktion 10h den Kommandozeileneditor von DOSKEY aufzu- rufen. Das vorliegende PowerBasic-Programm MAC2BAT.BAS verwendet den Multiplexer, um DOSKEY-Makros zu Batchdateien zu expandieren. Dadurch wird es z.B. m”g- lich, aus Batchprogrammen heraus DOSKEY-Makros zu starten. Bekanntlich be- finden sich Makros nur im Speicher, weshalb sie auch normalerweise nicht aus Batches heraus ausgefhrt werden k”nnen. Mit Hilfe der oben erw„hnten INT 2F-Funktionen kann man nun die Makrobefehle zu den definierten Befeh- len expandieren. Die Funktion des INT 2F erwartet in den Registern DS:DX die Adresse eines Puffers mit folgendem Aufbau: 1.Byte: Pufferlaenge (=80h, =128dez) 2.Byte: Zahl der gelesenen Bytes ab 3.Byte: Datenbytes Wichtig ist nun folgendes Verhalten der Int2F-Funktion: Wird vom Benutzer anstatt eines DOS-Befehls ein Makroname eingegeben, dann legt die Funktion keinen Text im Puffer ab, das 2. Byte enth„lt also den Wert 0. Ist dies der Fall, aktiviert man die Funktion ein zweites Mal, wobei der Makrotext ex- pandiert wird. Diesen Text sichert man in einer Stringvariablen und ko- piert diese in eine Batchdatei. In einer Schleife wird so das komplette Makro expandiert (Vergleiche Zeilen 35 bis 47 im Listing). Nach Aufruf des INT 2F erwartet die Funktion die Eingabe in die Kommando- zeile. Damit das Programm also nicht unterbrochen wird, wird diese Einga- be simuliert. Die beiden Routinen KEYSTACK und KEYBUFF schreiben den Ma- kronamen, der zusammen mit m”glichen Parametern dem PowerBasic-Programm bergeben wird, in einen erweiterten Tastaturpuffer, der nach Auswertung durch die INT 2F-Funktion wieder gel”scht wird. $endif '/Compilerdirectiven/ $compile exe $lib all off $error all - '/Const: boolean/ %FALSE=0 %TRUE =-1 '/Var: string/ defstr a-z dim buffer as string * 128 '/Definition der Variablen/ macro=left$(COMMAND$,127) file=extract$(macro," ")+".BAT" buffer=chr$(128) segment??=varseg(buffer) offset??=varptr(buffer) '/Beenden mit Errorlevel/ if doskey%=%FALSE then END 3 if len(macro)=0 then END 2 '/Hauptprogramm/ setbuffer &H200,&H280 'Tastaturpuffer verschieben und 'erweitern auf 256 Zeichen keystack keybuff (macro) 'Textstring aufbereiten und in 'den Tastaturpuffer schreiben int2F segment??,offset?? 'Multiplexer aufrufen if asc(mid$(buffer,2,1))=0 then 'Macrobefehl im Zeilenpuffer dnum?=freefile open "O",#dnum?,file print #dnum?,"@echo off" do keystack keybuff ("") int2F segment??,offset?? z?=asc(mid$(buffer,2,1)) print #dnum?,mid$(buffer,3,z?) loop until z?=0 close #dnum? errorlevel?=0 else 'kein Macrobef. im Zeilenpuffer errorlevel?=1 end if setbuffer &H1E,&H3E 'Tastaturpuffer wiederherstellen END errorlevel? '/Prozeduren, Funktionen sub int2F(byval sgm??,byval ofs??) ! mov ax,&H4810 ! mov ds,sgm?? ! mov dx,ofs?? ! int &H2F end sub sub keystack (txt) def seg=&H40 head??=peekI(&H80) tail??=head??+len(txt) pokeI &H1A,head?? pokeI &H1C,tail?? poke$ head??,txt def seg end sub sub setbuffer(head??,tail??) local def seg=&H40 pokeI &H1A,head?? pokeI &H1C,head?? pokeI &H80,head?? pokeI &H82,tail?? def seg end sub function keybuff (txt) local for i?=1 to len(txt) char=mid$(txt,i?,1)+chr$(0) buff=buff+char next keybuff=buff+chr$(13,0) end function function doskey% local local l% doskey%=%TRUE ! mov ax,&H4800 ! int &H2F ! mov l%,ax if l% > 0 then doskey%=%FALSE end function