TPIFileRegister.c

/*
    File:       TPIFileRegister.c
 
    Contains:   A trivial application to register a port for the TPIFile module.
 
    Written by: Quinn "The Eskimo!"
 
    Copyright:  © 1997 by Apple Computer, Inc., all rights reserved.
 
    Change History (most recent first):
 
    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.
*/
 
/////////////////////////////////////////////////////////////////////
// Pick up all the OT client info, specifically the OTRegisterPort.
 
#include <OpenTransport.h>
 
/////////////////////////////////////////////////////////////////////
// Pick up the OTAllocPortMem routine.
 
#include <OpenTptClient.h>
 
/////////////////////////////////////////////////////////////////////
// Pick up kOTSerialDevice.
 
#include <OpenTptLinks.h>
 
/////////////////////////////////////////////////////////////////////
// OK, so it's yet another console based sample from Quinn!
 
#include <stdio.h>
 
/////////////////////////////////////////////////////////////////////
// Pick up the TPIFilePortInfoRecord stuff.
 
#include "TPIFile.h"
 
/////////////////////////////////////////////////////////////////////
 
static OSErr RegisterTPIFilePort()
    // Register a port named "TPIFile" with Open Transport.
    // This allows clients to OTOpenEndpoint(OTCreateConfiguration("TPIFile"), ...)
    // to open up the TPIFile module.
{
    OSErr                       err;
    UInt16                      otherFieldOfPortRef;
    OTPortRef                   candidatePortRef;
    TPIFilePortInfoRecordPtr    portInfoStorage;
    OTPortRecord                portRecord;
    OTPortRecord                junkPortRecord;
 
    // First, figure out which port ref we're going to register with.  We
    //  do this by building candidatePortRef's until we get one that works.
    
    otherFieldOfPortRef = 0;
    do {
        candidatePortRef = OTCreatePortRef(kOTUnknownBusPort,
                                kOTSerialDevice,
                                0,
                                otherFieldOfPortRef);
        otherFieldOfPortRef += 1;
    } while ( OTFindPortByRef(&junkPortRecord, candidatePortRef) );
 
    // Now create the port info record for this port.  It's important that this info
    //  be allocated using OTAllocPortMem, so that the memory goes into the right
    //  memory pool, namely the "port pool".  This memory must be shared between the
    //  port scanner and the port driver, because portInfoStorage will be passed in
    //  as the contextPtr for the driver's InitStreamModule routine.
    
    err = noErr;
    portInfoStorage = OTAllocSharedClientMem(sizeof(TPIFilePortInfoRecord));
    if (portInfoStorage == nil) {
        err = memFullErr;
    }
    
    if (err == noErr) {
 
        // Now fill out the fields in the port info data structure.
        //  Obviously if you're talking to a real driver, you'd have more
        //  info to pass along here.
        
        portInfoStorage->magic1 = kTPIFilePortInfoMagic1;
        portInfoStorage->portRef = candidatePortRef;
        portInfoStorage->magic2 = kTPIFilePortInfoMagic2;
        
        // See "Open Tpt Module Dev. Note" for a description of all the fields
        //  of OTPortRecord.  Note that I've initialised some of these fields
        //  to 0, even though I've already block cleared the whole thing.  This
        //  makes it easier for me to experiment with weird values in the fields
        //  but you don't need it in production code.
 
        OTMemzero(&portRecord, sizeof(portRecord));
 
        portRecord.fRef                 = candidatePortRef;
        portRecord.fPortFlags           = 0;
        portRecord.fInfoFlags           = kOTPortIsTPI;
        portRecord.fCapabilities        = 0;
        portRecord.fNumChildPorts       = 0;
        
        // fPortName is the name of the port.
        OTStrCopy(portRecord.fPortName, "TPIFile");
 
        // fModuleName is the name of the module (ie driver) that controls
        //  the port.  OT finds the driver by looking up "OTModl$fModuleName".
        OTStrCopy(portRecord.fModuleName, kTPIFilePortName);
 
        // fSlotID is used to describe which slot a device is in.  In
        //  this case, the TPIFile port is not in a slot, so it doesn't make sense
        //  to init this field.  If you're a port scanner for a real device,
        //  you might want to set this up.
        portRecord.fSlotID[0]           = 0;
 
        // fResourceInfo holds a zero terminated string that is the name
        //  of the config helper library for this port.  The library
        //  is responsible for providing a user-visible name and icon
        //  for the port.
        // There is no helper for this port!
        // OTStrCopy(portRecord.fResourceInfo, "");
 
        err = OTRegisterPort( &portRecord, portInfoStorage );
        if (err == noErr) {
            portInfoStorage = nil;                  // record that we don't need to free portInfoStorage
        } else {
            DebugStr("\pRegisterTPIFilePort: OTRegisterPort failed.");
        }
    }
    
    if (portInfoStorage != nil) {
        OTFreeSharedClientMem(portInfoStorage);
    }
    
    return (err);
}
 
/////////////////////////////////////////////////////////////////////
 
void main(void)
{
    OSStatus err;
    OTPortRecord junkPortRecord;
    
    printf("Hello Cruel World!\n");
    
    err = InitOpenTransport();
    
    if (err == noErr) {
    
        if ( OTFindPort(&junkPortRecord, kTPIFilePortName) ) {
            printf("The ÒTPIFileÓ port is already registered.\n");
        } else {
            err = RegisterTPIFilePort();
        }
 
        CloseOpenTransport();
    }
    
    if (err == noErr) {
        printf("Success.\n");
    } else {
        printf("Failed with error %d.\n", err);
    }
    printf("Done.  Press command-Q to Quit.\n");
}