[net.micro.pc] DOS re-entrancy

karayan@nvuxr.UUCP (G J Karayannopoulos) (02/28/86)

I understand that there is a re-entrancy problem with DOS function 
calls (int 21h). In particular, if an application is interrupted 
WHILE making a DOS function call, by a hardware interrupt handler,
and the handler itself makes its own DOS function calls, then when
the handler returns, the original application cannot complete its
DOS function call. The reason is that int 21h is not re-entrant.

Is there any way around that? I know of one memory-resident program
that gets invoked by a particular combination of key strokes, but
if at the time you attempt to invoke it you are doind a DOS call,
the program will beep and refuse to operate. My question is this:
How does the resident program KNOW that a DOS function call was made
when it was invoked? Is there some DOS flag that one can test to see
if int 21h was running? I would appreciate any ideas or info.
Thanks in advance.


					George Karayannopoulos

geoff@suneast.uucp (Geoff Arnold) (03/04/86)

The obvious solution (so obvious it's gonna be posted umpteen times):
grab the int21 vector yourself, and set an "indos" flag when a user call
comes in. Your driver then checks "indos" on interrupt: if set, it
sets "servicewanted" and lets DOS continue; otherwise it just performs
the required activity (including int21's).. On the way out, DOS returns
to your int21 interceptor, which clears "indos" and (if "servicewanted"
is set) does the necessary servicing. You get the idea. The only
real complication is that you probably want to get the interceptor
out of the way while the service code is running.....
-- 
#include <sys/disclaimer.h> /* co. lawyers: will this do? */

Geoff Arnold, Sun Microsystems Inc. (East Coast Division)
SnailMail: One Cranberry Hill, Lexington, MA 02173; 617-863-8870 x136 
UUCP:      [East Coast] linus!security!sunne!suneast!geoff
           [West Coast] {hplabs,ihnp4,nsc,pyramid,decwrl}!sun!suneast!geoff

jrv@siemens.UUCP (03/06/86)

There is a flag buried in the internal data area for MS-DOS called INDOS.
A 0 value indicates that MS-DOS is not currently executing in a critical
section. Any other value indicates that you can not make a Int 21 call.

To find out the current value of this flag:

	1. Before interrupt processing starts execute the GET_INDOS_FLAG
	   function. This is function 34h in MS-DOS.
	   (i.e. AX = 34h when doing the Int 21)

	2. Upon return you don't get the flag but rather a pointer to
	   it in ES:BX.  ES = the segment address and BX = the offset
	   address of the INDOS flag.

	3. When the interrupt occurs directly test this byte from the
	   interrupt handler to determine if calls to MS-DOS are
	   allowable. You will have to determine appropriate actions
	   if the interrupt occurred during a critical section of MS-DOS.

Hope this helps.

Jim Vallino
{allegra,ihnp4}!princeton!siemens!jrv

glen@intelca.UUCP (Glen Shires) (03/07/86)

> The obvious solution (so obvious it's gonna be posted umpteen times):
> grab the int21 vector yourself, and set an "indos" flag when a user call
> comes in. Your driver then checks "indos" on interrupt: if set, it
> sets "servicewanted" and lets DOS continue; otherwise it just performs
> the required activity (including int21's).. On the way out, DOS returns
   :
> Geoff Arnold, Sun Microsystems Inc. (East Coast Division)
> SnailMail: One Cranberry Hill, Lexington, MA 02173; 617-863-8870 x136 
> UUCP:      [East Coast] linus!security!sunne!suneast!geoff
>            [West Coast] {hplabs,ihnp4,nsc,pyramid,decwrl}!sun!suneast!geoff

Obvious yes, functional no! atleast not with a LOT of tweaking.

DOS isn't that clean because:

    - It recursively calls itself
    - It has some functions that don't ever return (like TERMINATE)
    - It has plenty of undocumented function calls.
    -- 
^ ^    Glen Shires, Intel, Santa Clara, Ca.
O O     Usenet: {ucbvax!amd,pur-ee,hplabs}!intelca!glen
 >      ARPA:   "amd!intelca!glen"@BERKELEY
\-/    --- almost relevant

few@well.UUCP (Frank Whaley) (03/09/86)

In article <137@suneast.uucp> geoff@suneast.uucp (Geoff Arnold) writes:

>grab the int21 vector yourself, and set an "indos" flag when a user call
>comes in.

Better to make "indos" a counter, as DOS does call itself on occasion,
and you'll need to count the number of entries/exits.
-- 
Frank Whaley
EFS Management Software, Inc.
UUCP:		hplabs!
	   ihnp4!ptsfa!
	seismo!lll-crg!well!few
ARPA:	well!few@lll-crg.ARPA

connery@bnrmtv.UUCP (Glenn Connery) (03/11/86)

> 
> There is a flag buried in the internal data area for MS-DOS called INDOS.
> A 0 value indicates that MS-DOS is not currently executing in a critical
> section. Any other value indicates that you can not make a Int 21 call.
> 
> To find out the current value of this flag:
> 
> 	1. Before interrupt processing starts execute the GET_INDOS_FLAG
> 	   function. This is function 34h in MS-DOS.
> 	   (i.e. AX = 34h when doing the Int 21)
> 
> 	2. Upon return you don't get the flag but rather a pointer to
> 	   it in ES:BX.  ES = the segment address and BX = the offset
> 	   address of the INDOS flag.
> 
> 	3. When the interrupt occurs directly test this byte from the
> 	   interrupt handler to determine if calls to MS-DOS are
> 	   allowable. You will have to determine appropriate actions
> 	   if the interrupt occurred during a critical section of MS-DOS.
> 
> Hope this helps.
> 
> Jim Vallino
> {allegra,ihnp4}!princeton!siemens!jrv

-- 

Glenn Connery, Bell Northern Research, Mountain View, CA
{hplabs,amdahl,3comvax}!bnrmtv!connery

connery@bnrmtv.UUCP (Glenn Connery) (03/11/86)

> 
> There is a flag buried in the internal data area for MS-DOS called INDOS.
> A 0 value indicates that MS-DOS is not currently executing in a critical
> section. Any other value indicates that you can not make a Int 21 call.
> 
> To find out the current value of this flag:
> 
> 	1. Before interrupt processing starts execute the GET_INDOS_FLAG
> 	   function. This is function 34h in MS-DOS.
> 	   (i.e. AX = 34h when doing the Int 21)
> 
> 	2. Upon return you don't get the flag but rather a pointer to
> 	   it in ES:BX.  ES = the segment address and BX = the offset
> 	   address of the INDOS flag.
> 
> 	3. When the interrupt occurs directly test this byte from the
> 	   interrupt handler to determine if calls to MS-DOS are
> 	   allowable. You will have to determine appropriate actions
> 	   if the interrupt occurred during a critical section of MS-DOS.
> 
> Hope this helps.
> 
> Jim Vallino
> {allegra,ihnp4}!princeton!siemens!jrv


While this is accurate, it is only partially accurate.  Check out page
252 of PC Magazine October 15, 1985 for the gory details.  Basically
DOS switches to an internal stack which is where the re-entrancy problem
comes in.  There are actually three different stacks... one for 01H to
0CH, one for 0DH and above, and one for 01H through 0CH when a Critical
Error is in progress.  The DOS Print command uses the INDOS flag to tell
whether it can do anything with DOS file calls or not.  The problem is
that on the DOS command level we are in function 0AH waiting for keyboard
input ALL THE TIME!  So, PRINT takes advantage of yet another undocumented
feature of DOS... INT 28H which DOS executes whenever it is in a wait
state (like during keyboard input) during function calls 01H to 0CH.  Thus
when INT 28H is invoked, PRINT knows that a function call of 01H to 0CH
is in progress and because a separate stack is used for 01H to 0CH and
the file access calls... well you get the idea.

This should not be necessary if you don't need to work through DOS keyboard
input calls.  If you do, you'll have to install yourself in the chain for
INT 28H just like PRINT or you won't execute a whole lot (like never).

Of course with all of this undocumented and reasonably kludgey, it is
absolutely guaranteed to change the next DOS rev, so take your chances...

...Glenn
-- 

Glenn Connery, Bell Northern Research, Mountain View, CA
{hplabs,amdahl,3comvax}!bnrmtv!connery

maa@oasys.UUCP (03/12/86)

> In article <137@suneast.uucp> geoff@suneast.uucp (Geoff Arnold) writes:
> 
> >grab the int21 vector yourself, and set an "indos" flag when a user call
> >comes in.
> 
> Better to make "indos" a counter, as DOS does call itself on occasion,
> and you'll need to count the number of entries/exits.
> -- 

I've been doing some hacking at MSDOS and there is a VERY useful undocumented
function call that does this for you.

Function call 34h, "Get DOS_BUSY Pointer", returns in es:bx a pointer to the 
DOS_BUSY byte.  This byte is 0 if MSDOS may be called and >0 if MSDOS is busy.

The call to function 34h must be made from the main (non-interrupt) part of
the program and the pointer saved for the interrupt service routine to use
when it needs to find out if it can make a MSDOS call.

Also handy is function 51h, "Get PSP Address", which returns the segment 
address of the active program's PSP in bx.  This is identical to MSDOS 3.x's
function 62h.  Both function 51h and 62h execute the same code in MSDOS 3.1!
WHY DIDN'T MS DOCUMENT FUNCTION 51H INSTEAD OF INVENTING A NEW ONE??

Both of these functions (34h and 51h) work in 2.11 and 3.1.

Happy Hacking,
Mark