/* JOKER.C Written by DavidW Started on 15/11/91 */ #include #include #include #include #include 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(); }