🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #6800

Finding disks

#6800
From: Chris Hind Genly
Date: Sun, 18 Nov 1990 21:31
129 lines
5257 bytes
I posted a message a few days ago asking how to determine what disk
devices are on a system.  This is the kind of problem you need to
solve if you're writing a file requester and want to put up buttons
with disk device names on them.  I received one answer.  I was pointed
towards the fish disk with the info command.  I thought I'd post the
results since I imagine there are readers that would be interested.

The info replacement walked through the dos device list looking for a
device with an associated task.  There is a comment in the info source
to the effect that only disks will have an associated task.  I don't
think this is correct.  It appears that disk devices have a task, but
other devices do too.  The info replacement shows all the disks on my
system plus null:.  The Commodore info command doesn't show null:.

I have a good solution now.  The magic I needed came from the info
replacement command.  It showed me how to suppress requesters.  The
requester is suppressed by setting the window pointer in the process
structure to 0.

Once a device is found with a non-zero task entry, it can be tested to
see if it is really a disk device by trying to lock it.  If you can
lock it, its a disk.  If you can't it still might be a disk.  If its
df0: for example and there is no disk in df0: I don't want a requester
to pop up, so I suppress them.  If there's no disk, the lock operation
will fail.  If the device is a disk device the lock will fail with an
error such as: ERROR_NO_DISK.  This tells me the device is a disk
device. 

Here is my current solution.  You are free to do with the code as you wish.

static
void
FindDiskNames(
    char *DiskNames[],
    int   DiskNamesMax
)
{
    extern struct DosLibrary *DOSBase;
    struct RootNode *RootNode;
    struct DosInfo *DosInfo;
    struct DosList *Device, *Devices;
    struct Process *Process;
    char *DiskName, *t;
    APTR OldWindow;
    char *Name;
    int ADisk;
    BPTR lk;
    int i;
    
    DiskNames[0] = 0;
    
    if (DOSBase == 0) return;
    
    RootNode = (struct RootNode *)DOSBase->dl_Root;
    DosInfo  = (struct DosInfo *)BADDR(RootNode->rn_Info);
    Devices  = (struct DosList *)BADDR(DosInfo->di_DevInfo);
    
    for(Device = Devices;
        Device;
        Device = (struct DosList *)BADDR(Device->dol_Next))
    {
        /* Look for a device, not a volume */
        if (Device->dol_Type != 0)
            continue;
            
        /* A disk device has a task associated with it */
        if (Device->dol_Task == 0)
            continue;

        /* Get the device name */
        Name =  (char *)BADDR(Device->dol_Name);
        Name++;
        
        /* Make a copy with a colon at the end */
        DiskName = smalloc(strlen(Name)+2);
        strcpy(DiskName, Name);
        strcat(DiskName, ":");
        
        /* Disable requesters in case there's no disk present */
        Process = (struct Process *) FindTask(NULL);
        OldWindow = Process->pr_WindowPtr;
        Process->pr_WindowPtr = (APTR) -1;
        
        /* Attempt to create a lock to verify that its a disk */
        lk = Lock(DiskName, ACCESS_READ);
        if (lk) UnLock(lk);
        ADisk  = lk != 0 
              || IoErr() == ERROR_NOT_A_DOS_DISK	
              || IoErr() == ERROR_NO_DISK;
              
        /* Allow requesters */
        Process->pr_WindowPtr = OldWindow;
        
        /* If its a disk, add it to the list of disk names */
        if (ADisk) {
            for(i=0; i<DiskNamesMax; ++i) {
                if (DiskNames[i] == 0) break;
                if (stricmp(DiskName, DiskNames[i]) < 0) break;
            }
            for(; i<DiskNamesMax; ++i) {
                t = DiskNames[i];
                if (t == 0 && i == DiskNamesMax-1) {
                    sfree(DiskName);
                    break;
                } else {
                    DiskNames[i] = DiskName;
                    if (DiskName == 0) break;
                    DiskName = t;
                }
            }
        } else
            sfree(DiskName);
    }
}

sfree(), sstrdup(), and smalloc() are strict versions of free(), strdup(),
and malloc().  In addition to performing their normal function they check the
integrity of the memory pool.


       *                        *                        *
                                                            \|/
               *           _______                         --O--
                      ____/ KC1VP \____        *            /|\
 *             ______/  (203) 389-8680 \______
        ______/   Eggplant Software Tools     \________
 ______/  95 Fountain Terr., New Haven, CT, USA, 06515 \_______
/ Chris Hind Genly    chris@genly.uucp   uunet!hsi!genly!chris \
----------------------------------------------------------------
Technical Details
Message-ID: <chris.11172988@genly.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!hsi!genly!chris

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!hsi!genly!chris
From: chris@genly.UUCP (Chris Hind Genly)
Newsgroups: comp.sys.amiga.tech
Subject: Finding disks
Message-ID: <chris.11172988@genly.UUCP>
Date: 18 Nov 90 21:31:18 GMT
Organization: Eggplant Software Tools, New Haven, CT, USA
Lines: 129