home *** CD-ROM | disk | FTP | other *** search
- /*
- * DOSDEVICE.C V1.10 2 November 1987
- *
- * EXAMPLE DOS DEVICE DRIVER FOR AZTEC.C PUBLIC DOMAIN.
- *
- * By Matthew Dillon.
- *
- * Debugging routines are disabled by simply attempting to open the
- * file "debugoff", turned on again with "debugon". No prefix may be
- * attached to these names (you must be CD'd to TEST:).
- *
- * See Documentation for a detailed discussion.
- *
- * BUGS:
- * Currently the only known bug is with the implementation of the
- * RAM disk itself. Specifically, if filehandle A is at the end of
- * the file, and somebody appends to the file with another filehandle,
- * B, filehandle A will get confused as to it's current position in
- * the file.
- *
- * I am probably not updating all the right timestamps. This is
- * easy to fix... All you have to do is fool with the floppy and
- * see which datestamps get updated for certain operations.
- */
-
- #include "dos.h"
-
- /*
- * Since this code might be called several times in a row without being
- * unloaded, you CANNOT ASSUME GLOBALS HAVE BEEN ZERO'D!! This also goes
- * for any global/static assignments that might be changed by running the
- * code.
- */
-
- PORT *DosPort; /* Our DOS port... this is slick... */
- PROC *DosProc; /* Our Process */
- DEVNODE *DosNode; /* Our DOS node.. created by DOS for us */
- DEVLIST *DevList; /* Device List structure for our volume node */
-
- void *SysBase; /* EXEC library base */
- DOSLIB *DOSBase; /* DOS library base for debug process */
- RAMFILE RFRoot; /* Directory/File structure (root node) */
- LIST FHBase; /* Open Files */
- LIST LCBase; /* Open Locks */
-
- long TotalBytes; /* total bytes of data in filesystem */
-
-
- /* DEBUGGING */
- PORT *Dbport; /* owned by the debug process */
- PORT *Dback; /* owned by the DOS device driver */
- MSG DummyMsg; /* Dummy message that debug proc can use */
-
- RAMFILE xpath; /* This is used in case of off device path */
- char *buf1; /* This holds the translated path names */
- char *volname; /* This is my volume name */
-
- RAMFILE * checkoutpath();
- RAMFILE * vsearchpath();
- void *DeviceProc();
-
- /*
- * Don't call the entry point main(). This way, if you make a mistake
- * with the compile options you'll get a link error.
- */
-
- void
- noname()
- {
- register PACKET *packet;
- register short error;
- register ubyte *ptr;
- MSG *msg;
- ubyte notdone;
- ubyte buf[256];
- void *tmp;
-
- /*
- * Initialize all global variables. SysBase MUST be initialized before
- * we can make Exec calls. AbsExecBase is a library symbol
- * referencing absolute memory location 4. The DOS library is openned
- * for the debug process only.
- */
-
- Dbport = Dback = NULL;
- TotalBytes = 0;
- SysBase = AbsExecBase;
- DOSBase = OpenLibrary("dos.library",0);
- DosProc = FindTask(NULL);
- DosPort = (PORT *)AllocMem(sizeof(PORT), MEMF_CLEAR | MEMF_PUBLIC);
- DosPort->mp_Node.ln_Type = NT_MSGPORT;
- DosPort->mp_Node.ln_Name = "Dos Port";
- DosPort->mp_Flags = PA_SIGNAL;
- DosPort->mp_SigBit = AllocSignal(-1);
- DosPort->mp_SigTask = FindTask(NULL);
- NewList(&DosPort->mp_MsgList);
- buf1 = AllocMem(512, MEMF_PUBLIC);
- {
- WaitPort(&DosProc->pr_MsgPort); /* Get Startup Packet */
- msg = GetMsg(&DosProc->pr_MsgPort);
- packet = (PACKET *)msg->mn_Node.ln_Name;
-
- /*
- * Loading DosNode->dn_Task causes DOS *NOT* to startup a new
- * instance of the device driver for every reference. E.G. if
- * you were writing a CON device you would want this field to
- * be NULL.
- */
-
- if (DOSBase) {
- DOSINFO *di = BTOC(((ROOTNODE *)DOSBase->dl_Root)->rn_Info);
- register DEVLIST *dl = dosalloc(sizeof(DEVLIST));
-
- DosNode = BTOC(PArg3);
-
- /*
- * Create Volume node and add to the device list. This will
- * cause the WORKBENCH to recognize us as a disk. If we don't
- * create a Volume node, Wb will not recognize us. However,
- * we are a RAM: disk, Volume node or not.
- */
-
- volname = AllocMem(32,MEMF_PUBLIC);
- volname[0] = 11;
- strcpy(volname+1,"Path Server");
-
- DevList = dl;
- dl->dl_Type = DLT_VOLUME;
- dl->dl_Task = DosPort;
- dl->dl_DiskType = ID_DOS_DISK;
- dl->dl_Name = CTOB(volname); /* DosNode->dn_Name*/;
- dl->dl_Next = di->di_DevInfo;
- di->di_DevInfo = (long)CTOB(dl);
-
- /*
- * Set dn_Task field which tells DOS not to startup a new
- * process on every reference.
- */
-
- DosNode->dn_Task = DosPort;
- PRes1 = DOS_TRUE;
- PRes2 = 0;
- } else { /* couldn't open dos.library */
- PRes1 = DOS_FALSE;
- returnpacket(packet);
- return; /* exit process */
- }
- returnpacket(packet);
- }
-
- /*
- * Initialize debugging code
- */
-
- /*DB*/ dbinit();
-
- /* Initialize RAM disk */
-
- {
- ubyte *ptr = BTOC(DosNode->dn_Name);
- short len = *ptr;
-
- NewList(&FHBase); /* more globals */
- NewList(&LCBase);
- bzero(&RFRoot,sizeof(RFRoot));
- RFRoot.type = FILE_DIR; /* root directory */
- DateStamp(&RFRoot.date); /* datestamp */
- NewList(&RFRoot.list); /* sub dirs */
- RFRoot.name = AllocMem(len+1, MEMF_PUBLIC); /* Root NAME */
- bmov(ptr+1,RFRoot.name,len);
- RFRoot.name[len] = 0;
- /*DB*/ dbprintf("ROOT NAME: %ld '%s'\n", len, RFRoot.name);
- }
-
- /*
- * Here begins the endless loop, waiting for requests over our
- * message port and executing them. Since requests are sent over
- * our message port, this precludes being able to call DOS functions
- * ourselves (that is why the debugging routines are a separate process)
- */
-
- WaitPort(&DosProc->pr_MsgPort); /* Get Startup Packet */
- msg = GetMsg(&DosProc->pr_MsgPort);
- notdone = 1;
- goto entry;
-
- top:
- for (notdone = 1; notdone;) {
- WaitPort(DosPort);
- while (msg = GetMsg(DosPort)) {
- entry:
- packet = (PACKET *)msg->mn_Node.ln_Name;
- PRes1 = DOS_TRUE;
- PRes2 = 0;
- error = 0;
- /*DB*/ dbprintf("Packet: %3ld %08lx %08lx %08lx %10s ",
- /*DB*/ PType, PArg1, PArg2, PArg3, typetostr(PType) );
-
- switch(PType) {
- case ACTION_DIE: /* attempt to die? */
- notdone = 0; /* try to die */
- break;
- case ACTION_OPENRW: /* FileHandle,Lock,Name Bool */
- case ACTION_OPENOLD: /* FileHandle,Lock,Name Bool */
- case ACTION_OPENNEW: /* FileHandle,Lock,Name Bool */
- {
- register RAMFILE *ramfile;
- RAMFILE *parentdir = getlockfile(PArg2);
- char *ptr;
-
- btos(PArg3,buf);
- /*DB*/ dbprintf("'%s' ", buf);
- if (ramfile = searchpath(&parentdir,buf,&ptr)) {
- if (ramfile == &xpath) {
- FH *p;
- if (p = Open(buf1,PType)) {
- bmov(BTOC(p),BTOC(PArg1),sizeof(FH));
- FreeMem(BTOC(p),sizeof(FH));
- }
- else
- error = IoErr();
- goto openbreak;
- }
- if (ramfile->type == FILE_DIR) {
- error = ERROR_OBJECT_WRONG_TYPE;
- goto openbreak;
- }
- if (ramfile->locks < 0) {
- error = ERROR_OBJECT_IN_USE;
- goto openbreak;
- }
- if (PType == ACTION_OPENOLD) {
- ++ramfile->locks;
- } else {
- if (ramfile->locks > 0) {
- error = ERROR_OBJECT_IN_USE;
- } else {
- if (PType == ACTION_OPENNEW) {
- freedata(ramfile);
- ramfile->protection = 0;
- }
- --ramfile->locks;
- }
- }
- } else {
- if (!parentdir) {
- error = ERROR_INVALID_COMPONENT_NAME;
- goto openbreak;
- }
- if (PType == ACTION_OPENNEW) {
- ramfile = createramfile(parentdir,FILE_FILE,ptr);
- --ramfile->locks;
- } else {
- error = ERROR_OBJECT_NOT_FOUND;
- }
- }
- if (!error) {
- register MYFH *mfh = AllocMem(sizeof(MYFH), MEMF_PUBLIC|MEMF_CLEAR);
- ((FH *)BTOC(PArg1))->fh_Arg1 = (long)mfh;
- mfh->file = ramfile;
- mfh->fentry = GetHead(&ramfile->list);
- AddHead(&FHBase,mfh);
- }
- }
- openbreak:
- if (!GetHead(&FHBase) && !GetHead(&LCBase))
- notdone = 0;
- break;
- case ACTION_READ: /* FHArg1,CPTRBuffer,Length ActLength */
- {
- register MYFH *mfh = (MYFH *)PArg1;
- register FENTRY *fen = mfh->fentry;
- register ubyte *ptr = (ubyte *)PArg2;
- register long left = PArg3;
- register long scr;
-
- while (left && fen) {
- scr = fen->bytes - mfh->offset;
- if (left < scr) {
- bmov(fen->buf + mfh->offset, ptr, left);
- mfh->offset += left;
- left = 0;
- } else {
- bmov(fen->buf + mfh->offset, ptr, scr);
- left -= scr;
- ptr += scr;
- mfh->base += fen->bytes;
- mfh->offset = 0;
- fen = NextNode(fen);
- }
- }
- mfh->fentry = fen;
- PRes1 = PArg3 - left;
- }
- break;
- case ACTION_WRITE: /* FHArg1,CPTRBuffer,Length ActLength */
- {
- register MYFH *mfh = (MYFH *)PArg1;
- register FENTRY *fen = (FENTRY *)mfh->fentry;
- ubyte *ptr = (ubyte *)PArg2;
- long left = PArg3;
- long scr;
-
- /*
- * Doesn't work right if multiple readers/appenders.
- */
-
- while (left) {
- if (fen) {
- /*DB*/ dbprintf("FEN: %ld left: %ld\n",fen->bytes,left);
- scr = fen->bytes - mfh->offset;
- if (left < scr) {
- if (fen->bytes < mfh->offset + left) {
- /*DB*/ dbprintf("PANIC! AWR0\n");
- }
- else
- bmov(ptr, fen->buf + mfh->offset, left);
- mfh->offset += left;
- left = 0;
- } else {
- if (fen->bytes < mfh->offset + scr) {
- /*DB*/ dbprintf("PANIC! AWR1\n");
- }
- else
- bmov(ptr, fen->buf + mfh->offset, scr);
- ptr += scr;
- left -= scr;
- mfh->base += fen->bytes;
- mfh->offset = 0;
- fen = NextNode(fen);
- }
- } else {
- fen = AllocMem(sizeof(FENTRY), MEMF_PUBLIC);
- if (fen->buf = AllocMem(left, MEMF_PUBLIC)) {
- fen->bytes = left;
- mfh->file->bytes += left;
- mfh->base += left;
- mfh->offset = 0;
- TotalBytes += left;
- AddTail(&mfh->file->list, fen);
- /*DB*/ dbprintf("NEWFEN: (%ld)\n", fen->bytes);
- bmov(ptr, fen->buf, left);
- left = 0;
- } else {
- FreeMem(fen, sizeof(FENTRY));
- /*DB*/ dbprintf("NEWFEN: ****** Unable to allocate buffer %ld\n", left);
- mfh->offset = 0;
- break;
- }
- fen = NULL; /* cause append */
- }
- }
- PRes1 = PArg3 - left;
- mfh->fentry = fen;
- }
- break;
- case ACTION_CLOSE: /* FHArg1 Bool:TRUE */
- {
- register MYFH *mfh = (MYFH *)PArg1;
- register RAMFILE *file = mfh->file;
-
- Remove(mfh);
- FreeMem(mfh,sizeof(*mfh));
- if (--file->locks < 0)
- file->locks = 0;
- }
- if (!GetHead(&FHBase) && !GetHead(&LCBase))
- notdone = 0;
- break;
- case ACTION_SEEK: /* FHArg1,Position,Mode OldPosition*/
- {
- register MYFH *mfh = (MYFH *)PArg1;
- register FENTRY *fen;
- register long absseek;
-
- PRes1 = mfh->base + mfh->offset;
- absseek = PArg2;
- if (PArg3 == 0)
- absseek += mfh->base + mfh->offset;
- if (PArg3 == 1)
- absseek = mfh->file->bytes + absseek;
- if (absseek < 0 || absseek > mfh->file->bytes) {
- error = ERROR_SEEK_ERROR;
- break;
- }
- mfh->base = mfh->offset = 0;
-
- /*
- * Stupid way to do it but....
- */
-
- for (fen = GetHead(&mfh->file->list); fen; fen = NextNode(fen)) {
- if (mfh->base + fen->bytes > absseek) {
- mfh->offset = absseek - mfh->base;
- break;
- }
- mfh->base += fen->bytes;
- }
- mfh->fentry = fen;
- }
- break;
- /*
- * This implementation sucks. The right way to do it is with
- * a hash table. The directory must be searched for the file
- * name, then the next entry retrieved. If the next entry is
- * NULL there are no more entries. If the filename could not
- * be found we return the first entry, if any.
- *
- * You can't simply keep a pointer around to the next node
- * because it can be moved or removed at any time.
- */
-
- case ACTION_EXAMINE_NEXT: /* Lock,Fib Bool */
- {
- register FIB *fib = BTOC(PArg2);
- register RAMFILE *dir = getlockfile(PArg1);
- register RAMFILE *file;
-
- if (dir->type == FILE_FILE) {
- error = ERROR_OBJECT_WRONG_TYPE;
- break;
- }
- file = GetHead(&dir->list);
- if (fib->fib_DiskKey) {
- register int len = *(ubyte *)fib->fib_FileName;
- for (; file; file = NextNode(file)) {
- if (strlen(file->name) == len && nccmp(file->name, fib->fib_FileName+1, len))
- break;
- }
- if (file)
- file = NextNode(file);
- else
- file = GetHead(&dir->list);
- }
- fib->fib_DiskKey = 1;
- error = -1;
- if (!(tmp=file)) {
- error = ERROR_NO_MORE_ENTRIES;
- break;
- }
- }
- /* fall through */
- case ACTION_EXAMINE_OBJECT: /* Lock,Fib Bool */
- {
- register FIB *fib;
- register RAMFILE *file;
- register RAMFILE *dummy;
-
- fib = BTOC(PArg2);
- if (error) {
- file = tmp; /* fall through from above */
- } else {
- file = getlockfile(PArg1);
- fib->fib_DiskKey = 0;
- }
- error = 0;
- fib->fib_DirEntryType = file->type;
- strcpy(fib->fib_FileName+1, file->name);
- fib->fib_FileName[0] = strlen(file->name);
- fib->fib_Protection = file->protection;
- fib->fib_EntryType = NULL;
- fib->fib_Size = file->bytes;
- fib->fib_NumBlocks = file->bytes >> 9;
- fib->fib_Date = file->date;
- if (file->comment) {
- strcpy(fib->fib_Comment+1, file->comment);
- fib->fib_Comment[0] = strlen(file->comment);
- } else {
- fib->fib_Comment[0] = 0;
- }
- }
- break;
- case ACTION_INFO: /* Lock, InfoData Bool:TRUE */
- tmp = BTOC(PArg2);
- error = -1;
- /* fall through */
- case ACTION_DISK_INFO: /* InfoData Bool:TRUE */
- {
- register INFODATA *id;
-
- /*
- * Note: id_NumBlocks is never 0, but only to get
- * around a bug I found in my shell (where I divide
- * by id_NumBlocks). Other programs probably break
- * as well.
- */
-
- (error) ? (id = tmp) : (id = BTOC(PArg1));
- error = 0;
- bzero(id, sizeof(*id));
- id->id_DiskState = ID_VALIDATED;
- id->id_NumBlocks = (TotalBytes >> 9) + 1;
- id->id_NumBlocksUsed = (TotalBytes >> 9) + 1;
- id->id_BytesPerBlock = 512;
- id->id_DiskType = ID_DOS_DISK;
- id->id_VolumeNode = (long)CTOB(DosNode);
- id->id_InUse = (long)GetHead(&LCBase);
- }
- break;
- case ACTION_PARENT: /* Lock ParentLock */
- {
- register RAMFILE *file = getlockfile(PArg1);
- /*
- if (file->type == FILE_FILE) {
- error = ERROR_OBJECT_NOT_FOUND;
- break;
- }
- */
- if (file->locks < 0) {
- error = ERROR_OBJECT_IN_USE;
- break;
- }
- if (file->parent)
- PRes1 = (long)CTOB(ramlock(file->parent, ACCESS_READ));
- else
- error = ERROR_OBJECT_NOT_FOUND;
- }
- break;
- case ACTION_DELETE_OBJECT: /*Lock,Name Bool */
- {
- RAMFILE *parentdir = getlockfile(PArg1);
- RAMFILE *ramfile;
-
- btos(PArg2, buf);
- if (ramfile = searchpath(&parentdir,buf,NULL)) {
- if (ramfile == &xpath) {
- if (!DeleteFile(buf1)) error = IoErr();
- break;
- }
- if (ramfile->locks || ramfile == &RFRoot) {
- error = ERROR_OBJECT_IN_USE;
- break;
- }
- if (ramfile->type == FILE_DIR) {
- if (GetHead(&ramfile->list))
- error = ERROR_DIRECTORY_NOT_EMPTY;
- } else {
- freedata(ramfile);
- }
- if (!error) {
- freeramfile(ramfile);
- DateStamp(&parentdir->date);
- }
- } else {
- if (!parentdir)
- error = ERROR_INVALID_COMPONENT_NAME;
- else
- error = ERROR_OBJECT_NOT_FOUND;
- }
- }
- if (!GetHead(&FHBase) && !GetHead(&LCBase))
- notdone = 0;
- break;
- case ACTION_CREATE_DIR: /* Lock,Name Lock */
- {
- RAMFILE *parentdir = getlockfile(PArg1);
- RAMFILE *ramfile;
- char *ptr;
-
- btos(PArg2, buf);
- if (ramfile = vsearchpath(&parentdir,buf,&ptr)) {
- error = ERROR_OBJECT_EXISTS;
- break;
- }
- if (!parentdir) {
- error = ERROR_INVALID_COMPONENT_NAME;
- break;
- }
- ramfile = createramfile(parentdir, FILE_DIR, ptr);
- PRes1 = (long)CTOB(ramlock(ramfile, ACCESS_WRITE));
- }
- break;
- case ACTION_LOCATE_OBJECT: /* Lock,Name,Mode Lock */
- {
- RAMFILE *parentdir = getlockfile(PArg1);
- RAMFILE *ramfile;
-
- btos(PArg2, buf);
- /*DB*/ dbprintf("'%s' %ld ", buf, PArg3);
- if (ramfile = searchpath(&parentdir,buf,NULL)) {
- if (ramfile == &xpath) {
- PRes1 = Lock(buf1,PArg3);
- if (!PRes1) PRes2 = IoErr();
- break;
- }
- if (ramfile->locks < 0 || (ramfile->locks && PArg3 == ACCESS_WRITE)) {
- error = ERROR_OBJECT_IN_USE;
- break;
- }
- PRes1 = (long)CTOB(ramlock(ramfile, PArg3));
- } else {
- if (!parentdir)
- error = ERROR_INVALID_COMPONENT_NAME;
- else
- error = ERROR_OBJECT_NOT_FOUND;
- }
- }
- break;
- case ACTION_COPY_DIR: /* Lock, Lock */
- {
- register RAMFILE *ramfile = getlockfile(PArg1);
- if (ramfile->locks < 0)
- error = ERROR_OBJECT_IN_USE;
- else
- PRes1 = (long)CTOB(ramlock(ramfile, ACCESS_READ));
- }
- break;
- case ACTION_FREE_LOCK: /* Lock, Bool */
- if (PArg1);
- ramunlock(BTOC(PArg1));
- if (!GetHead(&FHBase) && !GetHead(&LCBase))
- notdone = 0;
- break;
- case ACTION_SET_PROTECT:/* -,Lock,Name,Mask Bool */
- {
- register RAMFILE *ramfile;
- RAMFILE *parentdir = getlockfile(PArg2);
- char *ptr;
-
- btos(PArg3, buf);
- if (ramfile = searchpath(&parentdir,buf,&ptr)) {
- if (ramfile == &xpath) {
- if (!SetProtection(buf1,PArg4))
- error = IoErr();
- break;
- }
- ramfile->protection = PArg4;
- } else {
- if (parentdir)
- error = ERROR_OBJECT_NOT_FOUND;
- else
- error = ERROR_INVALID_COMPONENT_NAME;
- }
- }
- break;
- case ACTION_SET_COMMENT:/* -,Lock,Name,Comment Bool */
- {
- register RAMFILE *ramfile;
- RAMFILE *parentdir = getlockfile(PArg2);
- char *ptr;
-
- btos(PArg3, buf);
- if (ramfile = searchpath(&parentdir,buf,&ptr)) {
- if (ramfile == &xpath) {
- btos(PArg4,buf);
- if (!SetComment(buf1,buf))
- error = IoErr();
- break;
- }
- btos(PArg4, buf);
- if (ramfile->comment)
- FreeMem(ramfile->comment,strlen(ramfile->comment)+1);
- ramfile->comment = AllocMem(strlen(buf)+1, MEMF_PUBLIC);
- strcpy(ramfile->comment, buf);
- } else {
- if (parentdir)
- error = ERROR_OBJECT_NOT_FOUND;
- else
- error = ERROR_INVALID_COMPONENT_NAME;
- }
- }
- break;
- case ACTION_RENAME_OBJECT:/* SLock,SName,DLock,DName Bool */
- {
- register RAMFILE *file1;
- RAMFILE *sourcedir = getlockfile(PArg1);
- RAMFILE *destdir = getlockfile(PArg3);
- char *ptr;
-
- btos(PArg2,buf);
- /*DB*/ dbprintf("\nRENAME '%s' (%ld) ", buf, strlen(buf));
- if (file1 = vsearchpath(&sourcedir,buf,NULL)) {
- btos(PArg4,buf);
- /*DB*/ dbprintf("TO '%s' (%ld)", buf, strlen(buf));
- if (vsearchpath(&destdir,buf,&ptr)) {
- error = ERROR_OBJECT_EXISTS;
- } else {
- if (destdir) {
- if (file1 == destdir) {
- /* moving inside self */
- error = ERROR_OBJECT_IN_USE;
- break;
- }
- /*DB*/ dbprintf("REN '%s' %ld", ptr, strlen(ptr));
- DateStamp(&sourcedir->date);
- DateStamp(&destdir->date);
- Remove(file1);
- file1->name = AllocMem(strlen(ptr)+1,MEMF_PUBLIC);
- file1->parent = destdir;
- strcpy(file1->name, ptr);
- AddHead(&destdir->list, file1);
- } else {
- error = ERROR_INVALID_COMPONENT_NAME;
- }
- }
- } else {
- if (sourcedir)
- error = ERROR_OBJECT_NOT_FOUND;
- else
- error = ERROR_INVALID_COMPONENT_NAME;
- }
- }
- break;
- /*
- * A few other packet types which we do not support
- */
- case ACTION_INHIBIT: /* Bool Bool */
- /* Return success for the hell of it */
- break;
- case ACTION_RENAME_DISK:/* BSTR:NewName Bool */
- case ACTION_MORECACHE: /* #BufsToAdd Bool */
- case ACTION_WAIT_CHAR: /* Timeout, ticks Bool */
- case ACTION_FLUSH: /* writeout bufs, disk motor off */
- case ACTION_RAWMODE: /* Bool(-1:RAW 0:CON) OldState */
- default:
- error = ERROR_ACTION_NOT_KNOWN;
- break;
- }
- if (packet) {
- if (error) {
- /*DB*/ dbprintf("ERR=%ld\n", error);
- PRes1 = DOS_FALSE;
- PRes2 = error;
- } else {
- /*DB*/ dbprintf("RES=%06lx\n", PRes1);
- }
- returnpacket(packet);
- }
- else {
- /*DB*/ dbprintf("NOREP\n");
- }
- }
- }
- /*DB*/ dbprintf("Can we remove ourselves? ");
- /*DB*/ Delay(50); /* I wanna even see the debug message! */
- Forbid();
- if (packetsqueued() || GetHead(&FHBase) || GetHead(&LCBase)
- || GetHead(&RFRoot.list)) {
- Permit();
- /*DB*/ dbprintf(" .. not yet!\n");
- goto top; /* sorry... can't exit */
- }
-
- /*
- * Causes a new process to be created on next reference
- */
-
- DosNode->dn_Task = FALSE;
-
- /*
- * Remove Volume entry. Since DOS uses singly linked lists, we
- * must (ugg) search it manually to find the link before our
- * Volume entry.
- */
-
- {
- DOSINFO *di = BTOC(((ROOTNODE *)DOSBase->dl_Root)->rn_Info);
- register DEVLIST *dl;
- register void *dlp;
-
- dlp = &di->di_DevInfo;
- for (dl = BTOC(di->di_DevInfo); dl && dl != DevList; dl = BTOC(dl->dl_Next))
- dlp = &dl->dl_Next;
- if (dl == DevList) {
- *(BPTR *)dlp = dl->dl_Next;
- dosfree(dl);
- } else {
- /*DB*/ dbprintf("****PANIC: Unable to find volume node\n");
- }
- }
-
- /*
- * Remove debug process, closedown, fall of the end of the world
- * (which is how you kill yourself if a PROCESS. A TASK would have
- * had to RemTask(NULL) itself).
- */
-
- /*DB*/ dbuninit();
- CloseLibrary(DOSBase);
- }
-
-
- /*DB*/ static FH *debugfh;
- /*DB*/
- /*DB*/ dbinit()
- /*DB*/ {
- /*DB*/ debugfh = Open("con:0/0/640/150/debugwindow", 1006);
- /*DB*/
- /*DB*/ }
- /*DB*/
- /*DB*/ dbuninit()
- /*DB*/ {
- /*DB*/ Close(debugfh);
- /*DB*/ }
- /*DB*/
- /*DB*/ dbprintf(a,b,c,d,e,f,g,h,i,j)
- /*DB*/ {
- /*DB*/ static char buf[256];
- /*DB*/
- /*DB*/ sprintf(buf,a,b,c,d,e,f,g,h,i,j);
- /*DB*/ Write(debugfh,buf,strlen(buf));
- /*DB*/
- /*DB*/ }
-