home *** CD-ROM | disk | FTP | other *** search
- /*-
- * $Id: pack.c,v 1.1 1993/12/02 20:45:46 Rhialto Exp $
- * $Log: pack.c,v $
- * Revision 1.1 1993/12/02 20:45:46 Rhialto
- * Initial revision
- *
- *
- * Originally:
- *
- * DOSDEVICE.C V1.10 2 November 1987
- *
- * EXAMPLE DOS DEVICE DRIVER FOR AZTEC.C PUBLIC DOMAIN.
- *
- * By Matthew Dillon.
- *
- * This has been stripped and refilled with network filesystem code
- * by Olaf Seibert.
- *
- * This code is (C) Copyright 1993 by Olaf Seibert. All rights reserved.
- * May not be used or copied without a licence.
- -*/
-
- #include "netfs.h"
- #include <string.h>
-
- #ifdef DEBUG
- # include "syslog.h"
- #else
- # define debug(x)
- #endif
-
-
- #define NETFL(something) ((NetFileLock *)(something))
- #define NETFH(something) ((NetFileHandle *)(something))
-
- Prototype struct ExecBase *SysBase;
- Prototype struct MsgPort *DosPort;
- Prototype struct DeviceNode *DevNode;
- Prototype struct DeviceList *VolNode;
- Prototype long UnitNr;
- Prototype char *DevName;
- Prototype ULONG DevFlags;
- Prototype struct DosPacket *DosPacket;
- Prototype ULONG error;
-
- Local BPTR MakeFileLock(NetFileLock *netfl, struct FileLock *fl, long mode);
-
- /*
- * 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.
- */
-
- struct MsgPort *DosPort; /* Our DOS port... */
- struct DeviceNode *DevNode; /* Our DOS node.. created by DOS for us */
- struct DeviceList *VolNode; /* Device List structure for our volume
- * node */
-
- struct DosLibrary *DOSBase; /* DOS library base */
- long WaitMask; /* The signal mask to wait for */
- long UnitNr; /* From */
- char *DevName; /* the */
- ULONG DevFlags; /* mountlist */
- struct DosPacket *DosPacket; /* For the SystemRequest pr_WindowPtr */
- long OpenCount; /* How many open files/locks there are */
- ULONG error;
-
-
- /*
- * Don't call the entry point main(). This way, if you make a mistake
- * with the compile options you'll get a link error.
- */
-
- Prototype void netfilesyshandler(void);
-
- void
- handlermain(void)
- {
- register struct DosPacket *packet;
- struct Message *msg;
- short done;
-
- /*
- * Initialize all global variables. SysBase MUST be initialized
- * before we can make Exec calls. AbsExecBase is a library symbol
- * referencing absolute memory location 4.
- */
-
- DOSBase = OpenLibrary("dos.library", 0L);
-
- #ifdef DEBUG
- /*
- * Initialize debugging code as soon as possible. Only SysBase required.
- */
-
- initsyslog();
- #endif /* DEBUG */
-
- DosPort = &((struct Process *)FindTask(NULL))->pr_MsgPort;
-
- debug(("WaitPort DosPort for startup...\n"));
- WaitPort(DosPort); /* Get Startup Packet */
- debug(("WaitPort DosPort done\n"));
- msg = GetMsg(DosPort);
- packet = (struct DosPacket *) msg->mn_Node.ln_Name;
-
- DevNode = BTOC(PArg3);
- {
- struct FileSysStartupMsg *fssm;
- struct DosEnvec *de;
-
- DevName = "parnet.device";
- UnitNr = 0;
- DevFlags = 0;
-
- if (fssm = (struct FileSysStartupMsg *)BTOC(DevNode->dn_Startup)) {
- /* Same as BTOC(packet->dp_Arg2) */
- UnitNr = fssm->fssm_Unit;
- if (fssm->fssm_Device)
- DevName = (char *)BTOC(fssm->fssm_Device)+1;
- DevFlags = fssm->fssm_Flags;
- de = BTOC(fssm->fssm_Environ);
-
- ClientDefaults(de->de_BlocksPerTrack, de->de_Interleave);
- }
- }
-
- if (DOSBase && OpenNetFS() == 0) {
- /*
- * Loading DevNode->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.
- */
-
- DevNode->dn_Task = DosPort;
-
- PRes1 = DOSTRUE;
- PRes2 = 0;
- } else { /* couldn't open dos.library */
- PRes1 = DOSFALSE;
- PRes2 = ERROR_DEVICE_NOT_MOUNTED; /* no better message available */
- returnpacket(packet);
- goto exit; /* exit process */
- }
- returnpacket(packet);
-
- /*
- * Get the first real packet.
- * This seems to be necessary because adding our Volume node at
- * this point causes some kind of deadlock. Which is kind
- * of silly since we returned the startup packet. Even calling
- * AttemptLockDosList does not seem to give any indication...
- */
- debug(("WaitPort DosPort for 1st real packet...\n"));
- WaitPort(DosPort);
- debug(("WaitPort DosPort done\n"));
- msg = GetMsg(DosPort);
-
- {
- struct DateStamp ds;
-
- DateStamp(&ds);
- VolNode = NewVolNode("Network", &ds);
- debug(("VolNode done\n"));
- }
- /* Initialize some more global variables */
-
- OpenCount = 0;
- WaitMask = (1L << DosPort->mp_SigBit) |
- (1L << RdPort->mp_SigBit);
-
- done = -1;
-
- goto entry;
-
- /*
- * Here begins the endless loop, waiting for requests over our message
- * port and executing them. Since requests are sent over the message
- * port in our device and volume nodes, we must not use our Process
- * message port for this: this precludes being able to call DOS
- * functions ourselves.
- */
-
- top:
- for (done = -1; done < 0;) {
- Wait(WaitMask);
- wakeup:
- while (msg = GetMsg(RdPort)) {
- /* Handle unsollicited network input */
- DoProtocol(msg, ((struct IOStdReq *)msg)->io_Data);
- }
- while (msg = GetMsg(DosPort)) {
- entry:
-
- packet = (PACKET *) msg->mn_Node.ln_Name;
- PRes1 = DOSFALSE;
- PRes2 = 0;
- error = 0;
- debug(("Packet: %4ld %08lx %08lx %08lx %s\n",
- PType, PArg1, PArg2, PArg3, typetostr(PType)));
-
- DosPacket = packet; /* For the System Requesters */
- ReqPacket.p_Action = PType;
-
- switch (PType) {
- case ACTION_DIE: /* attempt to die? */
- done = (PArg1 == MSH_MAGIC) ? PArg2 : 0; /* Argh! Hack! */
- break;
- case ACTION_CURRENT_VOLUME: /* - VolNode,UnitNr*/
- PRes1 = (long) CTOB(VolNode);
- PRes2 = UnitNr;
- break;
- case ACTION_LOCATE_OBJECT: /* Lock,Name,Mode Lock */
- {
- struct FileLock *lock;
- NetFileLock *netfl;
- long lockmode;
-
- lock = BTOC(PArg1);
- if ((lockmode = PArg3) != EXCLUSIVE_LOCK)
- lockmode = SHARED_LOCK;
- netfl = NetLock(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg2),
- lockmode);
- PRes1 = MakeFileLock(netfl, lock, lockmode);
- }
- break;
- case ACTION_RENAME_DISK: /* BSTR:NewName Bool */
- NewVolNodeName(BTOC(PArg1));
- PRes1 = DOSTRUE;
- break;
- case ACTION_FREE_LOCK: /* Lock Bool */
- {
- struct FileLock *lock;
- NetFileLock *netfl;
-
- PRes1 = DOSTRUE;
- lock = BTOC(PArg1);
- if (lock == NULL)
- break;
-
- netfl = NETFL(lock->fl_Key);
- FreeFileLock(lock);
- NetUnLock(netfl);
- }
- break;
- case ACTION_DELETE_OBJECT: /* Lock,Name Bool */
- {
- struct FileLock *lock;
-
- lock = BTOC(PArg1);
- PRes1 = NetDeleteFile(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg2));
- }
- break;
- case ACTION_RENAME_OBJECT: /* SLock,SName,DLock,DName Bool */
- {
- struct FileLock *slock, *dlock;
-
- slock = BTOC(PArg1);
- dlock = BTOC(PArg3);
- PRes1 = NetRename(NETFL(slock ? slock->fl_Key : 0),
- BTOC(PArg2),
- NETFL(dlock ? dlock->fl_Key : 0),
- BTOC(PArg4));
- }
- break;
- case ACTION_MORECACHE: /* #BufsToAdd bool,numbufs */
- PRes1 = 0; /* observed behaviour in std filesystem */
- PRes2 = 0; /* documented behaviour in manual */
- break;
- case ACTION_COPY_DIR: /* Lock Lock */
- {
- struct FileLock *lock;
- NetFileLock *netfl;
-
- lock = BTOC(PArg1);
-
- netfl = NetDupLock(NETFL(lock ? lock->fl_Key : 0));
-
- PRes1 = MakeFileLock(netfl, lock,
- lock ? lock->fl_Access : SHARED_LOCK);
- }
- break;
- case ACTION_SET_PROTECT: /* -,Lock,Name,Mask Bool */
- {
- struct FileLock *lock;
-
- lock = BTOC(PArg2);
- PRes1 = NetSetProtect(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg3), PArg4);
- }
- break;
- case ACTION_CREATE_DIR: /* Lock,Name Lock */
- {
- struct FileLock *lock;
- NetFileLock *netfl;
-
- lock = BTOC(PArg1);
-
- netfl = NetCreateDir(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg2));
-
- PRes1 = MakeFileLock(netfl, lock, SHARED_LOCK);
- }
- break;
- case ACTION_EXAMINE_OBJECT: /* Lock,Fib Bool */
- {
- struct FileLock *lock;
-
- lock = BTOC(PArg1);
- PRes1 = NetExamine(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg2));
- }
- break;
- case ACTION_EXAMINE_NEXT: /* Lock,Fib Bool */
- {
- struct FileLock *lock;
-
- lock = BTOC(PArg1);
- PRes1 = NetExNext(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg2));
- }
- break;
- case ACTION_DISK_INFO: /* InfoData Bool:TRUE */
- PRes1 = NetDiskInfo(BTOC(PArg1));
- break;
- case ACTION_INFO: /* Lock,InfoData Bool:TRUE */
- {
- struct FileLock *lock;
-
- lock = BTOC(PArg1);
- PRes1 = NetInfo(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg2));
- }
- break;
- /* case ACTION_FLUSH: / * writeout bufs, disk motor off */
- case ACTION_SET_COMMENT: /* -,Lock,Name,Comment Bool */
- {
- struct FileLock *lock;
-
- lock = BTOC(PArg2);
- PRes1 = NetSetComment(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg3), BTOC(PArg4));
- }
- break;
- case ACTION_PARENT: /* Lock ParentLock */
- {
- struct FileLock *lock;
- NetFileLock *netfl;
-
- lock = BTOC(PArg1);
-
- netfl = NetParentDir(NETFL(lock ? lock->fl_Key : 0));
-
- PRes1 = MakeFileLock(netfl, lock, SHARED_LOCK);
- }
- break;
- case ACTION_INHIBIT: /* Bool Bool */
- PRes1 = DOSFALSE;
- break;
- case ACTION_SET_DATE: /* -,Lock,Name,CPTRDateStamp Bool */
- {
- struct FileLock *lock;
-
- lock = BTOC(PArg2);
- PRes1 = NetSetDate(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg3),
- (struct DateStamp *)PArg4);
- }
- break;
- case ACTION_SAME_LOCK: /* Lock1,Lock2 Result */
- {
- struct FileLock *fl1, *fl2;
-
- fl1 = BTOC(PArg1);
- fl2 = BTOC(PArg2);
- if (fl1->fl_Volume == fl2->fl_Volume &&
- BTOC(fl1->fl_Volume) == VolNode) {
- PRes1 = NetSameLock(NETFL(fl1->fl_Key),
- NETFL(fl2->fl_Key));
- } else {
- PRes1 = DOSFALSE;
- error = ERROR_INVALID_LOCK;
- }
- }
- break;
- case ACTION_READ: /* FHArg1,CPTRBuffer,Length ActLength */
- PRes1 = NetRead(NETFH(PArg1), (UBYTE *)PArg2, PArg3);
- break;
- case ACTION_WRITE: /* FHArg1,CPTRBuffer,Length ActLength */
- PRes1 = NetWrite(NETFH(PArg1), (UBYTE *)PArg2, PArg3);
- break;
- case ACTION_OPENRW: /* FileHandle,Lock,Name Bool */
- case ACTION_OPENOLD: /* FileHandle,Lock,Name Bool */
- case ACTION_OPENNEW: /* FileHandle,Lock,Name Bool */
- {
- NetFileHandle *netfh;
- struct FileHandle *fh;
- struct FileLock *lock;
-
- fh = BTOC(PArg1);
- lock = BTOC(PArg2);
- netfh = NetOpen(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg3),
- PType);
- if (netfh) {
- fh->fh_Arg1 = (long) netfh;
- PRes1 = DOSTRUE;
- OpenCount++;
- }
- }
- break;
- case ACTION_CLOSE: /* FHArg1 Bool:Success */
- PRes1 = NetClose(NETFH(PArg1));
- OpenCount--;
- break;
- case ACTION_SEEK: /* FHArg1,Position,Mode OldPosition */
- PRes1 = NetSeek(NETFH(PArg1), PArg2, PArg3);
- break;
- #ifdef notdef
- case ACTION_FORMAT: /* vol,type Bool:success */
- PRes1 = NetFormat(BTOC(PArg1), PArg2);
- break;
- #endif
- case ACTION_MAKE_LINK: /* parent,name,target,soft Bool */
- {
- struct FileLock *lock;
- void *dest;
-
- lock = BTOC(PArg1);
- dest = PArg4 ? (char *)PArg3 /* C string! */
- : (void *)((struct FileLock *)BTOC(PArg3))->fl_Key;
- PRes1 = NetMakeLink(NETFL(lock ? lock->fl_Key : 0),
- BTOC(PArg2),
- dest,
- PArg4);
- }
- break;
- case ACTION_READ_LINK: /* parent,name,target,size length */
- {
- struct FileLock *lock;
- lock = BTOC(PArg1);
- PRes1 = NetReadLink(NETFL(lock ? lock->fl_Key : 0),
- (char *)PArg2, /* C string! */
- (char *)PArg3,
- PArg4);
- }
- break;
- case ACTION_SET_FILE_SIZE:
- PRes1 = NetSetFileSize(NETFH(PArg1), PArg2, PArg3);
- break;
- /* case ACTION_WRITE_PROTECT: */
- /* FH,Lock BOOL */
- case ACTION_FH_FROM_LOCK:
- {
- NetFileHandle *netfh;
- struct FileHandle *fh;
- struct FileLock *lock;
-
- fh = BTOC(PArg1);
- lock = BTOC(PArg2);
- netfh = NetOpenFromLock(NETFL(lock ? lock->fl_Key : 0));
- if (netfh) {
- fh->fh_Arg1 = (long) netfh;
- PRes1 = DOSTRUE;
- OpenCount++;
- /* Discard the lock */
- FreeFileLock(lock);
- }
- }
- break;
- case ACTION_IS_FILESYSTEM:
- PRes1 = DOSTRUE;
- break;
- case ACTION_CHANGE_MODE:
- {
- void *object;
-
- switch (PArg1) {
- case CHANGE_FH:
- object = NETFH(((struct FileHandle *)BTOC(PArg2))->fh_Arg1);
- break;
- case CHANGE_LOCK:
- object = NETFL(((struct FileLock *)BTOC(PArg2))->fl_Key);
- break;
- }
- PRes1 = NetChangeMode(PArg1, object, PArg3);
- }
- break;
- case ACTION_COPY_DIR_FH: /* fh_Arg1 Lock */
- case ACTION_PARENT_FH:
- {
- NetFileLock *netfl;
-
- if (PType == ACTION_PARENT_FH)
- netfl = NetParentOfFH(NETFH(PArg1));
- else
- netfl = NetDupLockFromFH(NETFH(PArg1));
-
- /* User has inserted disk by now, so we can use VolNode */
- PRes1 = MakeFileLock(netfl, NULL, SHARED_LOCK);
- }
- break;
- case ACTION_EXAMINE_FH: /* fh_Arg1,Fib Bool */
- PRes1 = NetExamineFH(NETFH(PArg1), BTOC(PArg2));
- break;
- /*
- * A few other packet types which we do not support
- */
- case ACTION_LOCK_RECORD: /* fh,pos,len,mode,time Bool */
- {
- debug(("fh(arg1) %x\n", PArg1));
-
- NetLockRecord(packet, NETFH(PArg1), PArg2, PArg3, PArg4, PArg5);
- packet = NULL;
- }
- break;
- case ACTION_FREE_RECORD: /* fh,pos,len Bool */
- {
- debug(("fh(arg1) %x\n", PArg1));
- /* NetFileHandle *netfh = NETFH(((struct FileHandle *)
- PArg1)->fh_Arg1); */
-
- PRes1 = NetFreeRecord(NETFH(PArg1), PArg2, PArg3);
- }
- break;
- /* case ACTION_WAIT_CHAR: / * Timeout, ticks Bool */
- /* case ACTION_RAWMODE: / * Bool(-1:RAW 0:CON) OldState */
- default:
- PRes1 = DOSFALSE;
- error = ERROR_ACTION_NOT_KNOWN;
- break;
- } /* end switch */
- if (packet) {
- if (error)
- PRes2 = error;
- debug(("RES=%06lx, ERR=%ld\n", PRes1, error));
- returnpacket(packet);
- DosPacket = NULL;
- }
- #ifdef DEBUG
- else {
- debug(("NOREP\n"));
- }
- #endif
- } /* end while (GetMsg()) */
-
- } /* end for (;done) */
-
- #ifdef DEBUG
- debug(("Can we remove ourselves? "));
- #endif /* DEBUG */
- Forbid();
- if (OpenCount || packetsqueued()) {
- Permit();
- debug((" .. not yet!\n"));
- goto top; /* sorry... can't exit */
- }
- debug((" .. yes!\n"));
-
- /*
- * Causes a new process to be created on next reference.
- */
-
- DevNode->dn_Task = NULL;
- CloseNetFS();
- FreeVolNode(VolNode);
- debug(("CloseNetFS() returned.\n"));
-
- /*
- * Remove debug, closedown, fall of the end of the world.
- */
- exit:
- #ifdef DEBUG
- uninitsyslog();
- #endif /* DEBUG */
-
- if (done & 2)
- UnLoadSeg(DevNode->dn_SegList); /* This is real fun. We are still */
- if (done & (2 | 1))
- DevNode->dn_SegList = NULL; /* Forbid()den, fortunately */
-
- CloseLibrary((struct Library *)DOSBase);
-
- /* Fall off the end of the world. Implicit Permit(). */
- }
-
- /*
- * Make a new struct FileLock, for DOS use. It is put on a singly linked
- * list, which is attached to the same VolumeNode the old lock was on.
- *
- * Also note that we must ALWAYS be prepared to UnLock() or DupLock()
- * any FileLocks we ever made, even if the volume in question has been
- * removed and/or inserted into another drive with another FileSystem
- * handler!
- *
- * DOS makes certain assumptions about LOCKS. A lock must minimally be a
- * FileLock structure, with additional private information after the
- * FileLock structure. The longword before the beginning of the structure
- * must contain the length of structure + 4.
- *
- * NOTE!!!!! The workbench does not follow the rules and assumes it can copy
- * lock structures. This means that if you want to be workbench
- * compatible, your lock structures must be EXACTLY sizeof(struct
- * FileLock). Also, it sometimes uses uninitialized values for the lock mode...
- */
-
- Prototype struct FileLock *NewFileLock(NetFileLock *netfl, struct FileLock *fl);
-
- struct FileLock *
- NewFileLock(NetFileLock *netfl, struct FileLock *fl)
- {
- struct FileLock *newlock;
- struct DeviceList *volnode = NULL;
-
- if (fl) {
- volnode = BTOC(fl->fl_Volume);
- }
- if (volnode == NULL) {
- volnode = VolNode;
- debug(("volnode 0->%lx\n", volnode));
- }
- #ifdef DEBUG
- if (volnode != VolNode) {
- debug(("volnode != VolNode %lx != %lx\n",
- volnode, VolNode));
- }
- if (volnode->dl_Task != DosPort) {
- debug(("volnode->dl_Task != DosPort %lx != %lx\n",
- volnode->dl_Task, DosPort));
- }
- #endif
-
- if (newlock = dosalloc((ULONG)sizeof (*newlock))) {
- newlock->fl_Key = (ULONG) netfl;
- newlock->fl_Task = DosPort;
- newlock->fl_Volume = (BPTR) CTOB(volnode);
- Forbid();
- newlock->fl_Link = volnode->dl_LockList;
- volnode->dl_LockList = (BPTR) CTOB(newlock);
- Permit();
- } else
- error = ERROR_NO_FREE_STORE;
-
- return newlock;
- }
-
- Prototype long FreeFileLock(struct FileLock *lock);
-
- long
- FreeFileLock(struct FileLock *lock)
- {
- register struct FileLock *fl;
- register struct FileLock **flp;
- struct DeviceList *volnode;
-
- volnode = (struct DeviceList *)BTOC(lock->fl_Volume);
- flp = (struct FileLock **) &volnode->dl_LockList;
- for (fl = BTOC(*flp); fl && fl != lock; fl = BTOC(fl->fl_Link))
- flp = (struct FileLock **)&fl->fl_Link;
-
- if (fl == lock) {
- *(BPTR *)flp = fl->fl_Link;
- dosfree((ULONG *)fl);
- OpenCount--;
- return DOSTRUE;
- } else {
- debug(("Huh?? Could not find filelock!\n"));
- return DOSFALSE;
- }
- }
-
- /*
- * MakeFileLock allocates and initializes a new FileLock, using info
- * from an existing FileLock. It always consumes the NetFileLock, even
- * in case of failure.
- */
-
- Prototype BPTR MakeFileLock(NetFileLock *netfl, struct FileLock *fl, long mode);
-
- BPTR
- MakeFileLock(NetFileLock *netfl, struct FileLock *fl, long mode)
- {
- struct FileLock *newlock;
-
- newlock = NULL;
- if (netfl) {
- if (newlock = NewFileLock(netfl, fl)) {
- newlock->fl_Access = mode;
- OpenCount++;
- } else
- NetUnLock(netfl);
- }
-
- return CTOB(newlock);
- }
-
- /*
- * 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 NET: disk, Volume node or not.
- */
-
- Prototype struct DeviceList *NewVolNode(char *name, struct DateStamp *date);
-
- struct DeviceList *
- NewVolNode(char *name, struct DateStamp *date)
- {
- struct DeviceList *volnode;
- char *volname; /* This is my volume name */
-
- if (volnode = dosalloc((ULONG)sizeof (struct DeviceList))) {
- if (volname = dosalloc(33L)) {
- volname[0] = strlen(name);
- strcpy(volname + 1, name); /* Make sure \0 terminated */
-
- volnode->dl_Type = DLT_VOLUME;
- volnode->dl_Task = DosPort;
- volnode->dl_DiskType = ID_DOS_DISK;
- volnode->dl_Name = (BSTR *)CTOB(volname);
- volnode->dl_VolumeDate = *date;
- volnode->dl_NetFileLockList = NULL;
-
- if (DOSBase->dl_lib.lib_Version >= 37) {
- struct DosList *dl;
- debug(("LockDosList...\n"));
- dl = AttemptLockDosList(LDF_VOLUMES | LDF_DEVICES | LDF_WRITE);
- if ((ULONG)dl <= 1) {
- debug(("LockDosList NOT ok\n"));
- goto brute_force;
- }
- UnLockDosList(LDF_VOLUMES | LDF_DEVICES | LDF_WRITE);
-
- debug(("AddDosEntry...\n"));
- if (AddDosEntry((struct DosList *)volnode) == DOSFALSE) {
- debug(("AddDosEntry for VolNode fails!\n"));
- goto error;
- }
- debug(("AddDosEntry: done\n"));
- } else {
- struct DosInfo *di;
-
- brute_force:
- di = BTOC(((struct RootNode *) DOSBase->dl_Root)->rn_Info);
-
- Forbid();
- volnode->dl_Next = di->di_DevInfo;
- di->di_DevInfo = (long) CTOB(volnode);
- Permit();
- }
- } else {
- error:
- dosfree((ULONG *)volnode);
- volnode = NULL;
- }
- } else {
- error = ERROR_NO_FREE_STORE;
- }
-
- return volnode;
- }
-
- /*
- * Give the VolNode a new name (given as a BCPL string).
- */
-
- Prototype void NewVolNodeName(char *newname);
-
- void
- NewVolNodeName(char *newname)
- {
- if (VolNode) {
- register char *volname = BTOC(VolNode->dl_Name);
-
- memcpy(volname, newname, 1 + newname[0]);
- }
- }
-
- /*
- * Remove Volume entry. Since DOS uses singly linked lists, we must
- * (ugg) search it manually to find the link before our Volume entry.
- */
-
- Prototype void FreeVolNode(struct DeviceList *volnode);
-
- void
- FreeVolNode(struct DeviceList *volnode)
- {
- debug(("FreeVolNode %08lx\n", volnode));
-
- if (volnode == NULL)
- return;
-
- if (DOSBase->dl_lib.lib_Version >= 37) {
- struct DosList *dl;
-
- dl = LockDosList(LDF_VOLUMES | LDF_WRITE);
- (void)RemDosEntry((struct DosList *)volnode);
- UnLockDosList(LDF_VOLUMES | LDF_WRITE);
- } else {
- struct DosInfo *di = BTOC(((struct RootNode *) DOSBase->dl_Root)->rn_Info);
- register struct DeviceList *dl;
- register void *dlp;
-
- dlp = &di->di_DevInfo;
- Forbid();
- for (dl = BTOC(di->di_DevInfo); dl && dl != volnode; dl = BTOC(dl->dl_Next))
- dlp = &dl->dl_Next;
- if (dl == volnode) {
- *(BPTR *) dlp = dl->dl_Next;
- }
- #ifdef DEBUG
- else {
- debug(("****PANIC: Unable to find volume node\n"));
- }
- #endif /* DEBUG */
- Permit();
- }
-
- dosfree(BTOC(volnode->dl_Name));
- dosfree((ULONG *)volnode);
-
- if (volnode == VolNode)
- VolNode = NULL;
- }
-