home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / YourFaultv1r2.lha / YourFault / Source.LhA / src / YourFault.c < prev   
Encoding:
C/C++ Source or Header  |  1995-06-07  |  8.5 KB  |  364 lines

  1. /*
  2.  * YourFault, 1995 Lee Kindness.
  3.  *
  4.  * Patches the error strings returned by dos.library to your own.
  5.  * WARNING: It patches a private dos function!! (dosPrivate5())
  6.  *
  7.  * This source is in the public domain, do with it as you wish...
  8.  *
  9.  * version 1.2
  10.  *
  11.  ***************************************************************************/
  12.  
  13. #include "gst.c"
  14.  
  15. /* Change the following to where you have it... (dev/c/SFPatch.lha) */
  16. #include "//SFPatch/SFPatch.h"
  17.  
  18. /* DONT auto open... */
  19. extern struct IntuitionBase *IntuitionBase = NULL;
  20. extern struct Library *CxBase = NULL;
  21. extern struct Library *IconBase = NULL;
  22.  
  23. /* Save a bit of typing */
  24. #define REG(x) register __ ## x
  25.  
  26. /* The function offset of dosPrivate5() */
  27. #define DP5OFFSET -978
  28.  
  29. /* Default file from which the strings are to read from */
  30. #define ERRSFILENAME "S:FaultStrings"
  31.  
  32. /* types */
  33. typedef STRPTR __asm (*dP5Caller)( REG(d1) LONG, REG(a6) struct Library *);
  34.  
  35. /* ErrorStringNode */
  36. typedef struct ESNode {
  37.     struct ESNode *es_Succ;
  38.     struct ESNode *es_Pred;
  39.     UBYTE          es_Type;
  40.     BYTE           es_Pri;
  41.     STRPTR         es_String;
  42.     LONG           es_Number;
  43. } ESNode;
  44.  
  45.  
  46. /* Prototypes */
  47. STRPTR __asm new_dosPrivate5(REG(d1) LONG,REG(a6) struct Library *);
  48. struct List *LoadErrStrings(STRPTR);
  49. BOOL OpenLibs(void);
  50. void CloseLibs(void);
  51. BOOL ShowWindow(void);
  52.  
  53. /* Global vars */
  54. SetFunc *dP5sf;
  55. struct List *codes;
  56. struct Remember *grk;
  57. BOOL Active;
  58. char vertag[] = "$VER: YourFault 1.2 "__AMIGADATE__;
  59.  
  60. /***************************************************************************/
  61.  
  62. /* main */
  63. int main(int argc, char **argv)
  64. {
  65.     int ret;        
  66.     ret = RETURN_OK;
  67.     Active = TRUE;
  68.     grk = NULL;
  69.     
  70.     /* check version */
  71.     if (OpenLibs()) {
  72.         char StringsFName[80] = ERRSFILENAME;
  73.         struct NewBroker nb = {
  74.             NB_VERSION,
  75.             "YourFault",
  76.             &vertag[6],
  77.             "Patches the system error strings.",
  78.             NBU_UNIQUE | NBU_NOTIFY,
  79.             COF_SHOW_HIDE,
  80.             -1,
  81.             NULL,
  82.             0
  83.         };
  84.         CxObj *broker;
  85.     
  86.         /* Get tooltypes */
  87.         if (argc ? FALSE : TRUE) {
  88.             BPTR oldcd;
  89.             struct DiskObject *dobj;
  90.             struct WBStartup *wbs;
  91.             #define PROGNAME wbs->sm_ArgList->wa_Name
  92.             #define PDIRLOCK wbs->sm_ArgList->wa_Lock
  93.             wbs = (struct WBStartup *)argv;
  94.             /* Run from WB */
  95.             oldcd = CurrentDir(PDIRLOCK);
  96.             if (dobj = GetDiskObject(PROGNAME)) {
  97.                 STRPTR s;
  98.                 if (s = FindToolType(dobj->do_ToolTypes, "FROM")) {
  99.                     strncpy((STRPTR)&StringsFName, s, 79);
  100.                     StringsFName[79] = NULL;
  101.                 }
  102.                 FreeDiskObject(dobj);
  103.             }
  104.             CurrentDir(oldcd);
  105.         } else {
  106.             struct RDArgs *rdargs;
  107.             STRPTR from = NULL;
  108.             #define TEMPLATE "FROM"
  109.             /* Run from Shell */
  110.             if (rdargs = ReadArgs(TEMPLATE, (LONG *)&from, NULL)) {
  111.                 if (from) {
  112.                     strncpy((STRPTR)&StringsFName, from, 79);
  113.                     StringsFName[79] = NULL;
  114.                 }
  115.                 FreeArgs(rdargs);    
  116.             }
  117.         }
  118.         
  119.         if ((nb.nb_Port = CreateMsgPort()) && (broker = CxBroker(&nb, NULL))) {
  120.             
  121.             ActivateCxObj(broker, 1L);
  122.             if (codes = LoadErrStrings((STRPTR)&StringsFName)) {
  123.                 /* Alloc our SetFunc */
  124.                 if (dP5sf = AllocVec(sizeof(SetFunc), MEMF_CLEAR)) {
  125.  
  126.                     /* init. sfs */
  127.                     dP5sf->sf_Func = new_dosPrivate5;
  128.                     dP5sf->sf_Library = (struct Library *)DOSBase;
  129.                     dP5sf->sf_Offset = DP5OFFSET;
  130.                     dP5sf->sf_QuitMethod = SFQ_COUNT;
  131.                     
  132.                     /* Replace the function */
  133.                     if (SFReplace(dP5sf)) {
  134.  
  135.                         ULONG sig, sret;
  136.                         BOOL finished;
  137.                                 
  138.                         finished = FALSE;
  139.                         sig = 1 << nb.nb_Port->mp_SigBit;
  140.                     
  141.                         do {
  142.                             sret = Wait(SIGBREAKF_CTRL_C | sig);
  143.                             if (sret & sig) {
  144.                                 CxMsg *msg;
  145.                                 while(msg = (CxMsg *)GetMsg(nb.nb_Port)) {
  146.                                     switch(CxMsgType(msg)) {
  147.                                         case CXM_COMMAND:
  148.                                             switch(CxMsgID(msg)) {
  149.                                                 case CXCMD_DISABLE:
  150.                                                     ActivateCxObj(broker, 0L);
  151.                                                     Active = FALSE;
  152.                                                     break;
  153.                                                 case CXCMD_ENABLE:
  154.                                                     ActivateCxObj(broker, 1L);
  155.                                                     Active = TRUE;
  156.                                                     break;
  157.                                                 case CXCMD_KILL:
  158.                                                     finished = TRUE;
  159.                                                     break;
  160.                                                 case CXCMD_UNIQUE:
  161.                                                     finished = ShowWindow();
  162.                                                     break;
  163.                                                 case CXCMD_APPEAR:
  164.                                                     finished = ShowWindow();
  165.                                                     break;
  166.                                             }
  167.                                             break;
  168.                                     }
  169.                                     ReplyMsg((struct Message *)msg);
  170.                                 }
  171.                             }
  172.                             if (sret & SIGBREAKF_CTRL_C)
  173.                                 finished = TRUE;
  174.                         } while (!finished);
  175.                         ActivateCxObj(broker, 0L);
  176.     
  177.                         /* Restore function */
  178.                         SFRestore(dP5sf);
  179.                     }
  180.                     FreeVec(dP5sf);
  181.                 }
  182.             } else {
  183.                 DisplayBeep(NULL);
  184.                 ret = RETURN_FAIL;
  185.             }
  186.     
  187.             DeleteCxObj(broker);
  188.             DeletePort(nb.nb_Port);
  189.         }
  190.     }
  191.     CloseLibs();
  192.     return(ret);
  193. }
  194.  
  195. /***************************************************************************/
  196. /* Show our window... currently only a requester */
  197. BOOL ShowWindow(void)
  198. {
  199.     struct EasyStruct ez = {
  200.         sizeof(struct EasyStruct),
  201.         0,
  202.         "YourFault",
  203.         "%s ©Lee Kindness.\n\n"
  204.         "Replaces the system error strings\n"
  205.         "with your own...\n\n"
  206.         "Read \"YourFault.guide\" for more information\n\n"
  207.         "(Program may take a couple of seconds to quit)",
  208.         "Quit|Hide"
  209.     };
  210.     return((BOOL)EasyRequest(NULL, &ez, NULL, &vertag[6]));
  211. }
  212.  
  213. /***************************************************************************/
  214. /* Open all used libraries */
  215. BOOL OpenLibs(void)
  216. {
  217.     BOOL ret;
  218.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  219.     CxBase = OpenLibrary("commodities.library", 36);
  220.     IconBase = OpenLibrary("icon.library", 0);
  221.     ret = ((DOSBase->dl_lib.lib_Version > 36) && 
  222.            (IntuitionBase) && 
  223.            (CxBase) && 
  224.            (IconBase));
  225.     return(ret);
  226. }
  227.  
  228. /***************************************************************************/
  229. /* Close all libraries */
  230. void CloseLibs(void)
  231. {
  232.     if (IconBase)
  233.         CloseLibrary(IconBase);
  234.     if (CxBase)
  235.         CloseLibrary(CxBase);
  236.     if (IntuitionBase)
  237.         CloseLibrary((struct Library *)IntuitionBase);
  238. }
  239.  
  240. /***************************************************************************/
  241. /* load the strings from the file fname into our list 
  242.  *
  243.  * The following tokens are special within the file:
  244.  *   ':', '|' and '#' on the first column of a line denote a comment.
  245.  *   '^' is replaced by '\n'
  246.  */
  247. struct List *LoadErrStrings(STRPTR fname)
  248. {
  249.     BPTR f;
  250.     char *sptr, *s, *buf;
  251.     struct List *l;
  252.     ESNode *esn;
  253.     
  254.     l = NULL;
  255.     /* alloc buffer */
  256.     buf = AllocVec(180, MEMF_CLEAR);
  257.     if (buf) {
  258.         /* open the file */
  259.         f = Open(fname, MODE_OLDFILE);
  260.         if (f) {
  261.             /* alloc the list */
  262.             l = AllocRemember(&grk, sizeof(struct List), MEMF_CLEAR);
  263.             if (l) {
  264.                 /* initilise the list */
  265.                 NewList(l);
  266.                 /* Parse the file... */
  267.                 s = FGets(f, buf, 180);
  268.                 while (s) {
  269.                     /* is it a comment? */
  270.                     if ((s[0] != ';') && (s[0] != '#') && (s[0] != '|')) {
  271.                         /* no, alloc node */
  272.                         esn = AllocRemember(&grk, sizeof(ESNode), MEMF_CLEAR);
  273.                         if (esn) {
  274.                             /* convert integer at start of string */
  275.                             esn->es_Number = atol(buf);
  276.                             sptr = strchr(buf, ':');
  277.                             if (sptr) {
  278.                                 sptr++;
  279.                                 /* remove 0x0A */
  280.                                 sptr[strlen(sptr)-1] = 0;
  281.                                 /* strip blanks */
  282.                                 sptr = stpblk(sptr);
  283.                                 /* alloc mem */
  284.                                 esn->es_String = AllocRemember(&grk, (strlen(sptr)+1), MEMF_CLEAR);
  285.                                 if (esn->es_String) {
  286.                                     STRPTR s;
  287.                                     #define FINDCHAR '^'
  288.                                     #define REPLACECHAR '\n'
  289.                                     
  290.                                     /* copy string */
  291.                                     strcpy(esn->es_String, sptr);
  292.                                     
  293.                                     /* replace all FINDCHAR with REPALCECHAR */
  294.                                     s = esn->es_String;
  295.                                     while(*s != '\0')
  296.                                     {
  297.                                         if(*s == FINDCHAR)
  298.                                             *s = REPLACECHAR;
  299.                                         s++;
  300.                                     }
  301.                                     
  302.                                     /* add to list */
  303.                                     AddTail(l, (struct Node *)esn);
  304.                                 }
  305.                             }
  306.                         }
  307.                     }
  308.                     s = FGets(f, buf, 180);
  309.                 }
  310.             }
  311.             Close(f);
  312.         }
  313.         FreeVec(buf);
  314.     }
  315.     return(l);
  316. }
  317.  
  318.  
  319.  
  320.  
  321. /***************************************************************************/
  322. /* The new dosPrivate5() */
  323. STRPTR __saveds __asm new_dosPrivate5(REG(d1) LONG code,
  324.                                       REG(a6) struct Library *lib)
  325. {
  326.     ESNode *esn, *foundnode;
  327.     STRPTR ret;
  328.  
  329.     /* increment count */
  330.     Forbid();
  331.     dP5sf->sf_Count += 1;
  332.     Permit();
  333.     
  334.     ret = NULL;
  335.     if (Active) 
  336.     {
  337.         foundnode = NULL;
  338.         /* search for a matching code in the list */
  339.         esn = (ESNode *)codes->lh_Head;
  340.         while (esn->es_Succ) {
  341.             if (esn->es_Number == code)
  342.                 foundnode = esn;
  343.             esn = esn->es_Succ;
  344.         }
  345.         if (foundnode) 
  346.         {
  347.             /* return the string */
  348.             ret = foundnode->es_String;
  349.         }
  350.     }
  351.     
  352.     if (ret == NULL)
  353.         /* pass the buck... */
  354.         ret = ((dP5Caller)(dP5sf->sf_OriginalFunc))(code, lib);
  355.  
  356.     /* decrement count */
  357.     Forbid();
  358.     dP5sf->sf_Count -= 1;
  359.     Permit();
  360.     
  361.     /* and return */
  362.     return(ret);
  363. }
  364. /***************************************************************************/