///////////////////////////////////////////////////////////////////////////// // ObjectARX EntryPoint extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt) { AcRxDynamicLinker *pLinker = acrxDynamicLinker; switch (msg) { case AcRx::kInitAppMsg: // Comment out the following line if your // application should be locked into memory pLinker->unlockApplication(pkt); pLinker->registerAppMDIAware(pkt); // check if the arx app is loaded or not. // if not, load it as UI so that we won't have // proxy if this dll is unloaded by OS if (!isModuleLoaded("AsdkSmileyDb.dbx")) { if (!pLinker->loadModule("AsdkSmileyDb.dbx", false, true)) return AcRx::kRetError; } // bump the reference count pLinker->loadModule("AsdkSmileyDb.dbx", false, false); InitApplication(); break; case AcRx::kUnloadAppMsg: pLinker->unloadModule("AsdkSmileyDb.dbx"); UnloadApplication(); break; } return AcRx::kRetOK; }
// Check to see if module has been loaded already. bool IOCatalogue::isModuleLoaded(OSDictionary * driver) const { OSString * moduleName = NULL; OSString * publisherName = NULL; if ( !driver ) return false; /* The personalities of codeless kexts often contain the bundle ID of the * kext they reference, and not the bundle ID of the codeless kext itself. * The prelinked kernel needs to know the bundle ID of the codeless kext * so it can include these personalities, so OSKext stores that bundle ID * in the IOPersonalityPublisher key, and we record it as requested here. */ publisherName = OSDynamicCast(OSString, driver->getObject(kIOPersonalityPublisherKey)); OSKext::recordIdentifierRequest(publisherName); moduleName = OSDynamicCast(OSString, driver->getObject(gIOModuleIdentifierKey)); if ( moduleName ) return isModuleLoaded(moduleName); /* If a personality doesn't hold the "CFBundleIdentifier" key * it is assumed to be an "in-kernel" driver. */ return true; }
/* Starts a CBE Experiment */ int startExp() { if (is_root() && isModuleLoaded()) { char command[100]; sprintf(command, "%c", START_EXP); send_to_timekeeper(command); return 0; } return 1; }
/* Takes an integer (pid of the process). This function will essentially 'freeze' the time of the process. It does this by sending a sigstop signal to the process. */ int freeze(int pid) { if (is_root() && isModuleLoaded()) { char command[100]; sprintf(command, "%c,%d,%d", FREEZE_OR_UNFREEZE, pid, SIGSTOP); send_to_timekeeper(command); return 1; } return -1; }
/* Same as unfreeze, except that it will unfreeze the process as well as all of its children. */ int unfreeze_all(int pid) { if (is_root() && isModuleLoaded()) { char command[100]; sprintf(command, "%c,%d,%d", FREEZE_OR_UNFREEZE_ALL, pid, SIGCONT); if (send_to_timekeeper(command) == -1) return -1; return 0; } return -1; }
/* Stop a running experiment (CBE or CS) **Do not call stopExp if you are waiting for a s3fProgress to return!!** */ int stopExp() { if (is_root() && isModuleLoaded()) { char command[100]; sprintf(command, "%c", STOP_EXP); if (send_to_timekeeper(command) == -1) return -1; return 0; } return -1; }
/* Reset all pre-specifed intervals for a given timeline (CS) */ int reset(int timeline) { if (is_root() && isModuleLoaded()) { char command[100]; sprintf(command, "%c,%d", RESET, timeline); if (send_to_timekeeper(command) == -1) return -1; return 0; } return -1; }
/* Set the interval in which a pid in a given timeline should advance (microsends) (CS) */ int setInterval(int pid, int interval, int timeline) { if (is_root() && isModuleLoaded()) { char command[100]; sprintf(command, "%c,%d,%d,%d", SET_INTERVAL, pid, interval, timeline); if (send_to_timekeeper(command) == -1) return -1; return 0; } return -1; }
/* Given all Pids added to experiment, will set all their virtual times to be the same, then freeze them all (CBE and CS) */ int synchronizeAndFreeze() { if (is_root() && isModuleLoaded()) { char command[100]; sprintf(command, "%c", SYNC_AND_FREEZE); if (send_to_timekeeper(command) == -1) return -1; return 0; } return -1; }
//Given a frozen process specified by PID, will advance it's virtual time by interval (microseconds) int leap(int pid, int interval) { if (is_root() && isModuleLoaded()) { char command[100]; if (interval > 0) { sprintf(command, "%c,%d,%d", LEAP, pid, interval); if (send_to_timekeeper(command) == -1) return -1; return 0; } } return -1; }
/* Given a pid, add that container to an experiment. If the timeline is less than 0, add to a CBE experiment else, it represents a specific timeline */ int addToExp(int pid, int timeline) { if (is_root() && isModuleLoaded()) { char command[100]; if (timeline < 0) { sprintf(command, "%c,%d", ADD_TO_EXP_CBE, pid); } else { sprintf(command, "%c,%d,%d", ADD_TO_EXP_CS, pid, timeline); } if (send_to_timekeeper(command) == -1) return -1; return 0; } return -1; }
/* Will set the TDF of a LXC and all of its children */ int dilate_all(int pid, double dilation) { if (is_root() && isModuleLoaded()) { char command[100]; int dil; if ( (dil = fixDilation(dilation)) == -1) { return -1; } printf("Trying to create dilation %d from %f\n",dil, dilation); if (dil < 0) { sprintf(command, "%c,%d,1,%d", DILATE_ALL, pid, dil*-1); } else { sprintf(command, "%c,%d,%d", DILATE_ALL, pid, dil); } if (send_to_timekeeper(command) == -1) return -1; return 0; } return -1; }
bool IOCatalogue::isModuleLoaded(OSString * moduleName) const { return isModuleLoaded(moduleName->getCStringNoCopy()); }
bool IOCatalogue::resetAndAddDrivers(OSArray * drivers, bool doNubMatching) { bool result = false; OSArray * newPersonalities = NULL; // do not release OSCollectionIterator * iter = NULL; // must release OSOrderedSet * matchSet = NULL; // must release const OSSymbol * key; OSArray * array; OSDictionary * thisNewPersonality = NULL; // do not release OSDictionary * thisOldPersonality = NULL; // do not release signed int idx, newIdx; if (drivers) { newPersonalities = OSDynamicCast(OSArray, drivers); if (!newPersonalities) { goto finish; } matchSet = OSOrderedSet::withCapacity(10, IOServiceOrdering, (void *)gIOProbeScoreKey); if (!matchSet) { goto finish; } iter = OSCollectionIterator::withCollection(personalities); if (!iter) { goto finish; } } result = true; IOLog("Resetting IOCatalogue.\n"); /* No goto finish from here to unlock. */ IORWLockWrite(lock); while ((key = (const OSSymbol *) iter->getNextObject())) { array = (OSArray *) personalities->getObject(key); if (!array) continue; for (idx = 0; (thisOldPersonality = (OSDictionary *) array->getObject(idx)); idx++) { if (thisOldPersonality->getObject("KernelConfigTable")) continue; if (newPersonalities) for (newIdx = 0; (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx)); newIdx++) { /* Unlike in other functions, this comparison must be exact! * The catalogue must be able to contain personalities that * are proper supersets of others. * Do not compare just the properties present in one driver * pesonality or the other. */ if (thisNewPersonality->isEqualTo(thisOldPersonality)) break; } if (thisNewPersonality) { // dup, ignore newPersonalities->removeObject(newIdx); } else { // not in new set - remove // only remove dictionary if this module in not loaded - 9953845 if ( isModuleLoaded(thisOldPersonality) == false ) { if (matchSet) matchSet->setObject(thisOldPersonality); array->removeObject(idx); idx--; } } } } // add new for (newIdx = 0; (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx)); newIdx++) { OSKext::uniquePersonalityProperties(thisNewPersonality); addPersonality(thisNewPersonality); matchSet->setObject(thisNewPersonality); } /* Finally, start device matching on all new & removed personalities. */ if (result && doNubMatching && (matchSet->getCount() > 0)) { IOService::catalogNewDrivers(matchSet); generation++; } IORWLockUnlock(lock); finish: if (matchSet) matchSet->release(); if (iter) iter->release(); return result; }