DriverGestaltDemo.c

/*
    File:       DriverGestaltDemo.c
    
    Description:This sample is a simple example of how to make some basic Driver
                Gestalt queries.
 
    Author:     VM
 
    Copyright:  Copyright: © 1996-1999 by Apple Computer, Inc.
                all rights reserved.
    
    Disclaimer: You may incorporate this sample code into your applications without
                restriction, though the sample code has been provided "AS IS" and the
                responsibility for its operation is 100% yours.  However, what you are
                not permitted to do is to redistribute the source as "DSC Sample Code"
                after having made changes. If you're going to re-distribute the source,
                we require that you make it clear in the source that the code was
                descended from Apple Sample Code, but that you've made changes.
    
    Change History (most recent first):
                6/23/99 Updated for Metrowerks Codewarrior Pro 2.1
 
*/
 
 
 
//------------------------------------------------------------------------------
 
#pragma mark Includes
//------------------------------------------------------------------------------
 
#include <stdio.h>
#include <stdlib.h>
 
#include <DriverGestalt.h>
#include <Devices.h>
#include <LowMem.h>
#include <Files.h>
 
//------------------------------------------------------------------------------
 
#pragma mark Defines
//------------------------------------------------------------------------------
 
 
#define CLEAR(what) do {                        \
        register Ptr        _ptr = (Ptr) &what; \
        register Size       _len = sizeof what; \
        for (; _len > 0; --_len)                \
            *_ptr++ = 0;                        \
    } while (0)
 
 
//------------------------------------------------------------------------------
 
#pragma mark DriverGestalt Info & Structures
//------------------------------------------------------------------------------
 
 
//enum {
//  kdgFlush                    = 'flus'    /*can disk driver flush */
//};
 
//struct DriverGestaltFlushResponse {
//  Boolean                         canFlush;
//  Boolean                         needsFlush;
//  UInt8                           pad[2];
//};
//typedef struct DriverGestaltFlushResponse DriverGestaltFlushResponse;
 
//typedef struct DriverGestaltSyncResponse DriverGestaltSyncResponse;
 
struct DriverGestaltVersResponse
{
    NumVersion driverVersion;
};
typedef struct DriverGestaltVersResponse DriverGestaltVersResponse;
 
 
union DriverGestaltInfo
{
    DriverGestaltSyncResponse       sync;
    DriverGestaltBootResponse       boot;
    DriverGestaltDevTResponse       devt;
    DriverGestaltIntfResponse       intf;
    DriverGestaltVersResponse       vers;
    DriverGestaltEjectResponse      ejec;
    DriverGestaltPowerResponse      powr;
    DriverGestaltFlushResponse      flus;
    UInt32                          i;
};
typedef union DriverGestaltInfo DriverGestaltInfo;
 
//------------------------------------------------------------------------------
 
#pragma mark Prototypes
//------------------------------------------------------------------------------
 
 
 
void        DisplayAllDriveInfo (void);
 
void        DisplayDriverGestaltInfo    (short refNum, short device);
 
OSErr       DoDriverGestalt     (   short driverRefnum,
                                    short driveNumber,
                                    OSType gestaltSelector,
                                    DriverGestaltInfo   *response );
 
char*       DrvrRefToName       (short refNum);
void        PrintNumVersion     (char *label, NumVersion version );
 
 
// ---------------------------------------------------------------------------
void     main   (void)
// ---------------------------------------------------------------------------
{
    DisplayAllDriveInfo();
}
 
 
// ---------------------------------------------------------------------------
void        DisplayAllDriveInfo (void)
// ---------------------------------------------------------------------------
//
//  Display information ATA Driver GestaltInfo
//
{
    register DrvQEl     *drvQElPtr;
    char*               drvrNamePtr;
    short               notused;
    OSErr               status;
 
 
#define DQEL    (*drvQElPtr)
    drvQElPtr = (DrvQEl *) GetDrvQHdr()->qHead;
 
    printf("Disk Drive Queue Information:\n\n");
    while (drvQElPtr != NULL) {
 
        drvrNamePtr = DrvrRefToName(DQEL.dQRefNum);
 
        printf("Drive: %d  %#s (%d) ",
                (int) DQEL.dQDrive,
drvrNamePtr,DQEL.dQRefNum);
 
        switch (DQEL.qType) {
        case 0:
            printf(
                "%lu blocks (small drive)\n",
                (unsigned long) DQEL.dQDrvSz
            );
            break;
        case 1:
            printf(
                "%lu blocks\n",
                ((unsigned long) DQEL.dQDrvSz)
                + (((unsigned long) DQEL.dQDrvSz2) * 0x10000L)
            );
            break;
        case 3:
            printf(
                "%lu blocks (MFS present)\n",
                ((unsigned long) DQEL.dQDrvSz)
            );
            break;
        default:
            printf(
                "%lu %lu (unknown queue type)\n",
                ((unsigned long) DQEL.dQDrvSz),
                ((unsigned long) DQEL.dQDrvSz2)
            );
            break;
        }
 
// Open driver
        status = OpenDriver((ConstStr255Param)drvrNamePtr, &notused);
        if (status != noErr) {
            printf("Cannot open %#s Error: %d\n", (int) status);
        exit(EXIT_FAILURE);
        }
 
        DisplayDriverGestaltInfo(DQEL.dQRefNum, DQEL.dQDrive);
        drvQElPtr = (DrvQEl *) DQEL.qLink;
    }
#undef DQEL
}
 
 
 
 
// ---------------------------------------------------------------------------
void        DisplayDriverGestaltInfo    (short refNum, short driveNum)
// ---------------------------------------------------------------------------
//
//  Display DriverGestalt information.
//
{
        OSErr               status;
        DriverGestaltInfo   response;
 
// display driver version
        status = DoDriverGestalt(refNum,driveNum, kdgVersion,
&response);
        if (status == noErr)
            PrintNumVersion("\t'vers' - version:",
response.vers.driverVersion);
 
 
// display device type
        status = DoDriverGestalt(refNum, driveNum, kdgDeviceType,
&response);
        if (status == noErr)
            printf("\t'devt' - Device:\t'%.4s'\n",
                (char *) &response.devt.deviceType
            );
 
 
// display API info
        status = DoDriverGestalt(refNum, driveNum, kdgInterface,
&response);
        if (status == noErr)
            printf("\t'intf' - Interface:\t'%.4s'\n",
                (char *) &response.intf.interfaceType
            );
 
// display boot record
        status = DoDriverGestalt(refNum, driveNum, kdgBoot, &response);
        if (status == noErr)
            printf("\t'boot' - Boot PRAM:\t%08lx\n",
                (* ((unsigned long *) &response))
            );
 
// display sync info
        status = DoDriverGestalt(refNum, driveNum,  kdgSync,
&response);
        if (status == noErr)
                    printf("\t'sync' - Driver is %s \n",
 
    (response.sync.behavesSynchronously)?"synchronous":"asynchronous");
 
 
// display driver flush capablities
        status = DoDriverGestalt(refNum, driveNum, kdgFlush, &response);
        if (status == noErr)
            printf("\t'flus' - Driver %s flush \n",
 
    (response.flus.canFlush)?"supports":"doesn't support");
 
// display power info
        status = DoDriverGestalt(refNum, driveNum,kdgSupportsPowerCtl, &response);
        if (status == noErr)  {
            printf("\t'psup' - Driver %s power switching\n",
                            (response.powr.powerValue)?"supports":"doesn't support");
 
            status = DoDriverGestalt(refNum, driveNum, kdgMin3VPower,&response);
            if (status == noErr)
                printf("\t'pmx3' - 3.3V power consumption %d microWatts \n",
                    (char *) &response.powr.powerValue);
    }
 
 
    printf("\n");
}
 
 
// ---------------------------------------------------------------------------
OSErr       DoDriverGestalt     (short
    driverRefnum,
                                 short
            driveNumber,
                                OSType
            gestaltSelector,
 
    DriverGestaltInfo   *response )
// ---------------------------------------------------------------------------
//
//  Do Driver Gestalt Call
//
{
        DriverGestaltParam      pb;
        OSErr                   status;
 
        CLEAR(pb);
        pb.ioVRefNum    = driveNumber;
        pb.ioCRefNum    = driverRefnum;
        pb.csCode       = kDriverGestaltCode;
        pb.driverGestaltSelector = gestaltSelector;
 
        status = PBStatusSync((ParmBlkPtr) &pb);
 
        if (status == noErr)
            response->i  = pb.driverGestaltResponse;
//      else printf("error %d\n",status);
        return (status);
}
 
// ---------------------------------------------------------------------------
char*       DrvrRefToName(short refNum)
// ---------------------------------------------------------------------------
//
//  lookup driver name in table
//
 
{
        AuxDCEHandle*       UTable  = (AuxDCEHandle*)
        LMGetUTableBase();
        DCtlPtr             dctl;
        Ptr                 p;
 
        if(!refNum) return ((char*) "\p<none>");
 
        dctl = (DCtlPtr) *UTable[~refNum];
        p    =  dctl->dCtlDriver;
        if( dctl->dCtlFlags  & 0x0040) p = (void*) *p;
 
        return  ( p?(char*) (p+18):(char*)"\p-Purged-");
}
 
// ---------------------------------------------------------------------------
void        PrintNumVersion     (char *label, NumVersion version )
// ---------------------------------------------------------------------------
//
//  Decode version number info
//
{
    char            *stage;
 
    switch (version.stage) {
    case developStage:  stage = "d";        break;
    case alphaStage:    stage = "a";        break;
    case betaStage:     stage = "b";        break;
    case finalStage:    stage = "";         break;
    default:            stage = "?";        break;
 
    }
    printf("%s %d.%d.%d",
        label,
        version.majorRev,
        (version.minorAndBugRev>>4), (version.minorAndBugRev & 0xf),
        stage);
    if(version.stage != finalStage) printf(".%d",version.nonRelRev);
 
    printf(" (hex %08lx)\n",    (* ((unsigned long *) &version)));
}