home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * ProcessUtils.c
- *
- * DESCRIPTION
- * Utiltiy routines for finding and manipulating processes.
- *
- * AUTHOR: Matt Pallakoff
- *
- * CREATED: 9-9-91
- *
- *****************************************************************************/
-
- #include "ProcessUtils.h"
-
- OSErr PUFindApp (ResType signature, FSSpec *aFSSpec);
- OSErr PULaunchApp (FSSpec *aFSSpec);
- OSErr PULaunchAppWithSignature (ResType serviceSignature);
-
- void ClearEvenSizeBlock(void *loc, Size len);
-
- /****************************************************************************/
-
- void ClearEvenSizeBlock(void *loc, Size len)
- {
- short *sPtr = loc;
- short sz = len>>1;
- for (sz = (len>>1)-1; sz >= 0; sz--);
- *sPtr++ = 0;
- }
-
- /****************************************************************************/
-
-
- OSErr PUFindApp (ResType signature, FSSpec *aFSSpec)
- {
- DTPBRec aDTPBRec;
- short dtRefNum, volRefNum;
- OSErr err, err2, volErr;
- short i;
- Str255 name;
- HParamBlockRec volPB;
-
- err = -1; /* representing 'not found' */
- /* For each mounted volume... */
- i = 0;
- volErr = noErr;
- while ((volErr == noErr) && (err != noErr)) {
- ++i;
-
- /* Get Volume information. */
- volPB.ioParam.ioCompletion = nil;
- volPB.ioParam.ioNamePtr = name;
- volPB.volumeParam.ioVolIndex = i;
- volErr = PBHGetVInfo(&volPB, false);
-
- if (!volErr) {
- volRefNum = volPB.volumeParam.ioVRefNum;
- aDTPBRec.ioNamePtr = name;
- aDTPBRec.ioVRefNum = volRefNum;
- /* Get Desktop File Database reference for the volume. */
-
- err2 = PBDTGetPath(&aDTPBRec);
- if (!err2) {
- dtRefNum = aDTPBRec.ioDTRefNum;
- aDTPBRec.ioCompletion = nil;
- aDTPBRec.ioNamePtr = name;
- aDTPBRec.ioDTRefNum = dtRefNum;
- aDTPBRec.ioIndex = 0; /* Find most recent. */
- aDTPBRec.ioFileCreator = signature;
- err = PBDTGetAPPL(&aDTPBRec, false); /* Search the desktop database for the application. */
- /* If found, return FSSpec specifying where it is. */
- if (!err)
- err = FSMakeFSSpec(volRefNum,aDTPBRec.ioAPPLParID,aDTPBRec.ioNamePtr,aFSSpec);
- }
- }
- } /* while */
-
- return err;
- }
-
- /****************************************************************************/
-
-
- /*
- * PULaunchApp launches the application corresponding to the given fsspec.
- */
- OSErr PULaunchApp (FSSpec *aFSSpec)
- {
- OSErr err;
- LaunchParamBlockRec myLaunchParams;
-
- myLaunchParams.launchBlockID = extendedBlock;
- myLaunchParams.launchEPBLength = extendedBlockLen;
- myLaunchParams.launchFileFlags = 0;
- myLaunchParams.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
- myLaunchParams.launchAppSpec = aFSSpec;
- myLaunchParams.launchAppParameters = nil;
- err = LaunchApplication(&myLaunchParams);
-
- return err;
- }
-
- /****************************************************************************/
-
-
- /* PULaunchAppWithSignature looks for an application with the given signature
- * on a mounted volume and if it finds it tries to launch it. If all goes well,
- * noErr is returned. If the app couldn't be found or launched then a non-noErr
- * value is returned.
- */
-
-
- OSErr PULaunchAppWithSignature (ResType serviceSignature)
- {
-
- FSSpec aFSSpec;
- OSErr err;
-
- err = PUFindApp(serviceSignature, &aFSSpec);
-
- if (!err)
- err = PULaunchApp(&aFSSpec);
-
- return err;
- }
-
- /****************************************************************************/
-
-
- OSErr PUFindLocalProcess (OSType processSignature,
- Boolean launchIfCan,
- LocationNameRec *theLocation,
- PortInfoRec *thePortInfo)
- {
- PPCPortRec myPortName;
- PortInfoRec myPortInfo;
- Boolean found = false;
- short index = 0;
- IPCListPortsPBPtr thePB = (IPCListPortsPBPtr)NewPtrClear(sizeof(IPCListPortsPBRec));
- OSErr err = MemError();
-
-
- /* Exit immedieately if couldn't allocte param block. */
- if (err)
- return err;
-
-
- /* Check local machine for process with given signature. */
-
- /* Match any port. We could match just ports with given signature and a given type,
- * but then we'd either have to assume the system always gives applications a type
- * of 'ep10' (which might not be true in the future) or we'd have to have services
- * explicitly open their ports using PPCOpenPort, providing their type (which will
- * usually by 'APPL'. It's easier just to look through all available local ports, looking
- * for a port with creator equal to the processSignature we're looking for.
- * We could also use the serviceName to determine the port, but then if we decided to
- * change the name of a service (e.g. "DECTalk Service" to "Talker Server") then
- * we'd have to recompile E.T. One is much less likely to change the services type.
- */
- while ((!err) && (!found)) {
- myPortName.nameScript = 0;
- myPortName.name[1] = '=';
- myPortName.name[0] = 1;
- myPortName.portKindSelector = ppcByString;
- myPortName.u.portTypeStr[1] = '=';
- myPortName.u.portTypeStr[0] = 1;
-
- thePB->ioCompletion = nil;
- thePB->startIndex = index;
- thePB->requestCount = 1;
- thePB->portName = &myPortName;
- thePB->locationName = nil;
- thePB->bufferPtr = &myPortInfo;
-
- err = IPCListPorts(thePB, FALSE);
- if (!err)
- if (thePB->actualCount <= 0)
- err = PROCESS_NOT_FOUND_ERR; /* Return PROCESS_NOT_FOUND_ERR if port not found. */
- else
- found = (((myPortName.portKindSelector == ppcByCreatorAndType) && (myPortInfo.name.u.port.portCreator == processSignature)) ||
- ((myPortName.portKindSelector == ppcByString) && (*(OSType *)(myPortInfo.name.u.portTypeStr + 1) == processSignature)));
-
- ++index;
- }
-
- /* Cleanup. */
- DisposPtr((Ptr)thePB);
-
-
- /* If we found the correct service process, return its location and name. */
- if (found) {
- ClearEvenSizeBlock(theLocation, sizeof(LocationNameRec)); /* Clear location means local machine. */
- BlockMove((Ptr)&myPortInfo, (Ptr)thePortInfo, sizeof(PortInfoRec));
- err = noErr;
- }
-
-
- /* Couldn't find running process. See if can find app on mounted volume and launch it. */
- if ((!found) && (launchIfCan)) {
- /* Try to launch application. */
- err = PULaunchAppWithSignature(processSignature);
-
- /* Call PUFindLocalProcess again to get location of newly launched app. */
- if (!err)
- err = PUFindLocalProcess(processSignature, false, theLocation, thePortInfo);
-
- found = (!err);
- }
-
- return err;
- }
-
- /*****************************************************************************************/
-
- OSErr PUSendAppleEventWith2Params(long sessionID,
- OSType signature,
- LocationNameRec *theLocation,
- PortInfoRec *thePortInfo,
- AEEventClass eventClass,
- AEEventID eventID,
- AEKeyword keyWord1,
- DescType dataType1,
- void *dataPtr1,
- Size dataSize1,
- AEKeyword keyWord2,
- DescType dataType2,
- void *dataPtr2,
- Size dataSize2,
- Boolean waitForReply,
- long timeOut,
- AppleEvent *theReply)
- {
- OSErr err,err2;
- TargetID theTargetID;
- AppleEvent theAevt;
- AEAddressDesc theTarget;
- AESendMode sendMode;
-
- if (sessionID != 0) {
- err = AECreateDesc(typeSessionID, (Ptr) &sessionID, (Size)sizeof(sessionID), &theTarget);
- } else if ((long)signature != 0) {
- err = AECreateDesc(typeApplSignature, (Ptr) &signature, (Size)sizeof(signature), &theTarget);
- } else {
- theTargetID.location = *theLocation;
- theTargetID.name = thePortInfo->name;
- err = AECreateDesc(typeTargetID, (Ptr) &theTargetID, (Size)sizeof(theTargetID), &theTarget);
- }
-
- if (err == noErr)
- err = AECreateAppleEvent(eventClass, eventID, &theTarget, kAutoGenerateReturnID, kAnyTransactionID, &theAevt);
-
- if ((err == noErr) && (dataPtr1 != 0))
- err = AEPutParamPtr(&theAevt, keyWord1, dataType1, (Ptr) dataPtr1, dataSize1);
-
- if ((err == noErr) && (dataPtr2 != 0))
- err = AEPutParamPtr(&theAevt, keyWord2, dataType2, (Ptr) dataPtr2, dataSize2);
-
- if (waitForReply)
- sendMode = kAEWaitReply;
- else
- sendMode = kAENoReply;
-
- if (err == noErr)
- err = AESend(&theAevt, theReply, sendMode, kAENormalPriority, timeOut, (AEIdleUPP)0, (AEFilterUPP)0);
-
- /* Get rid of structures */
- err2 = AEDisposeDesc(&theAevt);
- err2 = AEDisposeDesc(&theTarget);
-
- return(err);
- }
-
- /*****************************************************************************************/
-
- OSErr PUSendAppleEventWith1Param(LocationNameRec *theLocation,
- PortInfoRec *thePortInfo,
- AEEventClass eventClass,
- AEEventID eventID,
- DescType dataType,
- void *dataPtr,
- Size dataSize)
- {
- return PUSendAppleEventWith2Params(0, (OSType)0, theLocation, thePortInfo, eventClass, eventID,
- keyDirectObject, dataType, dataPtr, dataSize, keyDirectObject, (DescType)0,nil,(Size)0,
- false, 0, NULL);
- }
-
- /*****************************************************************************************/
-
- OSErr PUSendAppleEventWith1ParamAndWait(LocationNameRec *theLocation,
- PortInfoRec *thePortInfo,
- AEEventClass eventClass,
- AEEventID eventID,
- DescType dataType,
- void *dataPtr,
- Size dataSize,
- long timeout,
- AppleEvent *theReply)
- {
- return PUSendAppleEventWith2Params(0, (OSType)0, theLocation, thePortInfo, eventClass, eventID,
- keyDirectObject, dataType, dataPtr, dataSize, keyDirectObject, (DescType)0,nil,(Size)0,
- true, timeout, theReply);
-
- }
-
- /*****************************************************************************************/
-