home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 336.lha / KillReq / src / killreq.c next >
C/C++ Source or Header  |  1990-01-09  |  6KB  |  233 lines

  1. /*
  2.  * KillReq (C) Copyright Eddy Carroll 1989, may be Freely Redistributed.
  3.  *
  4.  * KillReq disables Intuition's AutoRequest() function, such that any calls
  5.  * to it will always return FALSE (as if the user had selected CANCEL).
  6.  * This is primarily of use for those who use their Amiga from a remote
  7.  * location, since it stops DOS putting up any requesters saying "Disk Full",
  8.  * "Read/Write error", "Please insert volume xyz" etc. Similar programs
  9.  * exist which will disable these requesters for a particular CLI, but
  10.  * KillReq disables them across the whole system.
  11.  *
  12.  * Usage: killreq          -- Displays usage message
  13.  *        killreq disable  -- Disables requesters
  14.  *        killreq enable   -- Enables requesters again
  15.  *
  16.  * Note that in this source, tabstops are set every 4 spaces.
  17.  * Compiles under Lattice C V5.04.
  18.  * (Optimisation causes intermediate file error, for some reason.)
  19.  *
  20.  */
  21.  
  22. #ifndef LATTICE_50
  23. #include "system.h"
  24. typedef void (*__fptr)(); /* The sort of thing returned by SetFunction */
  25. #endif
  26.  
  27. #define AutoRequestOffset    (-(0x15C))
  28.  
  29. /*
  30.  *        Assembly language defines
  31.  */
  32. #define MOVEQ_0_D0    0x7000
  33. #define RTS            0x4E75
  34. #define JMP            0x4EF9
  35.  
  36. #define YES        1
  37. #define NO        0
  38.  
  39. char Portname[] = "killreq by Eddy Carroll";
  40. char usage[] = "\
  41. killreq (C) Copyright Eddy Carroll 1989, disables Intuition/DOS Requesters\n\
  42. \n\
  43. Usage:  killreq disable         Disables requesters\n\
  44.         killreq enable          Enables requesters\n\
  45. \n";
  46.  
  47. struct MyMsgPort {
  48.     struct    MsgPort mp;                /* A genuine message port            */
  49.     char    portname[40];            /* Text of port name                */
  50.     int        active;                    /* True if patch currently active    */
  51.     __fptr    OldAutoRequest;            /* Address of original routine        */
  52.     union {
  53.         short mmu_code[3];            /* Space for MOVEQ #0,D0 / RTS        */
  54.         struct {
  55.             short    mmu_jmp;        /* Alternatively, use JMP $xxxxxx    */
  56.             __fptr    mmu_jmpdest;
  57.         } portstruct;
  58.     } portunion;
  59. } port;
  60.  
  61. #define mmp_code        portunion.mmu_code
  62. #define mmp_jmp            portunion.portstruct.mmu_jmp
  63. #define mmp_jmpdest        portunion.portstruct.mmu_jmpdest
  64.  
  65. typedef struct MessagePort        MP;
  66. typedef struct MyMsgPort        MyMP;
  67. typedef struct IntuitionBase    IBASE;
  68.  
  69. IBASE *IntuitionBase;
  70.  
  71.  
  72. /*
  73.  *        print()
  74.  *        -------
  75.  *        Outputs a string to the console
  76.  */
  77. void print(s)
  78. char *s;
  79. {
  80.     Write(Output(), s, strlen(s));
  81. }
  82.  
  83. /*
  84.  *        help()
  85.  *        ------
  86.  *        Prints a simple usage message. If the parameter is TRUE, then
  87.  *        indicates the patch is currently active, else indicates it is
  88.  *        inactive.
  89.  */
  90. void help(active)
  91. int active;
  92. {
  93.     print(usage);
  94.     if (active)
  95.         print("(Requesters are currently disabled.)\n");
  96.     else
  97.         print("(Requesters are currently enabled.)\n");
  98. }
  99.  
  100. /*
  101.  *        cleanup()
  102.  *        ---------
  103.  *        Cleans up and exits to DOS.
  104.  */
  105. void cleanup(err)
  106. int err;
  107. {
  108.     if (IntuitionBase != NULL)
  109.         CloseLibrary((IBASE *)IntuitionBase);
  110.     exit(err);
  111. }
  112.  
  113. /*
  114.  *        main()
  115.  *        ------
  116.  *        The mainline (actually, this is the whole program).
  117.  */        
  118. void main(argc,argv)
  119. int argc;
  120. char *argv[];
  121. {
  122.     MyMP    *myport;        /* Pointer to our message port                */
  123.     __fptr    lastfunc;        /* Previous function for AutoRequest()        */
  124.     int        active;            /* True if requesters currently disabled    */
  125.  
  126.     /*
  127.      *        Check if we are already running, and set active
  128.      *        to reflect whether we are or not.
  129.      */
  130.     myport = (MyMP *)FindPort(Portname);
  131.     active = (myport != NULL) && (myport->active == YES);
  132.  
  133.     if (argc != 2) {
  134.         help(active);
  135.         cleanup(5);
  136.     }
  137.  
  138.     IntuitionBase = (IBASE *)OpenLibrary("intuition.library",0L);
  139.     if (!IntuitionBase) {
  140.         print("Can't open intuition.library. What's happening??\n");
  141.         cleanup(5);
  142.     }
  143.  
  144.     switch (argv[1][0]) {
  145.  
  146.         case 'e':        /* --- Enable Intuition AutoRequesters --- */
  147.         case 'E':
  148.             if (!active) {
  149.                 print("Intuition requesters are already enabled\n");
  150.                 cleanup(5);
  151.             }
  152.             /*
  153.              *        Our patch is current installed, so we can go ahead and
  154.              *        unlink it from Intuition's library.
  155.              */
  156.             Forbid();
  157.             lastfunc = SetFunction(IntuitionBase, AutoRequestOffset,
  158.                                                     myport->OldAutoRequest);
  159.             if (lastfunc != (__fptr)myport->mmp_code) {
  160.                 /*
  161.                  *        Oh oh..someone has SetFunction()'d after us. We'd
  162.                  *        better put back their patch, and change our code to
  163.                  *        simply be a JMP back to the original AutoRequest()
  164.                  *        function.
  165.                  */
  166.                 myport->active        = NO;
  167.                 myport->mmp_jmp        = JMP;
  168.                 myport->mmp_jmpdest    = myport->OldAutoRequest;
  169.                 SetFunction(IntuitionBase, AutoRequestOffset, lastfunc);
  170.             } else {
  171.                 /*
  172.                  *        Nobody has SetFunction()'d us so just remove our
  173.                  *        message port from Public access and deallocate
  174.                  *        its memory. The SetFunction call before this `if'
  175.                  *        has already restored the AutoRequest vector to its
  176.                  *        original state.
  177.                  */
  178.                 RemPort(myport);
  179.                 FreeMem(myport, sizeof(MyMP));
  180.             }
  181.             Permit();
  182.             break;
  183.  
  184.         case 'd':        /* --- Disable Intuition AutoRequesters --- */
  185.         case 'D':
  186.             if (myport != NULL) {
  187.                 if (myport->active == YES) {
  188.                     print("Intuition requesters are already disabled\n");
  189.                     cleanup(5);
  190.                 } else {
  191.                     /*
  192.                      *        If we get here, someone SetFunctioned after us a
  193.                      *        while ago, and at some stage after that, the user
  194.                      *        enabled requesters again. So, just modify our
  195.                      *        existing patch to disable requesters again.
  196.                      */
  197.                     Forbid();
  198.                     myport->mmp_code[0] = MOVEQ_0_D0;
  199.                     myport->mmp_code[1] = RTS;
  200.                     myport->active        = YES;
  201.                     Permit();
  202.                 }
  203.             } else {
  204.                 /*
  205.                  *        If we get here, then this is the first time the
  206.                  *        user has run killreq, so install a completely
  207.                  *        new patch.
  208.                  */
  209.                 myport = AllocMem(sizeof(MyMP), MEMF_CLEAR);
  210.                 if (!myport) {
  211.                     print("Killreq: Out of memory!\n");
  212.                     cleanup(5);
  213.                 }
  214.                 strcpy(myport->portname, Portname);
  215.                 myport->mp.mp_Node.ln_Name    = myport->portname;
  216.                 myport->mmp_code[0]            = MOVEQ_0_D0;
  217.                 myport->mmp_code[1]            = RTS;
  218.                 myport->active                = YES;
  219.                 Forbid();
  220.                 myport->OldAutoRequest        = SetFunction(IntuitionBase,
  221.                                 AutoRequestOffset, (__fptr)myport->mmp_code);
  222.                 Permit();
  223.                 AddPort(myport);
  224.             }
  225.             break;
  226.  
  227.         default:        /* --- Silly user didn't give a valid option --- */
  228.             help(active);
  229.             cleanup(5);
  230.     }
  231.     cleanup(0);
  232. }
  233.