PortScanner.c

/*
    File:       PortScanner.c
 
    Contains:   Before using this code, check out the document "OTAdvancedClientProg1.0b1"
                which is available as part of the Open Transport SDK - specifically read
                the section regarding Open Transport Port Scanners.  A copy of the OT SDK
                is available at 
    
                <http://developer.apple.com/macos/opentransport/>
    
                You will find in this sample, 2 calls which are exported, one to register
                an OT port and the second to unregister the port.  These calls are
                implemented here and not in the code bases which might directly use them
                to circumvent loading problems if OT is not present.  For example a USB
                Ethernet driver shim would want to register it's port, however, since a
                USBShim is loaded before OT is present, CFM would either fail to load
                the shim if OT was hard linked, or OT calls would not function from the
                shim if OT was weak linked.  The latter case occurs because at the time
                the library is loaded, if CFM cannot resolve a weak linked fragment, the
                links to those dependent library calls do not get fixed up, even though
                later on, those library services become available.  Note that the above is
                also true for a PC card Enabler, which is the reason for this sample.
    
                The OT RegisterPort call can be made in the OT PortScanner code here, since
                the port scanner will always be called after OT is loaded. 
 
    Written by: Original port scanner code written by:  Quinn "The Eskimo!"
                Modified to support PC Cards 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
                
 
*/
 
//----------------------------------------------------------------------
 
#define DEBUG                   1
//----------------------------------------------------------------------
 
#include <OpenTptModule.h>
#include <OpenTptLinks.h>
#include <PCCardEnablerPlugin.h>
#include <PCCardTuples.h>
#include <Gestalt.h>
#include <DriverFamilyMatching.h>
#include "EnablerSample.h"
#include "MyRegisterPort.h"
 
// the following structure is required to register a PCI port
 
 
/////////////////////////////////////////////////////////////////////
 
 
extern void     OTScanPorts(UInt32 scanType);
extern Boolean  CanRegisterThisPort(RegEntryID *deviceRef);
 
/*
    Determine whether we need to register the port for this card.
    This check is made by verifying that the target device has a 
    "port-configured" property, which the enabler that goes along
    with this project creates, when it processes the AddDeviceProperties
    call gets made.
*/
Boolean  CanRegisterThisPort(RegEntryID *deviceRef)
{
    UInt32      size;
    OSStatus    err;
    UInt16      portConfigProperty;
    
    size = sizeof(UInt16);
    err = RegistryPropertyGet(deviceRef, kPortConfigured, 
                                &portConfigProperty, &size);
 
        // if an error occurred, then the property does not exist or the property
        // is a different size, so don't configure this card    
    if (err != noErr)
    {
        return false;
    }
            // check that the value is 0, meaning that we haven't 
            // registered the port associated with this card
            // 
    else if (portConfigProperty != 0)
        return false;
    else
        return true;
}
 
#pragma export on
 
 
/*
    The OTScanPorts symbol is the required symbol to be exported for a port scanner.
*/
 
#pragma export list OTScanPorts
 
extern void OTScanPorts(UInt32 scanType)
{
    RegEntryIter    cookie;
    RegEntryID      deviceID;
    OSType          cardType = 'pccd';
    OSStatus        err;
    Boolean         done = false;
    
        // the port scanner only handles the initial scan after system startup.
    if (scanType != kOTInitialScan)
    {
#if DEBUG
        DebugStr("\p scanType != kOTInitialScan");
#endif
        return;
    }
    
    if ( RegistryEntryIterateCreate(&cookie) != noErr )
    {
#if DEBUG
        DebugStr("\p RegistryEntryIterateCreate in OTScanPorts failed");
#endif
        return;
    }
    
#if DEBUG
        DebugStr("\p entering OTScanPorts do loop");
#endif
    do
    {
        err = RegistryEntrySearch(&cookie, kRegIterContinue, &deviceID, &done, 
                                    kNodeTypePropertyName, &cardType, sizeof(cardType));
            
            // check to see if we are done searching
        if (err != noErr) 
        {
#if DEBUG
            DebugStr("\p error calling RegistryEntrySearch");
#endif
            break;
        }
        
        if (CanRegisterThisPort(&deviceID) == true)
        {
            RegisterThePort(&deviceID);
        }
        else
        {
#if DEBUG
            DebugStr("\p CanRegisterThisPort returned false");
#endif
        }
    }
    while (done == false);
}
 
#pragma export off