/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* |_o_o|\\ Copyright (c) 1988 The Software Distillery. All Rights Reserved */ /* |. o.| || This program may not be distributed without the permission of */ /* | . | || the authors: BBS: (919) 481-6436 */ /* | o | || John Toebes John Mainwaring Jim Cooper */ /* | . |// Bruce Drake Gordon Keener Dave Baker */ /* ====== */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "handler.h" /******************************************************************************/ /******************************************************************************/ /********************* Dispatch table to handle all packets *******************/ /******************************************************************************/ /******************************************************************************/ #define BP1 1 #define BP2 2 #define BP3 4 #define BP4 8 typedef void (*ifuncp)(GLOBAL, struct DosPacket *); struct LookupTable { ifuncp subr; int flags; }; #define LO_FIRST 0 #define LO_LAST 34 struct LookupTable lowork[LO_LAST+1] = { { NULL, 0 | 0 | 0 | 0 }, /* 0 - ACTION_NIL */ { NULL, 0 | 0 | 0 | 0 }, /* 1 - Unknown */ { NULL, BP1| BP2| BP3| 0 }, /* 2 - ACTION_GET_BLOCK */ { NULL, 0 | BP2| BP3| 0 }, /* 3 - Unknown */ { NULL, BP1| BP2| BP3| 0 }, /* 4 - ACTION_SET_MAP */ { ActDie, 0 | 0 | 0 | 0 }, /* 5 - ACTION_DIE */ { NULL, 0 | 0 | 0 | 0 }, /* 6 - ACTION_EVENT */ { ActCurentVol, BP1| 0 | 0 | 0 }, /* 7 - ACTION_CURRENT_VOLUME */ { ActLock, BP1| BP2| 0 | 0 }, /* 8 - ACTION_LOCATE_OBJECT */ { ActRenameDisk, BP1| BP2| 0 | 0 }, /* 9 - ACTION_RENAME_DISK */ { NULL, 0 | 0 | 0 | 0 }, /* 10 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 11 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 12 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 13 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 14 - Unknown */ { ActUnLock, BP1| 0 | 0 | 0 }, /* 15 - ACTION_FREE_LOCK */ { ActDelete, BP1| BP2| 0 | 0 }, /* 16 - ACTION_DELETE_OBJECT */ { ActRename, BP1| BP2| BP3| BP4 }, /* 17 - ACTION_RENAME_OBJECT */ { NULL, 0 | 0 | 0 | 0 }, /* 18 - ACTION_MORE_CACHE */ { ActDupLock, BP1| 0 | 0 | 0 }, /* 19 - ACTION_COPY_DIR */ { NULL, 0 | 0 | 0 | 0 }, /* 20 - ACTION_WAIT_CHAR */ { ActSetProtection, 0 | BP2| BP3| 0 }, /* 21 - ACTION_SET_PROTECT */ { ActCreateDir, BP1| BP2| 0 | 0 }, /* 22 - ACTION_CREATE_DIR */ { ActExamine, BP1| BP2| 0 | 0 }, /* 23 - ACTION_EXAMINE_OBJECT */ { ActExNext, BP1| BP2| 0 | 0 }, /* 24 - ACTION_EXAMINE_NEXT */ { ActDiskInfo, BP1| 0 | 0 | 0 }, /* 25 - ACTION_DISK_INFO */ { ActInfo, BP1| BP2| 0 | 0 }, /* 26 - ACTION_INFO */ { ActFlush, 0 | 0 | 0 | 0 }, /* 27 - ACTION_FLUSH */ { ActSetComment, 0 | BP2| BP3| BP4 }, /* 28 - ACTION_SET_COMMENT */ { ActParent, BP1| 0 | 0 | 0 }, /* 29 - ACTION_PARENT */ { ActTimer, BP1| 0 | 0 | 0 }, /* 30 - ACTION_TIMER */ { ActInhibit, 0 | 0 | 0 | 0 }, /* 31 - ACTION_INHIBIT */ { NULL, BP1| 0 | 0 | 0 }, /* 32 - ACTION_DISK_TYPE */ { NULL, 0 | 0 | 0 | 0 }, /* 33 - ACTION_DISK_CHANGE */ { NULL, 0 | 0 | 0 | 0 } /* 34 - ACTION_SET_FILE_DATE */ }; #define HI_FIRST 1004 #define HI_LAST 1008 struct LookupTable hiwork[5] = { { ActFindwrite, BP1| BP2| BP3| 0 }, /* ACTION_FIND_WRITE - 1004 */ { ActFindin, BP1| BP2| BP3| 0 }, /* ACTION_FIND_INPUT - 1005 */ { ActFindout, BP1| BP2| BP3| 0 }, /* ACTION_FIND_OUTPUT - 1006 */ { ActEnd, 0 | 0 | 0 | 0 }, /* ACTION_END - 1007 */ { ActSeek, 0 | 0 | 0 | 0 } /* ACTION_SEEK - 1008 */ }; struct DosLibrary *DOSBase; void __saveds handler() { struct DosPacket *mypkt; /* a pointer to the dos packet sent */ int action; ifuncp subr; int flags; struct global global; DOSBase = (struct DosLibrary *)OpenLibrary(DOSNAME,0); /* Initialize our global data structure */ memset((char *)&global, 0, sizeof(struct global)); global.self = (struct Process *) FindTask(0L); /* find myself */ global.run = 1; global.port = &(global.self->pr_MsgPort); /* install our taskid ... */ /* Initialize the intuitext structures for the requesters we might have */ /* to display */ /* Because we have no scruples we can cheat and do this with a couple of */ /* long word assignments. We leave the acual C code commented out here */ /* so that if this structure ever changed we will still be able to work */ #if 0 global.line1.FrontPen = global.line1.BackPen = -1; global.line1.DrawMode = JAM1; global.line1.LeftEdge = global.line1.TopEdge = 4; global.line2 = global.line1; global.line3 = global.line1; global.retrytxt = global.line1; global.canceltxt = global.line1; #else *(long *)&global.line1.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.line1.LeftEdge = 0x00040004L; /* 4,4 */ *(long *)&global.line2.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.line2.LeftEdge = 0x0004000EL; /* 4,14 */ *(long *)&global.line3.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.line3.LeftEdge = 0x00040018L; /* 4,24 */ *(long *)&global.retrytxt.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.retrytxt.LeftEdge = 0x00040004L; *(long *)&global.canceltxt.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.canceltxt.LeftEdge = 0x00040004L; #endif global.retrytxt.IText = "Retry"; global.canceltxt.IText = "Cancel"; /* since we were started as a non-BCPL module we get sent the parameter */ /* packet (ie. parameter packet not in D1) */ mypkt = taskwait(&global); /* wait for parameter packet */ #ifdef DEBUG initdebug(); #endif global.devname = (((char *)BADDR(mypkt->dp_Arg1))+1); /* BSTR name passed to handler */ #if 0 global.extra = mypkt->dp_Arg2; /* Extra Info passed */ #endif /* get pointer to our device node */ global.node = (struct DeviceNode *) BADDR(mypkt->dp_Arg3); /* ptr to device node */ global.node->dn_Task = global.port; InitDevice(&global); /* Now mount the disk */ Mount(&global); OpenTimer(&global); mypkt->dp_Res1 = DOS_TRUE; retpkt(&global, mypkt); PostTimerReq(&global); while(global.run) /* start of the real work */ { mypkt = taskwait(&global); /* wait for a packet */ action = mypkt->dp_Type; BUG(("Execute: action #%ld\n", action)); switch (action) { case ACTION_READ: subr = ActRead; flags = 0; break; case ACTION_WRITE: subr = ActWrite; flags = 0; break; case ACTION_SET_RAW_MODE: subr = NULL; flags = 0; break; case ACTION_FIND_WRITE: /* 1004 */ case ACTION_FIND_INPUT: /* 1005 */ case ACTION_FIND_OUTPUT: /* 1006 */ case ACTION_END: /* 1007 */ case ACTION_SEEK: /* 1008 */ subr = hiwork[action-HI_FIRST].subr; flags = hiwork[action-HI_FIRST].flags; break; default: if ((action >= LO_FIRST) && (action <= LO_LAST)) { subr = lowork[action-LO_FIRST].subr; flags = lowork[action-LO_FIRST].flags; } else subr = NULL; } mypkt->dp_Res1 = DOS_FALSE; mypkt->dp_Res2 = ERROR_ACTION_NOT_KNOWN; if (subr != NULL) { global.reply = 1; if (flags & BP1) mypkt->dp_Arg1 <<= 2; if (flags & BP2) mypkt->dp_Arg2 <<= 2; if (flags & BP3) mypkt->dp_Arg3 <<= 2; if (flags & BP4) mypkt->dp_Arg4 <<= 2; if (global.changedisk) Mount(&global); (*subr)(&global, mypkt); if (global.changedisk) Mount(&global); } else { BUG(("Unknown packet type %ld\n",mypkt->dp_Type)); } /* Now return the packet to them */ if (global.reply) retpkt(&global, mypkt); BUG(("-----\n")); } /* do our final cleanup */ global.node->dn_Task = FALSE; /* zero the taskid field of device node */ global.node->dn_SegList = 0; /* make us be gone */ DisMount(&global); TermDevice(&global); FreeBlkBuffs(&global); }