home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / wb / assignwedge / source / assignwedge.c next >
C/C++ Source or Header  |  1994-12-23  |  24KB  |  1,067 lines

  1. /*
  2. **    AssignWedge - AmigaDOS 2.04 utility
  3. **
  4. **    Copyright © 1992-1994 by Olaf `Olsen' Barthel
  5. **        All Rights Reserved
  6. **
  7. ** :ts=4
  8. */
  9.  
  10. #include <intuition/intuitionbase.h>
  11.  
  12. #include <workbench/startup.h>
  13.  
  14. #include <dos/dosextens.h>
  15. #include <dos/dostags.h>
  16.  
  17. #include <exec/execbase.h>
  18. #include <exec/memory.h>
  19.  
  20. #include <libraries/locale.h>
  21. #include <libraries/asl.h>
  22.  
  23. #include <clib/intuition_protos.h>
  24. #include <clib/utility_protos.h>
  25. #include <clib/locale_protos.h>
  26. #include <clib/alib_protos.h>
  27. #include <clib/exec_protos.h>
  28. #include <clib/dos_protos.h>
  29. #include <clib/asl_protos.h>
  30.  
  31. #include <pragmas/intuition_pragmas.h>
  32. #include <pragmas/utility_pragmas.h>
  33. #include <pragmas/locale_pragmas.h>
  34. #include <pragmas/exec_pragmas.h>
  35. #include <pragmas/dos_pragmas.h>
  36. #include <pragmas/asl_pragmas.h>
  37.  
  38. #include <string.h>
  39. #include <stdarg.h>
  40.  
  41.     /* Create the requester strings. */
  42.  
  43. #define CATCOMP_ARRAY
  44.  
  45. #include "AssignWedge.h"
  46.  
  47.     /* The requester selection IDs. */
  48.  
  49. enum    {    REQ_CANCEL, REQ_RETRY, REQ_ASSIGN, REQ_MOUNT, REQ_DENY };
  50.  
  51.     /* Some handy signal macros. */
  52.  
  53. #define SIG_KILL    SIGBREAKF_CTRL_C
  54. #define SIG_NOTIFY    (1L << MainPort -> mp_SigBit)
  55.  
  56.     /* The MC680x0 `jump to absolute address' opcode. */
  57.  
  58. #define JMP_ABS 0x4EF9
  59.  
  60.     /* A simple wedge definition which is to consist of a jmp
  61.      * instruction and the destination of the jump.
  62.      */
  63.  
  64. struct Wedge
  65. {
  66.     UWORD Command;
  67.     ULONG Location;
  68. };
  69.  
  70.     /* Process and command names which are no longer allowed to
  71.      * access certain paths will be identified by information
  72.      * to be found in a list. The following structure definition
  73.      * holds the necessary data (name and process base address).
  74.      */
  75.  
  76. struct DenyNode
  77. {
  78.     struct MinNode     Node;
  79.  
  80.     struct Process    *Process;
  81.     LONG             DenyEmpty;
  82.     STRPTR             Name,
  83.                      ProgramName;
  84. };
  85.  
  86.     /* The library vector offset of the intuition.library routine to patch. */
  87.  
  88. extern ULONG __far     LVOEasyRequestArgs;
  89.  
  90.     /* The version ID tag. */
  91.  
  92. STATIC UBYTE Version[]    = "\0$VER: AssignWedge 1.4 (4.12.94)\r\n";
  93.  
  94.     /* Global and shared library identifiers. */
  95.  
  96. struct IntuitionBase    *IntuitionBase;
  97. struct ExecBase            *SysBase;
  98. struct DosLibrary        *DOSBase;
  99. struct Library            *UtilityBase,
  100.                         *AslBase;
  101.  
  102.     /* Locale support. */
  103.  
  104. struct LocaleBase        *LocaleBase;
  105. struct Catalog            *Catalog;
  106.  
  107.     /* Registration of programs which are not allowed to
  108.      * access certain devices.
  109.      */
  110.  
  111. struct SignalSemaphore     DenySemaphore;
  112. struct MinList             DenyList;
  113.  
  114.     /* The following counter and the associated access semaphore help
  115.      * to keep track of the number of programs currently using the
  116.      * patched EasyRequestArgs() routine.
  117.      */
  118.  
  119. struct SignalSemaphore     RunSemaphore;
  120. LONG                     RunCount;
  121.  
  122.     /* Handshake data. */
  123.  
  124. struct Process            *MainProcess;
  125. struct MsgPort            *MainPort;
  126. BOOL                     Removed;
  127.  
  128.     /* To compensate for possible incompatibilities introduced by internationalized
  129.      * requester texts, we will try to determine the text to turn up when an
  130.      * `please insert volume' requester is opened. The `SearchName' will receive
  131.      * the string to look for.
  132.      */
  133.  
  134. UBYTE                     SearchName[256];
  135.  
  136.     /* Function prototypes. */
  137.  
  138. LONG __saveds             Main(VOID);
  139. STRPTR __regargs         GetString(LONG ID);
  140. LONG __saveds __asm         NewEasyRequestArgs(register __a0 struct Window *Window,register __a1 struct EasyStruct *EasyStruct,register __a2 ULONG *IDCMPPtr,register __a3 APTR *Args);
  141. LONG                    (* __asm OldEasyRequestArgs)(register __a0 struct Window *,register __a1 struct EasyStruct *,register __a2 ULONG *,register __a3 APTR *,register __a6 struct IntuitionBase *);
  142. LONG __stdargs             StackCall(LONG *Success,LONG StackSize,LONG ArgCount,LONG (* __stdargs Function)(),...);
  143. VOID __stdargs             SPrintf(STRPTR buffer,STRPTR formatString,...);
  144. VOID                     CheckIn(VOID);
  145. VOID                     CheckOut(VOID);
  146.  
  147. LONG __saveds
  148. Main()
  149. {
  150.     struct WBStartup    *WBenchMsg;
  151.     LONG                 ReturnCode = RETURN_FAIL;
  152.  
  153.         /* Set up ExecBase */
  154.  
  155.     SysBase = *(struct ExecBase **)4;
  156.  
  157.         /* Determine current process identifier. */
  158.  
  159.     MainProcess = (struct Process *)SysBase -> ThisTask;
  160.  
  161.         /* Are we running from CLI? If not, wait for Workbench
  162.          * startup message.
  163.          */
  164.  
  165.     if(!MainProcess -> pr_CLI)
  166.     {
  167.         WaitPort(&MainProcess -> pr_MsgPort);
  168.  
  169.         WBenchMsg = (struct WBStartup *)GetMsg(&MainProcess -> pr_MsgPort);
  170.     }
  171.     else
  172.         WBenchMsg = NULL;
  173.  
  174.         /* Try to find the global handshake port and if present
  175.          * send a termination signal.
  176.          */
  177.  
  178.     Forbid();
  179.  
  180.     if(MainPort = FindPort("AssignWedge Rendezvous"))
  181.     {
  182.         Signal(MainPort -> mp_SigTask,SIG_KILL);
  183.  
  184.         ReturnCode = RETURN_OK;
  185.  
  186.         Permit();
  187.     }
  188.     else
  189.     {
  190.         Permit();
  191.  
  192.             /* Are we running under Kickstart version 37 or higher? */
  193.  
  194.         if(SysBase -> LibNode . lib_Version > 36)
  195.         {
  196.                 /* Create the global handshake port. */
  197.  
  198.             if(MainPort = CreateMsgPort())
  199.             {
  200.                     /* Give it a name and add it to the public list. */
  201.  
  202.                 MainPort -> mp_Node . ln_Name = "AssignWedge Rendezvous";
  203.  
  204.                 AddPort(MainPort);
  205.  
  206.                     /* Open the required libraries. */
  207.  
  208.                 if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
  209.                 {
  210.                     if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  211.                     {
  212.                         if(UtilityBase = OpenLibrary("utility.library",37))
  213.                         {
  214.                             if(AslBase = OpenLibrary(AslName,37))
  215.                             {
  216.                                 struct Wedge *Wedge;
  217.  
  218.                                     /* Try to open locale.library, but don't panic
  219.                                      * if it's not available.
  220.                                      */
  221.  
  222.                                 if(LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library",38))
  223.                                 {
  224.                                     if(!(Catalog = OpenCatalog(NULL,"assignwedge.catalog",
  225.                                         OC_BuiltInLanguage,    "english",
  226.                                         OC_BuiltInCodeSet,    0,
  227.                                     TAG_DONE)))
  228.                                     {
  229.                                         CloseLibrary((struct Library *)LocaleBase);
  230.  
  231.                                         LocaleBase = NULL;
  232.                                     }
  233.                                 }
  234.  
  235.                                     /* Initialize the access semaphore. */
  236.  
  237.                                 InitSemaphore(&RunSemaphore);
  238.  
  239.                                 RunCount = 0;
  240.  
  241.                                     /* Initialize the access semaphore and
  242.                                      * the list of programs to which access
  243.                                      * to certain devices has been denied.
  244.                                      */
  245.  
  246.                                 InitSemaphore(&DenySemaphore);
  247.  
  248.                                 NewList((struct List *)&DenyList);
  249.  
  250.                                     /* Allocate a system library function wedge. */
  251.  
  252.                                 if(Wedge = AllocMem(sizeof(struct Wedge),MEMF_PUBLIC))
  253.                                 {
  254.                                     struct DenyNode    *NextNode,
  255.                                                     *DenyNode;
  256.                                     UBYTE             LocalBuffer[80];
  257.  
  258.                                         /* Initialize the wedge. */
  259.  
  260.                                     Wedge -> Command    = JMP_ABS;
  261.                                     Wedge -> Location    = (ULONG)NewEasyRequestArgs;
  262.  
  263.                                     Removed = FALSE;
  264.  
  265.                                         /* Install the wedge. */
  266.  
  267.                                     Forbid();
  268.  
  269.                                     OldEasyRequestArgs = (LONG (* __asm)())SetFunction((struct Library *)IntuitionBase,(LONG)&LVOEasyRequestArgs,(ULONG (*)())Wedge);
  270.  
  271.                                         /* Make sure the data gets written to memory. */
  272.  
  273.                                     CacheClearU();
  274.  
  275.                                         /* Put up an example requester. Note: this requester
  276.                                          * will be trapped by the wedge routine, giving us
  277.                                          * the string to look for in the future.
  278.                                          */
  279.  
  280.                                     SPrintf(LocalBuffer,"AssignWedge.%08lx:",MainProcess);
  281.  
  282.                                     ErrorReport(ERROR_DEVICE_NOT_MOUNTED,REPORT_INSERT,(ULONG)LocalBuffer,NULL);
  283.  
  284.                                         /* We're up and running now. Note that the
  285.                                          * Forbid() will be broken by the Wait() for
  286.                                          * a ^C signal.
  287.                                          */
  288.  
  289.                                     Wait(SIG_KILL);
  290.  
  291.                                         /* We are no longer running,
  292.                                          * tell the wedge routine to
  293.                                          * skip the `access denied'
  294.                                          * part which requires the
  295.                                          * list to be initialized.
  296.                                          */
  297.  
  298.                                     Removed = TRUE;
  299.  
  300.                                         /* Redirect the wedge pointer to
  301.                                          * the original routine.
  302.                                          */
  303.  
  304.                                     Wedge -> Location = (ULONG)OldEasyRequestArgs;
  305.  
  306.                                         /* Make sure that the data
  307.                                          * gets written to memory.
  308.                                          */
  309.  
  310.                                     CacheClearU();
  311.  
  312.                                         /* Clear pending signals. */
  313.  
  314.                                     SetSignal(0,SIG_NOTIFY);
  315.  
  316.                                         /* Turn the multitasking back on. */
  317.  
  318.                                     Permit();
  319.  
  320.                                         /* Wait until our wedge routine
  321.                                          * is no longer in use.
  322.                                          */
  323.  
  324.                                     while(RunCount)
  325.                                         Wait(SIG_NOTIFY);
  326.  
  327.                                         /* Clear the `access denied' list. */
  328.  
  329.                                     DenyNode = (struct DenyNode *)DenyList . mlh_Head;
  330.  
  331.                                     while(NextNode = (struct DenyNode *)DenyNode -> Node . mln_Succ)
  332.