SCPreferencesRef SCPreferencesCreateWithOptions(CFAllocatorRef allocator, CFStringRef name, CFStringRef prefsID, AuthorizationRef authorization, CFDictionaryRef options) { CFDataRef authorizationData = NULL; SCPreferencesPrivateRef prefsPrivate; if (options != NULL) { if (!isA_CFDictionary(options)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } } if (authorization != NULL) { CFMutableDictionaryRef authorizationDict; CFBundleRef bundle; CFStringRef bundleID = NULL; authorizationDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); #if !TARGET_OS_IPHONE if (authorization != kSCPreferencesUseEntitlementAuthorization) { CFDataRef data; AuthorizationExternalForm extForm; OSStatus os_status; os_status = AuthorizationMakeExternalForm(authorization, &extForm); if (os_status != errAuthorizationSuccess) { SCLog(TRUE, LOG_INFO, CFSTR("_SCHelperOpen AuthorizationMakeExternalForm() failed")); _SCErrorSet(kSCStatusInvalidArgument); CFRelease(authorizationDict); return NULL; } data = CFDataCreate(NULL, (const UInt8 *)extForm.bytes, sizeof(extForm.bytes)); CFDictionaryAddValue(authorizationDict, kSCHelperAuthAuthorization, data); CFRelease(data); } #endif /* get the application/executable/bundle name */ bundle = CFBundleGetMainBundle(); if (bundle != NULL) { bundleID = CFBundleGetIdentifier(bundle); if (bundleID != NULL) { CFRetain(bundleID); } else { CFURLRef url; url = CFBundleCopyExecutableURL(bundle); if (url != NULL) { bundleID = CFURLCopyPath(url); CFRelease(url); } } if (bundleID != NULL) { if (CFEqual(bundleID, CFSTR("/"))) { CFRelease(bundleID); bundleID = NULL; } } } if (bundleID == NULL) { bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("Unknown(%d)"), getpid()); } CFDictionaryAddValue(authorizationDict, kSCHelperAuthCallerInfo, bundleID); CFRelease(bundleID); if (authorizationDict != NULL) { _SCSerialize((CFPropertyListRef)authorizationDict, &authorizationData, NULL, NULL); CFRelease(authorizationDict); } } prefsPrivate = __SCPreferencesCreate(allocator, name, prefsID, authorizationData, options); if (authorizationData != NULL) CFRelease(authorizationData); return (SCPreferencesRef)prefsPrivate; }
__private_extern__ Boolean __SCPreferencesCreate_helper(SCPreferencesRef prefs) { CFDataRef data = NULL; CFMutableDictionaryRef info; CFNumberRef num; Boolean ok; SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; uint32_t status = kSCStatusOK; CFStringRef str; uint32_t pid = getpid(); // start helper ok = _SCHelperOpen(prefsPrivate->authorizationData, &prefsPrivate->helper_port); if (!ok) { goto fail; } // create a dictionary of information to pass to the helper info = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // save prefsID if (prefsPrivate->prefsID != NULL) { CFDictionarySetValue(info, CFSTR("prefsID"), prefsPrivate->prefsID); } // save options if (prefsPrivate->options != NULL) { CFDictionarySetValue(info, CFSTR("options"), prefsPrivate->options); } // save preferences session "name" CFDictionarySetValue(info, CFSTR("name"), prefsPrivate->name); // save PID num = CFNumberCreate(NULL, kCFNumberSInt32Type, &pid); CFDictionarySetValue(info, CFSTR("PID"), num); CFRelease(num); // save process name str = CFStringCreateWithCString(NULL, getprogname(), kCFStringEncodingUTF8); CFDictionarySetValue(info, CFSTR("PROC_NAME"), str); CFRelease(str); // serialize the info ok = _SCSerialize(info, &data, NULL, NULL); CFRelease(info); if (data == NULL || !ok) { goto fail; } // have the helper "open" the prefs ok = _SCHelperExec(prefsPrivate->helper_port, SCHELPER_MSG_PREFS_OPEN, data, &status, NULL); if (data != NULL) CFRelease(data); if (!ok) { goto fail; } if (status != kSCStatusOK) { goto error; } return TRUE; fail : // close helper if (prefsPrivate->helper_port != MACH_PORT_NULL) { _SCHelperClose(&prefsPrivate->helper_port); } status = kSCStatusAccessError; error : // return error _SCErrorSet(status); return FALSE; }
static Boolean __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) { kern_return_t kr = KERN_SUCCESS; CFDataRef myName; /* serialized name */ xmlData_t myNameRef; CFIndex myNameLen; CFDataRef myOptions = NULL; /* serialized options */ xmlData_t myOptionsRef = NULL; CFIndex myOptionsLen = 0; int sc_status = kSCStatusFailed; mach_port_t server; if (!_SCSerializeString(storePrivate->name, &myName, (void **)&myNameRef, &myNameLen)) { goto done; } /* serialize the options */ if (storePrivate->options != NULL) { if (!_SCSerialize(storePrivate->options, &myOptions, (void **)&myOptionsRef, &myOptionsLen)) { CFRelease(myName); goto done; } } /* open a new session with the server */ server = MACH_PORT_NULL; updateServerPort(storePrivate, &server, &sc_status); while (server != MACH_PORT_NULL) { // if SCDynamicStore server available if (!storePrivate->serverNullSession) { // if SCDynamicStore session kr = configopen(server, myNameRef, (mach_msg_type_number_t)myNameLen, myOptionsRef, (mach_msg_type_number_t)myOptionsLen, &storePrivate->server, (int *)&sc_status); } else { // if NULL session if (storePrivate->server == MACH_PORT_NULL) { // use the [main] SCDynamicStore server port kr = mach_port_mod_refs(mach_task_self(), server, MACH_PORT_RIGHT_SEND, +1); if (kr == KERN_SUCCESS) { storePrivate->server = server; sc_status = kSCStatusOK; } else { storePrivate->server = MACH_PORT_NULL; } } else { // if the server port we used returned an error storePrivate->server = MACH_PORT_NULL; kr = MACH_SEND_INVALID_DEST; } } if (kr == KERN_SUCCESS) { break; } // our [cached] server port is not valid if ((kr != MACH_SEND_INVALID_DEST) && (kr != MIG_SERVER_DIED)) { // if we got an unexpected error, don't retry sc_status = kr; break; } updateServerPort(storePrivate, &server, &sc_status); } __MACH_PORT_DEBUG(TRUE, "*** SCDynamicStoreAddSession", storePrivate->server); // clean up CFRelease(myName); if (myOptions != NULL) CFRelease(myOptions); done : switch (sc_status) { case kSCStatusOK : return TRUE; case BOOTSTRAP_UNKNOWN_SERVICE : SCLog(TRUE, (kr == KERN_SUCCESS) ? LOG_DEBUG : LOG_ERR, CFSTR("SCDynamicStore server not available")); sc_status = kSCStatusNoStoreServer; break; default : SCLog(TRUE, (kr == KERN_SUCCESS) ? LOG_DEBUG : LOG_ERR, CFSTR("SCDynamicStoreAddSession configopen(): %s"), SCErrorString(sc_status)); break; } _SCErrorSet(sc_status); return FALSE; }
Boolean SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns) { SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; kern_return_t status; CFDataRef xmlKeys = NULL; /* keys (XML serialized) */ xmlData_t myKeysRef = NULL; /* keys (serialized) */ CFIndex myKeysLen = 0; CFDataRef xmlPatterns = NULL; /* patterns (XML serialized) */ xmlData_t myPatternsRef = NULL; /* patterns (serialized) */ CFIndex myPatternsLen = 0; int sc_status; CFMutableArrayRef tmp; if (store == NULL) { /* sorry, you must provide a session */ _SCErrorSet(kSCStatusNoStoreSession); return FALSE; } if (storePrivate->server == MACH_PORT_NULL) { _SCErrorSet(kSCStatusNoStoreServer); return FALSE; /* you must have an open session to play */ } /* serialize the keys */ if (keys != NULL) { if (!_SCSerialize(keys, &xmlKeys, (void **)&myKeysRef, &myKeysLen)) { _SCErrorSet(kSCStatusFailed); return FALSE; } } /* serialize the patterns */ if (patterns != NULL) { if (!_SCSerialize(patterns, &xmlPatterns, (void **)&myPatternsRef, &myPatternsLen)) { if (xmlKeys != NULL) CFRelease(xmlKeys); _SCErrorSet(kSCStatusFailed); return FALSE; } } retry : /* send the keys and patterns, fetch the associated result from the server */ status = notifyset(storePrivate->server, myKeysRef, myKeysLen, myPatternsRef, myPatternsLen, (int *)&sc_status); if (__SCDynamicStoreCheckRetryAndHandleError(store, status, &sc_status, "SCDynamicStoreSetNotificationKeys notifyset()")) { goto retry; } /* clean up */ if (xmlKeys != NULL) CFRelease(xmlKeys); if (xmlPatterns != NULL) CFRelease(xmlPatterns); if (sc_status != kSCStatusOK) { _SCErrorSet(sc_status); return FALSE; } /* in case we need to re-connect, save the keys/patterns */ tmp = (keys != NULL) ? CFArrayCreateMutableCopy(NULL, 0, keys) : NULL; if (storePrivate->keys != NULL) CFRelease(storePrivate->keys); storePrivate->keys = tmp; tmp = (patterns != NULL) ? CFArrayCreateMutableCopy(NULL, 0, patterns) : NULL; if (storePrivate->patterns != NULL) CFRelease(storePrivate->patterns); storePrivate->patterns = tmp; return TRUE; }
Boolean SCDynamicStoreSetMultiple(SCDynamicStoreRef store, CFDictionaryRef keysToSet, CFArrayRef keysToRemove, CFArrayRef keysToNotify) { SCDynamicStorePrivateRef storePrivate; kern_return_t status; CFDataRef xmlSet = NULL; /* key/value pairs to set (XML serialized) */ xmlData_t mySetRef = NULL; /* key/value pairs to set (serialized) */ CFIndex mySetLen = 0; CFDataRef xmlRemove = NULL; /* keys to remove (XML serialized) */ xmlData_t myRemoveRef = NULL; /* keys to remove (serialized) */ CFIndex myRemoveLen = 0; CFDataRef xmlNotify = NULL; /* keys to notify (XML serialized) */ xmlData_t myNotifyRef = NULL; /* keys to notify (serialized) */ CFIndex myNotifyLen = 0; int sc_status; if (store == NULL) { store = __SCDynamicStoreNullSession(); if (store == NULL) { /* sorry, you must provide a session */ _SCErrorSet(kSCStatusNoStoreSession); return FALSE; } } storePrivate = (SCDynamicStorePrivateRef)store; if (storePrivate->server == MACH_PORT_NULL) { _SCErrorSet(kSCStatusNoStoreServer); return FALSE; /* you must have an open session to play */ } /* serialize the key/value pairs to set*/ if (keysToSet != NULL) { CFDictionaryRef newInfo; Boolean ok; newInfo = _SCSerializeMultiple(keysToSet); if (newInfo == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } ok = _SCSerialize(newInfo, &xmlSet, (void **)&mySetRef, &mySetLen); CFRelease(newInfo); if (!ok) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } } /* serialize the keys to remove */ if (keysToRemove != NULL) { if (!_SCSerialize(keysToRemove, &xmlRemove, (void **)&myRemoveRef, &myRemoveLen)) { if (xmlSet != NULL) CFRelease(xmlSet); _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } } /* serialize the keys to notify */ if (keysToNotify != NULL) { if (!_SCSerialize(keysToNotify, &xmlNotify, (void **)&myNotifyRef, &myNotifyLen)) { if (xmlSet != NULL) CFRelease(xmlSet); if (xmlRemove != NULL) CFRelease(xmlRemove); _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } } retry : /* send the keys and patterns, fetch the associated result from the server */ status = configset_m(storePrivate->server, mySetRef, mySetLen, myRemoveRef, myRemoveLen, myNotifyRef, myNotifyLen, (int *)&sc_status); if (__SCDynamicStoreCheckRetryAndHandleError(store, status, &sc_status, "SCDynamicStoreSetMultiple configset_m()")) { goto retry; } /* clean up */ if (xmlSet != NULL) CFRelease(xmlSet); if (xmlRemove != NULL) CFRelease(xmlRemove); if (xmlNotify != NULL) CFRelease(xmlNotify); if (sc_status != kSCStatusOK) { _SCErrorSet(sc_status); return FALSE; } return TRUE; }
Boolean SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value) { SCDynamicStorePrivateRef storePrivate; kern_return_t status; CFDataRef utfKey; /* serialized key */ xmlData_t myKeyRef; CFIndex myKeyLen; CFDataRef xmlData; /* serialized data */ xmlData_t myDataRef; CFIndex myDataLen; int sc_status; int newInstance; if (store == NULL) { store = __SCDynamicStoreNullSession(); if (store == NULL) { /* sorry, you must provide a session */ _SCErrorSet(kSCStatusNoStoreSession); return FALSE; } } storePrivate = (SCDynamicStorePrivateRef)store; if (storePrivate->server == MACH_PORT_NULL) { /* sorry, you must have an open session to play */ _SCErrorSet(kSCStatusNoStoreServer); return FALSE; } /* serialize the key */ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } /* serialize the data */ if (!_SCSerialize(value, &xmlData, (void **)&myDataRef, &myDataLen)) { CFRelease(utfKey); _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } retry : /* send the key & data to the server, get new instance id */ status = configset(storePrivate->server, myKeyRef, myKeyLen, myDataRef, myDataLen, 0, &newInstance, (int *)&sc_status); if (__SCDynamicStoreCheckRetryAndHandleError(store, status, &sc_status, "SCDynamicStoreSetValue configset()")) { goto retry; } /* clean up */ CFRelease(utfKey); CFRelease(xmlData); if (sc_status != kSCStatusOK) { _SCErrorSet(sc_status); return FALSE; } return TRUE; }