예제 #1
0
CFStringRef copy_disk_app_identifier(CFURLRef disk_app_url) {
    CFURLRef plist_url = CFURLCreateCopyAppendingPathComponent(NULL, disk_app_url, CFSTR("Info.plist"), false);
    CFReadStreamRef plist_stream = CFReadStreamCreateWithFile(NULL, plist_url);
    CFReadStreamOpen(plist_stream);
    CFPropertyListRef plist = CFPropertyListCreateWithStream(NULL, plist_stream, 0, kCFPropertyListImmutable, NULL, NULL);
    CFStringRef bundle_identifier = CFRetain(CFDictionaryGetValue(plist, CFSTR("CFBundleIdentifier")));
    CFReadStreamClose(plist_stream);
	
    CFRelease(plist_url);
    CFRelease(plist_stream);
    CFRelease(plist);
	
    return bundle_identifier;
}
예제 #2
0
sdmmd_return_t SDMMD_ServiceReceiveStream(SocketConnection handle, CFPropertyListRef *data) {
	CFDataRef dataBuffer = NULL;
	if (SDM_MD_CallSuccessful(SDMMD_ServiceReceive(handle, &dataBuffer))) {
		if (dataBuffer && CFDataGetLength(dataBuffer)) {
			CFReadStreamRef read = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(dataBuffer), CFDataGetLength(dataBuffer), kCFAllocatorNull);
			CFReadStreamOpen(read);
			*data = CFPropertyListCreateWithStream(kCFAllocatorDefault, read, CFDataGetLength(dataBuffer), 0x2, 0, NULL);
			CFReadStreamClose(read);
			if (read)
				CFRelease(read);
		}
		return kAMDSuccess;
	} else {
		return kAMDNotConnectedError;
	}
}
예제 #3
0
static bool OnLionOrLater()
{
  if (sOnLionOrLater < 0) {
    SInt32 major = 0, minor = 0;

    CFURLRef url =
      CFURLCreateWithString(kCFAllocatorDefault,
                            CFSTR("file:///System/Library/CoreServices/SystemVersion.plist"),
                            NULL);
    CFReadStreamRef stream =
      CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
    CFReadStreamOpen(stream);
    CFDictionaryRef sysVersionPlist = (CFDictionaryRef)
      CFPropertyListCreateWithStream(kCFAllocatorDefault,
                                     stream, 0, kCFPropertyListImmutable,
                                     NULL, NULL);
    CFReadStreamClose(stream);
    CFRelease(stream);
    CFRelease(url);

    CFStringRef versionString = (CFStringRef)
      CFDictionaryGetValue(sysVersionPlist, CFSTR("ProductVersion"));
    CFArrayRef versions =
      CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault,
                                             versionString, CFSTR("."));
    CFIndex count = CFArrayGetCount(versions);
    if (count > 0) {
      CFStringRef component = (CFStringRef) CFArrayGetValueAtIndex(versions, 0);
      major = CFStringGetIntValue(component);
      if (count > 1) {
        component = (CFStringRef) CFArrayGetValueAtIndex(versions, 1);
        minor = CFStringGetIntValue(component);
      }
    }
    CFRelease(sysVersionPlist);
    CFRelease(versions);

    if (major < 10) {
      sOnLionOrLater = 0;
    } else {
      int version = 0x1000 + (minor << 4);
      sOnLionOrLater = version >= MAC_OS_X_VERSION_10_7_HEX ? 1 : 0;
    }
  }

  return sOnLionOrLater > 0 ? true : false;
}
예제 #4
0
CFStringRef get_bundle_id(const char *app_path)
{
  CFURLRef app_url = get_absolute_file_url(app_path);
  if (app_url == NULL)
  {
    return NULL;
  }

  CFURLRef url = CFURLCreateCopyAppendingPathComponent(NULL, app_url,
                                                       CFSTR("Info.plist"), false);
  CFRelease(app_url);
  if (url == NULL)
  {
    return NULL;
  }

  CFReadStreamRef stream = CFReadStreamCreateWithFile(NULL, url);
  CFRelease(url);
  if (stream == NULL)
  {
    return NULL;
  }

  CFPropertyListRef plist = NULL;
  if (CFReadStreamOpen(stream) == TRUE)
  {
    plist = CFPropertyListCreateWithStream(NULL, stream, 0,
                                           kCFPropertyListImmutable, NULL, NULL);
  }
  CFReadStreamClose(stream);
  CFRelease(stream);

  if (plist == NULL)
  {
    return NULL;
  }

  const void *value = CFDictionaryGetValue(plist, CFSTR("CFBundleIdentifier"));
  CFStringRef bundle_id = NULL;
  if (value != NULL)
  {
    bundle_id = CFRetain(value);
  }
  CFRelease(plist);
  return bundle_id;
}
예제 #5
0
static CFTypeRef
CopyKeyFromFile(CFStringRef domain, CFStringRef key)
{
    CFReadStreamRef s;
    CFDictionaryRef d;
    CFStringRef file;
    CFErrorRef e;
    CFURLRef url;
    CFTypeRef val;
    
    file = CFStringCreateWithFormat(NULL, 0, CFSTR("/Library/Preferences/%@.plist"), domain);
    if (file == NULL)
	return NULL;
    
    url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, domain, kCFURLPOSIXPathStyle, false);
    CFRelease(file);
    if (url == NULL)
	return NULL;
    
    s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
    CFRelease(url);
    if (s == NULL)
	return NULL;
    
    if (!CFReadStreamOpen(s)) {
	CFRelease(s);
	return NULL;
    }
    
    d = (CFDictionaryRef)CFPropertyListCreateWithStream (kCFAllocatorDefault, s, 0, kCFPropertyListImmutable, NULL, &e);
    CFRelease(s);
    if (d == NULL)
	return NULL;
    
    if (CFGetTypeID(d) != CFDictionaryGetTypeID()) {
	CFRelease(d);
	return NULL;
    }
    
    val = CFDictionaryGetValue(d, key);
    if (val)
	CFRetain(val);
    CFRelease(d);
    return val;
}
예제 #6
0
sdmmd_return_t SDMMD_ServiceReceiveStream(SocketConnection handle, CFPropertyListRef *data) {
	CFDataRef dataBuffer = NULL;
	sdmmd_return_t result = SDMMD_ServiceReceive(handle, &dataBuffer);

	CheckErrorAndReturn(result);
	
	if (dataBuffer && CFDataGetLength(dataBuffer)) {
		CFReadStreamRef read = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(dataBuffer), CFDataGetLength(dataBuffer), kCFAllocatorNull);

		CFReadStreamOpen(read);
		*data = CFPropertyListCreateWithStream(kCFAllocatorDefault, read, CFDataGetLength(dataBuffer), kCFPropertyListMutableContainersAndLeaves, NULL, NULL);
		CFReadStreamClose(read);
		CFSafeRelease(read);
	}
	result = kAMDSuccess;
	
	CFSafeRelease(dataBuffer);
	ExitLabelAndReturn(result);
}
예제 #7
0
static krb5_error_code
parse_plist_config(krb5_context context, const char *path, krb5_config_section **parent)
{
    CFReadStreamRef s;
    CFDictionaryRef d;
    CFURLRef url;

    url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)path, strlen(path), FALSE);
    if (url == NULL) {
        krb5_clear_error_message(context);
        return ENOMEM;
    }

    s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
    CFRelease(url);
    if (s == NULL) {
        krb5_clear_error_message(context);
        return ENOMEM;
    }

    if (!CFReadStreamOpen(s)) {
        CFRelease(s);
        krb5_clear_error_message(context);
        return ENOENT;
    }

#ifdef HAVE_CFPROPERTYLISTCREATEWITHSTREAM
    d = (CFDictionaryRef)CFPropertyListCreateWithStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL);
#else
    d = (CFDictionaryRef)CFPropertyListCreateFromStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL);
#endif
    CFRelease(s);
    if (d == NULL) {
        krb5_clear_error_message(context);
        return ENOENT;
    }

    CFDictionaryApplyFunction(d, convert_content, parent);
    CFRelease(d);

    return 0;
}
CFDictionaryRef get_escrow_record(int socket, CFDictionaryRef dict)
{
    CFStringRef hostid = CFDictionaryGetValue(dict, CFSTR("HostID"));
    if(hostid == NULL || CFGetTypeID(hostid) != CFStringGetTypeID())
        return NULL;
    
    //TODO: check return values...
    CFStringRef path = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("/mnt2/root/Library/Lockdown/escrow_records/%@.plist"), hostid);
    //CFStringRef path = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("/private/var/root/Library/Lockdown/escrow_records/%@.plist"), hostid);

    CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, FALSE);
    CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, fileURL);
    CFReadStreamOpen(stream);
    CFPropertyListRef plist = CFPropertyListCreateWithStream(kCFAllocatorDefault,
                        stream, 0, kCFPropertyListImmutable, NULL, NULL);

    CFRelease(fileURL);
    CFRelease(stream);
    CFRelease(path);
    return plist;
}
예제 #9
0
파일: plist.c 프로젝트: nivekkagicom/duti
    int
read_plist( char *plpath, CFDictionaryRef *dr )
{
    CFURLRef		cfurl = NULL;
    CFReadStreamRef	cfrs = NULL;
    CFDictionaryRef	cfdict = NULL;
    CFPropertyListFormat	fmt = kCFPropertyListXMLFormat_v1_0;
    CFStreamError	err;

    int			rc = 0;
    char		respath[ MAXPATHLEN ];
    
    if ( plpath == NULL ) {
	fprintf( stderr, "%s: Invalid plist path\n", __FUNCTION__ );
	return( -1 );
    }

    if ( realpath( plpath, respath ) == NULL ) {
	fprintf( stderr, "%s: realpath failed: %s\n",
		__FUNCTION__, strerror( errno ));
	return( -1 );
    }

    /*
     * must convert C string path to CFURL to read the plist
     * from disk. no convenience methods here like Cocoa's
     * -dictionaryWithContentsOfFile:
     */
    if (( cfurl = CFURLCreateFromFileSystemRepresentation(
			kCFAllocatorDefault, ( const UInt8 * )respath,
			( CFIndex )strlen( respath ), false )) == NULL ) {
	fprintf( stderr, "%s: failed to create URL for %s\n",
			__FUNCTION__, respath );
	return( -1 );
    }

    if (( cfrs = CFReadStreamCreateWithFile( kCFAllocatorDefault,
			cfurl )) == NULL ) {
	fprintf( stderr, "%s: failed to create read stream\n", __FUNCTION__ );
	rc = -1;
	goto cleanup;
    }
    if ( CFReadStreamOpen( cfrs ) == false ) {
	err = CFReadStreamGetError( cfrs );
	fprintf( stderr, "%s: failed to open read stream\n", __FUNCTION__ );
	if ( err.domain == kCFStreamErrorDomainPOSIX ) {
	    fprintf( stderr, "%s: %s\n", plpath, strerror( errno ));
	} else {
	    fprintf( stderr, "domain %d, error %d\n",
			( int )err.domain, ( int )err.error );
	}
	rc = -1;
	goto cleanup;
    }

    if (( cfdict = CFPropertyListCreateWithStream( kCFAllocatorDefault, cfrs,
			0, kCFPropertyListImmutable, &fmt, NULL )) == NULL ) {
	fprintf( stderr, "%s: failed to read plist\n", __FUNCTION__ );
	rc = -1;
	goto cleanup;
    }

    if ( !CFPropertyListIsValid( cfdict, fmt )) {
	fprintf( stderr, "%s: invalid plist\n", plpath );
	CFRelease( cfdict );
	cfdict = NULL;
	rc = -1;
    }

cleanup:
    if ( cfurl != NULL ) {
	CFRelease( cfurl );
    }
    if ( cfrs != NULL ) {
	CFReadStreamClose( cfrs );
	CFRelease( cfrs );
    }

    *dr = cfdict;

    return( rc );
}
예제 #10
0
static cups_array_t *			/* O - Message catalog */
appleMessageLoad(const char *locale)	/* I - Locale ID */
{
  char			filename[1024],	/* Path to cups.strings file */
			applelang[256],	/* Apple language ID */
			baselang[3];	/* Base language */
  CFURLRef		url;		/* URL to cups.strings file */
  CFReadStreamRef	stream = NULL;	/* File stream */
  CFPropertyListRef	plist = NULL;	/* Localization file */
#ifdef DEBUG
  CFErrorRef		error = NULL;	/* Error when opening file */
#endif /* DEBUG */


  DEBUG_printf(("appleMessageLoad(locale=\"%s\")", locale));

 /*
  * Load the cups.strings file...
  */

  snprintf(filename, sizeof(filename),
           CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings",
	   _cupsAppleLanguage(locale, applelang, sizeof(applelang)));

  if (access(filename, 0))
  {
   /*
    * <rdar://problem/22086642>
    *
    * Try with original locale string...
    */

    snprintf(filename, sizeof(filename), CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale);
  }

  DEBUG_printf(("1appleMessageLoad: filename=\"%s\"", filename));

  if (access(filename, 0))
  {
   /*
    * Try alternate lproj directory names...
    */

    if (!strncmp(locale, "en", 2))
      locale = "English";
    else if (!strncmp(locale, "nb", 2) || !strncmp(locale, "nl", 2))
      locale = "Dutch";
    else if (!strncmp(locale, "fr", 2))
      locale = "French";
    else if (!strncmp(locale, "de", 2))
      locale = "German";
    else if (!strncmp(locale, "it", 2))
      locale = "Italian";
    else if (!strncmp(locale, "ja", 2))
      locale = "Japanese";
    else if (!strncmp(locale, "es", 2))
      locale = "Spanish";
    else if (!strcmp(locale, "zh_HK"))
    {
     /*
      * <rdar://problem/22130168>
      *
      * Try zh_TW first, then zh...  Sigh...
      */

      if (!access(CUPS_BUNDLEDIR "/Resources/zh_TW.lproj/cups.strings", 0))
        locale = "zh_TW";
      else
        locale = "zh";
    }
    else if (strstr(locale, "_") != NULL || strstr(locale, "-") != NULL)
    {
     /*
      * Drop country code, just try language...
      */

      strlcpy(baselang, locale, sizeof(baselang));
      locale = baselang;
    }

    snprintf(filename, sizeof(filename),
	     CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale);
    DEBUG_printf(("1appleMessageLoad: alternate filename=\"%s\"", filename));
  }

  url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
                                                (UInt8 *)filename,
						(CFIndex)strlen(filename), false);
  if (url)
  {
    stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
    if (stream)
    {
     /*
      * Read the property list containing the localization data.
      *
      * NOTE: This code currently generates a clang "potential leak"
      * warning, but the object is released in _cupsMessageFree().
      */

      CFReadStreamOpen(stream);

#ifdef DEBUG
      plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0,
                                             kCFPropertyListImmutable, NULL,
                                             &error);
      if (error)
      {
        CFStringRef	msg = CFErrorCopyDescription(error);
    					/* Error message */

        CFStringGetCString(msg, filename, sizeof(filename),
                           kCFStringEncodingUTF8);
        DEBUG_printf(("1appleMessageLoad: %s", filename));

	CFRelease(msg);
        CFRelease(error);
      }

#else
      plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0,
                                             kCFPropertyListImmutable, NULL,
                                             NULL);
#endif /* DEBUG */

      if (plist && CFGetTypeID(plist) != CFDictionaryGetTypeID())
      {
         CFRelease(plist);
         plist = NULL;
      }

      CFRelease(stream);
    }

    CFRelease(url);
  }

  DEBUG_printf(("1appleMessageLoad: url=%p, stream=%p, plist=%p", url, stream,
                plist));

 /*
  * Create and return an empty array to act as a cache for messages, passing the
  * plist as the user data.
  */

  return (_cupsMessageNew((void *)plist));
}
예제 #11
0
/*
 * Get the OS X version information, and append it to the GString.
 * Return TRUE if we succeed, FALSE if we fail.
 */
static gboolean
get_os_x_version_info(GString *str)
{
	static const UInt8 server_version_plist_path[] =
	    "/System/Library/CoreServices/ServerVersion.plist";
	static const UInt8 system_version_plist_path[] =
	    "/System/Library/CoreServices/SystemVersion.plist";
	CFURLRef version_plist_file_url;
	CFReadStreamRef version_plist_stream;
	CFDictionaryRef version_dict;
	char *string;

	/*
	 * On OS X, report the OS X version number as the OS, and put
	 * the Darwin information in parentheses.
	 *
	 * Alas, Gestalt() is deprecated in Mountain Lion, so the build
	 * fails if you treat deprecation warnings as fatal.  I don't
	 * know of any replacement API, so we fall back on reading
	 * /System/Library/CoreServices/ServerVersion.plist if it
	 * exists, otherwise /System/Library/CoreServices/SystemVersion.plist,
	 * and using ProductUserVisibleVersion.  We also get the build
	 * version from ProductBuildVersion and the product name from
	 * ProductName.
	 */
	version_plist_file_url = CFURLCreateFromFileSystemRepresentation(NULL,
	    server_version_plist_path, sizeof server_version_plist_path - 1,
	    false);
	if (version_plist_file_url == NULL)
		return FALSE;
	version_plist_stream = CFReadStreamCreateWithFile(NULL,
	    version_plist_file_url);
	CFRelease(version_plist_file_url);
	if (version_plist_stream == NULL)
		return FALSE;
	if (!CFReadStreamOpen(version_plist_stream)) {
		CFRelease(version_plist_stream);

		/*
		 * Try SystemVersion.plist.
		 */
		version_plist_file_url = CFURLCreateFromFileSystemRepresentation(NULL,
		    system_version_plist_path, sizeof system_version_plist_path - 1,
		    false);
		if (version_plist_file_url == NULL)
			return FALSE;
		version_plist_stream = CFReadStreamCreateWithFile(NULL,
		    version_plist_file_url);
		CFRelease(version_plist_file_url);
		if (version_plist_stream == NULL)
			return FALSE;
		if (!CFReadStreamOpen(version_plist_stream)) {
			CFRelease(version_plist_stream);
			return FALSE;
		}
	}
#ifdef HAVE_CFPROPERTYLISTCREATEWITHSTREAM
	version_dict = (CFDictionaryRef)CFPropertyListCreateWithStream(NULL,
	    version_plist_stream, 0, kCFPropertyListImmutable,
	    NULL, NULL);
#else
	version_dict = (CFDictionaryRef)CFPropertyListCreateFromStream(NULL,
	    version_plist_stream, 0, kCFPropertyListImmutable,
	    NULL, NULL);
#endif
	if (version_dict == NULL) {
		CFRelease(version_plist_stream);
		return FALSE;
	}
	if (CFGetTypeID(version_dict) != CFDictionaryGetTypeID()) {
		/* This is *supposed* to be a dictionary.  Punt. */
		CFRelease(version_dict);
		CFReadStreamClose(version_plist_stream);
		CFRelease(version_plist_stream);
		return FALSE;
	}
	/* Get the product name string. */
	string = get_string_from_dictionary(version_dict,
	    CFSTR("ProductName"));
	if (string == NULL) {
		CFRelease(version_dict);
		CFReadStreamClose(version_plist_stream);
		CFRelease(version_plist_stream);
		return FALSE;
	}
	g_string_append_printf(str, "%s", string);
	g_free(string);

	/* Get the OS version string. */
	string = get_string_from_dictionary(version_dict,
	    CFSTR("ProductUserVisibleVersion"));
	if (string == NULL) {
		CFRelease(version_dict);
		CFReadStreamClose(version_plist_stream);
		CFRelease(version_plist_stream);
		return FALSE;
	}
	g_string_append_printf(str, " %s", string);
	g_free(string);

	/* Get the build string */
	string = get_string_from_dictionary(version_dict,
	    CFSTR("ProductBuildVersion"));
	if (string == NULL) {
		CFRelease(version_dict);
		CFReadStreamClose(version_plist_stream);
		CFRelease(version_plist_stream);
		return FALSE;
	}
	g_string_append_printf(str, ", build %s", string);
	g_free(string);
	CFRelease(version_dict);
	CFReadStreamClose(version_plist_stream);
	CFRelease(version_plist_stream);
	return TRUE;
}
예제 #12
0
static int
fuse_system_get_version(int *major, int *minor, int *bugfix)
{
    int ret = 0;

    CFStringRef plist_path = CFSTR(SYSTEM_VERSION_PATH);

    CFURLRef plist_url = CFURLCreateWithFileSystemPath(
            kCFAllocatorDefault, plist_path, kCFURLPOSIXPathStyle, false);
    CFReadStreamRef plist_stream = CFReadStreamCreateWithFile(
            kCFAllocatorDefault, plist_url);

    CFRelease(plist_url);
    if (!plist_stream) {
        return 1;
    }
    if (!CFReadStreamOpen(plist_stream)) {
        CFRelease(plist_stream);
        return 1;
    }

    CFPropertyListRef plist = CFPropertyListCreateWithStream(
            kCFAllocatorDefault, plist_stream, 0, kCFPropertyListImmutable,
            NULL, NULL);

    CFReadStreamClose(plist_stream);
    CFRelease(plist_stream);
    if (!plist) {
        return 1;
    }

    CFStringRef version = CFDictionaryGetValue(plist, CFSTR("ProductVersion"));
    if (!version) {
        ret = 1;
        goto out_plist;
    }

    CFArrayRef components = CFStringCreateArrayBySeparatingStrings(
            kCFAllocatorDefault, version, CFSTR("."));
    if (!components) {
        ret = 1;
        goto out_plist;
    }

    CFIndex count = CFArrayGetCount(components);

#define component_get(components, count, index) \
        ((index) < (count) \
         ? CFStringGetIntValue(CFArrayGetValueAtIndex((components), (index))) \
         : 0)

    if (major) {
        *major = component_get(components, count, 0);
    }
    if (minor) {
        *minor = component_get(components, count, 1);
    }
    if (bugfix) {
        *bugfix = component_get(components, count, 2);
    }

#undef component_get

    CFRelease(components);

out_plist:
    CFRelease(plist);

    return ret;
}
예제 #13
0
EMFInfo* EMF_init(Volume* volume, char* imagePath)
{
	uint8_t* emfk = NULL;
	uint8_t* dkey = NULL;
	
	uint64_t volume_id = *((uint64_t*) (&volume->volumeHeader->finderInfo[6]));
	FLIPENDIAN(volume_id);
	
	if(imagePath == NULL)
		imagePath = ".";
		
	printf("Volume identifier : %llx\n", volume_id);
	printf("Searching for %s/%llx.plist\n", imagePath, volume_id);
	
	CFStringRef path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s/%llx.plist"), imagePath, volume_id);
	
	CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, FALSE);
	CFRelease(path);
	
	CFReadStreamRef stream = CFReadStreamCreateWithFile(NULL, fileURL);
	CFRelease(fileURL);
	
	if(stream == NULL)
	{
		return NULL;
	}
	if(!CFReadStreamOpen(stream))
	{
		fprintf(stderr, "Cannot open file\n");
		return NULL;
	}
	CFPropertyListRef dict = CFPropertyListCreateWithStream(NULL, stream, 0, kCFPropertyListImmutable, NULL, NULL);

	CFRelease(stream);
	
	if (dict == NULL || CFGetTypeID(dict) != CFDictionaryGetTypeID())
		return NULL;
	
	CFStringRef emfHex = CFDictionaryGetValue(dict, CFSTR("EMF"));
	CFStringRef dkeyHex = CFDictionaryGetValue(dict, CFSTR("DKey"));
	CFNumberRef dataVolumeOffset = CFDictionaryGetValue (dict, CFSTR("dataVolumeOffset"));
	
	if (emfHex == NULL || CFGetTypeID(emfHex) != CFStringGetTypeID())
		return NULL;
	if (dkeyHex == NULL || CFGetTypeID(dkeyHex) != CFStringGetTypeID())
		return NULL;
	if (dataVolumeOffset == NULL || CFGetTypeID(dataVolumeOffset) != CFNumberGetTypeID())
		return NULL;

	EMFInfo* emf = malloc(sizeof(EMFInfo));
	
	if(emf == NULL)
		return NULL;

	memset(emf, 0, sizeof(EMFInfo));
	
	emf->volume = volume;
	
	CFNumberGetValue(dataVolumeOffset, kCFNumberLongType, &emf->volume_offset);
	
	printf("Data partition offset = %llx\n", emf->volume_offset);
	
	if(ConvertHexaCFString(emfHex, &emfk) != 32)
	{
		fprintf(stderr, "Invalid EMF key\n");
		free(emf);
		return NULL;
	}
	if(ConvertHexaCFString(dkeyHex, &dkey) != 32)
	{
		fprintf(stderr, "Invalid DKey key\n");
		free(emf);
		return NULL;
	}
	
	AES_set_encrypt_key(emfk, 32*8, &(emf->emfkey));
	AES_set_decrypt_key(dkey, 32*8, &(emf->classKeys[CLASS_DKEY-1]));
	emf->classKeys_bitset |= 1 << CLASS_DKEY;
	
	CFDictionaryRef classKeys = CFDictionaryGetValue(dict, CFSTR("classKeys"));
	
	if(classKeys != NULL && CFGetTypeID(classKeys) == CFDictionaryGetTypeID())
	{
		printf("Reading class keys, NSProtectionComplete files should be decrypted OK\n");
		CFDictionaryApplyFunction(classKeys, grabClassKey, (void*) emf);
	}
	else
	{
		printf("Only NSProtectionNone files will be decrypted\n");
	}
	
	free(emfk);
	free(dkey);
	return emf;
}