Files

339 lines
6.7 KiB
C
Raw Permalink Normal View History

2026-07-06 18:01:36 +01:00
/*
JOKER.C
Written by DavidW
Started on 15/11/91
*/
#include <p_std.h>
#include <p_file.h>
#include <epoc.h>
#include <wlib.h>
#include <hwif.h>
LOCAL_D TEXT *cmds[]=
{
"oOverwrite",
"dDouble free",
"fFaulty free",
"wWind up stack",
"bBusy",
"sSlow exit",
"xExit",
NULL
};
#define CORRUPT_ITEMS 3
#define SPECIAL_ITEMS 4
#define ITEMS_BEFORE_CORRUPT 0
#define ITEMS_BEFORE_SPECIAL CORRUPT_ITEMS
LOCAL_D H_MENU_DATA mdata[]=
{
"Corrupt heap",CORRUPT_ITEMS,
"Special",SPECIAL_ITEMS,
NULL
};
GLDEF_D TEXT ** _cmds=(&cmds[0]);
GLDEF_D H_MENU_DATA * _mdata=(&mdata[0]);
LOCAL_D UINT MainWid;
LOCAL_D LONG delay=50l;
LOCAL_C VOID DoSleep(VOID)
{
TEXT buf[30];
p_atos(&buf[0],"Waiting %ld/10 secs",delay);
wSetBusyMsg(&buf[0],W_CORNER_BOTTOM_LEFT);
p_sleep(delay);
wCancelBusyMsg();
}
LOCAL_C INT AddInDelayItem(VOID)
{
H_DI_NUMBER num;
num.value=(&delay);
num.low=0;
num.high=1000;
return(uAddDialogItem(H_DIALOG_NUMBER,"Delay (10ths of secs)",&num));
}
LOCAL_C INT AddNumberEditor(TEXT *prompt,LONG *pnum,INT low,INT high)
{
H_DI_NUMBER num;
num.value=pnum;
num.low=low;
num.high=high;
return(uAddDialogItem(H_DIALOG_NUMBER,prompt,&num));
}
LOCAL_C VOID OverwriteAllocCell(VOID)
{
LONG cellen;
LONG overwlen;
UBYTE *cell;
if (uOpenDialog("Overwrite alloc cell"))
return;
cellen=0x100;
if (AddNumberEditor("Length of cell to alloc",&cellen,4,0x1000))
return;
overwlen=4;
if (AddNumberEditor("Length of overwrite",&overwlen,1,0x100))
return;
if (AddInDelayItem())
return;
if (uRunDialog()<=0)
return;
cell=p_alloc((UWORD)cellen);
if (!cell)
{
wInfoMsg("Cell too large to alloc");
return;
}
DoSleep();
p_bfil(cell,(UWORD)(cellen+overwlen),0xee);
}
LOCAL_C VOID FreeCellTwice(VOID)
{
LONG cellen;
UBYTE *cell;
if (uOpenDialog("Free cell twice"))
return;
cellen=0x100;
if (AddNumberEditor("Length of cell to free twice",&cellen,4,0x1000))
return;
if (AddInDelayItem())
return;
if (uRunDialog()<=0)
return;
cell=p_alloc((UWORD)cellen);
if (!cell)
{
wInfoMsg("Cell too large to alloc");
return;
}
p_free(cell);
DoSleep();
p_free(cell);
}
LOCAL_C VOID FreeWrongCell(VOID)
{
LONG cellen;
UBYTE *cell;
if (uOpenDialog("Free wrong cell"))
return;
cellen=0x100;
if (AddNumberEditor("Length of correct cell",&cellen,4,0x1000))
return;
if (AddInDelayItem())
return;
if (uRunDialog()<=0)
return;
cell=p_alloc((UWORD)cellen);
if (!cell)
{
wInfoMsg("Cell too large to alloc");
return;
}
DoSleep();
p_free(cell+1);
}
LOCAL_C VOID MainLoop(VOID);
LOCAL_C VOID DoWindupStack(VOID)
{
UBYTE junk[256];
p_bfil(&junk[0],256,0);
MainLoop();
}
LOCAL_C VOID WindupStack(VOID)
{
if (uOpenDialog("Wind up stack"))
return;
if (AddInDelayItem())
return;
if (uRunDialog()<=0)
return;
DoSleep();
DoWindupStack();
}
#define Y_BUSY_LOW 10
#define Y_BUSY_HIGH 78
#define X_BUSY 83
#define BUSY_SCALE 1000
LOCAL_C VOID DoPrint(UINT y)
{
gPrintText(X_BUSY,y,"Busy",4);
wFlush();
}
LOCAL_C VOID GoBusy(VOID)
{
LONG nloops;
UWORD y;
UWORD lasty;
ULONG j;
if (uOpenDialog("Go busy"))
return;
nloops=3;
if (AddNumberEditor("Number of loops of activity",&nloops,1,10))
return;
if (AddInDelayItem())
return;
if (uRunDialog()<=0)
return;
DoSleep();
while (nloops--)
{
lasty=Y_BUSY_LOW;
DoPrint(lasty);
j=Y_BUSY_LOW*BUSY_SCALE;
FOREVER
{
j++;
y=(UWORD)(j/BUSY_SCALE);
if (y!=lasty)
{
DoPrint(lasty);
if (y>Y_BUSY_HIGH)
break;
lasty=y;
DoPrint(y);
}
}
}
}
LOCAL_C VOID SlowExit(VOID)
{
if (uOpenDialog("Slow exit"))
return;
if (AddInDelayItem())
return;
if (uRunDialog()<=0)
return;
DoSleep();
p_exit(0);
}
LOCAL_C VOID ManageCommand(INT index)
{
switch (index)
{
case ITEMS_BEFORE_CORRUPT:
OverwriteAllocCell();
break;
case ITEMS_BEFORE_CORRUPT+1:
FreeCellTwice();
break;
case ITEMS_BEFORE_CORRUPT+2:
FreeWrongCell();
break;
case ITEMS_BEFORE_SPECIAL:
WindupStack();
break;
case ITEMS_BEFORE_SPECIAL+1:
GoBusy();
break;
case ITEMS_BEFORE_SPECIAL+2:
SlowExit();
break;
case ITEMS_BEFORE_SPECIAL+3:
p_exit(0);
}
}
LOCAL_C VOID TryExecuteCommand(INT keycode)
{
keycode=uLocateCommand(keycode);
if (keycode>=0)
ManageCommand(keycode);
}
LOCAL_C VOID GoToSystemScreen(VOID)
{
wClientPosition(0,p_pidfind("SYS$SHLL.*"));
}
LOCAL_C VOID MainLoop(VOID)
{
INT ret;
WMSG_KEY key;
FOREVER
{
uGetKey(&key);
if (key.keycode&W_SPECIAL_KEY)
TryExecuteCommand(key.keycode&(~W_SPECIAL_KEY));
else if (key.keycode==W_KEY_MENU && !(key.modifiers&W_CTRL_MODIFIER))
{
ret=uPresentMenus();
if (ret>0)
TryExecuteCommand(ret);
}
else if (key.keycode==26)
GoToSystemScreen();
}
}
LOCAL_C VOID ReduceScreenSize(VOID)
{
W_WINDATA wd;
wd.extent.tl.x=wd.extent.tl.y=0;
wd.extent.width=189;
wd.extent.height=80;
wSetWindow(MainWid,W_WIN_EXTENT,&wd);
if (uErrorValue(wCheckPoint()))
p_exit(0);
}
LOCAL_C VOID CreateGC(VOID)
{
G_GC gc;
INT hgc;
gc.textmode=G_TRMODE_INV;
hgc=gCreateGC(MainWid,G_GC_MASK_TEXTMODE,&gc);
if (hgc<0)
p_exit(hgc);
}
LOCAL_C VOID SpecificInit(VOID)
{
MainWid=uFindMainWid();
CreateGC();
ReduceScreenSize();
gBorder(W_BORD_CORNER_4);
wsEnable();
wCaptureKey(26,W_CTRL_MODIFIER,W_CTRL_MODIFIER);
}
GLDEF_C VOID main(VOID)
{
uCommonInit();
SpecificInit();
MainLoop();
}