MyPortCalls.c

/*
    File:       MyPortCalls.c
 
    Contains:   Generic calls for working with the MyPortScanner sample, to allow a PC Card Enabler
                to force an OT port deregistration
 
    Written by: Rich Kubota 
 
    Copyright:  Copyright © 1998-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source 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 source
                code, but that you've made changes.
 
    Change History (most recent first):
                8/16/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
 
#include <PCCardEnablerPlugin.h>
#include <PCCardTuples.h>
#include <Errors.h>
#include <Devices.h>
#include <Gestalt.h>
#include <CodeFragments.h>
#include <DriverServices.h>
#include <OpenTptModule.h>
#include <OpenTptPCISupport.h>
#include <OpenTptDevLinks.h>
#include "EnablerSample.h"
#include "MyPortCalls.h"
 
#define  DEBUG  1
 
 
#pragma export on
 
/* A 'shlb' OT driver does not require a driver description record, however, the implementation 
    of this port register sample requires the description to be entered into the name registry
    for the port scanner to find and use in registering the network services for the card.
    The driverDescription is entered here so that it can be registered along with the other
    port properties which this technique requires.
*/
DriverDescription TheEnetDriverDescription = 
{
    kTheDescriptionSignature,           // Signature field of this structure
    kVersionOneDriverDescriptor,        // Version of this data structure
    {                                   // Type of Driver
        "\p"kDriverName,                // Driver Name/Info String
        kVersionMajor,                  // 1st part of version number in BCD
        kVersionMinor,                  // 2nd & 3rd part share a byte
        kVersionStage,                  // stage: dev, alpha, beta, or final
        kVersionNonRel                  // non-released revision level
    },
    {                                   // OS Runtime Requirements of Driver
        kDriverIsUnderExpertControl,    // Options for OS Runtime
        "\p"kDriverName                 // Driver's name to the OS
    },
    {                                   // Apple Service API Membership
        1,                              // Number of Services Supported
        {                               // The List of Services
            kServiceCategoryOpenTransport,      // Service Category Name
            OTPCIServiceType(kOTEthernetDevice, // This is an Ethernet device
                              kOTFramingEthernet |      // Ethernet Packets
                              kOTFramingEthernetIPX |   // IPX Packets
                              kOTFraming8022,           // 802.2 Packets,
                             false,     // it is not TPI
                             true),     // it is DLPI
            kVersionMajor,              // 1st part of version number in BCD
            kVersionMinor,              // 2nd & 3rd part share a byte
            kVersionStage,              // stage: dev, alpha, beta,  or final
            kVersionNonRel              // non-released revision level
        }
    }
};
 
 
 
 
/*
    The CreatePortProperties registers the various name registry properties that we
    want to get registered.
    
    Register the NetworkDriverDescription so that the port scanner can find it and
    use it's info to register the port.  This is similar to what the PCINetworkCard
    PortScanner does.
    
    Register the "port-configured" property to tell the default PC Card Port Scanner
    to not handle port registration of this device - the value is not important
    to the default port scanner
    
    Finally, register the "port-module" property to hold the name of the driver to be
    opened.  The use of the property only applies if you use the default
    pc card port scanner to register the ethernet port.  To do this, remove the code
    above to make the call to CallPortScanner. also comment out the code
    to register the "port-configured" property.  The default scanner checks for the
    port-module property, and if present, uses the name in the property as the module
    name that support this device.  This is the means by which a number of different
    PC Ethernet cards can be supported by the same driver module.
    
*/
 
OSStatus CreatePortProperties(const RegEntryID *cardRef)
{
    OSStatus    err = noErr;
    UInt16      portConfigProperty;
        
#if DEBUG   
    DebugStr("\pCustomCardEnabler:  CreatePortProperties");     
#endif
 
        // first we register TheEnetDriverDescription so that our custom port scanner
        // knows the attributes of the port to register
    err = RegistryPropertyCreate(cardRef, kDescriptorProperty, &TheEnetDriverDescription,
                                     sizeof(DriverDescription));
    if (err != noErr)
    {
#if DEBUG
        DebugStr("\p RegistryPropertyCreate failed creating driver-descriptor property");
#endif
        return err;
    }
    
    portConfigProperty = 0;
        // by setting this property, you keep the default PCCard Port Scanner from
        // registering this port as an ethernet device.
    err = RegistryPropertyCreate(cardRef, kPortConfigured, &portConfigProperty, sizeof(short));
    if (err != noErr)
    {
#if DEBUG
        DebugStr("\p RegistryPropertyCreate failed creating port-configured property");
#endif
    }
    else
    {
            // specify the module name to specify for the default PC Card Port scanner to
            // use to register this port.  Note that this only applies if the above
            // port-configured property is not created.  If the property is created, then
            // creating the port-module property is just another property but which will 
            // not be used by the PC Card Port Scanner.
        err = RegistryPropertyCreate(cardRef, kPortModule, &gDriverName, sizeof(gDriverName));
        if (err != noErr)
        {
#if DEBUG
            DebugStr("\p RegistryPropertyCreate failed creating port-module property");
#endif
        }
    }
    return err;
}
 
 
/*
    CallPortScanner looks for our port scanner and registers our port.
    Note that the call takes no argument and distinguishes cards that
    aren't registered by accessing the 'port-configured' property.  If
    the property is not present, then the scanner will not register a 
    port for the device.  If the property is present, and it's value is 0
    then it will register a port.  If the value is 1, then it knows that 
    it has already registered a port for this property. 
*/
void CallPortScanner(void)
{
    THz             savedZone;
    OSErr           err;
    CFragConnectionID   connID;
    PortScanProcPtr portScanProcPtr;
    CFragSymbolClass        symClass;
    Str32           portScannerName = "\pOTScanPorts";
    Str255          errName;
    
        // before we call the port scanner we need to check for the presence of OT.
        // if OT is not present, then we are at start up and our port scanner will
        // executed to register the port, later when OT is started up.  
        // The port scanner is only called automatically at system start up 
        // and when the system comes out of sleep. 
 
    if (!IsOpenTransportPresent())
        return;
        
#if DEBUG   
            DebugStr("\p CallPortScanner called");
#endif
        // Calls to GetSharedLibrary for fragments which are registered in the System heaqp
        // require that we set the correct zone context
    savedZone = GetZone();
    SetZone(SystemZone());
    
    err = GetSharedLibrary(kPascalPortScannerName, kPowerPCCFragArch, kReferenceCFrag, &connID,
                            (Ptr*)&portScanProcPtr, (unsigned char*)&errName);
    if (err == noErr)
    {
        err = FindSymbol(connID, portScannerName, (Ptr*)&portScanProcPtr, &symClass);
        if (err == noErr)
        {
            if (portScanProcPtr != nil)
                (*portScanProcPtr)(kOTInitialScan);
        }
        else
        {
#if DEBUG   
            DebugStr("\p FindSymbol failed");
#endif
        }
            // we're finished with the library
        CloseConnection(&connID);
    }
    else
    {
#if DEBUG   
        DebugStr("\p GetSharedLibrary failed");
#endif
    }
    
        // restore the zone
    SetZone(savedZone);
}
 
void    EnablerOfflinePort(const RegEntryID *cardRef)
{
    THz                     savedZone;
    OSErr                   err;
    CFragConnectionID       connID;
    PortOfflineProcPtr  portOfflineProcPtr;
    CFragSymbolClass        symClass;
    Str32                   offlinePortName = "\pOfflineThePort";
    Str255                  errName;
    
#if DEBUG   
            DebugStr("\p EnablerOfflinePort called");
#endif
        // Calls to GetSharedLibrary for fragments which are registered in the System heaqp
        // require that we set the correct zone context
    savedZone = GetZone();
    SetZone(SystemZone());
    
    err = GetSharedLibrary(kPascalPortScannerName, kPowerPCCFragArch, kReferenceCFrag, &connID,
                            (Ptr*)&portOfflineProcPtr, (unsigned char*)&errName);
    if (err == noErr)
    {
            // Find the exported proc ptr symbol
        err = FindSymbol(connID, offlinePortName, (Ptr*)&portOfflineProcPtr, &symClass);
        if (err == noErr)
        {
            if (portOfflineProcPtr != nil)
                (*portOfflineProcPtr)(cardRef);
        }
        else
        {
#if DEBUG   
            DebugStr("\p FindSymbol on OfflineThePort failed");
#endif
        }
            // we're finished with the library
        CloseConnection(&connID);
    }
    else
    {
#if DEBUG   
        DebugStr("\p GetSharedLibrary failed");
#endif
    }
    
        // restore the zone
    SetZone(savedZone);
 
}
 
Boolean IsOpenTransportPresent(void)
{
    long    result;
    OSErr   err;
    
    err = Gestalt(gestaltOpenTptVersions, &result);
    if (err == noErr)
        return true;
    else
        return false;
}
 
 
#pragma export off