/* * KillReq (C) Copyright Eddy Carroll 1989, may be Freely Redistributed. * * KillReq disables Intuition's AutoRequest() function, such that any calls * to it will always return FALSE (as if the user had selected CANCEL). * This is primarily of use for those who use their Amiga from a remote * location, since it stops DOS putting up any requesters saying "Disk Full", * "Read/Write error", "Please insert volume xyz" etc. Similar programs * exist which will disable these requesters for a particular CLI, but * KillReq disables them across the whole system. * * Usage: killreq -- Displays usage message * killreq disable -- Disables requesters * killreq enable -- Enables requesters again * * Note that in this source, tabstops are set every 4 spaces. * Compiles under Lattice C V5.04. * (Optimisation causes intermediate file error, for some reason.) * */ #ifndef LATTICE_50 #include "system.h" typedef void (*__fptr)(); /* The sort of thing returned by SetFunction */ #endif #define AutoRequestOffset (-(0x15C)) /* * Assembly language defines */ #define MOVEQ_0_D0 0x7000 #define RTS 0x4E75 #define JMP 0x4EF9 #define YES 1 #define NO 0 char Portname[] = "killreq by Eddy Carroll"; char usage[] = "\ killreq (C) Copyright Eddy Carroll 1989, disables Intuition/DOS Requesters\n\ \n\ Usage: killreq disable Disables requesters\n\ killreq enable Enables requesters\n\ \n"; struct MyMsgPort { struct MsgPort mp; /* A genuine message port */ char portname[40]; /* Text of port name */ int active; /* True if patch currently active */ __fptr OldAutoRequest; /* Address of original routine */ union { short mmu_code[3]; /* Space for MOVEQ #0,D0 / RTS */ struct { short mmu_jmp; /* Alternatively, use JMP $xxxxxx */ __fptr mmu_jmpdest; } portstruct; } portunion; } port; #define mmp_code portunion.mmu_code #define mmp_jmp portunion.portstruct.mmu_jmp #define mmp_jmpdest portunion.portstruct.mmu_jmpdest typedef struct MessagePort MP; typedef struct MyMsgPort MyMP; typedef struct IntuitionBase IBASE; IBASE *IntuitionBase; /* * print() * ------- * Outputs a string to the console */ void print(s) char *s; { Write(Output(), s, strlen(s)); } /* * help() * ------ * Prints a simple usage message. If the parameter is TRUE, then * indicates the patch is currently active, else indicates it is * inactive. */ void help(active) int active; { print(usage); if (active) print("(Requesters are currently disabled.)\n"); else print("(Requesters are currently enabled.)\n"); } /* * cleanup() * --------- * Cleans up and exits to DOS. */ void cleanup(err) int err; { if (IntuitionBase != NULL) CloseLibrary((IBASE *)IntuitionBase); exit(err); } /* * main() * ------ * The mainline (actually, this is the whole program). */ void main(argc,argv) int argc; char *argv[]; { MyMP *myport; /* Pointer to our message port */ __fptr lastfunc; /* Previous function for AutoRequest() */ int active; /* True if requesters currently disabled */ /* * Check if we are already running, and set active * to reflect whether we are or not. */ myport = (MyMP *)FindPort(Portname); active = (myport != NULL) && (myport->active == YES); if (argc != 2) { help(active); cleanup(5); } IntuitionBase = (IBASE *)OpenLibrary("intuition.library",0L); if (!IntuitionBase) { print("Can't open intuition.library. What's happening??\n"); cleanup(5); } switch (argv[1][0]) { case 'e': /* --- Enable Intuition AutoRequesters --- */ case 'E': if (!active) { print("Intuition requesters are already enabled\n"); cleanup(5); } /* * Our patch is current installed, so we can go ahead and * unlink it from Intuition's library. */ Forbid(); lastfunc = SetFunction(IntuitionBase, AutoRequestOffset, myport->OldAutoRequest); if (lastfunc != (__fptr)myport->mmp_code) { /* * Oh oh..someone has SetFunction()'d after us. We'd * better put back their patch, and change our code to * simply be a JMP back to the original AutoRequest() * function. */ myport->active = NO; myport->mmp_jmp = JMP; myport->mmp_jmpdest = myport->OldAutoRequest; SetFunction(IntuitionBase, AutoRequestOffset, lastfunc); } else { /* * Nobody has SetFunction()'d us so just remove our * message port from Public access and deallocate * its memory. The SetFunction call before this `if' * has already restored the AutoRequest vector to its * original state. */ RemPort(myport); FreeMem(myport, sizeof(MyMP)); } Permit(); break; case 'd': /* --- Disable Intuition AutoRequesters --- */ case 'D': if (myport != NULL) { if (myport->active == YES) { print("Intuition requesters are already disabled\n"); cleanup(5); } else { /* * If we get here, someone SetFunctioned after us a * while ago, and at some stage after that, the user * enabled requesters again. So, just modify our * existing patch to disable requesters again. */ Forbid(); myport->mmp_code[0] = MOVEQ_0_D0; myport->mmp_code[1] = RTS; myport->active = YES; Permit(); } } else { /* * If we get here, then this is the first time the * user has run killreq, so install a completely * new patch. */ myport = AllocMem(sizeof(MyMP), MEMF_CLEAR); if (!myport) { print("Killreq: Out of memory!\n"); cleanup(5); } strcpy(myport->portname, Portname); myport->mp.mp_Node.ln_Name = myport->portname; myport->mmp_code[0] = MOVEQ_0_D0; myport->mmp_code[1] = RTS; myport->active = YES; Forbid(); myport->OldAutoRequest = SetFunction(IntuitionBase, AutoRequestOffset, (__fptr)myport->mmp_code); Permit(); AddPort(myport); } break; default: /* --- Silly user didn't give a valid option --- */ help(active); cleanup(5); } cleanup(0); }