예제 #1
0
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(&currentSetID);
	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);
}
예제 #2
0
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;	
}
예제 #3
0
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);
}
예제 #4
0
파일: MoreCFQ.c 프로젝트: paullalonde/B
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;
}
예제 #5
0
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;
}
예제 #6
0
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(&currentSetID);
	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);
}
예제 #7
0
파일: MoreCFQ.c 프로젝트: paullalonde/B
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;
}
예제 #8
0
	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);
	    }
	}
예제 #9
0
	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 ;
}	
예제 #12
0
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) );
	}
}
예제 #13
0
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);
}
예제 #14
0
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);
}
예제 #15
0
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);
}
예제 #16
0
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);
}
예제 #17
0
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));
}
예제 #18
0
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);
}
예제 #19
0
 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);
     }
 }
예제 #20
0
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);
}
예제 #21
0
	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);
	}
예제 #22
0
파일: MoreCFQ.c 프로젝트: paullalonde/B
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;
}
예제 #23
0
파일: MoreCFQ.c 프로젝트: paullalonde/B
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;
}
예제 #24
0
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;
	}
}
예제 #25
0
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;
}
예제 #26
0
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;
}
예제 #27
0
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;
}
예제 #28
0
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);
}