Sources/Process.cp

/*
    File:       Process.cp
 
    Contains:   TProcess is a Process Manager class.
                Process.cp contains the class body information for the TProcess class member functions.
 
 
    Written by: Kent Sandvik    
 
    Copyright:  Copyright © 1992-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/18/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
// Include files
#ifndef _PROCESS_
#include "Process.h"
#endif
 
 
// _________________________________________________________________________________________________________ //
// TProcess class member function implementations
 
//  CONSTRUCTORS & DESTRUCTORS
#pragma segment Process                      
TProcess::TProcess(ProcessSerialNumber theNum)
// Default constructor.
{
    fFirstTime = true;                          // signal that we are inside constructor
    fLast = false;
    fProcessID.highLongOfPSN = theNum.highLongOfPSN;
    fProcessID.lowLongOfPSN = theNum.lowLongOfPSN;
 
    fError = ::GetCurrentProcess(&fMyProcessID);// always get our own PSN
    VASSERT(fError == noErr, ("pProblems with GetCurrentProcess() = %d", fError));
 
    fState = this->IProcess();                  // initialize the object
 
    fFirstPSN = fProcessID;                     // define the first one
    fFirstTime = false;                         // signal this time is over
}
 
 
#pragma segment Process
TProcess::~TProcess()
// Destructor, we are not doing anything inside this one just now.
{
}
 
 
//  INITIATION ROUTINES
#pragma segment Process
Boolean TProcess::IProcess()
// We are using a special IProcess member function for initializing class fields to
// known values.
{
    // get our own PSN number
    if (fFirstTime)                             // our first PSN (our own)
    {
        fError = ::GetNextProcess(&fProcessID);
        VASSERT(fError == noErr, ("Problems with GetNextProcess() = %d", fError));
 
        if (fError != noErr)
            goto IProcessFalse;
 
        goto IProcessOK;
    }
    else
    {
        fError = ::GetNextProcess(&fProcessID); // fetch other PSNs
 
        if (fError != noErr)
        {
            fLast = true;
            this->First();
            goto IProcessFalse;
        }
        else
            goto IProcessOK;
    }
IProcessFalse:return false;
IProcessOK:return true;
}
 
 
//   MAIN INTERFACE
#pragma segment Process
Boolean TProcess::KillApplication(ProcessSerialNumber* thePSN)
// quit the application which is defined by the PSN
{
    AEAddressDesc target;
    AppleEvent theAE,  theAEReply;
 
    theAE.dataHandle = theAEReply.dataHandle = target.dataHandle = NULL;
 
    fError = ::AECreateDesc(typeProcessSerialNumber, (Ptr)thePSN, sizeof(ProcessSerialNumber), &target);
    VASSERT(fError == noErr, ("Problems with AECreateDesc() = %d", fError));
 
    if (fError != noErr)
        goto KillApplicationFalse;
 
    fError = ::AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &target, kAutoGenerateReturnID, kAnyTransactionID, &theAE);
    VASSERT(fError == noErr, ("Problems with AECreateAppleEvent() = %d", fError));
 
    if (fError != noErr)
    {
        ::AEDisposeDesc(&target);
        goto KillApplicationFalse;
    }
 
    fError = ::AESend(&theAE, &theAEReply, kAENoReply, kAENormalPriority, kNoTimeOut, NULL, NULL);
    VASSERT(fError == noErr, ("Problems with AESend() = %d", fError));
 
    ::AEDisposeDesc(&target);
    ::AEDisposeDesc(&theAE);
 
    if (fError != noErr)
        goto KillApplicationFalse;
    else
        goto KillApplicationOK;
 
 
KillApplicationFalse:return false;
KillApplicationOK:return true;
}
 
 
#pragma segment Process
short TProcess::GetNumProcesses()
// Get the amount of currently running processes.
{
    ProcessSerialNumber aPSN;
    short num = 0;
 
    aPSN.highLongOfPSN = 0;
    aPSN.lowLongOfPSN = kNoProcess;
 
    while (GetNextProcess(&aPSN) == noErr)
        num++;
 
    return num;
}
 
 
#pragma segment Process
ProcessInfoRec TProcess::GetProcessInfoRec()
// Return the full ProcInfoRec of specified process, NULL if we got into trouble.
{
    ProcessInfoRec theRec;
 
    theRec.processName = NULL;
    theRec.processAppSpec = NULL;
    theRec.processInfoLength = sizeof(theRec);
 
    fError = ::GetProcessInformation(&fProcessID, &theRec);
    VASSERT(fError == noErr, ("Problems with GetProcessInformation() = %d", fError));
 
    return theRec;
}
 
 
#pragma segment Process
unsigned long TProcess::GetProcessSize()
// Return size of process.
{
    ProcessInfoRec temp = this->GetProcessInfoRec();
    return temp.processSize;
}
 
 
#pragma segment Process
unsigned long TProcess::GetFreeMem()
// Return the amount of free memory available for the process
{
    ProcessInfoRec temp = this->GetProcessInfoRec();
    return temp.processFreeMem;
}
 
 
#pragma segment Process
unsigned long TProcess::GetLaunchDate()
// Return in seconds the point when the application was launched.
{
    ProcessInfoRec temp = this->GetProcessInfoRec();
    return temp.processLaunchDate;
}
 
 
#pragma segment Process
Boolean TProcess::FindProcess(OSType signature)
// Find process with the right signature, style 'MACS'.
{
    ProcessInfoRec theRec;
    fProcessID.highLongOfPSN = 0;
    fProcessID.lowLongOfPSN = kNoProcess;       // start from beginning
 
    theRec.processName = NULL;
    theRec.processAppSpec = NULL;
    theRec.processInfoLength = sizeof(theRec);
 
    while (::GetNextProcess(&fProcessID) == noErr)
    {
        if (::GetProcessInformation(&fProcessID, &theRec) == noErr)
        {
            if (theRec.processSignature == signature)
                goto FindProcessOK;             // we found it
        }
    }
    goto FindProcessFalse;                      // we didn't find the processÉ
 
FindProcessFalse:return false;
FindProcessOK:return true;
}
 
 
//  PUBLIC ACCESSORS AND MUTATORS           
 
#pragma segment Process                      
ProcessSerialNumber TProcess::GetMyProcessID() const
{
    return fMyProcessID;
}
 
 
#pragma segment Process                      
ProcessSerialNumber TProcess::GetProcessID() const
{
    return fProcessID;
}
 
 
// ITERATORS
 
#pragma segment Process                      
void TProcess::Next()
{
    this->IProcess();
}
 
 
#pragma segment Process                      
Boolean TProcess::Last()
{
    return fLast;
}
 
 
#pragma segment Process                      
void TProcess::First()
{
    fProcessID = fFirstPSN;
}
 
 
// _________________________________________________________________________________________________________ //
 
/*  Change History (most recent last):
  No        Init.   Date        Comment
  1         khs     6/10/92     New file
  2         khs     7/6/92      First decent working class
*/