MIB Bits/MoreProcesses.cp

/*
    File:       MoreProcesses.cp
 
    Contains:   
 
    Written by: Pete Gontier
 
    Copyright:  Copyright (c) 1998 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):
 
         <6>     20/3/00    Quinn   Added MoreProcIsProcessAtFront.  Tidied up some copy and paste
                                    errors in the comments.  Support passing nil to more routines to
                                    mean "current process".
         <5>      3/9/00    gaw     API changes for MoreAppleEvents
         <4>      6/3/00    Quinn   Added MoreProcGetProcessAppFile.
         <3>     1/22/99    PCG     TARGET_CARBON
         <2>    11/11/98    PCG     fix header
         <1>    11/10/98    PCG     first big re-org at behest of Quinn
 
    Old Change History (most recent first):
 
         <3>     11/9/98    PCG     fix comment 2
         <2>     11/9/98    PCG     add copyright blurb
         <1>     6/16/98    PCG     initial checkin
*/
 
#include "MoreProcesses.h"
/******************************************************************************
    Return a ProcessSerialNumber for a process whose signature (creator)
    matches the input values.  This routine will find the first process that
    matches the creator.
    
    The ProcessSerialNumber will be kNoProcess is the requested process cannot
    be found. 
 
    pCreator            input:  The creator of the process to be found.
    pPSN                input:  Pointer to a ProcessSerialNumber.
                        output: A valid PSN or kNoProcess in no match is found.
 
    RESULT CODES
    ____________
    noErr              0    No error
    procNotFound    Ð600    No process matched specified creator
    ____________
*/
 
pascal OSStatus MoreProcFindProcessByCreator(const OSType pCreator,ProcessSerialNumber *pPSN)
{
    OSStatus err = noErr;
 
    if (!(MoreAssert (pPSN)))
        err = paramErr;
    else
    {
        pPSN->lowLongOfPSN  = kNoProcess;
        pPSN->highLongOfPSN = kNoProcess;
 
        while (!(err = GetNextProcess (pPSN)))
        {
            ProcessInfoRec pir;
 
            if (!(err = MoreProcGetProcessInformation (pPSN,&pir)))
                if (pCreator == pir.processSignature)
                    break;
        }
    }
 
    return err;
}
/******************************************************************************
    Return a ProcessSerialNumber for a process whose signature (type and creator)
    matches the input values.  This routine will find the first process that
    matches the type and creator.
    
    The ProcessSerialNumber will be kNoProcess is the requested process cannot
    be found. 
 
    pCreator                input:  The creator type of the process to be found.
    pType               input:  The file type of the process to be found.
    pPSN                input:  Pointer to a ProcessSerialNumber.
                        output: A valid PSN or kNoProcess in no match is found.
 
    RESULT CODES
    ____________
    noErr              0    No error
    procNotFound    Ð600    No process matched specified type and creator
    ____________
*/
 
pascal OSStatus MoreProcFindProcessBySignature(const OSType pCreator,const OSType pType,ProcessSerialNumber *pPSN)
{
    OSStatus err = noErr;
 
    if (!(MoreAssert (pPSN)))
        err = paramErr;
    else
    {
        pPSN->lowLongOfPSN  = kNoProcess;
        pPSN->highLongOfPSN = kNoProcess;
 
        while (!(err = GetNextProcess (pPSN)))
        {
            ProcessInfoRec pir;
 
            if (!(err = MoreProcGetProcessInformation (pPSN,&pir)))
                if ((pCreator == pir.processSignature) && (pType == pir.processType))
                    break;
        }
    }
 
    return err;
}
/******************************************************************************
    Returns the name of the process specified by ProcessSerialNumberPtr.
    
    The string pointed to by pProcessName will be untouched if the process
    can't be found. 
 
    pPSN            input:  The process whose name you want (nil for current).
    pProcessName    input:  Pointer to a Str31 for the process name.
                    output: The process name.
    
    RESULT CODES
    ____________
    noErr              0    No error
    paramErr         Ð50    Process serial number is invalid
    ____________
*/
pascal  OSStatus    MoreProcGetProcessName(
                                const ProcessSerialNumberPtr pPSN,
                                StringPtr pProcessName)
{
    OSStatus        anErr = noErr;  
    ProcessInfoRec  infoRec;
    ProcessSerialNumber localPSN;
 
    MoreAssertQ(pProcessName != nil);
        
    infoRec.processInfoLength = sizeof(ProcessInfoRec);
    infoRec.processName = pProcessName;
    infoRec.processAppSpec = nil;
    
    if ( pPSN == nil ) {
        localPSN.highLongOfPSN = 0;
        localPSN.lowLongOfPSN  = kCurrentProcess;
    } else {
        localPSN = *pPSN;
    }
    
    anErr = GetProcessInformation(&localPSN, &infoRec);
    
    return anErr;
}//end MoreProcGetProcessName
/******************************************************************************
    Returns information about the process specified by ProcessSerialNumberPtr.
    
    pProcessType and pCreator will be untouched if the process
    can't be found. 
 
    pPSN                input:  The process whose info you want (nil for current).
    pProcessType        output: The process's type.
    pCreator            output: The process's signature.
    
    RESULT CODES
    ____________
    noErr              0    No error
    paramErr         Ð50    Process serial number is invalid
    ____________
*/
pascal  OSStatus    MoreProcGetProcessTypeSignature(
                        const ProcessSerialNumberPtr pPSN,
                        OSType *pProcessType,
                        OSType *pCreator)
{
    OSStatus            anErr = noErr;  
    ProcessInfoRec      infoRec;
    ProcessSerialNumber localPSN;
    
    infoRec.processInfoLength = sizeof(ProcessInfoRec);
    infoRec.processName = nil;
    infoRec.processAppSpec = nil;
 
    if ( pPSN == nil ) {
        localPSN.highLongOfPSN = 0;
        localPSN.lowLongOfPSN  = kCurrentProcess;
    } else {
        localPSN = *pPSN;
    }
    
    anErr = GetProcessInformation(&localPSN, &infoRec);
    if (anErr == noErr)
    {
        *pProcessType = infoRec.processType;
        *pCreator = infoRec.processSignature;
    }
    
    return anErr;
}//end MoreProcGetProcessTypeSignature
 
/******************************************************************************
    Returns the FSSpec for the current process
    
    pFSSpec             output: The process's FSSpec.
    
    RESULT CODES
    ____________
    noErr              0    No error
    paramErr         Ð50    pFSSpec is nil
    ____________
*/
pascal OSStatus MoreProcGetCurrentProcessFSSpec(FSSpec *pFSSpec)
{
    return MoreProcGetProcessAppFile(nil,pFSSpec);
}
/******************************************************************************
    Returns the FSSpec for the process specified by ProcessSerialNumberPtr.
    
    pPSN                input:  The process's Serial Number
                                if nil return the AppFile for the current process
    pAppFile            output: The process's appFile.
    
    RESULT CODES
    ____________
    noErr              0    No error
    paramErr         Ð50    Process serial number is invalid (or pPSN or pAppFile is nil)
    ____________
*/
pascal OSStatus MoreProcGetProcessAppFile(const ProcessSerialNumber *pPSN,FSSpec *pAppFile)
{
    OSStatus            err;
    ProcessInfoRec      processInfo;
    ProcessSerialNumber localPSN;
    
    if (nil == pAppFile)
        return paramErr;
    
    if ( pPSN == nil ) {
        localPSN.highLongOfPSN = 0;
        localPSN.lowLongOfPSN  = kCurrentProcess;
    } else {
        localPSN = *pPSN;
    }
    processInfo.processInfoLength   = sizeof(processInfo);
    processInfo.processName         = nil;
    processInfo.processAppSpec      = pAppFile;
 
    err = GetProcessInformation(&localPSN, &processInfo);
 
    return err;
}
/******************************************************************************
    Returns the Process Information for the process specified by pPSN.
    
    pPSN                input:  The process's Serial Number
    pPIR                output: The process's Information.
    
    RESULT CODES
    ____________
    noErr              0    No error
    paramErr         Ð50    Process serial number is invalid (or pPSN or pPIR is nil)
    ____________
*/
pascal OSStatus MoreProcGetProcessInformation(const ProcessSerialNumber *pPSN,ProcessInfoRec *pPIR)
{
    if (!MoreAssert (pPIR))
        return paramErr;
 
    pPIR->processInfoLength = sizeof (*pPIR);
    pPIR->processName       = nil;
    pPIR->processAppSpec    = nil;
 
    if (pPSN)
        return GetProcessInformation (pPSN,pPIR);
    else
    {
        ProcessSerialNumber psn = { kNoProcess,kCurrentProcess };
        return GetProcessInformation (&psn,pPIR);
    }
}
/******************************************************************************
    Returns true if the process specified by pPSN is a background only application.
    
    pPSN                input:  The process's Serial Number
    pIsBOA              output: The process's Information.
    
    RESULT CODES
    ____________
    noErr              0    No error
    paramErr         Ð50    Process serial number is invalid (or pPSN or pIsBOA is nil)
    ____________
*/
pascal OSStatus MoreProcIsProcessBackgroundOnly(const ProcessSerialNumber *pPSN,Boolean *pIsBOA)
{
    OSStatus err = noErr;
    ProcessInfoRec pir;
 
    if (!MoreAssert (pIsBOA))
        return paramErr;
 
    if (!(err = MoreProcGetProcessInformation (pPSN,&pir)))
    {
        *pIsBOA = (modeOnlyBackground & pir.processMode) ? true : false;
    }
 
    return err;
}
 
extern pascal Boolean MoreProcIsProcessAtFront(const ProcessSerialNumber *pPSN)
    // See comment in header.
{   
    OSStatus            err;
    ProcessSerialNumber localPSN;
    ProcessSerialNumber frontPSN;
    Boolean             isSame;
    
    if ( pPSN == nil ) {
        localPSN.highLongOfPSN = 0;
        localPSN.lowLongOfPSN  = kCurrentProcess;
    } else {
        localPSN = *pPSN;
    }
    
    err = GetFrontProcess(&frontPSN);
    if (err == noErr) {
        err = SameProcess(&localPSN, &frontPSN, &isSame);
    }
    MoreAssertQ(err == noErr);          // If either of the previous return an error, we want to know why.
    return (err == noErr) && isSame;
}