Article View: comp.sys.ibm.pc.programmer
Article #353Re: An advance DOS question .. may be!
From: Rhys Weatherley
Date: Wed, 02 May 1990 06:45
Date: Wed, 02 May 1990 06:45
140 lines
5897 bytes
5897 bytes
lubkt@vax1.cc.lehigh.edu writes:
>Here is a DOS question:
>Suppose there is a program which does not permit DOS I/O-redirection
>(I don't know why). Suppose you really want to force this program to
>read a set of keystrokes stored in a file. After reading this file,
>which can be controlled by a user, the program should read input from
>the keyboard. Basically, the idea is to automate hitting keystrokes to
>some extent. Any suggestions?
>I love C, but I could consider writing it in assembly language if I
>have to. Thanks in advance.
Usually a program will not respond to input redirection if it bypasses
the normal DOS input handling routines and either:
1. Uses the BIOS ROM routines to get keypresses, through
interrupt 16H.
2. Traps the interrupt 09H which is called every time a key
is pressed on the keyboard and retreives its keys from
the hardware before processing them.
3. Accesses the keyboard hardware directly through some
sort of polling mechanism.
I have never come across any programs that use the last method, but if
the program does use it, there is nothing you can do unfortunately. The
second method also gives problems since you would need to re-write the
program's interrupt 09H handler, which may not be possible unless you
have the program source, or you are a very proficient machine code
hacker :-). The first method however, can be tackled by one of the
following methods:
(a) Try and find some keyboard macro processor, which is
usually a TSR (Terminate-and-Stay-Resident) program
which takes over the keyboard handling of the computer
to allow it to insert its own characters into the
keyboard buffer. These programs usually allow you
to define keys, for example ALT-X could be defined to
produce a sequence of keystrokes to exit from your
favourite editor. The macro processor sits in the
background and when you press ALT-X it will pass the
required keys through instead of ALT-X itself. If you
can find a macro processor that allows you to assign
a file's contents to a key (or even part of a file)
you would be right. However, since I don't use these
types of programs much I cannot recommend any, sorry.
(b) Write your own macro processor!! You could write your
own TSR program which traps either interrupt 09H or
interrupt 16H (16H is the better one) to return your
file's contents when a certain "hotkey" is pressed.
However, this introduces the many problems associated
with writing TSR's, notably of keeping DOS happy so
that you don't try and access the file when DOS is
already doing something else - the roof will cave in
otherwise. Various books exist on the subject of
writing TSR's, including 'Performance Programming under
MS-DOS' by 'M.J. Young', published by Sybex, but usually
they don't give you the whole story, keeping the "juicy"
bits for themselves :-). I have written a number of
TSR's but to date have not written a macro processor.
(c) The final option (that I can think of anyway) is a
hybrid program which combines TSR and normal programming
techniques, by writing a "harness" program which traps
the interrupt 16H keyboard service, and then runs the
program you want to redirect input into. An example
"skeleton" Turbo C program is given below. Many details
have been left out but should be pretty obvious:
#include "process.h"
int input_done;
main ()
{
install_int_16h ();
/* open the input file to use here */
input_done = 0;
spawnv ("PATHNAME-OF-PROGRAM-TO-RUN","",0); /* or some similar call */
/* close the input file here */
uninstall_int_16h ();
}
install_int_16h ()
{
/* get the old address of the INT 16H handler and save it */
/* set the INT 16H address to point to 'key_service' */
}
uninstall_int_16h ()
{
/* restore the saved INT 16H address */
}
/* Actual details of the required behaviour of the */
/* INT 16H handler below can be found in manuals about */
/* the BIOS ROM's. */
void interrupt key_service ( /* regs */ )
{
int ch;
if ((AH & 0x03) != 2 && !input_done)
{
if ((AH & 0x03) == 1)
{
ZF = /* ?? - indicate key is available */
AX = /* some useful key value - doesn't matter to much */
return;
}
ch = /* next character from input file */
if (ch == EOF)
input_done = 1;
else
{
AL = ch;
AH = /* scan code equivalent of the character 'ch' */
ZF = /* ?? - indicate a key is available */
return;
}
}
/* call the original INT 16H handler at the saved address */
}
Note that this is only a skeleton program and the actual details
need to be fleshed out, especially the setting of registers, and
the ZF (zero flag). Also, you need a very "well-behaved" program
for this technique to work satisfactorily, otherwise you could
get a very spectacular CRASH (interrupt routines produce the
weirdest problems!!) so your best bet is still probably writing a
real TSR with the problems it involves.
Hope this information has helped a little, and I would also be
interested in any other feedback that the original question
generates.
Rhys Weatherley, University of Queensland, Australia. G'day!!
Technical Details
Message-ID:
<3469@moondance.cs.uq.oz.au>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!jarthur!usc!samsung!munnari.oz.au!metro!bunyip!moondance!batserver.cs.uq.oz.au!rhysReferences:
<10150.263d718c@vax1.cc.lehigh.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!jarthur!usc!samsung!munnari.oz.au!metro!bunyip!moondance!batserver.cs.uq.oz.au!rhys From: rhys@batserver.cs.uq.oz.au (Rhys Weatherley) Newsgroups: comp.sys.ibm.pc.programmer Subject: Re: An advance DOS question .. may be! Message-ID: <3469@moondance.cs.uq.oz.au> Date: 2 May 90 06:45:08 GMT References: <10150.263d718c@vax1.cc.lehigh.edu> Sender: news@moondance.cs.uq.oz.au Reply-To: rhys@batserver.cs.uq.oz.au Lines: 140