static void TestDuplicateAndDeleteSet(void) // A test of the set duplication and deleting routines. { OSStatus err; CFStringRef currentSetID; CFStringRef newSetID; currentSetID = NULL; newSetID = NULL; err = MoreSCCopyCurrentSet(¤tSetID); if (err == noErr) { err = MoreSCDuplicateSet(currentSetID, CFSTR("Frog"), &newSetID); } if (err == noErr) { if (!gRunQuiet) { fprintf(stderr, "New set ID is "); CFShow(newSetID); } err = MoreSCDeleteSet(newSetID); } CFQRelease(currentSetID); CFQRelease(newSetID); PrintTestResult(err, NULL); }
static OSStatus WorkaroundNetworkPrefsBug(CFDictionaryRef *entitiesDictPtr) // If this is an Ethernet interface and LCPEchoEnabled is false, // set it to true. This works around what I think is a bug in // the Network preferences panel <rdar://problem/3182846> where the // LCPEchoEnabled flag is mysteriously set to false for PCI Ethernet // interfaces. { OSStatus err; CFStringRef hardwarePath[2]; CFStringRef lcpPath[2]; CFStringRef hardwareStr; CFNumberRef lcpValue; long enabled; hardwarePath[0] = kSCEntNetInterface; hardwarePath[1] = kSCPropNetInterfaceHardware; lcpPath[0] = kSCEntNetPPP; lcpPath[1] = kSCPropNetPPPLCPEchoEnabled; hardwareStr = NULL; // just to make debugging easier lcpValue = NULL; err = noErr; if ( CFQDictionaryGetValueAtPath(*entitiesDictPtr, (const void **) hardwarePath, 2, (const void **) &hardwareStr) == noErr && CFEqual(hardwareStr, kSCEntNetEthernet) && CFQDictionaryGetValueAtPath(*entitiesDictPtr, (const void **) lcpPath, 2, (const void **) &lcpValue) == noErr && CFNumberGetValue(lcpValue, kCFNumberLongType, &enabled) && (enabled == 0) ) { CFMutableDictionaryRef newDict; CFNumberRef numRef; if ( ! gRunQuiet ) { fprintf(stderr, "Applied workaround\n"); } numRef = NULL; newDict = CFDictionaryCreateMutableCopy(NULL, 0, *entitiesDictPtr); err = CFQError(newDict); if (err == noErr) { enabled = true; numRef = CFNumberCreate(NULL, kCFNumberLongType, &enabled); err = CFQError(numRef); } if (err == noErr) { err = CFQDictionarySetValueAtPath(newDict, (const void **) lcpPath, 2, numRef); } if (err == noErr) { CFQRelease(*entitiesDictPtr); *entitiesDictPtr = newDict; newDict = NULL; } CFQRelease(newDict); CFQRelease(numRef); } return err; }
static void TestRenameService(void) // A test of the MoreSCRenameService routine. { OSStatus err; CFArrayRef localServiceIDs; CFStringRef originalName; CFStringRef newName; CFStringRef serviceZero; localServiceIDs = NULL; originalName = NULL; newName = NULL; // Use NULL for the set ID to indicate that we're operating on // the current set. // // Can't use NULL for a service ID, so we have to come up with // a valid service ID first. We do this by choosing the first // service ID. err = MoreSCCopyServiceIDs(NULL, &localServiceIDs, NULL); if (err == noErr) { assert( CFArrayGetCount(localServiceIDs) > 0 ); serviceZero = (CFStringRef) CFArrayGetValueAtIndex(localServiceIDs, 0); err = MoreSCCopyUserVisibleNameOfService(NULL, serviceZero, &originalName); } if (err == noErr) { err = MoreSCRenameService(NULL, serviceZero, CFSTR("Frog")); } if (err == noErr) { err = MoreSCCopyUserVisibleNameOfService(NULL, serviceZero, &newName); } if (err == noErr) { if ( ! CFEqual(newName, CFSTR("Frog")) ) { fprintf(stderr, "*** newName isn't 'Frog'\n"); CFShow(newName); } err = MoreSCRenameService(NULL, serviceZero, originalName); } if (err == noErr) { CFQRelease(newName); newName = NULL; err = MoreSCCopyUserVisibleNameOfService(NULL, serviceZero, &newName); } if (err == noErr) { if ( ! CFEqual(newName, originalName) ) { fprintf(stderr, "*** newName isn't the same as originalName\n"); CFShow(newName); } } CFQRelease(localServiceIDs); CFQRelease(originalName); CFQRelease(newName); PrintTestResult(err, NULL); }
extern pascal OSStatus CFQBundleCreateFromFrameworkName(CFStringRef frameworkName, CFBundleRef *bundlePtr) // See comment in header. { OSStatus err; FSRef frameworksFolderRef; CFURLRef baseURL; CFURLRef bundleURL; assert(frameworkName != NULL); assert( bundlePtr != NULL); assert(*bundlePtr == NULL); *bundlePtr = NULL; baseURL = NULL; bundleURL = NULL; // Find the frameworks folder and create a URL for it. err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef); if (err == noErr) { baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef); err = CFQError(baseURL); } // Append the name of the framework to the URL. if (err == noErr) { bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, frameworkName, false); err = CFQError(bundleURL); } // Create a bundle based on that URL and load the bundle into memory. if (err == noErr) { *bundlePtr = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL); err = CFQError(*bundlePtr); } if (err == noErr) { err = CFQErrorBoolean( CFBundleLoadExecutable( *bundlePtr ) ); } // Clean up. if (err != noErr) { CFQRelease(*bundlePtr); *bundlePtr = NULL; } CFQRelease(bundleURL); CFQRelease(baseURL); assert( (err == noErr) == (*bundlePtr != NULL) ); return err; }
static OSStatus CompareSets(CFStringRef newSet, CFStringRef defSet) // A routine to compare two sets to see if they're identical. // TestCreateSet uses this to check that the newly created set // was created correctly. { OSStatus err; CFArrayRef newServices; CFArrayRef defServices; CFIndex serviceCount; CFIndex serviceIndex; // MoreSCCopyUserVisibleNameOfSet not called because // user visible name of sets will be different. newServices = NULL; defServices = NULL; // Services within the set err = MoreSCCopyServiceIDs(newSet, &newServices, NULL); if (err == noErr) { err = MoreSCCopyServiceIDs(defSet, &defServices, NULL); } if (err == noErr) { if ( CFArrayGetCount(newServices) != CFArrayGetCount(defServices) ) { fprintf(stderr, "*** Service counts not equal.\n"); fprintf(stderr, "%ld\n", CFArrayGetCount(newServices)); fprintf(stderr, "%ld\n", CFArrayGetCount(defServices)); err = -1; } } if (err == noErr) { serviceCount = CFArrayGetCount(newServices); for (serviceIndex = 0; serviceIndex < serviceCount; serviceIndex++) { err = CompareServices(newSet, (CFStringRef) CFArrayGetValueAtIndex(newServices, serviceIndex), defSet, (CFStringRef) CFArrayGetValueAtIndex(defServices, serviceIndex)); if (err != noErr) { break; } } } // Global entities if (err == noErr) { err = CompareGlobalEntities(newSet, defSet); } CFQRelease(newServices); CFQRelease(defServices); return err; }
static void TestRenameSet(void) // A test of the MoreSCRenameSet routine. { OSStatus err; CFStringRef currentSetID; CFStringRef originalName; CFStringRef newName; currentSetID = NULL; originalName = NULL; newName = NULL; err = MoreSCCopyCurrentSet(¤tSetID); if (err == noErr) { err = MoreSCCopyUserVisibleNameOfSet(currentSetID, &originalName); } if (err == noErr) { err = MoreSCRenameSet(currentSetID, CFSTR("Frog")); } if (err == noErr) { err = MoreSCCopyUserVisibleNameOfSet(currentSetID, &newName); } if (err == noErr) { if ( ! CFEqual(newName, CFSTR("Frog")) ) { fprintf(stderr, "*** newName isn't 'Frog'\n"); CFShow(newName); } err = MoreSCRenameSet(currentSetID, originalName); } if (err == noErr) { CFQRelease(newName); newName = NULL; err = MoreSCCopyUserVisibleNameOfSet(currentSetID, &newName); } if (err == noErr) { if ( ! CFEqual(newName, originalName) ) { fprintf(stderr, "*** newName isn't the same as originalName\n"); CFShow(newName); } } CFQRelease(currentSetID); CFQRelease(originalName); CFQRelease(newName); PrintTestResult(err, NULL); }
extern pascal OSStatus CFQPropertyListCreateFromXMLCFURL(CFURLRef xmlFile, CFPropertyListMutabilityOptions options, CFPropertyListRef *result) // See comment in header. { OSStatus err; CFDataRef xmlData; assert(xmlFile != NULL); assert( result != NULL); assert(*result == NULL); xmlData = NULL; err = noErr; if ( ! CFURLCreateDataAndPropertiesFromResource(NULL, xmlFile, &xmlData, NULL, NULL, &err) && (err == noErr) ) { err = coreFoundationUnknownErr; } if (err == noErr) { *result = CFPropertyListCreateFromXMLData(NULL, xmlData, options, NULL); if (*result == NULL) { err = coreFoundationUnknownErr; } } CFQRelease(xmlData); assert( (err == noErr) == (*result != NULL) ); return err; }
static void DebugModemScriptSearch(void) // Used for debugging the modem script code. { OSStatus err; CFArrayRef cclArray; CFIndex indexOfDefaultCCL; cclArray = NULL; err = MoreSCCreateCCLArray(&cclArray, &indexOfDefaultCCL); if (err == noErr) { CFIndex i; CFIndex c; c = CFArrayGetCount(cclArray); fprintf(stderr, "CCL Count = %ld\n", c); for (i = 0; i < c; i++) { fprintf(stderr, "%3ld %c ", i, i == indexOfDefaultCCL ? '*' : ' '); CFShow(CFArrayGetValueAtIndex(cclArray, i)); } } CFQRelease(cclArray); if (err == noErr) { fprintf(stderr, "Success!\n"); } else { fprintf(stderr, "*** Failed with error %ld!\n", err); } }
extern pascal OSStatus MoreAToSCopySymbolNamesUsingDyld(ItemCount count, MoreAToSAddr addresses[], MoreAToSSymInfo symbols[]) { OSStatus err; ItemCount index; assert(addresses != NULL); assert(symbols != NULL); err = noErr; for (index = 0; index < count; index++) { const char * thisSymbol; const char * cleanSymbol; unsigned int thisSymbolOffset; Boolean thisSymbolPublic; CFStringRef thisSymbolStr; MoreAToSSymbolType thisSymbolType; thisSymbolStr = NULL; thisSymbol = NULL; if (addresses[index] != NULL) { // NULL is never a useful symbol thisSymbol = GetFunctionName( (unsigned int) addresses[index], &thisSymbolOffset, &thisSymbolPublic); } if (thisSymbol != NULL) { // Mach-O symbols virtually always start with '_'. If there's one there, // let's strip it. if (thisSymbol[0] == '_') { cleanSymbol = &thisSymbol[1]; } else { cleanSymbol = thisSymbol; } thisSymbolStr = CFStringCreateWithCString(NULL, cleanSymbol, kCFStringEncodingASCII); err = CFQError(thisSymbolStr); if (thisSymbolPublic) { thisSymbolType = kMoreAToSDyldPubliSymbol; } else { thisSymbolType = kMoreAToSDyldPrivateSymbol; } if (err == noErr) { ReplaceSymbolIfBetter(&symbols[index], thisSymbolType, thisSymbolStr, (UInt32) thisSymbolOffset); } } CFQRelease(thisSymbolStr); free( (void *) thisSymbol); if (err != noErr) { break; } } return err; }
CFDictionaryRef CreateErrorDictionary( char* failedFunction, int returnValue, int daErrno, char* moreInfo ) { // Create the dictionary CFMutableDictionaryRef error = CFDictionaryCreateMutable( NULL, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ) ; // Add the failedFunction key/value CFStringRef failedFunctionObject = CFStringCreateWithCString( NULL, failedFunction, kCFStringEncodingASCII ) ; CFDictionaryAddValue(error, CFSTR(kFailedFunction), failedFunctionObject) ; CFQRelease(failedFunctionObject) ; // Add the return value key/value CFNumberRef returnValueObject = CFNumberCreate(NULL, kCFNumberIntType, &returnValue) ; CFDictionaryAddValue(error, CFSTR(kReturnValue), returnValueObject) ; CFQRelease(returnValueObject) ; // Add the errno key/value CFNumberRef errnoObject = CFNumberCreate(NULL, kCFNumberIntType, &daErrno) ; CFDictionaryAddValue(error, CFSTR(kErrno), errnoObject) ; CFQRelease(errnoObject) ; // Add the moreInfo key/value, if any if (moreInfo != NULL) { CFStringRef moreInfoObject = CFStringCreateWithCString( NULL, moreInfo, kCFStringEncodingASCII ) ; CFDictionaryAddValue(error, CFSTR(kMoreInfo), moreInfoObject) ; CFQRelease(moreInfoObject) ; } return error ; }
OSStatus DoWriteDataToFile(COMMAND_PROC_ARGUMENTS) { #pragma unused (auth) #pragma unused (userData) OSStatus retval = noErr; // Pre-conditions // userData may be NULL assert(request != NULL); assert(response != NULL); // asl may be NULL // aslMsg may be NULL // Get data to write and assert that it's a CFDataRef CFDataRef data = CFDictionaryGetValue(request, CFSTR(kData)) ; assert(data != NULL) ; assert(CFGetTypeID(data) == CFDataGetTypeID()) ; // Get path and assert that it's a CFStringRef CFStringRef filePath = CFDictionaryGetValue(request, CFSTR(kPath)) ; assert(filePath != NULL) ; assert(CFGetTypeID(filePath) == CFStringGetTypeID()) ; CFURLRef url = CFURLCreateWithFileSystemPath ( kCFAllocatorDefault, filePath, kCFURLPOSIXPathStyle, false ) ; SInt32 errorCode ; Boolean ok = CFURLWriteDataAndPropertiesToResource ( url, data, NULL, &errorCode ) ; if (!ok) { retval = errorCode ; } asl_log(asl, aslMsg, ASL_LEVEL_DEBUG, "DoWriteDataToFile result ok=%d for %s", ok, CFStringGetCStringPtr( filePath, CFStringGetSystemEncoding() ) ) ; // Clean up CFQRelease(url) ; return retval ; }
static pascal void PrintPropertyListCallback(CFTypeRef key, CFTypeRef node, void *context) // A callback routine used by PrintPropertyList to print // a property list in a nicely formatted way. { #pragma unused(key) int i; int depth; depth = (int)context; for (i = 0; i < depth; i++) { fprintf(stderr, " "); } { CFStringRef fullDesc; CFStringRef typeDesc; CFStringRef valueDesc; fullDesc = NULL; typeDesc = CFCopyTypeIDDescription(CFGetTypeID(node)); valueDesc = NULL; if ( CFQPropertyListIsLeaf(node) ) { if ( CFGetTypeID(node) == CFStringGetTypeID() ) { valueDesc = (CFStringRef) CFRetain(node); } else if ( CFGetTypeID(node) == CFNumberGetTypeID() ) { valueDesc = (CFStringRef) CFRetain(node); } else { valueDesc = CFCopyDescription(node); } fullDesc = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ : %@ [%d] = %@"), key, typeDesc, CFGetRetainCount(node), valueDesc); } else { fullDesc = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ : %@ [%d]"), key, typeDesc, CFGetRetainCount(node)); } CFShow(fullDesc); CFQRelease(fullDesc); CFQRelease(valueDesc); CFQRelease(typeDesc); } if ( ! CFQPropertyListIsLeaf(node) ) { CFQPropertyListShallowApplyFunction(node, PrintPropertyListCallback, (void *) (depth + 1) ); } }
static void TestServiceEnumerate(void) // A test of the service enumeration routines. { OSStatus err; ItemCount serviceCount; ItemCount serviceIndex; CFArrayRef localServiceIDs; CFArrayRef resolvedServiceIDs; localServiceIDs = NULL; resolvedServiceIDs = NULL; err = MoreSCCopyServiceIDs(NULL, &localServiceIDs, &resolvedServiceIDs); if (err == noErr) { serviceCount = CFArrayGetCount(localServiceIDs); for (serviceIndex = 0; serviceIndex < serviceCount; serviceIndex++) { CFStringRef userVisible; Boolean active; userVisible = NULL; err = MoreSCCopyUserVisibleNameOfService(NULL, (CFStringRef) CFArrayGetValueAtIndex(localServiceIDs, serviceIndex), &userVisible); if (err == noErr) { err = MoreSCIsServiceActive(NULL, (CFStringRef) CFArrayGetValueAtIndex(localServiceIDs, serviceIndex), &active); } if (err == noErr && !gRunQuiet) { fprintf(stderr, "#%ld %c ", serviceIndex, (active) ? ' ' : 'X'); CFShow(userVisible); CFShow(CFArrayGetValueAtIndex(localServiceIDs, serviceIndex)); CFShow(CFArrayGetValueAtIndex(resolvedServiceIDs, serviceIndex)); } CFQRelease(userVisible); if (err != noErr) { break; } } } CFQRelease(localServiceIDs); CFQRelease(resolvedServiceIDs); PrintTestResult(err, NULL); }
static void TestPortScanner(void) // A simple test of the port scanner code. This doesn't do a // lot of automated testing, but you can look at the results // and visually check them. { OSStatus err; CFArrayRef portArray; CFIndex portCount; CFIndex portIndex; long order; CFNumberRef supportsHold; portArray = NULL; err = MoreSCCreatePortArray(&portArray); if (err == noErr) { portCount = CFArrayGetCount(portArray); for (portIndex = 0; portIndex < portCount; portIndex++) { CFDictionaryRef thisPort; thisPort = (CFDictionaryRef) CFArrayGetValueAtIndex(portArray, portIndex); if (!gRunQuiet) { fprintf(stderr, "Port %ld\n", portIndex); fprintf(stderr, " device = "); CFShow(CFDictionaryGetValue(thisPort, kSCPropNetInterfaceDeviceName)); fprintf(stderr, " name = "); CFShow(CFDictionaryGetValue(thisPort, kSCPropUserDefinedName)); fprintf(stderr, " hardware = "); CFShow(CFDictionaryGetValue(thisPort, kSCPropNetInterfaceHardware)); fprintf(stderr, " variant = "); CFShow(CFDictionaryGetValue(thisPort, kMoreSCPropNetInterfaceHardwareVariant)); fprintf(stderr, " type = "); CFShow(CFDictionaryGetValue(thisPort, kSCPropNetInterfaceType)); fprintf(stderr, " subtype = "); CFShow(CFDictionaryGetValue(thisPort, kSCPropNetInterfaceSubType)); fprintf(stderr, " MAC = "); CFShow(CFDictionaryGetValue(thisPort, kSCPropMACAddress)); (void) CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(thisPort, CFSTR("SortOrder")), kCFNumberLongType, &order); supportsHold = (CFNumberRef) CFDictionaryGetValue(thisPort, kSCPropNetInterfaceSupportsModemOnHold); if (supportsHold != NULL) { long hold; CFNumberGetValue(supportsHold, kCFNumberLongType, &hold); fprintf(stderr, " hold = %ld\n", hold); } fprintf(stderr, " sort = %ld\n", order); } } } CFQRelease(portArray); PrintTestResult(err, NULL); }
static void TestCreateSet(void) // A routine to test the set creation and deletion code. // It compares the newly created set against a set called // "DefaultLocationForMoreSCFTest" to ensure that the set // created by MoreSCF matches a set created by the control // panel. { OSStatus err; OSStatus err2; CFStringRef newSetID; CFStringRef templateSetID; newSetID = NULL; templateSetID = NULL; err = MoreSCFindSetByUserVisibleNameAndCopyID(CFSTR(kDefaultLocationName), &templateSetID); if (err != noErr || templateSetID == NULL) { fprintf(stderr, "*** TestCreateSet requires that you create a default set named '%s' using the Network preferences panel.\n", kDefaultLocationName); err = -1; } if (err == noErr) { err = MoreSCNewSet(CFSTR("Frog"), &newSetID); } if (err == noErr) { if (!gRunQuiet) { fprintf(stderr, "New set ID is "); CFShow(newSetID); } err = CompareSets(newSetID, templateSetID); err2 = MoreSCDeleteSet(newSetID); if (err == noErr) { err = err2; } } CFQRelease(newSetID); CFQRelease(templateSetID); PrintTestResult(err, NULL); }
static void TestEnumerateEntities(void) // A test of the MoreSCCopyEntities routine. { OSStatus err; CFArrayRef localServiceIDs; ItemCount entityCount; ItemCount entityIndex; CFArrayRef protocols; CFArrayRef values; // Use NULL for the set ID to indicate that we're operating on // the current set. // // Can't use NULL for a service ID, so we have to come up with // a valid service ID first. We do this by choosing the first // service ID. localServiceIDs = NULL; protocols = NULL; values = NULL; err = MoreSCCopyServiceIDs(NULL, &localServiceIDs, NULL); if (err == noErr) { assert(CFArrayGetCount(localServiceIDs) > 0); err = MoreSCCopyEntities(NULL, (CFStringRef) CFArrayGetValueAtIndex(localServiceIDs, 0), &protocols, &values); } if (err == noErr && !gRunQuiet) { entityCount = CFArrayGetCount(protocols); for (entityIndex = 0; entityIndex < entityCount; entityIndex++) { fprintf(stderr, "#%ld ", entityIndex); CFShow(CFArrayGetValueAtIndex(protocols, entityIndex)); CFShow(CFArrayGetValueAtIndex(values, entityIndex)); } } CFQRelease(localServiceIDs); CFQRelease(protocols); CFQRelease(values); PrintTestResult(err, NULL); }
extern pascal void MoreAToSDestroy(ItemCount count, MoreAToSSymInfo symbols[]) { ItemCount index; assert(symbols != NULL); for (index = 0; index < count; index++) { CFQRelease(symbols[index].symbolName); } memset(symbols, 0, count * sizeof(*symbols)); }
static void TestCopySetsDict(void) // A test of the MoreSCCopySetsDict routine, which proved key // in tracking down a reference count leak. { OSStatus err; CFDictionaryRef setsDict; setsDict = NULL; err = MoreSCCopySetsDict(&setsDict); CFQRelease(setsDict); PrintTestResult(err, NULL); }
static void DebugCreatePPPoE(void) { OSStatus err; CFStringRef setID; setID = NULL; err = MoreSCFindSetByUserVisibleNameAndCopyID(kPPPoESetName, &setID); if (err == noErr && setID != NULL) { err = MoreSCDeleteSet(setID); CFQRelease(setID); setID = NULL; } if (err == noErr) { MoreSCPPPDigest ppp; BlockZero(&ppp, sizeof(ppp)); ppp.active = true; ppp.authName = CFSTR("Quinn"); ppp.authPassword = CFSTR("eskimo"); err = MoreSCMakeNewPPPoESet(NULL, kPPPoESetName, &ppp, NULL, NULL, &setID); } if (err == noErr) { fprintf(stderr, "PPPoE set ID is "); CFShow(setID); } CFQRelease(setID); if (err == noErr) { fprintf(stderr, "Success!\n"); } else { fprintf(stderr, "*** Failed with error %ld\n", err); } }
static void TestDuplicateAndDeleteService(void) // A test of the service duplication and deleting routines. { OSStatus err; CFArrayRef localServiceIDs; CFStringRef newServiceID; newServiceID = NULL; localServiceIDs = NULL; // Use NULL for the set ID to indicate that we're operating on // the current set. // // Can't use NULL for a service ID, so we have to come up with // a valid service ID first. We do this by choosing the first // service ID. err = MoreSCCopyServiceIDs(NULL, &localServiceIDs, NULL); if (err == noErr) { assert( CFArrayGetCount(localServiceIDs) > 0 ); err = MoreSCDuplicateService(NULL, (CFStringRef) CFArrayGetValueAtIndex(localServiceIDs, 0), CFSTR("Frog"), &newServiceID); } if (err == noErr) { if (!gRunQuiet) { fprintf(stderr, "New service ID is "); CFShow(newServiceID); } err = MoreSCDeleteService(NULL, newServiceID); } CFQRelease(localServiceIDs); CFQRelease(newServiceID); PrintTestResult(err, NULL); }
static void DebugCreateProxiesEntity(void) // Used for debugging MoreSCCreateProxiesEntity. { OSStatus err; MoreSCProxiesDigest proxy; CFDictionaryRef entity; BlockZero(&proxy, sizeof(proxy)); entity = NULL; err = MoreSCCreateProxiesEntity(&proxy, &entity); if (err == noErr) { PrintPropertyList(entity); } CFQRelease(entity); }
extern pascal OSStatus CFQDictionarySetNumber(CFMutableDictionaryRef dict, const void *key, long value) // See comment in header. { OSStatus err; CFNumberRef valueNum; // Create a CFNumber and add it to the dictionary. err = noErr; valueNum = CFNumberCreate(NULL, kCFNumberLongType, &value); if (valueNum == NULL) { err = coreFoundationUnknownErr; } if (err == noErr) { CFDictionarySetValue(dict, key, valueNum); } CFQRelease(valueNum); return err; }
extern pascal OSStatus CFQPropertyListCreateFromXMLFSRef(const FSRef *xmlFile, CFPropertyListMutabilityOptions options, CFPropertyListRef *result) // See comment in header. { OSStatus err; CFURLRef xmlURL; assert(xmlFile != NULL); assert( result != NULL); assert(*result == NULL); xmlURL = CFURLCreateFromFSRef(NULL, xmlFile); err = CFQError(xmlURL); if (err == noErr) { err = CFQPropertyListCreateFromXMLCFURL(xmlURL, options, result); } CFQRelease(xmlURL); assert( (err == noErr) == (*result != NULL) ); return err; }
static void ReplaceSymbolIfBetter(MoreAToSSymInfo *existingSymbol, MoreAToSSymbolType symbolType, CFStringRef symbolName, UInt32 symbolOffset) { Boolean replace; assert(existingSymbol != NULL); assert(symbolType != kMoreAToSNoSymbol); assert(symbolName != NULL); assert( (existingSymbol->symbolType == kMoreAToSNoSymbol) == (existingSymbol->symbolName == NULL) ); if (existingSymbol->symbolType == kMoreAToSNoSymbol) { replace = true; } else { replace = (symbolOffset < existingSymbol->symbolOffset); } if (replace) { CFQRelease(existingSymbol->symbolName); CFRetain(symbolName); existingSymbol->symbolType = symbolType; existingSymbol->symbolName = symbolName; existingSymbol->symbolOffset = symbolOffset; } }
extern OSStatus MoreSCCreateCCLArray(CFArrayRef *result, CFIndex *indexOfDefaultCCL) // See comment in header. { OSStatus err; CFMutableArrayRef localResult; UInt32 domainIndex; FSRef folderRef; static const SInt16 kFolderDomains[] = {kUserDomain, kNetworkDomain, kLocalDomain, kSystemDomain, 0}; assert( result != NULL); assert(*result == NULL); // Create an array containing the names of the CCLs from the Modem Scripts // folder in each domain. localResult = NULL; err = CFQArrayCreateMutable(&localResult); if (err == noErr) { UInt32 scannedFolders; scannedFolders = 0; domainIndex = 0; do { err = FSFindFolder(kFolderDomains[domainIndex], kModemScriptsFolderType, false, &folderRef); if (err != noErr) { // If we can't find the folder in this domain, just ignore the domain. err = noErr; } else { scannedFolders += 1; // If we found the folder, add each CCL in it to the array. err = AddCCLsInFolderToArray(&folderRef, localResult); } domainIndex += 1; } while (err == noErr && kFolderDomains[domainIndex] != 0); // Testing reveals that under certain circumstances, the above loop // will never find any folders. The specific case I saw was on // Mac OS 9.1 with CarbonLib 1.6 when running the application off // the non-boot volume. So, if FSFindFolder never returns any // folders in the domains we looped over above, let's do it the old // way and call FSFindFolder with kOnSystemDisk. // // I didn't file a bug against FSFindFolder because traditional Mac OS // bugs are no longer being fixed at this time. // -- Quinn, 10 Dec 2002 if ( (err == noErr) && (scannedFolders == 0) ) { if (FSFindFolder(kOnSystemDisk, kModemScriptsFolderType, false, &folderRef) == noErr) { err = AddCCLsInFolderToArray(&folderRef, localResult); } } } // Sort the resulting array and delete any duplicates. if (err == noErr) { CFIndex cursor; CFArraySortValues(localResult, CFRangeMake(0, CFArrayGetCount(localResult)), (CFComparatorFunction) CFStringCompare, (void *) kMyStringCompareOptions); cursor = 1; while (cursor < CFArrayGetCount(localResult)) { if ( CFEqual(CFArrayGetValueAtIndex(localResult, cursor), CFArrayGetValueAtIndex(localResult, cursor - 1)) ) { CFArrayRemoveValueAtIndex(localResult, cursor); } else { cursor += 1; } } } // Find the index of the default CCL (or use the first CCL if the default // isn't found). The array is already sorted for user presentation, so // we can use CFArrayBSearchValues rather than searching by hand. This // might even be a relevant speed increase because the number of CCLs can // range into the hundreds. if (err == noErr && indexOfDefaultCCL != NULL) { CFStringRef defaultCCLName; CFIndex itemIndex; defaultCCLName = MoreSCCopyDefaultCCL(); itemIndex = CFArrayBSearchValues(localResult, CFRangeMake(0, CFArrayGetCount(localResult)), defaultCCLName, (CFComparatorFunction) CFStringCompare, (void *) kMyStringCompareOptions); // itemIndex is either: // // o pointing directly at the correct element, if an exact match is found, or // // o if no exact match is found, pointing after the element that's immediately // less than defaultCCLName // // So, to confirm that we have the default script we check that the item is in // bounds and that its value matches defaultCCLName. If either of these // checks fails, we return the index of the first CCL. if ( (itemIndex < CFArrayGetCount(localResult)) && (CFStringCompare(defaultCCLName, (CFStringRef) CFArrayGetValueAtIndex(localResult, itemIndex), kMyStringCompareOptions) == kCFCompareEqualTo)) { *indexOfDefaultCCL = itemIndex; } else { *indexOfDefaultCCL = 0; } CFQRelease(defaultCCLName); } // Clean up. if (err != noErr) { CFQRelease(localResult); localResult = NULL; } *result = localResult; assert( (err == noErr) == (*result != NULL) ); assert( (err != noErr) // either we got an error || (indexOfDefaultCCL == NULL) // or the user didn't ask for the default CCL || (CFArrayGetCount(*result) == 0) // or there are no CCLs || (*indexOfDefaultCCL >= 0 && *indexOfDefaultCCL < CFArrayGetCount(*result)) ); // or the default CCL we're returning is in bounds return err; }
static OSStatus AddCCLsInFolderToArray(const FSRef *folderRef, CFMutableArrayRef result) // Iterates through the contents of the folder specified by folderRef, // adding the name of each CCL file (ie any file that's visible) to // the result array. { OSStatus err; OSStatus junk; FSRef * scriptRefs; HFSUniStr255 * scriptNames; FSIterator iter; ItemCount actCount; ItemCount thisItemIndex; Boolean done; iter = NULL; scriptRefs = NULL; scriptNames = NULL; // Allocate buffers for the FSRefs and long Unicode names. Given that // we're processing 50 files at a time, these buffers are way too big // to store on the stack (25 KB for scriptNames alone). scriptRefs = (FSRef *) malloc( kFolderItemsPerBulkCall * sizeof(FSRef) ); scriptNames = (HFSUniStr255 *) malloc( kFolderItemsPerBulkCall * sizeof(HFSUniStr255) ); err = noErr; if (scriptRefs == NULL || scriptNames == NULL) { err = memFullErr; } // Create the iterator. if (err == noErr) { err = FSOpenIterator(folderRef, kFSIterateFlat, &iter); } // Iterate over the contents of the directory. For each item found // we check whether it's a visible plain file and, if it is, add its // name to the array. if (err == noErr) { done = false; do { err = FSGetCatalogInfoBulk(iter, kFolderItemsPerBulkCall, &actCount, NULL, kFSCatInfoNone, NULL, scriptRefs, NULL, scriptNames); if (err == errFSNoMoreItems) { // We ran off the end of the directory. Record that we're // done, but set err to noErr so that we process any partial // results. done = true; err = noErr; } if (err == noErr) { for (thisItemIndex = 0; thisItemIndex < actCount; thisItemIndex++) { Boolean visible; err = MyIsVisibleFile(&scriptRefs[thisItemIndex], &visible); if ( (err == noErr) && visible ) { CFStringRef thisItemName; thisItemName = CFStringCreateWithCharacters(NULL, scriptNames[thisItemIndex].unicode, scriptNames[thisItemIndex].length); if (thisItemName == NULL) { err = coreFoundationUnknownErr; } if (err == noErr) { CFArrayAppendValue(result, thisItemName); } CFQRelease(thisItemName); } if (err != noErr) { break; } } } } while (err == noErr && !done); } // Clean up. if (iter != NULL) { junk = FSCloseIterator(iter); assert(junk == noErr); } if (scriptRefs != NULL) { free(scriptRefs); } if (scriptNames != NULL) { free(scriptNames); } return err; }
static CFStringRef MoreSCCopyDefaultCCL(void) { // If the user hasn't supplied a default, first see if the internal // modem support V.92. If so, use the V.92 modem script as the default. // // Except, if bug-for-bug compatibility is enabled and we're running on // 10.4 and later, don't try to do this. Apparently 10.4 always sets // the default modem script to V.90, even if the modem supports V.92. if ( (gDefaultCCL == NULL) && ! gMoreSCFCCLScannerBugForBugCompatibility && (MoreSCGetSystemVersion() < 0x01040) ) { OSStatus err; CFArrayRef ports; CFIndex portCount; CFIndex portIndex; ports = NULL; err = MoreSCCreatePortArray(&ports); if (err == noErr) { portCount = CFArrayGetCount(ports); for (portIndex = 0; portIndex < portCount; portIndex++) { CFDictionaryRef thisPort; CFStringRef thisPortHardware; CFStringRef thisPortName; CFNumberRef onHoldRef; int onHold; thisPort = (CFDictionaryRef) CFArrayGetValueAtIndex(ports, portIndex); assert(thisPort != NULL); assert( CFGetTypeID(thisPort) == CFDictionaryGetTypeID() ); thisPortHardware = (CFStringRef) CFDictionaryGetValue(thisPort, kSCPropNetInterfaceHardware); assert(thisPortHardware != NULL); assert( CFGetTypeID(thisPortHardware) == CFStringGetTypeID() ); if ( (thisPortHardware != NULL) && CFEqual(thisPortHardware, kSCEntNetModem) ) { thisPortName = (CFStringRef) CFDictionaryGetValue(thisPort, kSCPropNetInterfaceDeviceName); assert(thisPortName != NULL); assert( CFGetTypeID(thisPortName) == CFStringGetTypeID() ); if ( (thisPortName != NULL) && CFEqual(thisPortName, CFSTR("modem")) ) { onHoldRef = (CFNumberRef) CFDictionaryGetValue(thisPort, kSCPropNetInterfaceSupportsModemOnHold); assert(onHoldRef != NULL); assert( CFGetTypeID(onHoldRef) == CFNumberGetTypeID() ); if ( (onHoldRef != NULL) && CFNumberGetValue(onHoldRef, kCFNumberIntType, &onHold) && (onHold != 0) ) { assert(onHold == 1); // would be weird otherwise gDefaultCCL = CFSTR("Apple Internal 56K Modem (v.92)"); CFQRetain(gDefaultCCL); } // Regardless of whether we set on hold or not, we stop // once we've found the built-in modem. break; } } } } CFQRelease(ports); assert(err == noErr); // just for debugging } // If we still don't have a default, go with the standard default. if (gDefaultCCL == NULL) { gDefaultCCL = CFSTR("Apple Internal 56K Modem (v.90)"); CFQRetain(gDefaultCCL); } CFQRetain(gDefaultCCL); return gDefaultCCL; }
extern void MoreSCSetDefaultCCL(CFStringRef cclName) { CFQRelease(gDefaultCCL); gDefaultCCL = cclName; CFQRetain(gDefaultCCL); }
static OSStatus CreateCFArrayFromAEDescList( const AEDescList * descList, CFArrayRef * itemsPtr ) // This routine's input is an AEDescList that contains replies // from the "properties of every login item" event. Each element // of the list is an AERecord with two important properties, // "path" and "hidden". This routine creates a CFArray that // corresponds to this list. Each element of the CFArray // contains two properties, kLIAEURL and // kLIAEHidden, that are derived from the corresponding // AERecord properties. // // On entry, descList must not be NULL // On entry, itemsPtr must not be NULL // On entry, *itemsPtr must be NULL // On success, *itemsPtr will be a valid CFArray // On error, *itemsPtr will be NULL { OSStatus err; CFMutableArrayRef result; long itemCount; long itemIndex; AEKeyword junkKeyword; DescType junkType; Size junkSize; assert( itemsPtr != NULL); assert(*itemsPtr == NULL); result = NULL; // Create a place for the result. err = noErr; result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); if (result == NULL) { err = coreFoundationUnknownErr; } // For each element in the descriptor list... if (err == noErr) { err = AECountItems(descList, &itemCount); } if (err == noErr) { for (itemIndex = 1; itemIndex <= itemCount; itemIndex++) { if (itemIndex == 4) { int notused = 0; notused++; } AERecord thisItem; UInt8 thisPath[1024]; Size thisPathSize; FSRef thisItemRef; CFURLRef thisItemURL; Boolean thisItemHidden; CFDictionaryRef thisItemDict; thisItem = kAENull; thisItemURL = NULL; thisItemDict = NULL; // Get this element's AERecord. err = AEGetNthDesc(descList, itemIndex, typeAERecord, &junkKeyword, &thisItem); if (err != noErr) { err = noErr; continue; } // Extract the path and create a CFURL. if (err == noErr) { err = AEGetKeyPtr( &thisItem, propPath, typeUTF8Text, &junkType, thisPath, sizeof(thisPath) - 1, // to ensure that we can always add null terminator &thisPathSize ); } if (err == noErr) { thisPath[thisPathSize] = 0; err = FSPathMakeRef(thisPath, &thisItemRef, NULL); if (err == noErr) { thisItemURL = CFURLCreateFromFSRef(NULL, &thisItemRef); } else { err = noErr; // swallow error and create an imprecise URL thisItemURL = CFURLCreateFromFileSystemRepresentation( NULL, thisPath, thisPathSize, false ); } if (thisItemURL == NULL) { err = coreFoundationUnknownErr; } } // Extract the hidden flag. if (err == noErr) { err = AEGetKeyPtr( &thisItem, propHidden, typeBoolean, &junkType, &thisItemHidden, sizeof(thisItemHidden), &junkSize ); // Work around <rdar://problem/4052117> by assuming that hidden // is false if we can't get its value. if (err != noErr) { thisItemHidden = false; err = noErr; } } // Create the CFDictionary for this item. if (err == noErr) { CFStringRef keys[2]; CFTypeRef values[2]; keys[0] = kLIAEURL; keys[1] = kLIAEHidden; values[0] = thisItemURL; values[1] = (thisItemHidden ? kCFBooleanTrue : kCFBooleanFalse); thisItemDict = CFDictionaryCreate( NULL, (const void **) keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); if (thisItemDict == NULL) { err = coreFoundationUnknownErr; } } // Add it to the results array. if (err == noErr) { CFArrayAppendValue(result, thisItemDict); } AEDisposeDescQ(&thisItem); CFQRelease(thisItemURL); CFQRelease(thisItemDict); if (err != noErr) { break; } } } // Clean up. if (err != noErr) { CFQRelease(result); result = NULL; } *itemsPtr = result; assert( (err == noErr) == (*itemsPtr != NULL) ); return err; }
static void DoRefresh(void) // Called in response to a click of the "Refresh" button. // Also called to refresh the list after other actions have // changed it. Also called at application startup to // establish an initial value for the list. { OSStatus err; CFArrayRef items; CFIndex itemCount; CFIndex itemIndex; DataBrowserItemID * itemsIDArray; itemsIDArray = NULL; items = NULL; // Get the array from LoginItemsAE. err = LIAECopyLoginItems(&items); if (err == noErr) { // Swap it into gItems. CFQRelease(gItems); gItems = items; items = NULL; // to prevent the release at the end of this function // Remove any existing items. if (err == noErr) { err = RemoveDataBrowserItems( gDataControl, kDataBrowserNoItem, // from root 0, // all items NULL, // " " kDataBrowserItemNoProperty ); } // Add the new items. if (err == noErr) { itemCount = CFArrayGetCount(gItems); itemsIDArray = calloc(itemCount, sizeof(DataBrowserItemID)); if (itemsIDArray == NULL) { err = memFullErr; } } if (err == noErr) { // Each item ID is the item's index into the gItems array, // plus one because a value of 0 is invalid (it's kDataBrowserNoItem). for (itemIndex = 0; itemIndex < itemCount; itemIndex++) { itemsIDArray[itemIndex] = (DataBrowserItemID) (itemIndex + 1); } err = AddDataBrowserItems( gDataControl, kDataBrowserNoItem, // to root (UInt32) itemCount, itemsIDArray, kDataBrowserItemNoProperty ); } } // Clean up. CFQRelease(items); free(itemsIDArray); DisplayError(err); }