/*
FUNC0E32.C -- take over INT 21h Function 0Eh; return 32 in AL

cl func0e32.c
func0e32 lastdrv
*/

#include <stdlib.h>
#include <stdio.h>
#include <process.h>
#include <dos.h>

#pragma pack(1)

typedef struct {
#ifdef __TURBOC__
    unsigned bp,di,si,ds,es,dx,cx,bx,ax;
#else
    unsigned es,ds,di,si,bp,sp,bx,dx,cx,ax;     /* same as PUSHA */
#endif
    unsigned ip,cs,flags;
    } REG_PARAMS;

void interrupt far dos(REG_PARAMS r);

void (interrupt far *old)();
unsigned long calls = 0;
unsigned long changed = 0;

void fail(char *s) { puts(s); exit(1); }

main(int argc, char *argv[])
{
    if (argc < 2)
        fail("usage: func0e32 [program name] <args...>");
    
    /* hook INT 21 */
    old = _dos_getvect(0x21);
    _dos_setvect(0x21, dos);

    /* run command */
    spawnvp(P_WAIT, argv[1], &argv[1]);
    
    /* unhook INT 21h */
    _dos_setvect(0x21, old);
    printf("\n%lu DOS calls\n", calls);
    printf("%lu changed\n", changed);
}

void interrupt far dos(REG_PARAMS r)
{
    calls++;
    if ((r.ax >> 8) == 0x0E)
    {
        (*old)();
        r.ax = 0x0E00 + 32;
        changed++;
    }
    else
        _chain_intr(old);
}
