home *** CD-ROM | disk | FTP | other *** search
- /*
- ** PatchOpen von Patrick Ohly
- ** Beispiel-Patch der Open-Funktion
- ** © 1994 Patrick Ohly
- */
-
-
- #ifdef _DCC
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #else
- #include <proto/exec.h>
- #include <proto/dos.h>
- #endif
- #include <clib/alib_protos.h>
- #include <stdio.h>
- #include <string.h>
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <exec/semaphores.h>
- #include <dos/dos.h>
-
- #include "PatchUtil.h"
-
- #define PATCH_PORT "PatchDosOpen Port"
-
- /* in amiga.lib enthalten */
- extern __far LONG LVOOpen;
-
- /* CTRL-C-Handling unterdrücken */
- #ifdef _DCC
- void chkabort(void) { }
- #endif
-
- /*
- ** Ausgabe über dieses FileHandle
- ** muß durch Semaphore geschuetzt werden.
- */
- struct SignalSemaphore FH_Sema;
- BPTR FH;
-
- /*
- ** die vorherige Funktion
- ** !!! Achtung !!!
- ** Register A6 muß weiterhin einen Zeiger auf die
- ** jeweilige Library enthalten!
- ** Da der Compiler dies bei Zeigern auf die
- ** Funktionen nicht automatisch macht, muß ein
- ** weiteres Argument hinzugefügt werden!
- */
-
- __regargs BPTR (* OldOpen)(__D1 char *name,
- __D2 LONG mode,
- __A6 struct DosLibrary *DOSBase);
-
- /* Anzahl der gerade aktiven Funktions-Aufrufe */
- WORD FunctionCounter = 0;
-
- /*
- ** gibt bei jedem Aufruf von Open() Filename und
- ** Modus aus - verwendet dazu Standardausgabe
- */
- __regargs __geta4 __interrupt BPTR NewOpen(
- __D1 char *name, __D2 LONG mode)
- {
- char buffer[120];
- BPTR fh;
-
- FunctionCounter++;
-
- sprintf(buffer, "\nFileName: %.68s\n"
- "Zugriff: ", name);
- switch(mode)
- {
- case MODE_OLDFILE:
- strcat(buffer, "MODE_OLDFILE\n");
- break;
- case MODE_NEWFILE:
- strcat(buffer, "MODE_NEWFILE\n");
- break;
- case MODE_READWRITE:
- strcat(buffer, "MODE_READWRITE\n");
- break;
- default:
- strcat(buffer, "unbekannt\n");
- break;
- }
-
- /* vor Ausgabe Semaphore anfordern */
- ObtainSemaphore(&FH_Sema);
- Write(FH, buffer, strlen(buffer));
- ReleaseSemaphore(&FH_Sema);
-
- /* Original-Funktion aufrufen und deren
- Resultat zurückgeben */
- fh = OldOpen(name, mode, DOSBase);
- FunctionCounter--;
- return(fh);
- }
-
- int main(int argc, char **argv)
- {
- struct MsgPort *msg_port;
-
- if(msg_port = FindPort(PATCH_PORT))
- {
- /* bereits installiertes PatchDosOpen
- entfernen */
- Signal(msg_port->mp_SigTask,
- 1L<<msg_port->mp_SigBit);
- puts("Versuche bereits installiertes"
- " PatchOpen zu entfernen...");
- }
- else
- {
- /* neu installieren
- erzeuge öffentlichen Port */
- if(msg_port = CreatePort(PATCH_PORT, 0))
- {
- APTR handle;
-
- InitSemaphore(&FH_Sema);
- FH = Output();
-
- Forbid();
- OldOpen = SafeSetFunction((struct Library *)DOSBase,
- (LONG)&LVOOpen, NewOpen,
- &handle);
- Permit();
-
- if(OldOpen)
- {
- puts("PatchOpen wurde installiert.");
-
- /* warte auf Ctrl-C oder nochmaligen
- Start von PatchDosOpen */
- Wait(SIGBREAKF_CTRL_C |
- 1L<<msg_port->mp_SigBit);
- SetSignal(0, SIGBREAKF_CTRL_C);
-
- RemoveFunction(OldOpen, handle);
- DeletePort(msg_port);
-
- /* unsere Funktion steht nicht mehr im
- Vektor, aber andere Tasks könnten immer
- noch unseren Code benutzen
- => noch warten */
- do Delay(10);
- while(FunctionCounter);
- puts("PatchOpen wurde entfernt.");
- }
- else
- puts("Konnte Open() nicht patchen!");
- }
- }
- return(0);
- }
-