home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Utilities.c
-
- Contains: Location Manager SDK Sample Module handy routines
-
- Version: ALM SDK 2.0
- Package: Location Manager SDK 2.0
-
- Copyright: © 1996-1997 by Apple Computer, Inc.
- All rights reserved.
-
- Bugs?: Please include the the file and version information (from above) with
- the problem description. Developers belonging to one of the Apple
- developer programs can submit bug reports to:
-
- devsupport@apple.com
-
- */
-
- // -------------------------------------------------------------------------------------------------
-
- // Module Include...
-
- #include "Utilities.h"
-
- // Project Includes...
-
- #include "APLocation.h"
-
- // Connectix includes
-
- #include "MacOS_ConnectixUtils.h"
- #include "MacOS_UAppleEvents.h"
-
- // MacOS Includes...
-
- #include <ASRegistry.h>
- #include <FSM.h>
- #include <Folders.h>
- #include <Gestalt.h>
- #include <LowMem.h>
- #include <PLStringFuncs.h>
- #include <Resources.h>
- #include <Script.h>
- #include <Timer.h>
-
- // ANSI Includes...
-
- #include <string.h>
- #include <stdio.h>
-
- // -------------------------------------------------------------------------------------------------
-
- // Readability Constants...
-
- #define kInvalidRefNum (-1)
- #define kUseSetting false
- #define kReadSetting true
- #define kNoIdleProc NULL
- #define kNoFilterProc NULL
- #define kTimeToQuit (10*60) // 10 seconds to quit...
- #define kDontUseIndex 0
- #define kNoFileName "\p"
- #define kUseVRefNumOnly NULL
- #define kExtractFileFlagsFromFinder 0
- #define kGetMostRecentlyCreatedMatch 0
-
- // Expressive Macros...
-
- #define ShareTime() { EventRecord e; WaitNextEvent (0, &e, 1, NULL); }
- #define EmptyAEDesc(desc) { desc.descriptorType = typeNull; \
- desc.dataHandle = NULL; }
- #define SetFirstProcess(psn) { psn.highLongOfPSN = 0; \
- psn.lowLongOfPSN = kNoProcess; }
-
- // -------------------------------------------------------------------------------------------------
-
- // Local prototypes...
-
- static OSErr
- SetPower(Boolean inPowerOn);
-
- static OSErr
- JoinNetwork(ConstStr255Param inNetwork);
-
- static OSErr
- SendQuitApplication (Boolean* wasOpen, OSType creator);
- // Send a "quit" AppleEvent to the application whose creator is given...
-
- static OSErr
- LaunchIt (ConstFSSpecPtr theApplication, LaunchFlags theFlags);
- // Launch the specified application with the specified flags...
-
- static Boolean
- FindProcessByCreator (ProcessSerialNumber* psn, OSType creator);
- // Given a creator code, return the process serial number of the first matching process...
-
- static Boolean
- ProcessManagerAvailable (void);
- // Good way to tell if it's INIT time...
-
- static Boolean
- ProcessBecameInvalid (ProcessSerialNumber* psn, UInt32 timeoutInTicks);
- // Little routine to wait for a process to quit (since we can't wait for a reply
- // event)...
-
- // -------------------------------------------------------------------------------------------------
-
- static void
- WaitTicks(
- long inTicks)
- {
- long startTime = TickCount();
- while (TickCount() < startTime + inTicks)
- ShareTime();
- }
-
-
- /*------------------------------------------------------------------
- UseSetting
- ------------------------------------------------------------------*/
-
- extern OSErr
- UseSetting(
- GlobalsHandle inGlobals,
- APSettingHandle inOldSetting,
- APSettingHandle inNewSetting,
- ALMRebootFlags * inFlags)
- {
- OSErr err;
-
- // fix me - verify settings version
-
- // Launch "AirPort Scripting" and join the specified network.
- err = LaunchAPScripting();
- require(err == noErr, LaunchAPScriptingFailed);
-
- check((**inNewSetting).version == 'nheg');
-
- if ((**inOldSetting).powerOn != (**inNewSetting).powerOn)
- {
- err = SetPower((**inNewSetting).powerOn);
- require(err == noErr, SetPowerFailed);
-
- if ((**inNewSetting).powerOn)
- {
- // This is ugly, but "AirPort Scripting" is uglier.
- WaitTicks(5 * 60);
- }
- }
-
- if ((**inNewSetting).powerOn)
- {
- err = JoinNetwork((**inNewSetting).network);
- require(err == noErr, JoinNetworkFailed);
-
- // Let things settle down before moving on.
- WaitTicks(60);
- }
-
- LaunchAPScriptingFailed:
- SetPowerFailed:
- JoinNetworkFailed:
- return err;
- }
-
-
- /*------------------------------------------------------------------
- ReadSetting
- ------------------------------------------------------------------*/
-
- OSErr
- ReadSetting(
- GlobalsHandle inGlobals,
- APSettingHandle inSetting)
- {
- OSErr err;
-
- LaunchAPScripting();
-
- SetHandleSize(reinterpret_cast<Handle>(inSetting), sizeof(APSettingRec));
-
- // Save our cookie/version.
- (**inSetting).version = 'nheg';
-
- AEAppleEvent getEvent(kAECoreSuite, kAEGetData, '1wse');
- AEAppleEvent reply;
- AEDescriptor cardDesc;
-
- // Create descriptor for "card 1".
- err = ::CreateIndexObjectSpecifier('cair', &kAENullDescriptor, 1, &cardDesc);
- require(err == noErr, FatalError);
-
- // Find out if the card is on.
- {
- AEDescriptor powerDesc;
- Boolean powerOn;
-
- // Create descriptor for "power of card 1".
- err = CreatePropertyObjectSpecifier(cProperty, &cardDesc, '42po', &powerDesc);
- require(err == noErr, FatalError);
-
- err = getEvent.PutParameterDesc(keyDirectObject, powerDesc);
- require(err == noErr, FatalError);
-
- err = getEvent.Send(reply, kAEWaitReply);
- require(err == noErr, FatalError);
-
- err = reply.GetParameter(keyDirectObject, (**inSetting).powerOn);
- require_action(err == noErr, GetParameterFailed, err = GetAEErrorNumber(&reply););
- }
-
- // If the power was on, get the network name.
- if ((**inSetting).powerOn)
- {
- AEDescriptor networkDesc;
- AEDescriptorRecord networkRec;
-
- // Create descriptor for "network of card 1"
- err = ::CreatePropertyObjectSpecifier(cProperty, &cardDesc, 'cwir', &networkDesc);
- require(err == noErr, FatalError);
-
- err = getEvent.PutParameterDesc(keyDirectObject, networkDesc);
- require(err == noErr, FatalError);
-
- err = getEvent.Send(reply, kAEWaitReply);
- require(err == noErr, FatalError);
-
- err = reply.GetParameterDesc(keyDirectObject, typeAERecord, networkRec);
- require(err == noErr, FatalError);
-
- // Extract the name from the returned network object.
- err = networkRec.GetPStringKey('42nm', (**inSetting).network);
- require_action(err == noErr, GetPStringKeyFailed, err = GetAEErrorNumber(&reply););
- }
-
- FatalError:
- GetParameterFailed:
- GetPStringKeyFailed:
- return err;
- }
-
-
- // -------------------------------------------------------------------------------------------------
-
- extern void
- InsParamStr (StringPtr matchThis, StringPtr replaceWithThis, StringPtr replaceInThis) {
-
- UInt8 matchLen = StrLength (matchThis);
- UInt8 replaceLen = StrLength (replaceWithThis);
- UInt8 replaceInLen = StrLength (replaceInThis);
- Ptr matchPtr;
- Str255 tempStr;
-
- matchPtr = PLstrstr (replaceInThis, matchThis);
- PLstrcpy (tempStr, replaceInThis);
-
- if (matchPtr != NULL) {
-
- UInt8 matchPos = (UInt32) matchPtr - (UInt32) replaceInThis;
- UInt8 contPos = matchPos + matchLen;
- UInt8 frontLen = matchPos - 1;
- UInt8 backLen = replaceInLen - frontLen - matchLen;
-
- BlockMoveData (&replaceWithThis[1], &replaceInThis[matchPos], replaceLen);
- BlockMoveData (&tempStr[contPos], &replaceInThis[frontLen + replaceLen + 1], backLen);
- replaceInThis[0] = ((UInt32) replaceInLen - (UInt32) matchLen + (UInt32) replaceLen);
-
- } // if
-
- } // InsParamStr
-
- // -------------------------------------------------------------------------------------------------
-
- /*------------------------------------------------------------------
- SetPower
- ------------------------------------------------------------------*/
-
- OSErr
- SetPower(
- Boolean inPowerOn)
- {
- OSErr err = noErr;
-
- Boolean powerOn = inPowerOn;
- AEAppleEvent setEvent(kAECoreSuite, kAESetData, '1wse');
- AEDescriptor cardDesc;
- AEDescriptor powerDesc;
- AEDescriptor powerOnDesc(inPowerOn ? typeTrue : typeFalse, NULL, 0);
-
- // Create the descriptor for "card 1".
- err = CreateIndexObjectSpecifier('cair', &kAENullDescriptor, 1, &cardDesc);
- require(err == noErr, FatalError);
-
- // Create descriptor for "power of card 1".
- err = CreatePropertyObjectSpecifier(cProperty, &cardDesc, '42po', &powerDesc);
- require(err == noErr, FatalError);
-
- err = setEvent.PutParameterDesc(keyDirectObject, powerDesc);
- require(err == noErr, PutParameterDescFailed);
-
- err = setEvent.PutParameterDesc(keyAEData, powerOnDesc);
- require(err == noErr, PutParameterDescFailed);
-
- err = setEvent.Send(kAEWaitReply);
- require(err == noErr, SendFailed);
-
- FatalError:
- AssignFailed:
- PutParameterDescFailed:
- SendFailed:
- return err;
- }
-
-
- /*------------------------------------------------------------------
- JoinNetwork
- ------------------------------------------------------------------*/
-
- OSErr
- JoinNetwork(
- ConstStr255Param inNetwork)
- {
- OSErr err = noErr;
-
- AEAppleEvent joinEvent('aeAP', 'aeJN', '1wse');
- AEDescriptor nameDesc(typeText, &inNetwork[1], inNetwork[0]);
-
- err = joinEvent.PutParameterDesc(keyDirectObject, nameDesc);
- require(err == noErr, AEPutParamDescFailed);
-
- err = joinEvent.Send(kAEWaitReply);
- require(err == noErr, AESendFailed);
-
- AEPutParamDescFailed:
- AESendFailed:
- return err;
- }
-
-
- /*------------------------------------------------------------------
- LaunchAP
- ------------------------------------------------------------------*/
-
- OSErr
- LaunchAP()
- {
- OSErr err = noErr;
- FSSpec appl = {0};
-
- err = FindFolderItemByTypeAndCreator(kOnSystemDisk, kAppleMenuFolderType, false, 'APPL', '1wna', &appl);
- require(err == noErr, FindFolderFailed);
-
- err = LaunchIt(&appl, launchContinue | launchNoFileFlags);
- require(err == noErr, LaunchItFailed);
-
- FindFolderFailed:
- LaunchItFailed:
- return err;
- }
-
-
- /*------------------------------------------------------------------
- LaunchAPScripting
- ------------------------------------------------------------------*/
-
- OSErr
- LaunchAPScripting()
- {
- OSErr err = noErr;
- FSSpec appl = {0};
-
- err = FindFolderItemByTypeAndCreator(kOnSystemDisk, kScriptingAdditionsFolderType, false, 'APPL', '1wse', &appl);
- require(err == noErr, FindFolderFailed);
-
- err = LaunchIt(&appl, launchContinue | launchNoFileFlags | launchDontSwitch);
- require(err == noErr, LaunchItFailed);
-
- FindFolderFailed:
- LaunchItFailed:
- return err;
- }
-
-
- /*------------------------------------------------------------------
- QuitAPScripting
- ------------------------------------------------------------------*/
-
- OSErr
- QuitAPScripting()
- {
- ProcessSerialNumber psn = {0};
-
- // Make sure the process is running because this might
- // get called during startup.
- if (FindProcessByCreator(&psn, '1wse'))
- {
- // fix me - should wait several seconds
- #if 0
- Boolean wasOpen;
-
- SendQuitApplication(&wasOpen, '1wse');
- check(wasOpen);
- #endif
- }
-
- return noErr;
- }
-
- /*------------------------------------------------------------------
- SendQuitApplication
- ------------------------------------------------------------------*/
-
- static OSErr
- SendQuitApplication (Boolean* wasOpen, OSType creator) {
-
- OSErr err = noErr;
- ProcessSerialNumber applicationPSN;
- AEAddressDesc applicationAddr;
- AppleEvent quitEvent;
- AppleEvent theReply;
-
- EmptyAEDesc (applicationAddr);
- EmptyAEDesc (quitEvent);
- EmptyAEDesc (theReply);
-
- // Find a process matching the creator, if any; if it is found, send it an
- // AppleEvent to quit (it does support the core suite, right?)...
-
- *wasOpen = FindProcessByCreator (&applicationPSN, creator);
-
- if (*wasOpen) {
- if (err == noErr) {
- err = AECreateDesc (typeProcessSerialNumber, &applicationPSN,
- sizeof (applicationPSN), &applicationAddr);
- } // if
- if (err == noErr) {
- err = AECreateAppleEvent (kCoreEventClass, kAEQuitApplication,
- &applicationAddr, kAutoGenerateReturnID, kAnyTransactionID,
- &quitEvent);
- } // if
- if (err == noErr) {
- err = AESend (&quitEvent, &theReply, kAENoReply | kAENeverInteract,
- kAEHighPriority, kAEDefaultTimeout, kNoIdleProc,
- kNoFilterProc);
- } // if
- if (err == noErr) {
- if (!ProcessBecameInvalid (&applicationPSN, kTimeToQuit)) {
- err = kSampleCouldNotQuitIdx; // We'll tell the user we tried...
- } // if
- } // if
- } // if
-
- (void) AEDisposeDesc (&applicationAddr);
- (void) AEDisposeDesc (&quitEvent);
-
- return err;
-
- } // SendQuitApplication
-
- // -------------------------------------------------------------------------------------------------
-
- static OSErr
- LaunchIt (ConstFSSpecPtr theApplication, LaunchFlags theFlags) {
-
- OSErr err = noErr;
- LaunchParamBlockRec lpb = {0};
-
- lpb.launchBlockID = extendedBlock;
- lpb.launchEPBLength = extendedBlockLen;
- lpb.launchFileFlags = kExtractFileFlagsFromFinder;
- lpb.launchControlFlags = theFlags;
- lpb.launchAppSpec = (FSSpecPtr) theApplication;
-
- err = LaunchApplication (&lpb);
-
- return err;
-
- } // LaunchIt
-
- // -------------------------------------------------------------------------------------------------
-
- static Boolean
- FindProcessByCreator (ProcessSerialNumber* psn, OSType creator) {
-
- OSErr err = noErr;
- Boolean found = false;
- ProcessInfoRec curProcessInfo;
- ProcessSerialNumber curPSN;
-
- SetFirstProcess (curPSN);
-
- // If we're running at INIT time, none of this will work (and we don't need to
- // do it anyway!), so
-
- if (ProcessManagerAvailable ()) {
-
- do {
- curProcessInfo.processInfoLength = sizeof (curProcessInfo);
- curProcessInfo.processName = NULL;
- curProcessInfo.processAppSpec = NULL;
- if (err == noErr) {
- err = GetNextProcess (&curPSN);
- } // if
- if (err == noErr) {
- err = GetProcessInformation (&curPSN, &curProcessInfo);
- } // if
- if (err == noErr) {
- if (curProcessInfo.processSignature == creator) {
- *psn = curPSN;
- found = true;
- break;
- } // if
- } // if
- } while (err == noErr);
-
- } // if
-
- return found;
-
- } // FindProcessByCreator
-
- // -------------------------------------------------------------------------------------------------
-
- static Boolean
- ProcessManagerAvailable (void) {
-
- OSErr err;
- SInt32 response;
- Boolean reply;
-
- err = Gestalt (gestaltOSAttr, &response);
-
- reply = (err == noErr) && (response & (1 << gestaltLaunchControl));
-
- return reply;
-
- } // ProcessManagerAvailable
-
- // -------------------------------------------------------------------------------------------------
-
- static Boolean
- ProcessBecameInvalid (ProcessSerialNumber* psn, UInt32 timeoutInTicks) {
-
- OSErr err = noErr;
- Boolean stillAround = true;
- UInt32 startTime = LMGetTicks ();
- UInt32 curTime = startTime;
- UInt32 endTime = startTime + timeoutInTicks;
- ProcessInfoRec processInfo;
-
- // Wait around, being background friendly, for the specified process to
- // terminate...
-
- do {
- ShareTime ();
- if (err == noErr) {
- processInfo.processInfoLength = sizeof (processInfo);
- processInfo.processName = NULL;
- processInfo.processAppSpec = NULL;
- err = GetProcessInformation (psn, &processInfo);
- if ((err == paramErr) || (err == procNotFound)) {
- stillAround = false;
- break;
- } // if
- } // if
- curTime = LMGetTicks ();
- } while (curTime < endTime);
-
- return !stillAround;
-
- } // ProcessBecameInvalid
-
-