home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Phoenix CD 2.0
/
Phoenix_CD.cdr
/
24b
/
microc.zip
/
CING-38.FIG
next >
Wrap
Text File
|
1987-10-28
|
5KB
|
124 lines
/**************************************************************************/
Figure 1 - In-Line Assembly Code for exec() Function
#pragma inline
/**************/
exec(char *program, char *argument) /* new ANSI way of declaring args */
{
/* The rules of this game are rather too involved to explain here. See
Ray Duncan's <i>Advanced MSDOS<d>, chapter 10, for a lucid explanation
of the MSDOS's ``exec'' function. This is done in the ``large'' model so
pointers will all be 4 bytes long and coding will be straightforward.*/
char comline[30]; /* to construct command line */
struct{ /* structure needed by DOS 0x4b service */
unsigned envseg;
char *command,*fcb1,*fcb2;
} paramblock,*pbptr;
paramblock.envseg=0; /* keep the old environment */
comline[0] = strlen(argument); /* first char: length of line */
strcpy(comline+1,argument);
strcat(comline,"\r"); /* terminate with 0xd */
paramblock.command = comline;
paramblock.fcb1=paramblock.fcb2=(char *)0xffffffff; /* Ignore fcb's */
pbptr = ¶mblock;
asm push ds /* DS & BP must be saved. Turbo saves SI & DI */
asm push bp
/* The next two routines work because this is the LARGE model and
pointers are 32-bit entities and work with lds & les. Cute, no? */
asm lds dx,program /* DS:DX pointed to program path */
asm les bx,pbptr /* ES:BX pointed to parameter structure */
asm mov word ptr cs:fill[0],ss /* save SS & SP */
asm mov word ptr cs:fill[2],sp
asm jmp next
asm fill dw 0,0 /* store SS & SP in code segment */
next:
asm mov al,0
asm mov ah,4bh
asm int 21h /* do exec call */
asm cli
asm mov ss,cs:fill[0] /* restore SS & SP */
asm mov sp,cs:fill[2]
asm sti
asm pop bp
asm pop ds
}
/*******************************************************************/
/*Figure 2 - Getting Rid of Resident Programs*/
/* LARGE MODEL USED SO POINTERS ARE 32 BITS.
This compiles to 5.6K, which supports Borland's claim to
relatively tight code. Incidentally, I can do the same in 2.3K in DeSmet C
and about 1K in assembler. Neither coding is half so simple, however.
This sort of direct manipulation of MSDOS allocation headers
is an example of ill-behaved programming at its most incorrigible. But don't
long C pointers make crime EASY??*/
#include <dos.h>
#include <stdio.h>
#define RSHIFT 1 /* corresponding bits on shift state byte @ 00:417H */
#define LSHIFT 2
#define ALT 8
#define TESTIT (RSHIFT | LSHIFT | ALT)
#define TICKINT 8
#define NEWTICK 0x80
#define FINI 0x5a
char intable[0x400],*shiftptr=(char *) 0x417L;
typedef struct { /* MSDOS allocation header format */
char flag; /* Either 5Ah for end or 4Dh for not end */
unsigned nextpsp,paragraphs;
} HEAD;
HEAD *header;
extern unsigned _psp;
unsigned meminstall; /* how much memory is installed in PC? */
/******************/
void interrupt tickhandler()
{ /* check shift state for three shifts depressed */
if( (*shiftptr & TESTIT) == TESTIT) deallocate();
geninterrupt(NEWTICK); /* chain the interrupt */
}
/***************/
deallocate()
{
HEAD *nextheader;
/* _AX is a "pseudovariable" which can be used to get or change
the value stored in AX. The possibilities are mind-boggling. */
_AX=0xe00+7; /* just a beep to show something happened */
geninterrupt(0x10);
memcpy(NULL,intable,0x400); /* restore old int table */
nextheader = MK_FP(_psp + header->paragraphs,0);
nextheader->flag = FINI; /* tell MSDOS that everything's free above */
nextheader->nextpsp = 0;
nextheader->paragraphs = meminstall - 1 - _psp - header->paragraphs;
}
/*********************/
main()
{
char **newtick,**oldtick; /*just so it's 32 bits. char * is a convenience. */
header = MK_FP(_psp - 1, 0); /* point to TSR's allocation header */
newtick = MK_FP(0,4*NEWTICK); /* swap interrupt vectors */
oldtick = MK_FP(0,4*TICKINT);
disable(); /* stop hardware */
*newtick = *oldtick;
*oldtick = (char *) tickhandler; /* put interrupt address into table */
enable();
memcpy(intable,NULL,0x400); /* save old interrupt table */
geninterrupt(0x12); /*how much memory installed? */
meminstall = _AX*0x40; /* store amount in paragraphs */
/* Note that TurboC concatenates strings for you. */
puts("\nDEINSTALLATION PROGRAM INSTALLED\n"
" Press Alt-Leftshift-Rightshift\n"
"to deinstall subsequent resident programs.\n" );
keep(0,_SS - _psp +1); /* lop off stack, terminate & stay...*/
}/* keep(0,n) uses DOS function 31h to set aside n paragraphs of memory */
/********************/