[comp.sys.mac.programmer] Telling Floppies from Hard Disks

jamesm@cpsc.ucalgary.ca (Mark James) (08/23/89)

I'm looking for a method to test a volume to see if it is a floppy or a hard
drive.  I have written an INIT to patch PBMountVol to check an inserted disk
for viruses before mounting it and giving a dialog box if it is infected.
The problem is it takes far to long to mount a hard drive this way.  Any
sample code (or even references to IM if I've missed it) would be
appreciated.

     M.  

jamesm@cpsc.ucalgary.ca

blob@apple.com (Brian Bechtel) (08/24/89)

In article <1742@cs-spool.calgary.UUCP> jamesm@cpsc.ucalgary.ca (Mark 
James) writes:
> I'm looking for a method to test a volume to see if it is a floppy or a 
> hard drive.  I have written an INIT to patch PBMountVol to check an 
> inserted disk for viruses before mounting it and giving a dialog box if 
> it is infected.  The problem is it takes far to long to mount a hard 
> drive this way. 

It sounds like what you really want to check is if a device in the drive 
queue is removable or not.  To do this, examine the four bytes of flags 
preceeding the drive queue entry for this device.  See Inside Mac 
IV-181 & 182 for details.  C source is:

/* we assume that you get the drive number from some appropriate
   place, such as doing a PBHGetVInfo for the volume or looking directly 
   in the vcb (ackk!)
*/
Boolean
IsEjectable(driveNumber)
short driveNumber
{
    DrvQElPtr   d;
    QHdrPtr     queueHeader;
    Ptr         p;

    queueHeader = GetDrvQHdr();
    d = (DrvQElPtr)queueHeader->qHead;

    while (d != nil)    /* find the appropriate drive # */
    {
        if (d->dQDrive == driveNumber)   /* is this the drive we want? */
        {
            p = (Ptr)d;
            p -= 3; /* to get to the byte with eject info */
            if (*p == 8)
                return false;           /* non ejectable disk in drive */
            else
                return true;
        }
        d = (DrvQElPtr)d->qLink;
    }
    return false;   /* you specified an invalid drive number */
}

Now if you really want to know if a volume is a floppy or not, use 
PBHGetVInfo, and multiply out the ioVNmAlBlks (remember, it's unsigned!) 
times ioVAlBlkSiz.  Currently valid sizes include 400K, 800K, 720K, 1440K. 
How will you handle other sizes from the future?  Nasty.  That's why I 
think you are really asking to detect removable media.

In such an INIT, you might also want to check that the volume isn't 
extremely large (i.e. CD-ROM), so that you don't waste an incredible 
amount of time mounting those volumes, either.

--Brian Bechtel     blob@apple.com     "My opinion, not Apple's"

maarten@janus.UUCP (Maarten Carels) (08/24/89)

blob@apple.com (Brian Bechtel) writes:
>In article <1742@cs-spool.calgary.UUCP> jamesm@cpsc.ucalgary.ca (Mark 
>James) writes:
>> I'm looking for a method to test a volume to see if it is a floppy or a 
>> hard drive.  I have written an INIT to patch PBMountVol to check an 
... stuff deleted...
>It sounds like what you really want to check is if a device in the drive 
>queue is removable or not.  To do this, examine the four bytes of flags 
>preceeding the drive queue entry for this device.  See Inside Mac 
>IV-181 & 182 for details.  C source is:
Then some C source appears, only the relevant parts kept:

>    d = ... /* pointer to some drive queue element */
>        if (d->dQDrive == driveNumber)   /* is this the drive we want? */
>        {
>            p = (Ptr)d;
>            p -= 3; /* to get to the byte with eject info */
>            if (*p == 8)
****                   ^ This is plain wrong, see below
>                /* non ejectable disk in drive */
>            else
>                /* ejectable disk in drive */

The flag byte tested above contains (IM IV-181):
0	if no disk in drive
1 or 2	if disk in drive
8	if nonejectable disk in drive
$fc-$ff	if disk was ejected within last 1.5 seconds
$48	if disk in drive is nonejectable but driver wants a call

if there is 48 in the flags byte, the disk is considered nonejectable
by both the Finder and Standard File. Unmounting the disk (dragging to
the trash) causes an Eject control call to thye driver, that can be used
to clean up after unmounting (such as updating internal data structures
of the driver).

Code like this (checking for 8, and failing to recognize 48 for non-ejectable
disks) causes problems with some disks (such as mine) in programs like
DiskExpress, PrintQueue (of Super(Laser)Spool, FEdit, to name some.

So, please do not check for only for flags value 8, but also for $48,
or test for the specific bit (3).

--maarten

In real life:	Maarten Carels
		Computer Science Department
		University of Amsterdam
email:		maarten@fwi.uva.nl
-- 
In real life:	Maarten Carels
		Computer Science Department
		University of Amsterdam
email:		maarten@fwi.uva.nl

jln@accuvax.nwu.edu (John Norstad) (08/25/89)

Marten Carels is correct - be sure to test the drive queue element flag
byte for either 8 or $48.  I made the mistake of checking only for 8 in
an early development version of Disinfectant.

I have some c code very similar to Brian Bechtel's to test for an ejectable
volume.  Write to me if you'd like a copy.

John Norstad        Northwestern University      jln@acns.nwu.edu

ts@cup.portal.com (Tim W Smith) (08/25/89)

Not quite.  The check for removable drives recently posted here will
fail for many hard drives.  The following code was used:

	if ( *p == 8 )
		/* assume non-removable */
	else
		/* removable */

This fails because the value 0x48 can be used to signify non-removable
drives.  A value of 8 means that the drive is non-removable.  A value
of 0x48 means that the drive is non-removable, but the driver wants to
receive a control call when someone tries to eject the drive.

I have no idea why anyone would want to use 0x48.  Does anyone have
any ideas?

						Tim Smith

thecloud@dhw68k.cts.com (Ken McLeod) (08/27/89)

In article <3841@internal.Apple.COM> blob@apple.com (Brian Bechtel) writes:
>In article <1742@cs-spool.calgary.UUCP> jamesm@cpsc.ucalgary.ca (Mark 
>James) writes:
>> I'm looking for a method to test a volume to see if it is a floppy or a 
>> hard drive.  I have written an INIT to patch PBMountVol to check an 
>
>It sounds like what you really want to check is if a device in the drive 
>queue is removable or not.  To do this, examine the four bytes of flags 
>preceeding the drive queue entry for this device.  See Inside Mac 
> [code to examine DQE flags omitted...]
>Now if you really want to know if a volume is a floppy or not, use 
>PBHGetVInfo, and multiply out the ioVNmAlBlks (remember, it's unsigned!) 
>times ioVAlBlkSiz.  Currently valid sizes include 400K, 800K, 720K, 1440K. 
>How will you handle other sizes from the future?  Nasty.  That's why I 
>think you are really asking to detect removable media.

     Is there a method for determining whether a given floppy drive in
the queue is a FDHD (SuperDrive)?  Volume-related calls are useless, since
the drive may not currently contain a mounted volume... and the flags
preceding the entry in the drive queue seem to be invalid if a disk hasn't
yet been inserted (i.e. you boot from a hard drive).

     My application wants to display information about the drive itself,
and not the volume which it may or may not contain. I've tried sleuthing
the driver variables pointed to by the global at $134, using the MPW 3.0
Sony equates as a guide, but none of the values in the FDHD-related fields
are different from that of a standard 800K drive (until you do something
like mount an MFM disk).

     Thanks for any reponses, code snippets, etc.!

>--Brian Bechtel     blob@apple.com     "My opinion, not Apple's"

-ken
-- 
==========     .......     =============================================
Ken McLeod    :.     .:    UUCP: ...{spsd,zardoz,felix}!dhw68k!thecloud
==========   :::.. ..:::   INTERNET: thecloud@dhw68k.cts.com
                ////       =============================================