Need help with a TSR hooking INT 21h 
Author Message
 Need help with a TSR hooking INT 21h

I have recently come across a situation where I need to redirect stderr output
from a program to stdout in MSDOS.  I've found no way to do this in the
standard DOS manual so I'm trying to write a Terminate and Stay Resident program
to take care of it.  Unfortunately, I have to intercept the DOS dispatch
function to do it.

So here is the situation so far:  Once my program hooks INT 21h I can still
do things at the command prompt like 'dir' or looking at a file by 'type'ing
it, but when I try to execute a program the system hangs.  The only thing my
handler does right now is jumps to the old vector for INT 21h.  

Any suggestions or insight into this problem would be greatly appreciated.

NULL    EQU     0               ; Null value
STDOUT  EQU     1               ; Device handle for stdout
STDERR  EQU     2               ; Device handle for stderr
WRITEF  EQU     40h             ; Function for DOS Write to file
DOS     EQU     21h             ; DOS Dispatch interrupt handler

        NOSMART

        ORG 100h

code    segment public  para    use16   'CODE'
        assume cs:code,es:nothing,ds:nothing,ss:nothing

OLD_DOS         LABEL   DWORD
oldwfile        dd FAR PTR      NULL    ; Vector of old int 21h handler.

;
; WARP:
;
;   This is an interrupt handler for 21h.  When installed it will change all
;   requests to write to stderr (handle=2) to stdout (handle=1) and then
;   transfers control back to the old handler.
;
;   At the moment Warp only gives control back to the old handler.
;
Warp    proc    far

        jmp     OLD_DOS         ; Give control back to the original handler.

Warp    endp

Endw:

;
; Main:
;   Main links Warp into the interrupt vector table at the int 21h entry and
;   saves the old interrupt vector into oldwfile (OLD_DOS).
;

Main    proc    far

        mov     al,DOS          ; Get INT vector for the write file func.
        mov     ah,35h
        int     21h
                                ; Save the vector in oldwfile.
        mov     word ptr cs:oldwfile,BX                 ; Save offset
        mov     word ptr cs:oldwfile+2,ES               ; Save segment

        mov     bx,DOS*4        ; Set the vector to point to Warp
        mov     ax,0
        mov     es,ax
        cli
        mov     word ptr es:[bx], OFFSET Warp
        mov     word ptr es:[bx+2], SEG Warp
        sti

        mov     ax,OFFSET end_of_program
        mov     bx,OFFSET OLD_DOS
        sub     ax,bx           ; AX = # of bytes to keep.
        mov     bx,16
        mov     dx,0
        div     bx              ; AX = # of paragraphs to keep.
        cmp     dx,0            ; if remainder is not zero
        jz      no_remainder
        inc     ax
no_remainder:
        mov     dx,ax           ; DX = No. of paragraphs to keep.
        mov     ax,3100h        ; TSR and return w/ 0
        int     21h

        nop                     ; Does not reach this.
Main    endp

end_of_program:

code    ends

END     Main

Thanks in advance.

Forrest
--
 Forrest S. Trimbell            

---------------============== DANGER MOUSE 2099! ==============---------------



Fri, 25 Jul 1997 07:21:32 GMT  
 Need help with a TSR hooking INT 21h

Quote:
> I have recently come across a situation where I need to redirect stderr
> output from a program to stdout in MSDOS.  I've found no way to do this in
> the standard DOS manual so I'm trying to write a Terminate and Stay
> Resident program to take care of it.  Unfortunately, I have to intercept
> the DOS dispatch function to do it.

MASM comes with a utility (ERROUT.EXE) designed for precisely this
purpose - a legacy of the bad old days when MASM would write its error
messages to stderr, and, since you can't redirect stderr from the command
line, they'd scroll off the screen before you could read them.

Of course, you seem to be using TASM.  I don't think it comes with such a
utility, since the Borland developers were bright enough to write error
messages to stdout in the first place.

ERROUT is an example of a "stub loader" - a program that performs some
function that alters the execution environment (in this case, redirecting
stderr to a specified file or device), and then spawns another program
(which inherits the alterations) as a child process.

Unlike a TSR, it only alters the environment for the duration of the spawned
program, and doesn't take up permanent memory.

Such a program is easy to write in C, using freopen() to redirect output
and one of the spawn() family to execute the child process.

Quote:
> So here is the situation so far:  Once my program hooks INT 21h I can still
> do things at the command prompt like 'dir' or looking at a file by 'type'ing
> it, but when I try to execute a program the system hangs.  The only thing my
> handler does right now is jumps to the old vector for INT 21h.  

That's because of the code sequence that calculates the number of paragraphs
of memory to keep resident.  What DOS wants is the number of paragraphs
FROM THE START OF YOUR PROGRAM'S MEMORY BLOCK (the beginning of the PSP).

You're calculating the size of just the resident code itself, i.e,

(OFFSET BeginResident - OFFSET EndResident) / 16 + (maybe) 1

...when you need to calculate:

OFFSET EndResident / 16 + (maybe) 1

...since the PSP begins at offset 0.

As soon as DOS execs some other program, your code gets overwritten
and the machine hangs, because DOS only keeps however many paragraphs
you specify FROM THE START OF THE PSP.

You can't tell DOS "Keep just the space from point A to point B".  You
can only tell it "Keep n paragraphs starting at offset 0" - that is,
"the space from offset 0 to point B".

Quote:
> Any suggestions or insight into this problem would be greatly appreciated.

There are several other things I'd do differently (like: why do you use
Fxn 35h to get the Int 21h vector, but then use direct memory manipulation
to set it, instead of using Fxn 25h?), but they're more style issues
than anything else.  I'd be glad to expound further, if you like, but I
really think writing a stub loader would be a better and simpler choice.

Indeed, given the history of the problem, there are probably freeware or
shareware utilities similar to ERROUT on one of the big ftp sites.
Personally, I'd check SimTel or x2ftp or Garbo before I bothered to code
anything myself.

---
Glen Blankenship




Fri, 25 Jul 1997 17:54:27 GMT  
 Need help with a TSR hooking INT 21h
And, following up on my own followup:

Quote:
> Indeed, given the history of the problem, there are probably freeware or
> shareware utilities similar to ERROUT on one of the big ftp sites.
> Personally, I'd check SimTel or x2ftp or Garbo before I bothered to code
> anything myself.

For example, try:

ftp://oak.oakland.edu/SimTel/msdos/sysutil/rdstderr.zip

It does exactly what you need.

---
Glen Blankenship




Fri, 25 Jul 1997 18:13:38 GMT  
 Need help with a TSR hooking INT 21h

Quote:


>> I have recently come across a situation where I need to redirect stderr
>> output from a program to stdout in MSDOS.  I've found no way to do this in
>> the standard DOS manual so I'm trying to write a Terminate and Stay
>> Resident program to take care of it.  Unfortunately, I have to intercept
>> the DOS dispatch function to do it.
>ERROUT is an example of a "stub loader" - a program that performs some
>function that alters the execution environment (in this case, redirecting
>stderr to a specified file or device), and then spawns another program
>(which inherits the alterations) as a child process.

There's a free program available from ftp.mednet.net, in 'pub/msdos/log.com'
which logs all console output to a file.  It also is a 'stub loader', but it
always runs command.com.  Thus, after you run 'log', all of the output from
all of the commands you type is logged into a file, until you type 'exit'.

Quote:
>> So here is the situation so far:  Once my program hooks INT 21h

Instead of int 21h, you might try the undocumented 'int 29h'.  DOS calls
this interrupt whenever it does console output.  Each character written gets
a single call with the character to write in AL.


Fri, 25 Jul 1997 18:53:58 GMT  
 Need help with a TSR hooking INT 21h

Quote:

>For example, try:
>ftp://oak.oakland.edu/SimTel/msdos/sysutil/rdstderr.zip
>It does exactly what you need.

And, you could get 4dos
(ftp://oak.oakland.edu/SimTel/msdos/4dos(?)/4dos55[ab].zip) which **IS**
capable of letting you redirect stderr via the >& operator, like so:
prog > outfile >& errfile
...just like unix! (course, (t)csh doesn't think this means the same thing:
in bash, you'd say prog > outfile 2> errfile to get the same effect...just
so people have a framework for comparison :) )  I've tested this, so I know
it works.
--
Richard Cooley Extraordinaire           "Yeah.  Arrgh."


"It seems I've found myself on a voyage of the damned." The Doctor


Fri, 25 Jul 1997 23:52:51 GMT  
 Need help with a TSR hooking INT 21h

Quote:

> Instead of int 21h, you might try the undocumented 'int 29h'.  DOS calls
> this interrupt whenever it does console output.  Each character written gets
> a single call with the character to write in AL.

That won't work in this instance.  DOS only uses Int 29h for (some of)
its own output, not for program output written to stdout or stderr, and
only then if the CON driver supports Int 29h.

Just FYI, unless ANSI.SYS or some alternate CON driver is installed,
the only thing Int 29h does is save a bunch of registers on the stack,
then pass the character in AL to the BIOS Write TTY function (Int 10h,
AH = 0Eh), and, on return, restore the registers it saved.

---
Glen Blankenship




Sat, 26 Jul 1997 01:22:00 GMT  
 Need help with a TSR hooking INT 21h

Quote:
>I have recently come across a situation where I need to redirect stderr output
>from a program to stdout in MSDOS.  I've found no way to do this in the
>standard DOS manual so I'm trying to write a Terminate and Stay Resident program
>to take care of it.  Unfortunately, I have to intercept the DOS dispatch
>function to do it.

>So here is the situation so far:  Once my program hooks INT 21h I can still
>do things at the command prompt like 'dir' or looking at a file by 'type'ing
>it, but when I try to execute a program the system hangs.  The only thing my
>handler does right now is jumps to the old vector for INT 21h.  

TSRs can be tricky. The problem is you did not tell DOS to keep enough
memory resident. When I looked at the code, I saw you were calculating the
number of paragraphs of actual code and data ("end_of_program"-"OLD_DOS").
This does not include the PSP. Therefore, you were telling DOS to keep 10H
paragraphs of memory too few. When you started another program, it
overwrote the last 10H paragraphs of your TSR.

Quote:
>  ORG 100h

>code segment  public   para  use16 'CODE'
>  assume cs:code,es:nothing,ds:nothing,ss:nothing

>OLD_DOS          LABEL DWORD

 (some code deleted)

Quote:
>  mov     ax,OFFSET end_of_program
>  mov   bx,OFFSET OLD_DOS
>  sub   ax,bx    ; AX = # of bytes to keep.
>  mov   bx,16
>  mov   dx,0
>  div     bx     ; AX = # of paragraphs to keep.
>  cmp   dx,0     ; if remainder is not zero
>  jz no_remainder
>  inc   ax
>no_remainder:
>  mov   dx,ax    ; DX = No. of paragraphs to keep.
>  mov   ax,3100h ; TSR and return w/ 0
>  int   21h

>  nop         ; Does not reach this.
>Main endp

>end_of_program:

For a COM program, your "keep" code should just convert "OFFSET
end_of_program" to number of paragraphs and pass that number back to DOS.
The easy way to do this is:

   MOV   DX,OFFSET end_of_program      ;number of bytes used
   ADD   DX,15                         ;round up to next paragraph
            ;COM programs start at 100H, which include the PSP
            ;if program is an EXE, you also have to add 100H bytes for PSP
   SHR   DX,4                          ;change bytes to paragraphs
   MOV   AX,3100H                      ;DOS's terminate and stay resident
   INT   21H

(I have not tested any of this, but your keep code does have a problem.)

   Scott C. Sadow          |  My work is good, quick, or cheap - pick any 2.

                           |  is not quick. A quick cheap job is not good.



Thu, 07 Aug 1997 19:09:52 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Need help with a TSR hooking INT 21h

2. Problem hooking INT 21h from TSR

3. int 21h hooking problem, please HELP !

4. Is possible hook Int 21h??

5. Hooking Int 21h

6. hook a vector using int 21h

7. Hooking int 21h

8. Hooking int 21h

9. hooking int 21h

10. TSR probs/ proc set by int 21h, fcn 25h won't work

11. TSR Int 21h

12. INT 21h - need help

 

 
Powered by phpBB® Forum Software