Allow multiple volumes with the same name if their creation dates differ.
[AROS.git] / workbench / system / Snoopy / patches.c
blob213871be7e899214f8460cb5e5338ef571fb6b04
1 /*
2 Copyright © 2006-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
7 #include <proto/dos.h>
8 #include <proto/exec.h>
9 #include <proto/icon.h>
10 #include <proto/intuition.h>
11 #include <proto/graphics.h>
12 #include <proto/alib.h>
14 #include "main.h"
15 #include "patches.h"
16 #include "setup.h"
17 #include "locale.h"
21 * DO NOT USE functions that require a call into arosc.library in patch code as
22 * this can lead to leaking the Snoopy's aroscbase to the process that calls
23 * patched functions.
26 #define MAX_LOCK_LEN 100 /* Max. length of a lock string */
28 #define MAX(x,y) ((x) > (y) ? (x) : (y))
29 #define MIN(x,y) ((x) < (y) ? (x) : (y))
31 // dos.library
32 #define LVO_CreateDir ( -20 * (WORD)LIB_VECTSIZE)
33 #define LVO_CurrentDir ( -21 * (WORD)LIB_VECTSIZE)
34 #define LVO_DeleteFile ( -12 * (WORD)LIB_VECTSIZE)
35 #define LVO_DeleteVar ( -152 * (WORD)LIB_VECTSIZE)
36 #define LVO_Execute ( -37 * (WORD)LIB_VECTSIZE)
37 #define LVO_FindVar ( -153 * (WORD)LIB_VECTSIZE)
38 #define LVO_GetVar ( -151 * (WORD)LIB_VECTSIZE)
39 #define LVO_LoadSeg ( -25 * (WORD)LIB_VECTSIZE)
40 #define LVO_Lock ( -14 * (WORD)LIB_VECTSIZE)
41 #define LVO_MakeLink ( -74 * (WORD)LIB_VECTSIZE)
42 #define LVO_NewLoadSeg ( -128 * (WORD)LIB_VECTSIZE)
43 #define LVO_Open ( -5 * (WORD)LIB_VECTSIZE)
44 #define LVO_Rename ( -13 * (WORD)LIB_VECTSIZE)
45 #define LVO_RunCommand ( -84 * (WORD)LIB_VECTSIZE)
46 #define LVO_SetVar ( -150 * (WORD)LIB_VECTSIZE)
47 #define LVO_SystemTagList ( -101 * (WORD)LIB_VECTSIZE)
49 // exec.library
50 #define LVO_FindPort ( -65 * (WORD)LIB_VECTSIZE)
51 #define LVO_FindResident ( -16 * (WORD)LIB_VECTSIZE)
52 #define LVO_FindSemaphore ( -99 * (WORD)LIB_VECTSIZE)
53 #define LVO_FindTask ( -49 * (WORD)LIB_VECTSIZE)
54 #define LVO_OpenDevice ( -74 * (WORD)LIB_VECTSIZE)
55 #define LVO_OpenLibrary ( -92 * (WORD)LIB_VECTSIZE)
56 #define LVO_OpenResource ( -83 * (WORD)LIB_VECTSIZE)
58 // intuition.library
59 #define LVO_LockPubScreen ( -85 * (WORD)LIB_VECTSIZE)
61 // graphics.library
62 #define LVO_OpenFont ( -12 * (WORD)LIB_VECTSIZE)
64 // icon.library
65 #define LVO_FindToolType ( -16 * (WORD)LIB_VECTSIZE)
66 #define LVO_MatchToolValue ( -17 * (WORD)LIB_VECTSIZE)
68 struct Library *libbases[LIB_last];
70 typedef LONG (*FP)();
72 struct Patches
74 LONG (*oldfunc)();
75 LONG (*newfunc)();
76 LONG libidx;
77 struct Library *lib;
78 LONG lvo;
79 BOOL enabled;
80 } patches[PATCH_last] =
82 // must be in same order as in enum in patches.h
83 {NULL, NULL, LIB_Dos, 0, LVO_CreateDir, FALSE},
84 {NULL, NULL, LIB_Dos, 0, LVO_CurrentDir, FALSE},
85 {NULL, NULL, LIB_Dos, 0, LVO_DeleteFile, FALSE},
86 {NULL, NULL, LIB_Dos, 0, LVO_DeleteVar, FALSE},
87 {NULL, NULL, LIB_Dos, 0, LVO_Execute, FALSE},
88 {NULL, NULL, LIB_Dos, 0, LVO_FindVar, FALSE},
89 {NULL, NULL, LIB_Dos, 0, LVO_GetVar, FALSE},
90 {NULL, NULL, LIB_Dos, 0, LVO_LoadSeg, FALSE},
91 {NULL, NULL, LIB_Dos, 0, LVO_Lock, FALSE},
92 {NULL, NULL, LIB_Dos, 0, LVO_MakeLink, FALSE},
93 {NULL, NULL, LIB_Dos, 0, LVO_NewLoadSeg, FALSE},
94 {NULL, NULL, LIB_Dos, 0, LVO_Open, FALSE},
95 {NULL, NULL, LIB_Dos, 0, LVO_Rename, FALSE},
96 {NULL, NULL, LIB_Dos, 0, LVO_RunCommand, FALSE},
97 {NULL, NULL, LIB_Dos, 0, LVO_SetVar, FALSE},
98 {NULL, NULL, LIB_Dos, 0, LVO_SystemTagList, FALSE},
99 {NULL, NULL, LIB_Exec, 0, LVO_FindPort, FALSE},
100 {NULL, NULL, LIB_Exec, 0, LVO_FindResident, FALSE},
101 {NULL, NULL, LIB_Exec, 0, LVO_FindSemaphore, FALSE},
102 {NULL, NULL, LIB_Exec, 0, LVO_FindTask, FALSE},
103 {NULL, NULL, LIB_Exec, 0, LVO_OpenDevice, FALSE},
104 {NULL, NULL, LIB_Exec, 0, LVO_OpenLibrary, FALSE},
105 {NULL, NULL, LIB_Exec, 0, LVO_OpenResource, FALSE},
106 {NULL, NULL, LIB_Intuition, 0, LVO_LockPubScreen, FALSE},
107 {NULL, NULL, LIB_Graphics, 0, LVO_OpenFont, FALSE},
108 {NULL, NULL, LIB_Icon, 0, LVO_FindToolType, FALSE},
109 {NULL, NULL, LIB_Icon, 0, LVO_MatchToolValue, FALSE},
112 // ----------------------------------------------------------------------------------
114 AROS_LH1(BPTR, New_CreateDir,
115 AROS_LHA(CONST_STRPTR, name, D1),
116 struct DosLibrary *, DOSBase, 20, Dos)
118 AROS_LIBFUNC_INIT
120 // result is exclusive lock or NULL
121 BPTR result = AROS_CALL1(BPTR, patches[PATCH_CreateDir].oldfunc,
122 AROS_LDA(CONST_STRPTR, name, D1),
123 struct DosLibrary *, DOSBase);
125 if (patches[PATCH_CreateDir].enabled)
127 main_output("CreateDir", name, 0, (IPTR)result, TRUE, TRUE);
130 return result;
132 AROS_LIBFUNC_EXIT
135 // ----------------------------------------------------------------------------------
137 AROS_LH1(BPTR, New_CurrentDir,
138 AROS_LHA(BPTR, lock, D1),
139 struct DosLibrary *, DOSBase, 21, Dos)
141 AROS_LIBFUNC_INIT
142 char lockbuf[MAX_LOCK_LEN+1];
143 char *lockpath;
145 // returns lock to old directory, 0 means boot filesystem
146 BPTR result = AROS_CALL1(BPTR, patches[PATCH_CurrentDir].oldfunc,
147 AROS_LDA(BPTR, lock, D1),
148 struct DosLibrary *, DOSBase);
150 if (patches[PATCH_CurrentDir].enabled)
152 lockpath = MyNameFromLock(lock, NULL, lockbuf, MAX_LOCK_LEN);
153 main_output("CurrentDir", lockpath, 0, TRUE, TRUE, FALSE);
156 return result;
158 AROS_LIBFUNC_EXIT
161 // ----------------------------------------------------------------------------------
163 AROS_LH1(BOOL, New_DeleteFile,
164 AROS_LHA(CONST_STRPTR, name, D1),
165 struct DosLibrary *, DOSBase, 12, Dos)
167 AROS_LIBFUNC_INIT
169 // true means deleting was OK
170 BOOL result = AROS_CALL1(BOOL, patches[PATCH_DeleteFile].oldfunc,
171 AROS_LDA(CONST_STRPTR, name, D1),
172 struct DosLibrary *, DOSBase);
174 if (patches[PATCH_DeleteFile].enabled)
176 main_output("Delete", name, 0, result, TRUE, TRUE);
179 return result;
181 AROS_LIBFUNC_EXIT
184 // ----------------------------------------------------------------------------------
186 AROS_LH2(LONG, New_DeleteVar,
187 AROS_LHA(CONST_STRPTR, name, D1),
188 AROS_LHA(ULONG , flags, D2),
189 struct DosLibrary *, DOSBase, 152, Dos)
191 AROS_LIBFUNC_INIT
193 // true means variable was deleted
194 LONG result = AROS_CALL2(LONG, patches[PATCH_DeleteVar].oldfunc,
195 AROS_LDA(CONST_STRPTR, name, D1),
196 AROS_LDA(ULONG , flags, D2),
197 struct DosLibrary *, DOSBase);
199 if (patches[PATCH_DeleteVar].enabled)
201 CONST_STRPTR opt;
202 if (flags & GVF_GLOBAL_ONLY) opt = MSG(MSG_GLOBAL);
203 else if ((flags & 7) == LV_VAR) opt = MSG(MSG_LOCAL);
204 else if ((flags & 7) == LV_ALIAS) opt = MSG(MSG_ALIAS);
205 else opt = MSG(MSG_UNKNOWN);
207 main_output("DeleteVar", name, opt, result, TRUE, FALSE);
210 return result;
212 AROS_LIBFUNC_EXIT
215 // ----------------------------------------------------------------------------------
217 AROS_LH3(LONG, New_Execute,
218 AROS_LHA(CONST_STRPTR, string, D1),
219 AROS_LHA(BPTR , input , D2),
220 AROS_LHA(BPTR , output, D3),
221 struct DosLibrary *, DOSBase, 37, Dos)
223 AROS_LIBFUNC_INIT
225 // true means command could be started
226 LONG result = AROS_CALL3(LONG, patches[PATCH_Execute].oldfunc,
227 AROS_LDA(CONST_STRPTR, string, D1),
228 AROS_LDA(BPTR, input , D2),
229 AROS_LDA(BPTR, output, D3),
230 struct DosLibrary *, DOSBase);
232 if (patches[PATCH_Execute].enabled)
234 main_output("Execute", string ,0 , result, TRUE, FALSE);
237 return result;
239 AROS_LIBFUNC_EXIT
242 // ----------------------------------------------------------------------------------
244 AROS_LH2(struct LocalVar *, New_FindVar,
245 AROS_LHA(CONST_STRPTR, name, D1),
246 AROS_LHA(ULONG , type, D2),
247 struct DosLibrary *, DOSBase, 153, Dos)
249 AROS_LIBFUNC_INIT
251 // NULL means variable not found
252 struct LocalVar *result = AROS_CALL2(struct LocalVar *, patches[PATCH_FindVar].oldfunc,
253 AROS_LDA(CONST_STRPTR, name, D1),
254 AROS_LDA(ULONG, type, D2),
255 struct DosLibrary *, DOSBase);
257 if (patches[PATCH_FindVar].enabled)
259 CONST_STRPTR opt;
260 if ((type & 7) == LV_VAR) opt = MSG(MSG_LOCAL);
261 else if ((type & 7) == LV_ALIAS) opt = MSG(MSG_ALIAS);
262 else opt = MSG(MSG_UNKNOWN);
264 main_output("FindVar", name, opt, (IPTR)result, TRUE, FALSE);
267 return result;
269 AROS_LIBFUNC_EXIT
272 // ----------------------------------------------------------------------------------
274 AROS_LH4(LONG, New_GetVar,
275 AROS_LHA(CONST_STRPTR, name, D1),
276 AROS_LHA(STRPTR, buffer, D2),
277 AROS_LHA(LONG, size, D3),
278 AROS_LHA(LONG, flags, D4),
279 struct DosLibrary *, DOSBase, 151, Dos)
281 AROS_LIBFUNC_INIT
283 // -1 means variable not defined
284 LONG result = AROS_CALL4(LONG, patches[PATCH_GetVar].oldfunc,
285 AROS_LDA(CONST_STRPTR, name, D1),
286 AROS_LDA(STRPTR, buffer, D2),
287 AROS_LDA(LONG, size, D3),
288 AROS_LDA(LONG, flags, D4),
289 struct DosLibrary *, DOSBase);
291 if (patches[PATCH_GetVar].enabled)
293 CONST_STRPTR opt;
294 if (flags & GVF_GLOBAL_ONLY) opt = MSG(MSG_GLOBAL);
295 else if ((flags & 7) == LV_ALIAS) opt = MSG(MSG_ALIAS);
296 else if (flags & GVF_LOCAL_ONLY) opt = MSG(MSG_LOCAL);
297 else opt = MSG(MSG_ANY);
299 main_output("GetVar", name, opt, result != -1, TRUE, FALSE);
302 return result;
304 AROS_LIBFUNC_EXIT
307 // ----------------------------------------------------------------------------------
309 AROS_LH1(BPTR, New_LoadSeg,
310 AROS_LHA(CONST_STRPTR, name, D1),
311 struct DosLibrary *, DOSBase, 25, Dos)
313 AROS_LIBFUNC_INIT
315 // 0 means load failed
316 BPTR result = AROS_CALL1(BPTR, patches[PATCH_LoadSeg].oldfunc,
317 AROS_LDA(CONST_STRPTR, name, D1),
318 struct DosLibrary *, DOSBase);
320 if (patches[PATCH_LoadSeg].enabled)
322 main_output("LoadSeg", name, 0, (IPTR)result, TRUE, TRUE);
325 return result;
327 AROS_LIBFUNC_EXIT
330 // ----------------------------------------------------------------------------------
332 AROS_LH2(BPTR, New_Lock,
333 AROS_LHA(CONST_STRPTR, name, D1),
334 AROS_LHA(LONG, accessMode, D2),
335 struct DosLibrary *, DOSBase, 14, Dos)
337 AROS_LIBFUNC_INIT
339 // 0 means error
340 BPTR result = AROS_CALL2(BPTR, patches[PATCH_Lock].oldfunc,
341 AROS_LDA(CONST_STRPTR, name, D1),
342 AROS_LDA(LONG, accessMode, D2),
343 struct DosLibrary *, DOSBase);
345 if (patches[PATCH_Lock].enabled)
347 CONST_STRPTR opt;
348 if (accessMode == ACCESS_READ) opt = MSG(MSG_READ);
349 else if (accessMode == ACCESS_WRITE) opt = MSG(MSG_WRITE);
350 else opt = MSG(MSG_READ_ASK);
352 CONST_STRPTR curname = name;
353 if ( ! curname)
355 curname="NULL";
357 else if ( ! setup.showPaths && *curname == '\0')
359 curname = "\"\"";
362 main_output("Lock", curname, opt, (IPTR)result, TRUE, FALSE);
365 return result;
367 AROS_LIBFUNC_EXIT
370 // ----------------------------------------------------------------------------------
372 AROS_LH3(LONG, New_MakeLink,
373 AROS_LHA(CONST_STRPTR, name, D1),
374 AROS_LHA(APTR, dest, D2),
375 AROS_LHA(LONG , soft, D3),
376 struct DosLibrary *, DOSBase, 74, Dos)
378 AROS_LIBFUNC_INIT
380 // result is boolean
381 LONG result = AROS_CALL3(LONG, patches[PATCH_MakeLink].oldfunc,
382 AROS_LDA(CONST_STRPTR, name, D1),
383 AROS_LDA(APTR, dest, D2),
384 AROS_LDA(LONG, soft, D3),
385 struct DosLibrary *, DOSBase);
387 if (patches[PATCH_MakeLink].enabled)
389 struct Process *myproc = (struct Process *)FindTask(NULL);
391 CONST_STRPTR opt;
392 if (soft) opt = "Softlink";
393 else opt = "Hardlink";
395 int len = strlen(name);
396 char namestr[MAX_STR_LEN + 1];
397 if (len >= MAX_STR_LEN)
399 strncpy(namestr, name, MAX_STR_LEN);
400 namestr[MAX_STR_LEN] = 0;
402 else
404 if (setup.showPaths)
406 strcpy(namestr, MyNameFromLock(myproc->pr_CurrentDir,
407 (char *)name, namestr, MAX_STR_LEN-2));
408 len = strlen(namestr);
410 else
411 strcpy(namestr, name);
413 strcat(namestr, " --> ");
414 if (soft)
416 strncat(namestr, (char *)dest, MAX_STR_LEN - len - 1);
417 namestr[MAX_STR_LEN] = 0;
419 else
421 strcat(namestr, MyNameFromLock((BPTR)dest, NULL, namestr+len+1,
422 MAX_STR_LEN-len-1));
426 main_output("MakeLink", namestr, opt, result, TRUE, FALSE);
429 return result;
431 AROS_LIBFUNC_EXIT
434 // ----------------------------------------------------------------------------------
436 AROS_LH2(BPTR, New_NewLoadSeg,
437 AROS_LHA(CONST_STRPTR, file, D1),
438 AROS_LHA(struct TagItem *, tags, D2),
439 struct DosLibrary *, DOSBase, 128, Dos)
441 AROS_LIBFUNC_INIT
443 // 0 means load failed
444 BPTR result = AROS_CALL2(BPTR, patches[PATCH_NewLoadSeg].oldfunc,
445 AROS_LDA(CONST_STRPTR, file, D1),
446 AROS_LDA(struct TagItem *, tags, D2),
447 struct DosLibrary *, DOSBase);
449 if (patches[PATCH_NewLoadSeg].enabled)
451 main_output("NewLoadSeg", file, 0, (IPTR)result, TRUE, TRUE);
454 return result;
456 AROS_LIBFUNC_EXIT
459 // ----------------------------------------------------------------------------------
461 AROS_LH2(BPTR, New_Open,
462 AROS_LHA(CONST_STRPTR, name, D1),
463 AROS_LHA(LONG, accessMode, D2),
464 struct DosLibrary *, DOSBase, 5, Dos)
466 AROS_LIBFUNC_INIT
468 // 0 means error
469 BPTR result = AROS_CALL2(BPTR, patches[PATCH_Open].oldfunc,
470 AROS_LDA (CONST_STRPTR, name, D1),
471 AROS_LDA (LONG, accessMode, D2),
472 struct DosLibrary *, DOSBase);
474 if (patches[PATCH_Open].enabled)
476 CONST_STRPTR opt = NULL;
477 char optstr[10];
478 if (accessMode == MODE_OLDFILE) opt = MSG(MSG_READ);
479 else if (accessMode == MODE_NEWFILE) opt = MSG(MSG_WRITE);
480 else if (accessMode == MODE_READWRITE) opt = MSG(MSG_MODIFY);
481 else
482 opt = MSG(MSG_UNKNOWN);
484 main_output("Open", name, opt ? opt : (STRPTR)optstr, (IPTR)result, TRUE, TRUE);
487 return result;
489 AROS_LIBFUNC_EXIT
492 // ----------------------------------------------------------------------------------
494 AROS_LH2(LONG, New_Rename,
495 AROS_LHA(CONST_STRPTR, oldName, D1),
496 AROS_LHA(CONST_STRPTR, newName, D2),
497 struct DosLibrary *, DOSBase, 13, Dos)
499 AROS_LIBFUNC_INIT
501 // bool
502 LONG result = AROS_CALL2(LONG, patches[PATCH_Rename].oldfunc,
503 AROS_LDA(CONST_STRPTR, oldName, D1),
504 AROS_LDA(CONST_STRPTR, newName, D2),
505 struct DosLibrary *, DOSBase);
507 if (patches[PATCH_Rename].enabled)
509 main_output("Rename", oldName, 0, result, FALSE, TRUE);
510 main_output("to -->", newName, 0, result, TRUE, TRUE);
513 return result;
515 AROS_LIBFUNC_EXIT
518 // ----------------------------------------------------------------------------------
520 AROS_LH4(LONG, New_RunCommand,
521 AROS_LHA(BPTR, segList, D1),
522 AROS_LHA(ULONG, stacksize, D2),
523 AROS_LHA(CONST_STRPTR, argptr, D3),
524 AROS_LHA(ULONG, argsize, D4),
525 struct DosLibrary *, DOSBase, 84, Dos)
527 AROS_LIBFUNC_INIT
529 // -1 means error
530 LONG result = AROS_CALL4(LONG, patches[PATCH_RunCommand].oldfunc,
531 AROS_LDA(BPTR, segList, D1),
532 AROS_LDA(ULONG, stacksize, D2),
533 AROS_LDA(CONST_STRPTR, argptr, D3),
534 AROS_LDA(ULONG, argsize, D4),
535 struct DosLibrary *, DOSBase);
537 if (patches[PATCH_RunCommand].enabled)
539 char argstr[MAX_STR_LEN + 1];
540 int pos;
541 for (pos = 0; pos < MAX_STR_LEN && argptr[pos] != 0 ; pos++)
543 if (argptr[pos] == '\n')
544 argstr[pos] = ' ';
545 else
546 argstr[pos] = argptr[pos];
549 argstr[pos] = 0;
550 main_output("RunCommand", argstr, 0, result != -1, TRUE, FALSE);
553 return result;
555 AROS_LIBFUNC_EXIT
558 // ----------------------------------------------------------------------------------
560 AROS_LH4(BOOL, New_SetVar,
561 AROS_LHA(CONST_STRPTR, name, D1),
562 AROS_LHA(CONST_STRPTR, buffer, D2),
563 AROS_LHA(LONG , size, D3),
564 AROS_LHA(LONG , flags, D4),
565 struct DosLibrary *, DOSBase, 150, Dos)
567 AROS_LIBFUNC_INIT
569 BOOL result = AROS_CALL4(BOOL, patches[PATCH_SetVar].oldfunc,
570 AROS_LDA(CONST_STRPTR, name, D1),
571 AROS_LDA(CONST_STRPTR, buffer, D2),
572 AROS_LDA(LONG, size, D3),
573 AROS_LDA(LONG, flags, D4),
574 struct DosLibrary *, DOSBase);
576 if (patches[PATCH_SetVar].enabled)
578 CONST_STRPTR opt;
579 char varstr[MAX_STR_LEN + 1];
580 int vlen;
582 if (flags & GVF_GLOBAL_ONLY) opt = MSG(MSG_GLOBAL);
583 else if ((flags & 7) == LV_VAR) opt = MSG(MSG_LOCAL);
584 else if ((flags & 7) == LV_ALIAS) opt = MSG(MSG_ALIAS);
585 else opt = MSG(MSG_UNKNOWN);
588 * Now create a string that looks like "Variable=Value"
590 * We go to some pains to ensure we don't overwrite our
591 * string length
593 vlen = strlen(name);
594 if (vlen > (MAX_STR_LEN-1)) {
595 strncpy(varstr, name, MAX_STR_LEN);
596 varstr[MAX_STR_LEN] = 0;
597 } else {
598 strcpy(varstr, name);
599 strcat(varstr, "=");
600 vlen = 98 - vlen;
601 if (size != -1)
602 vlen = MIN(vlen, size);
604 strncat(varstr, buffer, vlen);
605 varstr[MAX_STR_LEN] = 0;
607 main_output("SetVar", varstr, opt, result, TRUE, FALSE);
610 return result;
612 AROS_LIBFUNC_EXIT
615 // ----------------------------------------------------------------------------------
617 AROS_LH2(LONG, New_SystemTagList,
618 AROS_LHA(CONST_STRPTR , command, D1),
619 AROS_LHA(struct TagItem *, tags, D2),
620 struct DosLibrary *, DOSBase, 101, Dos)
622 AROS_LIBFUNC_INIT
624 // -1 means error
625 LONG result = AROS_CALL2(LONG, patches[PATCH_SystemTagList].oldfunc,
626 AROS_LDA(CONST_STRPTR, command, D1),
627 AROS_LDA(struct TagItem *, tags, D2),
628 struct DosLibrary *, DOSBase);
630 if (patches[PATCH_SystemTagList].enabled)
632 TEXT optstr[20];
633 __sprintf(optstr, "%d", (LONG)result);
634 main_output("SystemTagList", command, optstr, result != -1, TRUE, FALSE);
637 return result;
639 AROS_LIBFUNC_EXIT
642 // ----------------------------------------------------------------------------------
644 AROS_LH1(struct MsgPort *, New_FindPort,
645 AROS_LHA(STRPTR, name, A1),
646 struct ExecBase *, SysBase, 65, Exec)
648 AROS_LIBFUNC_INIT
650 // NULL means error
651 struct MsgPort *result = AROS_CALL1(struct MsgPort *, patches[PATCH_FindPort].oldfunc,
652 AROS_LDA(STRPTR, name, A1),
653 struct ExecBase *, SysBase);
655 if (patches[PATCH_FindPort].enabled)
657 main_output("FindPort", name, 0, (IPTR)result, TRUE, FALSE);
660 return result;
662 AROS_LIBFUNC_EXIT
665 // ----------------------------------------------------------------------------------
667 AROS_LH1(struct Resident *, New_FindResident,
668 AROS_LHA(const UBYTE *, name, A1),
669 struct ExecBase *, SysBase, 16, Exec)
671 AROS_LIBFUNC_INIT
673 // NULL means error
674 struct Resident *result = AROS_CALL1(struct Resident *, patches[PATCH_FindResident].oldfunc,
675 AROS_LDA(const UBYTE *, name, A1),
676 struct ExecBase *, SysBase);
678 if (patches[PATCH_FindResident].enabled)
680 main_output("FindResident", name, 0, (IPTR)result, TRUE, FALSE);
683 return result;
685 AROS_LIBFUNC_EXIT
688 // ----------------------------------------------------------------------------------
690 AROS_LH1(struct SignalSemaphore *, New_FindSemaphore,
691 AROS_LHA(STRPTR, name, A1),
692 struct ExecBase *, SysBase, 99, Exec)
694 AROS_LIBFUNC_INIT
696 // NULL means error
697 struct SignalSemaphore *result = AROS_CALL1(struct SignalSemaphore *, patches[PATCH_FindSemaphore].oldfunc,
698 AROS_LDA(STRPTR, name, A1),
699 struct ExecBase *, SysBase);
701 if (patches[PATCH_FindSemaphore].enabled)
703 main_output("FindSemaphore", name, 0, (IPTR)result, TRUE, FALSE);
706 return result;
708 AROS_LIBFUNC_EXIT
711 // ----------------------------------------------------------------------------------
713 AROS_LH1(struct Task *, New_FindTask,
714 AROS_LHA(STRPTR, name, A1),
715 struct ExecBase *, SysBase, 49, Exec)
717 AROS_LIBFUNC_INIT
719 // NULL means error
720 struct Task *result = AROS_CALL1(struct Task *, patches[PATCH_FindTask].oldfunc,
721 AROS_LDA(STRPTR, name, A1),
722 struct ExecBase *, SysBase);
724 if ((name != NULL) && patches[PATCH_FindTask].enabled)
726 main_output("FindTask", name, 0, (IPTR)result, TRUE, FALSE);
729 return result;
731 AROS_LIBFUNC_EXIT
734 // ----------------------------------------------------------------------------------
736 AROS_LH4(LONG, New_OpenDevice,
737 AROS_LHA(CONST_STRPTR, devName, A0),
738 AROS_LHA(IPTR, unitNumber, D0),
739 AROS_LHA(struct IORequest *, iORequest, A1),
740 AROS_LHA(ULONG, flags, D1),
741 struct ExecBase *, SysBase, 74, Exec)
743 AROS_LIBFUNC_INIT
745 // 0 means OK
746 LONG result = AROS_CALL4(LONG, patches[PATCH_OpenDevice].oldfunc,
747 AROS_LDA(CONST_STRPTR, devName, A0),
748 AROS_LDA(IPTR, unitNumber, D0),
749 AROS_LDA(struct IORequest *, iORequest, A1),
750 AROS_LDA(ULONG, flags, D1),
751 struct ExecBase *, SysBase);
753 if (patches[PATCH_OpenDevice].enabled)
755 TEXT unitstr[20];
756 // FIXME: unitNumber can be a pointer
757 __sprintf(unitstr, "Unit %d", (IPTR)unitNumber);
758 main_output("OpenDevice", devName, unitstr, !result, TRUE, FALSE);
761 return result;
763 AROS_LIBFUNC_EXIT
766 // ----------------------------------------------------------------------------------
768 AROS_LH2(struct Library *, New_OpenLibrary,
769 AROS_LHA(CONST_STRPTR, libName, A1),
770 AROS_LHA(ULONG, version, D0),
771 struct ExecBase *, SysBase, 92, Exec)
773 AROS_LIBFUNC_INIT
775 // 0 means error
776 struct Library *result = AROS_CALL2(struct Library *, patches[PATCH_OpenLibrary].oldfunc,
777 AROS_LDA(CONST_STRPTR, libName, A1),
778 AROS_LDA(ULONG, version, D0),
779 struct ExecBase *, SysBase);
781 if (patches[PATCH_OpenLibrary].enabled)
783 TEXT verstr[20];
784 __sprintf(verstr, MSG(MSG_VERSION), version);
785 main_output("OpenLibrary", libName, verstr, (IPTR)result, TRUE, FALSE);
788 return result;
790 AROS_LIBFUNC_EXIT
793 // ----------------------------------------------------------------------------------
795 AROS_LH1(APTR, New_OpenResource,
796 AROS_LHA(CONST_STRPTR, resName, A1),
797 struct ExecBase *, SysBase, 83, Exec)
799 AROS_LIBFUNC_INIT
801 // 0 means error
802 APTR result = AROS_CALL1(APTR, patches[PATCH_OpenResource].oldfunc,
803 AROS_LDA(CONST_STRPTR, resName, A1),
804 struct ExecBase *, SysBase);
806 if (patches[PATCH_OpenResource].enabled)
808 main_output("OpenResource", resName, 0, (IPTR)result, TRUE, FALSE);
811 return result;
813 AROS_LIBFUNC_EXIT
816 // ----------------------------------------------------------------------------------
818 AROS_LH1(struct Screen *, New_LockPubScreen,
819 AROS_LHA(CONST_STRPTR, name, A0),
820 struct IntuitionBase *, IntuitionBase, 85, Intuition)
822 AROS_LIBFUNC_INIT
824 // 0 means error
825 struct Screen *result = AROS_CALL1(struct Screen *, patches[PATCH_LockPubScreen].oldfunc,
826 AROS_LDA(CONST_STRPTR, name, A0),
827 struct IntuitionBase *, IntuitionBase);
829 if (patches[PATCH_LockPubScreen].enabled)
831 main_output("LockPubScreen", name, 0, (IPTR)result, TRUE, TRUE);
834 return result;
836 AROS_LIBFUNC_EXIT
839 // ----------------------------------------------------------------------------------
841 AROS_LH1(struct TextFont *, New_OpenFont,
842 AROS_LHA(struct TextAttr *, textAttr, A0),
843 struct GfxBase *, GfxBase, 12, Graphics)
845 AROS_LIBFUNC_INIT
847 // 0 means error
848 struct TextFont *result = AROS_CALL1(struct TextFont *, patches[PATCH_OpenFont].oldfunc,
849 AROS_LDA(struct TextAttr *, textAttr, A0),
850 struct GfxBase *, GfxBase);
852 if (patches[PATCH_OpenFont].enabled)
854 STRPTR name;
855 TEXT sizestr[20];
857 if (textAttr) {
858 __sprintf(sizestr, MSG(MSG_SIZE), textAttr->ta_YSize);
859 name = textAttr->ta_Name;
860 } else {
861 *sizestr = '\0';
862 name = "\"\"";
864 main_output("OpenFont", name, sizestr, (IPTR)result, TRUE, FALSE);
867 return result;
869 AROS_LIBFUNC_EXIT
872 // ----------------------------------------------------------------------------------
874 AROS_LH2(UBYTE *, New_FindToolType,
875 AROS_LHA(CONST STRPTR *, toolTypeArray, A0),
876 AROS_LHA(CONST STRPTR, typeName, A1),
877 struct Library *, IconBase, 16, Icon)
879 AROS_LIBFUNC_INIT
881 // 0 means error
882 UBYTE *result = AROS_CALL2(UBYTE *, patches[PATCH_FindToolType].oldfunc,
883 AROS_LDA(CONST STRPTR *, toolTypeArray, A0),
884 AROS_LDA(CONST STRPTR, typeName, A1),
885 struct Library *, IconBase);
887 if (patches[PATCH_FindToolType].enabled)
889 main_output("FindToolType", typeName, 0, (IPTR)result, TRUE, FALSE);
892 return result;
894 AROS_LIBFUNC_EXIT
897 // ----------------------------------------------------------------------------------
899 AROS_LH2(BOOL, New_MatchToolValue,
900 AROS_LHA(UBYTE *, typeString, A0),
901 AROS_LHA(UBYTE *, value, A1),
902 struct Library *, IconBase, 17, Icon)
904 AROS_LIBFUNC_INIT
906 BOOL result = AROS_CALL2(BOOL, patches[PATCH_MatchToolValue].oldfunc,
907 AROS_LDA(UBYTE *, typeString, A0),
908 AROS_LDA(UBYTE *, value, A1),
909 struct Library *, IconBase);
911 if (patches[PATCH_MatchToolValue].enabled)
913 main_output("MatchToolValue", typeString, value, result, TRUE, FALSE);
916 return result;
918 AROS_LIBFUNC_EXIT
921 // ----------------------------------------------------------------------------------
923 void patches_init(void)
925 libbases[LIB_Exec] = (struct Library*)SysBase;
926 libbases[LIB_Dos] = (struct Library*)DOSBase;
927 libbases[LIB_Icon] = IconBase;
928 libbases[LIB_Intuition] = (struct Library*)IntuitionBase;
929 libbases[LIB_Graphics] = (struct Library*)GfxBase;
931 patches[PATCH_CreateDir].newfunc = (FP)AROS_SLIB_ENTRY(New_CreateDir, Dos, 20);
932 patches[PATCH_CurrentDir].newfunc = (FP)AROS_SLIB_ENTRY(New_CurrentDir, Dos, 21);
933 patches[PATCH_DeleteFile].newfunc = (FP)AROS_SLIB_ENTRY(New_DeleteFile, Dos, 12);
934 patches[PATCH_DeleteVar].newfunc = (FP)AROS_SLIB_ENTRY(New_DeleteVar, Dos, 152);
935 patches[PATCH_Execute].newfunc = (FP)AROS_SLIB_ENTRY(New_Execute, Dos, 37);
936 patches[PATCH_FindVar].newfunc = (FP)AROS_SLIB_ENTRY(New_FindVar, Dos, 153);
937 patches[PATCH_GetVar].newfunc = (FP)AROS_SLIB_ENTRY(New_GetVar, Dos, 151);
938 patches[PATCH_LoadSeg].newfunc = (FP)AROS_SLIB_ENTRY(New_LoadSeg, Dos, 25);
939 patches[PATCH_Lock].newfunc = (FP)AROS_SLIB_ENTRY(New_Lock, Dos, 14);
940 patches[PATCH_MakeLink].newfunc = (FP)AROS_SLIB_ENTRY(New_MakeLink, Dos, 74);
941 patches[PATCH_NewLoadSeg].newfunc = (FP)AROS_SLIB_ENTRY(New_NewLoadSeg, Dos, 128);
942 patches[PATCH_Open].newfunc = (FP)AROS_SLIB_ENTRY(New_Open, Dos, 5);
943 patches[PATCH_Rename].newfunc = (FP)AROS_SLIB_ENTRY(New_Rename, Dos, 13);
944 patches[PATCH_RunCommand].newfunc = (FP)AROS_SLIB_ENTRY(New_RunCommand, Dos, 84);
945 patches[PATCH_SetVar].newfunc = (FP)AROS_SLIB_ENTRY(New_SetVar, Dos, 150);
946 patches[PATCH_SystemTagList].newfunc = (FP)AROS_SLIB_ENTRY(New_SystemTagList, Dos, 101);
947 patches[PATCH_FindPort].newfunc = (FP)AROS_SLIB_ENTRY(New_FindPort, Exec, 65);
948 patches[PATCH_FindResident].newfunc = (FP)AROS_SLIB_ENTRY(New_FindResident, Exec, 16);
949 patches[PATCH_FindSemaphore].newfunc = (FP)AROS_SLIB_ENTRY(New_FindSemaphore, Exec, 99);
950 patches[PATCH_FindTask].newfunc = (FP)AROS_SLIB_ENTRY(New_FindTask, Exec, 49);
951 patches[PATCH_OpenDevice].newfunc = (FP)AROS_SLIB_ENTRY(New_OpenDevice, Exec, 74);
952 patches[PATCH_OpenLibrary].newfunc = (FP)AROS_SLIB_ENTRY(New_OpenLibrary, Exec, 92);
953 patches[PATCH_OpenResource].newfunc = (FP)AROS_SLIB_ENTRY(New_OpenResource, Exec, 83);
954 patches[PATCH_LockPubScreen].newfunc = (FP)AROS_SLIB_ENTRY(New_LockPubScreen, Intuition, 85);
955 patches[PATCH_OpenFont].newfunc = (FP)AROS_SLIB_ENTRY(New_OpenFont, Graphics, 12);
956 patches[PATCH_FindToolType].newfunc = (FP)AROS_SLIB_ENTRY(New_FindToolType, Icon, 16);
957 patches[PATCH_MatchToolValue].newfunc = (FP)AROS_SLIB_ENTRY(New_MatchToolValue, Icon, 17);
959 patches_set();
961 int i;
962 for (i=0; i<PATCH_last; i++)
964 if (patches[i].newfunc);
966 Forbid();
967 patches[i].oldfunc = SetFunction(libbases[patches[i].libidx], patches[i].lvo, patches[i].newfunc);
968 Permit();
973 // ----------------------------------------------------------------------------------
975 void patches_set(void)
977 patches[PATCH_CreateDir].enabled = setup.enableMakeDir;
978 patches[PATCH_CurrentDir].enabled = setup.enableChangeDir;
979 patches[PATCH_DeleteFile].enabled = setup.enableDelete;
980 patches[PATCH_DeleteVar].enabled = setup.enableSetVar;
981 patches[PATCH_Execute].enabled = setup.enableExecute;
982 patches[PATCH_FindVar].enabled = setup.enableGetVar;
983 patches[PATCH_GetVar].enabled = setup.enableGetVar;
984 patches[PATCH_LoadSeg].enabled = setup.enableLoadSeg;
985 patches[PATCH_Lock].enabled = setup.enableLock;
986 patches[PATCH_MakeLink].enabled = setup.enableMakeLink;
987 patches[PATCH_NewLoadSeg].enabled = setup.enableLoadSeg;
988 patches[PATCH_Open].enabled = setup.enableOpen;
989 patches[PATCH_Rename].enabled = setup.enableRename;
990 patches[PATCH_RunCommand].enabled = setup.enableRunCommand;
991 patches[PATCH_SetVar].enabled = setup.enableSetVar;
992 patches[PATCH_SystemTagList].enabled = setup.enableSystem;
993 patches[PATCH_FindPort].enabled = setup.enableFindPort;
994 patches[PATCH_FindResident].enabled = setup.enableFindResident;
995 patches[PATCH_FindSemaphore].enabled = setup.enableFindSemaphore;
996 patches[PATCH_FindTask].enabled = setup.enableFindTask;
997 patches[PATCH_OpenDevice].enabled = setup.enableOpenDevice;
998 patches[PATCH_OpenLibrary].enabled = setup.enableOpenLibrary;
999 patches[PATCH_OpenResource].enabled = setup.enableOpenResource;
1000 patches[PATCH_LockPubScreen].enabled = setup.enableLockScreen;
1001 patches[PATCH_OpenFont].enabled = setup.enableOpenFont;
1002 patches[PATCH_FindToolType].enabled = setup.enableReadToolTypes;
1003 patches[PATCH_MatchToolValue].enabled = setup.enableReadToolTypes;
1007 // ----------------------------------------------------------------------------------
1009 void patches_reset(void)
1011 int i;
1013 for (i=0; i<PATCH_last; i++)
1015 patches[i].enabled = FALSE;
1018 for (i=0; i<PATCH_last; i++)
1020 if (patches[i].oldfunc)
1022 Forbid();
1023 SetFunction(libbases[patches[i].libidx], patches[i].lvo, patches[i].oldfunc);
1024 Permit();
1025 patches[i].oldfunc = NULL;
1032 * GetVolName(lock, buf, maxlen)
1034 * Copies the volume name associated with lock into the buffer,
1035 * with terminating ':'. If lock is NULL, the volume address is
1036 * taken directly from volume.
1038 * If UseDevNames is true, the device list is searched looking
1039 * for the device node associated with the volume node (i.e. two
1040 * nodes sharing the same task address).
1042 * WARNING: This function must not be called from within a DOS
1043 * device handler due to potential deadlock errors!
1045 void GetVolName(BPTR lock, char *buf, int maxlen)
1047 struct DeviceList *vol;
1048 struct DosList *dl;
1049 int gotdev = 0;
1051 if (lock == BNULL)
1053 NameFromLock(lock, buf, maxlen);
1054 return;
1056 vol = BADDR(((struct FileLock *)BADDR(lock))->fl_Volume);
1058 if (setup.useDevNames == 0 || vol->dl_Task == NULL)
1061 * Use volume name, especially if the volume isn't currently
1062 * mounted!
1064 UBYTE *volname = AROS_BSTR_ADDR(vol->dl_Name);
1065 int len = MIN(maxlen-2, AROS_BSTR_strlen(volname));
1067 memcpy(buf, volname, len);
1068 buf[len++] = ':';
1069 buf[len] = '\0';
1070 return;
1074 * The user wants the device name. The only way to obtain this
1075 * is to search the device list looking for the device node with
1076 * the same task address as this volume.
1078 dl = LockDosList(LDF_DEVICES | LDF_READ);
1079 while ((dl = NextDosEntry(dl, LDF_DEVICES)))
1081 if (dl->dol_Task == vol->dl_Task)
1084 * Found our task, so now copy device name
1086 UBYTE *devname = AROS_BSTR_ADDR(dl->dol_Name);
1087 int len = MIN(maxlen-2, AROS_BSTR_strlen(devname));
1089 memcpy(buf, devname, len);
1090 buf[len++] = ':';
1091 buf[len] = '\0';
1092 gotdev = 1;
1093 break;
1096 UnLockDosList(LDF_DEVICES | LDF_READ);
1097 if (!gotdev)
1098 strcpy(buf, "???:");
1102 * MyNameFromLock(lock, filename, buf, maxlen)
1104 * This is a custom version of the DOS function NameFromLock()
1105 * which expands a disk lock into a full path.
1107 * Our version adds the following features. The device name will be
1108 * given as either the physical device (like DH0:) if UseDevNames
1109 * is true, or the volume name (like System3.0:) if UseDevNames is
1110 * false.
1112 * If filename is non-NULL, then it will be appended to the lock
1113 * path. If filename contains path info, then this will be taken
1114 * into account when generating the lock, so that an absolute path
1115 * in filename will not have any effect, and a relative filename
1116 * (like //directory) will cause the original lock to be ParentDir()'d
1117 * twice before being resolved.
1119 * This function can't fail. In the event of an error (string too
1120 * long, or something like that), the buffer will be filled accordingly.
1121 * It is assumed that the buffer will always be big enough to hold short
1122 * error messages or a volume name.
1124 * Returns a pointer to the path (which will not necessarily be at
1125 * the start of the buffer, but is guaranteed null-terminated.)
1126 * Note that it's even possible that the pointer returned will be
1127 * to the original filename if no path expansion was required.
1129 * New: We now preserve the IoErr() that was present on entry, since
1130 * it may have been set by the calling function if OnlyShowFails is
1131 * true. Otherwise, IoErr() will be screwed up by the operations we
1132 * do here (e.g. SAS/C deleting a non-existent file when OnlyShowFails
1133 * is true).
1135 * WARNING: This function must not be called from within a DOS
1136 * device handler due to potential deadlock errors!
1138 char *MyNameFromLock(BPTR lock, char *filename, char *buf, int maxlen)
1140 struct Process *myproc = (struct Process *)FindTask(NULL);
1141 int pos = maxlen - 1;
1142 D_S(fib, struct FileInfoBlock);
1143 LONG savedioerr = IoErr();
1144 BPTR curlock;
1145 BPTR newlock;
1146 void *savewinptr;
1147 char *p;
1148 int len;
1149 int skipfirstslash = 0; /* If true, skip first slash when building name */
1150 int err = 0;
1153 * Check for special magic filehandle
1155 if (filename && *filename)
1157 if (strcmp(filename, "*") == 0)
1158 return (filename);
1161 * First determine if we have any work to do.
1163 if (*filename == ':')
1166 * Got a reference relative to the root directory. Simply
1167 * grab the volume (or device) name from the lock and go
1168 * with that.
1170 int len;
1172 GetVolName(lock, buf, maxlen);
1173 len = strlen(buf);
1174 strncat(buf+len, filename+1, maxlen-len);
1175 buf[maxlen-1] = '\0';
1176 SetIoErr(savedioerr);
1177 return (buf);
1179 for (p = filename; *p; p++)
1181 if (*p == ':') /* If absolute path name, leave it alone */
1182 return (filename);
1185 else
1188 * Filename is null, so indicate we want to skip the first
1189 * slash when building the directory path
1191 skipfirstslash = 1;
1194 savewinptr = myproc->pr_WindowPtr;
1195 myproc->pr_WindowPtr = (APTR)-1; /* Disable error requesters */
1197 newlock = DupLock(lock);
1198 if (lock && !newlock)
1200 GetVolName(lock, buf, 20);
1201 if (filename)
1203 strcat(buf, ".../");
1204 strcat(buf, filename);
1206 myproc->pr_WindowPtr = savewinptr; /* Re-enable error requesters */
1207 SetIoErr(savedioerr);
1208 return (buf);
1210 buf[pos] = '\0';
1211 curlock = newlock;
1212 if (filename)
1214 while (newlock && *filename == '/')
1217 * Handle leading /'s by moving back a directory level
1218 * but nothing else
1220 newlock = ParentDir(curlock);
1221 if (newlock)
1223 UnLock(curlock);
1224 curlock = newlock;
1225 filename++;
1228 len = strlen(filename);
1229 if (len > (pos-2))
1231 memcpy(buf+2, filename+len-pos, pos-2);
1232 buf[0] = buf[1] = '.';
1233 pos = 0;
1234 UnLock(curlock);
1236 else
1238 pos -= len;
1239 memcpy(buf+pos, filename, len);
1244 * At this point, we have buf containing the filename (minus any
1245 * leading /'s), starting at the index given by pos. If filename
1246 * was NULL or empty, then pos indexes to a \0 terminator.
1248 * Next, we want to pre-pend directory names to the front of
1249 * the filename (assuming there _is_ a filename) until we get
1250 * to the device root.
1252 newlock = curlock;
1253 while (newlock)
1255 if (!Examine(curlock, fib))
1257 err++;
1258 break;
1260 len = strlen(fib->fib_FileName);
1261 if (len > (pos-3))
1264 * Not enough room: prefix dots at start to indicate
1265 * an overrun. We use pos-3 since we need one char
1266 * for a possible slash and two more to accomodate a
1267 * leading ".."
1269 memcpy(buf+2, fib->fib_FileName+len-pos+3, pos-2);
1270 buf[0] = buf[1] = '.';
1271 buf[pos-1] = '/';
1272 pos = 0;
1273 break;
1275 newlock = ParentDir(curlock);
1276 if (newlock)
1278 UnLock(curlock);
1279 curlock = newlock;
1280 pos -= len + 1;
1281 memcpy(buf + pos, fib->fib_FileName, len);
1282 if (skipfirstslash)
1284 skipfirstslash = 0;
1285 buf[pos+len] = '\0';
1287 else
1288 buf[pos+len] = '/';
1292 * Now we've built the path components; add the volume node
1293 * to the beginning if possible.
1295 if (err)
1298 * If an error occurred, the volume is probably not mounted,
1299 * so we include a ".../" component in the path to show
1300 * we couldn't get all the info
1302 pos -= 4;
1303 memcpy(buf + pos, ".../", 4);
1305 if (pos > 0)
1307 char volname[20];
1308 int len;
1309 char *p;
1311 GetVolName(curlock, volname, 20);
1312 len = strlen(volname);
1313 if (len > pos)
1315 p = volname + len - pos;
1316 len = pos;
1318 else
1319 p = volname;
1320 pos -= len;
1321 memcpy(buf + pos, p, len);
1323 if (curlock)
1324 UnLock(curlock);
1326 myproc->pr_WindowPtr = savewinptr; /* Re-enable error requesters */
1327 SetIoErr(savedioerr);
1328 return (buf+pos);