bool OggSpeexMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; // TODO: Use unique_ptr once the switch to C++11 STL is made std::auto_ptr<TagLib::FileStream> stream(new TagLib::FileStream(reinterpret_cast<const char *>(buf), true)); if(!stream->isOpen()) { if(error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” could not be opened for reading."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Input/output error"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file may have been renamed, moved, deleted, or you may not have appropriate permissions."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } TagLib::Ogg::Speex::File file(stream.get()); if(!file.isValid()) { if(nullptr != error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg Speex file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not an Ogg Speex file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("Ogg Speex")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) { std::vector<AttachedPicture *> pictures; AddXiphCommentToDictionary(mMetadata, pictures, file.tag()); for(auto picture : pictures) AddSavedPicture(picture); } return true; }
bool WavPackMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, FALSE, buf, PATH_MAX)) return false; auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::WavPack::File file(stream); if(!file.isValid()) { if(nullptr != error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid WavPack file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not a WavPack file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("WavPack")); if(file.audioProperties()) { auto properties = file.audioProperties(); AddAudioPropertiesToDictionary(mMetadata, properties); if(properties->bitsPerSample()) AddIntToDictionary(mMetadata, kPropertiesBitsPerChannelKey, properties->bitsPerSample()); if(properties->sampleFrames()) AddIntToDictionary(mMetadata, kPropertiesTotalFramesKey, properties->sampleFrames()); } if(file.ID3v1Tag()) AddID3v1TagToDictionary(mMetadata, file.ID3v1Tag()); if(file.APETag()) { std::vector<AttachedPicture *> pictures; AddAPETagToDictionary(mMetadata, pictures, file.APETag()); for(auto picture : pictures) AddSavedPicture(picture); } return true; }
void SFB::Audio::Metadata::MergeChangedMetadataIntoMetadata() { CFIndex count = CFDictionaryGetCount(mChangedMetadata); CFTypeRef *keys = (CFTypeRef *)malloc(sizeof(CFTypeRef) * (size_t)count); CFTypeRef *values = (CFTypeRef *)malloc(sizeof(CFTypeRef) * (size_t)count); CFDictionaryGetKeysAndValues(mChangedMetadata, keys, values); for(CFIndex i = 0; i < count; ++i) { if(kCFNull == values[i]) CFDictionaryRemoveValue(mMetadata, keys[i]); else CFDictionarySetValue(mMetadata, keys[i], values[i]); } free(keys), keys = nullptr; free(values), values = nullptr; CFDictionaryRemoveAllValues(mChangedMetadata); auto iter = std::begin(mPictures); while(iter != std::end(mPictures)) { auto picture = *iter; if(AttachedPicture::ChangeState::Removed == picture->mState) iter = mPictures.erase(iter); else { picture->MergeChangedMetadataIntoMetadata(); picture->mState = AttachedPicture::ChangeState::Saved; ++iter; } } }
void SFB::Audio::Metadata::RevertUnsavedChanges() { CFDictionaryRemoveAllValues(mChangedMetadata); for(auto picture : mPictures) { if(AttachedPicture::ChangeState::Removed == picture->mState) picture->mState = AttachedPicture::ChangeState::Saved; picture->RevertUnsavedChanges(); } }
void CASettingsStorage::RemoveAllValues() { // make sure our cache is up to date RefreshSettings(); // remove the given key CFDictionaryRemoveAllValues(mSettingsCache); // write the settings to the file SaveSettings(); }
void rb_gc_call_finalizer_at_exit(void) { if (__os_finalizers != NULL) { CFDictionaryApplyFunction((CFDictionaryRef)__os_finalizers, os_finalize_cb, NULL); CFDictionaryRemoveAllValues(__os_finalizers); CFRelease(__os_finalizers); } auto_collect(__auto_zone, AUTO_COLLECT_FULL_COLLECTION, NULL); }
CarbonEventHandler::~CarbonEventHandler() { if (mHandlers != NULL) { int count = CFDictionaryGetCount(mHandlers); EventHandlerRef *theHandlers = (EventHandlerRef*) malloc(count * sizeof(EventHandlerRef)); CFDictionaryGetKeysAndValues(mHandlers, NULL, (const void **)theHandlers); for (int i = 0; i < count; i++) RemoveEventHandler(theHandlers[i]); CFDictionaryRemoveAllValues(mHandlers); CFRelease (mHandlers); free(theHandlers); } }
void SFB::Audio::Metadata::RevertUnsavedChanges() { CFDictionaryRemoveAllValues(mChangedMetadata); auto iter = std::begin(mPictures); while(iter != std::end(mPictures)) { auto picture = *iter; if(AttachedPicture::ChangeState::Removed == picture->mState) { picture->mState = AttachedPicture::ChangeState::Saved; picture->RevertUnsavedChanges(); } else picture->RevertUnsavedChanges(); } }
/* CF_EXPORT */ void CFNetServiceBrowserInvalidate(CFNetServiceBrowserRef b) { __CFNetServiceBrowser* browser = (__CFNetServiceBrowser*)b; // Lock the browser __CFSpinLock(&(browser->_lock)); // Release the user's context info if there is some and a release method if (browser->_client.info && browser->_client.release) browser->_client.release(browser->_client.info); // Cancel the outstanding trigger if (browser->_trigger) { // Remove the trigger from run loops and modes _CFTypeUnscheduleFromMultipleRunLoops(browser->_trigger, browser->_schedules); // Go ahead and invalidate the trigger _CFTypeInvalidate(browser->_trigger); // Release the browse now. CFRelease(browser->_trigger); browser->_trigger = NULL; } // Need to clean up the service discovery stuff if there is if (browser->_browse) { // Release the underlying service discovery reference DNSServiceRefDeallocate(browser->_browse); browser->_browse = NULL; // Dump all the lists of items. CFDictionaryRemoveAllValues(browser->_found); CFArrayRemoveAllValues(browser->_adds); CFArrayRemoveAllValues(browser->_removes); } // Zero out the callback and client context. browser->_callback = NULL; memset(&(browser->_client), 0, sizeof(browser->_client)); // Unlock the browser. __CFSpinUnlock(&(browser->_lock)); }
Boolean SCPreferencesRemoveAllValues(SCPreferencesRef prefs) { SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; if (prefs == NULL) { /* sorry, you must provide a session */ _SCErrorSet(kSCStatusNoPrefsSession); return FALSE; } __SCPreferencesAccess(prefs); CFDictionaryRemoveAllValues(prefsPrivate->prefs); prefsPrivate->changed = TRUE; return TRUE; }
void SFB::Audio::AttachedPicture::MergeChangedMetadataIntoMetadata() { CFIndex count = CFDictionaryGetCount(mChangedMetadata); CFTypeRef *keys = (CFTypeRef *)malloc(sizeof(CFTypeRef) * (size_t)count); CFTypeRef *values = (CFTypeRef *)malloc(sizeof(CFTypeRef) * (size_t)count); CFDictionaryGetKeysAndValues(mChangedMetadata, keys, values); for(CFIndex i = 0; i < count; ++i) { if(kCFNull == values[i]) CFDictionaryRemoveValue(mMetadata, keys[i]); else CFDictionarySetValue(mMetadata, keys[i], values[i]); } free(keys), keys = nullptr; free(values), values = nullptr; CFDictionaryRemoveAllValues(mChangedMetadata); }
bool MP3Metadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::MPEG::File file(stream, TagLib::ID3v2::FrameFactory::instance()); if(!file.isValid()) { if(nullptr != error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MPEG file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not an MPEG file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MP3")); if(file.audioProperties()) { auto properties = file.audioProperties(); AddAudioPropertiesToDictionary(mMetadata, properties); // TODO: Is this too much information? #if 0 switch(properties->version()) { case TagLib::MPEG::Header::Version1: switch(properties->layer()) { case 1: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-1 Layer I")); break; case 2: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-1 Layer II")); break; case 3: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-1 Layer III")); break; } break; case TagLib::MPEG::Header::Version2: switch(properties->layer()) { case 1: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-2 Layer I")); break; case 2: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-2 Layer II")); break; case 3: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-2 Layer III")); break; } break; case TagLib::MPEG::Header::Version2_5: switch(properties->layer()) { case 1: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-2.5 Layer I")); break; case 2: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-2.5 Layer II")); break; case 3: CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MPEG-2.5 Layer III")); break; } break; } #endif if(properties->xingHeader() && properties->xingHeader()->totalFrames()) AddIntToDictionary(mMetadata, kPropertiesTotalFramesKey, properties->xingHeader()->totalFrames()); } if(file.APETag()) { std::vector<AttachedPicture *> pictures; AddAPETagToDictionary(mMetadata, pictures, file.APETag()); for(auto picture : pictures) AddSavedPicture(picture); } if(file.ID3v1Tag()) AddID3v1TagToDictionary(mMetadata, file.ID3v1Tag()); if(file.ID3v2Tag()) { std::vector<AttachedPicture *> pictures; AddID3v2TagToDictionary(mMetadata, pictures, file.ID3v2Tag()); for(auto picture : pictures) AddSavedPicture(picture); } return true; }
bool FLACMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::FLAC::File file(stream, TagLib::ID3v2::FrameFactory::instance()); if(!file.isValid()) { if(nullptr != error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("FLAC")); if(file.audioProperties()) { auto properties = file.audioProperties(); AddAudioPropertiesToDictionary(mMetadata, properties); if(properties->sampleWidth()) AddIntToDictionary(mMetadata, kPropertiesBitsPerChannelKey, properties->sampleWidth()); if(properties->sampleFrames()) AddLongLongToDictionary(mMetadata, kPropertiesTotalFramesKey, properties->sampleFrames()); } // Add all tags that are present if(file.ID3v1Tag()) AddID3v1TagToDictionary(mMetadata, file.ID3v1Tag()); if(file.ID3v2Tag()) { std::vector<AttachedPicture *> pictures; AddID3v2TagToDictionary(mMetadata, pictures, file.ID3v2Tag()); for(auto picture : pictures) AddSavedPicture(picture); } if(file.xiphComment()) { std::vector<AttachedPicture *> pictures; AddXiphCommentToDictionary(mMetadata, pictures, file.xiphComment()); for(auto picture : pictures) AddSavedPicture(picture); } // Add album art for(auto iter : file.pictureList()) { CFDataRef data = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(iter->data().data()), iter->data().size()); CFStringRef description = nullptr; if(!iter->description().isNull()) description = CFStringCreateWithCString(kCFAllocatorDefault, iter->description().toCString(true), kCFStringEncodingUTF8); AttachedPicture *picture = new AttachedPicture(data, static_cast<AttachedPicture::Type>(iter->type()), description); AddSavedPicture(picture); if(data) CFRelease(data), data = nullptr; if(description) CFRelease(description), description = nullptr; } return true; }
bool FLACMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new(); // ENOMEM sux if(NULL == chain) return false; if(!FLAC__metadata_chain_read(chain, reinterpret_cast<const char *>(buf))) { // Attempt to provide a descriptive error message if(NULL != error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 32, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); switch(FLAC__metadata_chain_status(chain)) { case FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE: { CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not a FLAC file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; break; } case FLAC__METADATA_CHAIN_STATUS_BAD_METADATA: { CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not a FLAC file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file contains bad metadata."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; break; } default: { CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not a FLAC file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; break; } } *error = CFErrorCreate(kCFAllocatorDefault, AudioMetadataErrorDomain, AudioMetadataFileFormatNotRecognizedError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } FLAC__metadata_chain_delete(chain), chain = NULL; return false; } FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new(); if(NULL == iterator) { FLAC__metadata_chain_delete(chain), chain = NULL; return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("FLAC")); FLAC__metadata_iterator_init(iterator, chain); FLAC__StreamMetadata *block = NULL; CFMutableDictionaryRef additionalMetadata = CFDictionaryCreateMutable(kCFAllocatorDefault, 32, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); do { block = FLAC__metadata_iterator_get_block(iterator); if(NULL == block) break; switch(block->type) { case FLAC__METADATA_TYPE_VORBIS_COMMENT: for(unsigned i = 0; i < block->data.vorbis_comment.num_comments; ++i) { char *fieldName = NULL; char *fieldValue = NULL; // Let FLAC parse the comment for us if(!FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(block->data.vorbis_comment.comments[i], &fieldName, &fieldValue)) { // Ignore malformed comments continue; } CFStringRef key = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(fieldName), strlen(fieldName), kCFStringEncodingASCII, false, kCFAllocatorMalloc); CFStringRef value = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(fieldValue), strlen(fieldValue), kCFStringEncodingUTF8, false, kCFAllocatorMalloc); if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ALBUM"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataAlbumTitleKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ARTIST"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataArtistKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ALBUMARTIST"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataAlbumArtistKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("COMPOSER"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataComposerKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("GENRE"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataGenreKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DATE"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataReleaseDateKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DESCRIPTION"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataCommentKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("TITLE"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataTitleKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("TRACKNUMBER"), kCFCompareCaseInsensitive)) { int num = CFStringGetIntValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num); CFDictionarySetValue(mMetadata, kMetadataTrackNumberKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("TRACKTOTAL"), kCFCompareCaseInsensitive)) { int num = CFStringGetIntValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num); CFDictionarySetValue(mMetadata, kMetadataTrackTotalKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("COMPILATION"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataCompilationKey, CFStringGetIntValue(value) ? kCFBooleanTrue : kCFBooleanFalse); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DISCNUMBER"), kCFCompareCaseInsensitive)) { int num = CFStringGetIntValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num); CFDictionarySetValue(mMetadata, kMetadataDiscNumberKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DISCTOTAL"), kCFCompareCaseInsensitive)) { int num = CFStringGetIntValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num); CFDictionarySetValue(mMetadata, kMetadataDiscTotalKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ISRC"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataISRCKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("MCN"), kCFCompareCaseInsensitive)) CFDictionarySetValue(mMetadata, kMetadataMCNKey, value); else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_REFERENCE_LOUDNESS"), kCFCompareCaseInsensitive)) { double num = CFStringGetDoubleValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num); CFDictionarySetValue(mMetadata, kReplayGainReferenceLoudnessKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_TRACK_GAIN"), kCFCompareCaseInsensitive)) { double num = CFStringGetDoubleValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num); CFDictionarySetValue(mMetadata, kReplayGainTrackGainKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_TRACK_PEAK"), kCFCompareCaseInsensitive)) { double num = CFStringGetDoubleValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num); CFDictionarySetValue(mMetadata, kReplayGainTrackPeakKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_ALBUM_GAIN"), kCFCompareCaseInsensitive)) { double num = CFStringGetDoubleValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num); CFDictionarySetValue(mMetadata, kReplayGainAlbumGainKey, number); CFRelease(number), number = NULL; } else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_ALBUM_PEAK"), kCFCompareCaseInsensitive)) { double num = CFStringGetDoubleValue(value); CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num); CFDictionarySetValue(mMetadata, kReplayGainAlbumPeakKey, number); CFRelease(number), number = NULL; } // Put all unknown tags into the additional metadata else CFDictionarySetValue(additionalMetadata, key, value); CFRelease(key), key = NULL; CFRelease(value), value = NULL; fieldName = NULL; fieldValue = NULL; } break; case FLAC__METADATA_TYPE_PICTURE: { CFDataRef data = CFDataCreate(kCFAllocatorDefault, block->data.picture.data, block->data.picture.data_length); CFDictionarySetValue(mMetadata, kAlbumArtFrontCoverKey, data); CFRelease(data), data = NULL; } break; case FLAC__METADATA_TYPE_STREAMINFO: { CFNumberRef sampleRate = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &block->data.stream_info.sample_rate); CFDictionarySetValue(mMetadata, kPropertiesSampleRateKey, sampleRate); CFRelease(sampleRate), sampleRate = NULL; CFNumberRef channelsPerFrame = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &block->data.stream_info.channels); CFDictionarySetValue(mMetadata, kPropertiesChannelsPerFrameKey, channelsPerFrame); CFRelease(channelsPerFrame), channelsPerFrame = NULL; CFNumberRef bitsPerChannel = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &block->data.stream_info.bits_per_sample); CFDictionarySetValue(mMetadata, kPropertiesBitsPerChannelKey, bitsPerChannel); CFRelease(bitsPerChannel), bitsPerChannel = NULL; CFNumberRef totalFrames = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &block->data.stream_info.total_samples); CFDictionarySetValue(mMetadata, kPropertiesTotalFramesKey, totalFrames); CFRelease(totalFrames), totalFrames = NULL; double length = static_cast<double>(block->data.stream_info.total_samples / block->data.stream_info.sample_rate); CFNumberRef duration = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &length); CFDictionarySetValue(mMetadata, kPropertiesDurationKey, duration); CFRelease(duration), duration = NULL; double losslessBitrate = static_cast<double>(block->data.stream_info.sample_rate * block->data.stream_info.channels * block->data.stream_info.bits_per_sample) / 1000; CFNumberRef bitrate = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &losslessBitrate); CFDictionarySetValue(mMetadata, kPropertiesBitrateKey, bitrate); CFRelease(bitrate), bitrate = NULL; } break; case FLAC__METADATA_TYPE_PADDING: break; case FLAC__METADATA_TYPE_APPLICATION: break; case FLAC__METADATA_TYPE_SEEKTABLE: break; case FLAC__METADATA_TYPE_CUESHEET: break; case FLAC__METADATA_TYPE_UNDEFINED: break; default: break; } } while(FLAC__metadata_iterator_next(iterator)); if(CFDictionaryGetCount(additionalMetadata)) SetAdditionalMetadata(additionalMetadata); CFRelease(additionalMetadata), additionalMetadata = NULL; FLAC__metadata_iterator_delete(iterator), iterator = NULL; FLAC__metadata_chain_delete(chain), chain = NULL; return true; }
/* CF_EXPORT */ void CFNetServiceBrowserStopSearch(CFNetServiceBrowserRef b, CFStreamError* error) { __CFNetServiceBrowser* browser = (__CFNetServiceBrowser*)b; // By default, the error is marked as a cancel CFStreamError extra = {kCFStreamErrorDomainNetServices , kCFNetServicesErrorCancel}; // Make sure error has a value. if (!error) error = &extra; // Lock down the browser __CFSpinLock(&(browser->_lock)); // Make sure there is something to cancel. if (browser->_trigger) { CFRunLoopSourceContext ctxt = { 0, // version browser, // info NULL, // retain NULL, // release NULL, // copyDescription NULL, // equal NULL, // hash NULL, // schedule NULL, // cancel (void(*)(void*))(&_BrowserCancel) // perform }; // Remove the trigger from run loops and modes _CFTypeUnscheduleFromMultipleRunLoops(browser->_trigger, browser->_schedules); // Go ahead and invalidate the trigger _CFTypeInvalidate(browser->_trigger); // Release the trigger now. CFRelease(browser->_trigger); // Need to clean up the service discovery stuff if there is if (browser->_browse) { // Release the underlying service discovery reference DNSServiceRefDeallocate(browser->_browse); browser->_browse = NULL; // Dump all the lists of items. CFDictionaryRemoveAllValues(browser->_found); CFArrayRemoveAllValues(browser->_adds); CFArrayRemoveAllValues(browser->_removes); } // Copy the error into place memmove(&(browser->_error), error, sizeof(error[0])); // Create the cancel source browser->_trigger = CFRunLoopSourceCreate(CFGetAllocator(browser), 0, &ctxt); // If the cancel was created, need to schedule and signal it. if (browser->_trigger) { CFArrayRef schedules = browser->_schedules; CFIndex i, count = CFArrayGetCount(schedules); // Schedule the new trigger _CFTypeScheduleOnMultipleRunLoops(browser->_trigger, schedules); // Signal the cancel for immediate attention. CFRunLoopSourceSignal((CFRunLoopSourceRef)(browser->_trigger)); // Make sure the signal can make it through for (i = 0; i < count; i += 2) { // Grab the run loop for checking CFRunLoopRef runloop = (CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i); // If it's sleeping, need to further check it. if (CFRunLoopIsWaiting(runloop)) { // Grab the mode for further check CFStringRef mode = CFRunLoopCopyCurrentMode(runloop); if (mode) { // If the trigger is in the right mode, need to wake up the run loop. if (CFRunLoopContainsSource(runloop, (CFRunLoopSourceRef)(browser->_trigger), mode)) { CFRunLoopWakeUp(runloop); } // Don't need this anymore. CFRelease(mode); } } } } } // Unlock the browser __CFSpinUnlock(&(browser->_lock)); }
// // Insert New NDAS device info. // // Return : false if Bad parameters or No memory. // true if success. // bool NDASPreferencesInsert(PNDASPreferencesParameter parameter) { CFStringRef strEntryKey = NULL; CFStringRef strIDKey[4] = { NULL }; CFStringRef strWriteKeyKey = NULL; CFStringRef strConfigurationKey = NULL; CFStringRef strIDValue[4] = { NULL }; CFStringRef strWriteKeyValue = NULL; CFNumberRef numberConfigurationValue = NULL; CFStringRef strNameKey = NULL; CFMutableDictionaryRef dictEntry = NULL; int count; bool result = false; if(parameter->slotNumber == 0) { return false; } // Create Dict dictEntry = CFDictionaryCreateMutable (kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (NULL == dictEntry) { return false; } // Copy ID for(count = 0; count < 4; count++) { // Create Key. strIDKey[count] = CFStringCreateWithFormat(NULL, NULL, CFSTR(KEY_ID_STRING), count); // Create Value. strIDValue[count] = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), parameter->chID[count]); if (NULL == strIDKey[count] || NULL == strIDValue[count]) { goto cleanup; } if (!NDASPreferencesSetIDorWriteKey(dictEntry, strIDKey[count], strIDValue[count])) { goto cleanup; } } // Copy WriteKey. strWriteKeyKey = CFStringCreateWithFormat(NULL, NULL, CFSTR(KEY_WRITEKEY_STRING)); strWriteKeyValue = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), parameter->chWriteKey); if (NULL == strWriteKeyKey || NULL == strWriteKeyValue) { goto cleanup; } if(!NDASPreferencesSetIDorWriteKey(dictEntry, strWriteKeyKey, strWriteKeyValue)) { goto cleanup; } // Copy Name strNameKey = CFStringCreateWithFormat(NULL, NULL, CFSTR(KEY_NAME_STRING)); if (NULL == strNameKey) { goto cleanup; } //strNameValue = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), parameter->Name); //strNameValue = CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar *)parameter->Name, MAX_NDAS_NAME_SIZE / 2); CFDictionaryAddValue(dictEntry, strNameKey, parameter->cfsName ); // Copy Configuration. strConfigurationKey = CFStringCreateWithFormat(NULL, NULL, CFSTR(KEY_CONFIGURATION_STRING)); numberConfigurationValue = CFNumberCreate (NULL, kCFNumberSInt32Type, ¶meter->configuration); if (NULL == strConfigurationKey || NULL == numberConfigurationValue) { goto cleanup; } CFDictionaryAddValue(dictEntry, strConfigurationKey, numberConfigurationValue); // Slot Number is the Key. strEntryKey = CFStringCreateWithFormat(NULL, NULL, CFSTR(KEY_SLOT_NUMBER_STRING), parameter->slotNumber); // Set Values. CFPreferencesSetValue( strEntryKey, dictEntry, NDAS_PREFERENCES_FILE_REGISTER, kCFPreferencesAnyUser, kCFPreferencesCurrentHost ); // Write out the preference data. CFPreferencesSynchronize( NDAS_PREFERENCES_FILE_REGISTER, kCFPreferencesAnyUser, kCFPreferencesCurrentHost ); result = true; cleanup: CFDictionaryRemoveAllValues(dictEntry); // Clean up. if(strEntryKey) CFRelease(strEntryKey); if(dictEntry) CFRelease(dictEntry); if(strWriteKeyKey) CFRelease(strWriteKeyKey); if(strWriteKeyValue) CFRelease(strWriteKeyValue); if(strConfigurationKey) CFRelease(strConfigurationKey); if(numberConfigurationValue) CFRelease(numberConfigurationValue); if(strNameKey) CFRelease(strNameKey); for(count = 0; count < 4; count++) { if(strIDKey[count]) CFRelease(strIDKey[count]); if(strIDValue[count]) CFRelease(strIDValue[count]); } return result; }
/* static */ void _BrowseReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* serviceName, const char* regtype, const char* replyDomain, void* context) { __CFNetServiceBrowser* browser = context; CFNetServiceBrowserClientCallBack cb = NULL; CFStreamError error = {0, 0}; void* info = NULL; CFNetServiceRef service = NULL; // Retain here to guarantee safety really after the trigger release, // but definitely before the callback. CFRetain(browser); // Lock the browser __CFSpinLock(&browser->_lock); // If the browse canceled, don't need to do any of this. if (browser->_browse) { // If there is an error, fold the browse. if (errorCode) { // Save the error browser->_error.error = _DNSServiceErrorToCFNetServiceError(errorCode); browser->_error.domain = kCFStreamErrorDomainNetServices; // Remove the browse from run loops and modes _CFTypeUnscheduleFromMultipleRunLoops(browser->_trigger, browser->_schedules); // Go ahead and invalidate the socket CFSocketInvalidate((CFSocketRef)(browser->_trigger)); // Release the browse now. CFRelease(browser->_trigger); browser->_trigger = NULL; // Clean up the underlying service discovery stuff DNSServiceRefDeallocate(browser->_browse); browser->_browse = NULL; // Dump all the lists of items. CFDictionaryRemoveAllValues(browser->_found); CFArrayRemoveAllValues(browser->_adds); CFArrayRemoveAllValues(browser->_removes); } // If got service info from service discovery, create the CFNetServiceRef. else if (serviceName && regtype && replyDomain) { // Create CFString's for each of the service components CFAllocatorRef alloc = CFGetAllocator(browser); CFStringRef domain = CFStringCreateWithCString(alloc, replyDomain, kCFStringEncodingUTF8); CFStringRef type = CFStringCreateWithCString(alloc, regtype, kCFStringEncodingUTF8); CFStringRef name = CFStringCreateWithCString(alloc, serviceName, kCFStringEncodingUTF8); // Can only make the service if all the strings were created. This // will skip over items that are not properly UTF8 encoded on the wire. if (domain && type && name) service = _CFNetServiceCreateCommon(alloc, domain, type, name, 0); if (domain) CFRelease(domain); if (type) CFRelease(type); if (name) CFRelease(name); if (service) { intptr_t count = (intptr_t)CFDictionaryGetValue(browser->_found, service); if (flags & kDNSServiceFlagsAdd) { count++; if (count != 1) CFDictionaryReplaceValue(browser->_found, service, (const void*)count); else { CFIndex i = CFArrayGetFirstIndexOfValue(browser->_removes, CFRangeMake(0, CFArrayGetCount(browser->_removes)), service); CFDictionaryAddValue(browser->_found, service, (const void*)count); CFArrayAppendValue(browser->_adds, service); if (i != kCFNotFound) CFArrayRemoveValueAtIndex(browser->_removes, i); } } else { count--; if (count > 0) CFDictionaryReplaceValue(browser->_found, service, (const void*)count); else { CFIndex i = CFArrayGetFirstIndexOfValue(browser->_adds, CFRangeMake(0, CFArrayGetCount(browser->_adds)), service); CFDictionaryRemoveValue(browser->_found, service); CFArrayAppendValue(browser->_removes, service); if (i != kCFNotFound) CFArrayRemoveValueAtIndex(browser->_adds, i); } } CFRelease(service); } } cb = browser->_callback; // Save the error and client information for the callback memmove(&error, &(browser->_error), sizeof(error)); info = browser->_client.info; } // If there is a callback, inform the client of the error. if (cb && error.error) { // Unlock the browser so the callback can be made safely. __CFSpinUnlock(&browser->_lock); cb((CFNetServiceBrowserRef)browser, 0, NULL, &error, info); } else if (cb && ((flags & kDNSServiceFlagsMoreComing) == 0)) { CFIndex i, adds = CFArrayGetCount(browser->_adds); CFIndex removes = CFArrayGetCount(browser->_removes); CFIndex total = adds + removes; for (i = 0; i < adds; i++) { const void* saved = browser->_trigger; service = (CFNetServiceRef)CFArrayGetValueAtIndex(browser->_adds, i); // Unlock the browser so the callback can be made safely. __CFSpinUnlock(&browser->_lock); cb((CFNetServiceBrowserRef)browser, (i == (total - 1)) ? 0 : kCFNetServiceFlagMoreComing, service, &error, info); // Lock the browser __CFSpinLock(&browser->_lock); if (saved != browser->_trigger) { cb = NULL; break; } } if (cb) { for (i = 0; i < removes; i++) { const void* saved = browser->_trigger; service = (CFNetServiceRef)CFArrayGetValueAtIndex(browser->_removes, i); // Unlock the browser so the callback can be made safely. __CFSpinUnlock(&browser->_lock); cb((CFNetServiceBrowserRef)browser, kCFNetServiceFlagRemove | ((i == (removes - 1)) ? 0 : kCFNetServiceFlagMoreComing), service, &error, info); // Lock the browser __CFSpinLock(&browser->_lock); if (saved != browser->_trigger) break; } } // Dump the lists of items, so can start new again. CFArrayRemoveAllValues(browser->_adds); CFArrayRemoveAllValues(browser->_removes); // Unlock the browser so the callback can be made safely. __CFSpinUnlock(&browser->_lock); } else __CFSpinUnlock(&browser->_lock); // Go ahead and release now that the callback is done. CFRelease(browser); }
void DAPreferenceListRefresh( void ) { struct stat status1; struct stat status2; /* * Determine whether the preference list is up-to-date. */ if ( stat( ___PREFS_DEFAULT_DIR "/" "autodiskmount.plist", &status1 ) ) { __gDAPreferenceListTime1.tv_sec = 0; __gDAPreferenceListTime1.tv_nsec = 0; } if ( stat( ___PREFS_DEFAULT_DIR "/" _kDADaemonName ".plist", &status2 ) ) { __gDAPreferenceListTime2.tv_sec = 0; __gDAPreferenceListTime2.tv_nsec = 0; } if ( __gDAPreferenceListTime1.tv_sec != status1.st_mtimespec.tv_sec || __gDAPreferenceListTime1.tv_nsec != status1.st_mtimespec.tv_nsec || __gDAPreferenceListTime2.tv_sec != status2.st_mtimespec.tv_sec || __gDAPreferenceListTime2.tv_nsec != status2.st_mtimespec.tv_nsec ) { SCPreferencesRef preferences; __gDAPreferenceListTime1.tv_sec = status1.st_mtimespec.tv_sec; __gDAPreferenceListTime1.tv_nsec = status1.st_mtimespec.tv_nsec; __gDAPreferenceListTime2.tv_sec = status2.st_mtimespec.tv_sec; __gDAPreferenceListTime2.tv_nsec = status2.st_mtimespec.tv_nsec; /* * Clear the preference list. */ CFDictionaryRemoveAllValues( gDAPreferenceList ); /* * Build the preference list. */ preferences = SCPreferencesCreate( kCFAllocatorDefault, CFSTR( "autodiskmount" ), CFSTR( "autodiskmount.plist" ) ); if ( preferences ) { CFTypeRef value; value = SCPreferencesGetValue( preferences, CFSTR( "AutomountDisksWithoutUserLogin" ) ); if ( value == kCFBooleanTrue ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountDeferExternalKey, kCFBooleanFalse ); CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountDeferRemovableKey, kCFBooleanFalse ); CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountTrustExternalKey, kCFBooleanTrue ); } else if ( value == kCFBooleanFalse ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountDeferExternalKey, kCFBooleanFalse ); CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountDeferRemovableKey, kCFBooleanTrue ); CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountTrustExternalKey, kCFBooleanTrue ); } CFRelease( preferences ); } preferences = SCPreferencesCreate( kCFAllocatorDefault, CFSTR( _kDADaemonName ), CFSTR( _kDADaemonName ".plist" ) ); if ( preferences ) { CFTypeRef value; value = SCPreferencesGetValue( preferences, kDAPreferenceMountDeferExternalKey ); if ( value ) { if ( CFGetTypeID( value ) == CFBooleanGetTypeID( ) ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountDeferExternalKey, value ); } } value = SCPreferencesGetValue( preferences, kDAPreferenceMountDeferInternalKey ); if ( value ) { if ( CFGetTypeID( value ) == CFBooleanGetTypeID( ) ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountDeferInternalKey, value ); } } value = SCPreferencesGetValue( preferences, kDAPreferenceMountDeferRemovableKey ); if ( value ) { if ( CFGetTypeID( value ) == CFBooleanGetTypeID( ) ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountDeferRemovableKey, value ); } } value = SCPreferencesGetValue( preferences, kDAPreferenceMountTrustExternalKey ); if ( value ) { if ( CFGetTypeID( value ) == CFBooleanGetTypeID( ) ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountTrustExternalKey, value ); } } value = SCPreferencesGetValue( preferences, kDAPreferenceMountTrustInternalKey ); if ( value ) { if ( CFGetTypeID( value ) == CFBooleanGetTypeID( ) ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountTrustInternalKey, value ); } } value = SCPreferencesGetValue( preferences, kDAPreferenceMountTrustRemovableKey ); if ( value ) { if ( CFGetTypeID( value ) == CFBooleanGetTypeID( ) ) { CFDictionarySetValue( gDAPreferenceList, kDAPreferenceMountTrustRemovableKey, value ); } } CFRelease( preferences ); } } }
/* Create and identity and try to retrieve it. */ static void tests(void) { SecCertificateRef cert = NULL; SecKeyRef privKey = NULL; SecIdentityRef identity = NULL; isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), NULL, "create certificate"); isnt(privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1), kSecKeyEncodingPkcs1), NULL, "create private key"); const void *certkeys[] = { kSecValueRef }; const void *certvalues[] = { cert }; CFDictionaryRef certDict = CFDictionaryCreate(NULL, certkeys, certvalues, array_size(certkeys), NULL, NULL); ok_status(SecItemAdd(certDict, NULL), "add certificate"); CFReleaseNull(certDict); const void *privkeys[] = { kSecValueRef }; const void *privvalues[] = { privKey }; CFDictionaryRef privDict = CFDictionaryCreate(NULL, privkeys, privvalues, array_size(privkeys), NULL, NULL); ok_status(SecItemAdd(privDict, NULL), "add private key"); CFReleaseNull(privDict); isnt(identity = SecIdentityCreate(NULL, cert, privKey), NULL, "create identity"); /* Lookup the key and certificate using SecItemCopyMatching(). */ CFDataRef pk_digest = CFDataCreate(NULL, _k1_digest, sizeof(_k1_digest)); const void *q_keys[] = { kSecClass, kSecAttrApplicationLabel, kSecReturnRef }; const void *q_values[] = { kSecClassKey, pk_digest, kCFBooleanTrue }; CFDictionaryRef query = CFDictionaryCreate(NULL, q_keys, q_values, array_size(q_keys), NULL, NULL); CFTypeRef result_key; ok_status(SecItemCopyMatching(query, &result_key), "lookup key"); isnt(CFEqual(privKey, result_key), 0, "keys match"); CFReleaseNull(query); q_keys[1] = kSecAttrPublicKeyHash; q_values[0] = kSecClassCertificate; query = CFDictionaryCreate(NULL, q_keys, q_values, array_size(q_keys), NULL, NULL); CFTypeRef result_cert; ok_status(SecItemCopyMatching(query, &result_cert), "lookup certificate"); isnt(CFEqual(cert, result_cert), 0, "certificates match"); CFReleaseNull(query); /* Cleanup. */ CFReleaseNull(result_key); CFReleaseNull(result_cert); /* identity lookup */ const void *idnt_keys[] = { kSecClass, kSecAttrApplicationLabel, kSecReturnRef }; const void *idnt_values[] = { kSecClassIdentity, pk_digest, kCFBooleanTrue }; CFTypeRef result_idnt; SecCertificateRef result_cert2; query = CFDictionaryCreate(NULL, idnt_keys, idnt_values, array_size(idnt_keys), NULL, NULL); ok_status(SecItemCopyMatching(query, &result_idnt), "lookup identity"); isnt(result_idnt, NULL, "found identity?"); is(CFGetRetainCount(result_idnt), 1, "result_idnt rc = 1"); isnt(CFEqual(identity, result_idnt), 0, "identities match"); CFReleaseNull(identity); ok_status(SecIdentityCopyCertificate((SecIdentityRef)result_idnt, &result_cert2), "get cert from identity"); isnt(CFEqual(cert, result_cert2), 0, "certificates match"); CFRelease(query); CFRelease(pk_digest); CFReleaseNull(result_cert2); certDict = CFDictionaryCreate(NULL, certkeys, certvalues, array_size(certkeys), NULL, NULL); ok_status(SecItemDelete(certDict), "delete certificate via ref"); is_status(errSecItemNotFound, SecItemCopyMatching(certDict, NULL), "verify certificate is gone"); CFReleaseNull(certDict); privDict = CFDictionaryCreate(NULL, privkeys, privvalues, array_size(privkeys), NULL, NULL); ok_status(SecItemDelete(privDict), "delete key via ref"); is_status(errSecItemNotFound, SecItemCopyMatching(privDict, NULL), "verify key is gone"); CFReleaseNull(privDict); /* add certificate to offset cert row id from key row id */ SecCertificateRef apple_ca_cert = NULL; isnt(apple_ca_cert = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), NULL, "create apple ca certificate"); CFDictionaryRef appleCertDict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&apple_ca_cert, 1, NULL, NULL); ok_status(SecItemAdd(appleCertDict, NULL), "add apple ca certificate to offset key and cert rowid"); /* add identity, get persistent ref */ const void *keys_identity[] = { kSecValueRef, kSecReturnPersistentRef }; const void *values_identity[] = { result_idnt, kCFBooleanTrue }; CFDictionaryRef identity_add = CFDictionaryCreate(NULL, keys_identity, values_identity, array_size(keys_identity), NULL, NULL); CFTypeRef persist = NULL; ok_status(SecItemAdd(identity_add, &persist), "add identity ref"); ok(persist, "got back persistent ref"); /* <rdar://problem/6537195> SecItemAdd returns success when it shouldn't */ CFTypeRef persist_again = NULL; is_status(errSecDuplicateItem, SecItemAdd(identity_add, &persist_again), "fail to add identity ref again"); ok(!persist_again, "no persistent ref this time"); /* find by persistent ref */ const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef }; const void *values_persist[] = { kCFBooleanTrue, persist }; CFDictionaryRef persist_find = CFDictionaryCreate(NULL, keys_persist, values_persist, (array_size(keys_persist)), NULL, NULL); CFTypeRef results2 = NULL; ok_status(SecItemCopyMatching(persist_find, &results2), "find identity by persistent ref"); is(CFGetRetainCount(results2), 1, "results2 rc = 1"); // not implemented ok(CFEqual(result_idnt, results2), "same item (attributes)"); CFReleaseNull(results2); /* find identity, key and cert by ref and return persistent ref */ const void *keys_ref_to_persist[] = { kSecReturnPersistentRef, kSecValueRef }; const void *values_ref_to_persist[] = { kCFBooleanTrue, NULL }; CFTypeRef items[] = { result_idnt, privKey, cert, NULL }; CFTypeRef *item = items; while (*item) { values_ref_to_persist[1] = *item; CFDictionaryRef ref_to_persist_find = CFDictionaryCreate(NULL, keys_ref_to_persist, values_ref_to_persist, (array_size(keys_ref_to_persist)), NULL, NULL); results2 = NULL; ok_status(SecItemCopyMatching(ref_to_persist_find, &results2), "find persistent ref for identity ref"); ok(NULL != results2, "good persistent ref"); is(CFGetRetainCount(results2), 1, "results2 rc = 1"); CFReleaseNull(results2); CFReleaseNull(ref_to_persist_find); item++; } /* delete identity by identity ref */ ok_status(SecItemDelete(identity_add), "delete identity by identity ref"); is(SecItemCopyMatching(persist_find, &results2), errSecItemNotFound, "make sure identity by persistent ref is no longer there"); CFRelease(persist_find); CFReleaseNull(persist); ok_status(SecItemAdd(identity_add, &persist), "add identity ref back"); CFRelease(identity_add); /* delete identity by persistent ref */ CFDictionaryRef persist_delete = CFDictionaryCreate(NULL, &kSecValuePersistentRef, &persist, 1, NULL, NULL); ok_status(SecItemDelete(persist_delete), "delete identity by persistent ref"); is(SecItemCopyMatching(persist_delete, &results2), errSecItemNotFound, "make sure identity by persistent ref is no longer there"); CFRelease(persist_delete); CFReleaseNull(persist); /* add identity with a label set */ CFStringRef zomg_label = CFSTR("zomg"); CFMutableDictionaryRef lbl_idnt_query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(lbl_idnt_query, kSecValueRef, result_idnt); CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label); ok_status(SecItemAdd(lbl_idnt_query, NULL), "add identity ref"); /* find identity with label*/ CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity); CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label); ok_status(SecItemCopyMatching(lbl_idnt_query, NULL), "find identity by label"); /* find certs with label */ CFTypeRef zomg_cert; CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassCertificate); CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label); CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue); ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_cert), "find cert by label"); /* find keys with label */ CFTypeRef zomg_key; CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassKey); CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label); CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue); ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_key), "find key by label"); /* update label on key */ CFStringRef new_label_value = CFSTR("zzzomg"); CFDictionaryRef new_label = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&kSecAttrLabel, (const void **)&new_label_value, 1, NULL, NULL); CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecValueRef, zomg_key); ok_status(SecItemUpdate(lbl_idnt_query, new_label), "update label to zzzomg for key"); CFTypeRef zomg_idnt = NULL; CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue); CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label); CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity); ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "still finding zomg ident"); CFReleaseNull(zomg_idnt); CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecValueRef, zomg_cert); ok_status(SecItemUpdate(lbl_idnt_query, new_label), "update label to zzzomg for cert"); CFReleaseNull(new_label); CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue); CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label); CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity); is_status(errSecItemNotFound, SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "no longer find identity by label"); CFDictionaryRemoveAllValues(lbl_idnt_query); CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue); CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, new_label_value); CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity); ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "finding ident with zzzomg label"); /* Find zomg identity with canonical issuer */ { unsigned char DN[] = { 0x30, 0x32, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43, 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c, 0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d }; unsigned int DN_len = 52; CFMutableDictionaryRef find_by_issuer = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); CFDataRef issuer = SecCertificateGetNormalizedIssuerContent(cert); CFTypeRef found_by_issuer = NULL; CFDictionarySetValue(find_by_issuer, kSecAttrIssuer, issuer); CFDictionarySetValue(find_by_issuer, kSecClass, kSecClassIdentity); CFDictionarySetValue(find_by_issuer, kSecReturnRef, kCFBooleanTrue); ok_status(SecItemCopyMatching(find_by_issuer, &found_by_issuer), "find identity by cert issuer"); ok(CFEqual(found_by_issuer, zomg_idnt), "should be same as zomg_idnt"); CFReleaseNull(found_by_issuer); issuer = CFDataCreate(kCFAllocatorDefault, DN, DN_len); CFDictionarySetValue(find_by_issuer, kSecAttrIssuer, issuer); ok_status(SecItemCopyMatching(find_by_issuer, &found_by_issuer), "find identity by cert issuer"); CFReleaseNull(issuer); ok(CFEqual(found_by_issuer, zomg_idnt), "should be same as zomg_idnt"); CFReleaseNull(found_by_issuer); CFReleaseNull(find_by_issuer); } ok_status(SecItemDelete(lbl_idnt_query), "delete ident with zzzomg label"); /* Delete the apple cert last */ ok_status(SecItemDelete(appleCertDict), "delete apple ca certificate"); CFReleaseNull(appleCertDict); CFReleaseNull(apple_ca_cert); CFRelease(zomg_key); CFRelease(zomg_cert); CFRelease(zomg_idnt); CFRelease(zomg_label); CFRelease(new_label_value); CFRelease(lbl_idnt_query); CFReleaseNull(result_idnt); CFReleaseNull(privKey); CFReleaseNull(cert); }
static void tests(void) { SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL; SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL; int keysize = 2048; CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize); const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size_num }; CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault, keygen_keys, keygen_vals, array_size(keygen_vals), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); CFReleaseNull(key_size_num); CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl")); int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions }; const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions }; CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault, key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} }; SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} }; SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} }; SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} }; SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} }; SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL }; ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate key pair"); ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "generate key pair"); int self_key_usage = kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign; CFNumberRef self_key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &self_key_usage); int path_len = 0; CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len); const void *self_key[] = { kSecCertificateKeyUsage, kSecCSRBasicContraintsPathLen }; const void *self_val[] = { self_key_usage_num, path_len_num }; CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault, self_key, self_val, array_size(self_key), NULL, NULL); const void * ca_o[] = { kSecOidOrganization, CFSTR("Apple Inc.") }; const void * ca_cn[] = { kSecOidCommonName, CFSTR("Root CA") }; CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL); CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL); const void *ca_dn_array[2]; ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL); ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL); CFArrayRef ca_rdns = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL); SecCertificateRef ca_cert = SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, ca_publicKey, ca_privateKey); SecCertificateRef ca_cert_phone_key = SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, phone_publicKey, phone_privateKey); CFReleaseSafe(self_signed_parameters); CFReleaseSafe(self_key_usage_num); CFReleaseSafe(path_len_num); CFReleaseNull(ca_o_dn); CFReleaseNull(ca_cn_dn); CFReleaseNull(ca_dn_array[0]); CFReleaseNull(ca_dn_array[1]); CFReleaseNull(ca_rdns); isnt(ca_cert, NULL, "got back a cert"); ok(SecCertificateIsSelfSignedCA(ca_cert), "cert is self-signed ca cert"); isnt(ca_cert_phone_key, NULL, "got back a cert"); ok(SecCertificateIsSelfSignedCA(ca_cert_phone_key), "cert is self-signed ca cert"); CFDataRef data = SecCertificateCopyData(ca_cert); //write_data("/tmp/ca_cert.der", data); CFReleaseSafe(data); SecIdentityRef ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, ca_privateKey); SecIdentityRef ca_identity_phone_key = SecIdentityCreate(kCFAllocatorDefault, ca_cert_phone_key, phone_privateKey); isnt(ca_identity, NULL, "got a identity"); isnt(ca_identity_phone_key, NULL, "got a identity"); CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL); ok_status(SecItemAdd(dict, NULL), "add ca identity"); CFReleaseSafe(dict); #if TARGET_OS_IPHONE TODO: { todo("Adding a cert with the same issuer/serial but a different key should return something other than errSecDuplicateItem"); #else { #endif dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity_phone_key, 1, NULL, NULL); is_status(errSecDuplicateItem, SecItemAdd(dict, NULL), "add ca identity"); CFReleaseSafe(dict); } CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, NULL, phone_publicKey, phone_privateKey); isnt(csr, NULL, "got back a csr"); CFReleaseNull(csr); //dict[kSecSubjectAltName, dict[ntPrincipalName, "*****@*****.**"]] CFStringRef nt_princ_name_val = CFSTR("*****@*****.**"); CFStringRef nt_princ_name_key = CFSTR("ntPrincipalName"); CFDictionaryRef nt_princ = CFDictionaryCreate(NULL, (const void **)&nt_princ_name_key, (const void **)&nt_princ_name_val, 1, NULL, NULL); CFDictionaryRef params = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltName, (const void **)&nt_princ, 1, NULL, NULL); csr = SecGenerateCertificateRequestWithParameters(atvs_phone, params, phone_publicKey, phone_privateKey); isnt(csr, NULL, "got back a csr"); //write_data("/var/tmp/csr-nt-princ", csr); CFReleaseNull(csr); CFReleaseNull(params); CFReleaseNull(nt_princ); csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, phone_publicKey, phone_privateKey); isnt(csr, NULL, "csr w/ params"); //write_data("/tmp/csr", csr); CFDataRef subject, extensions; CFStringRef challenge; ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr"); CFReleaseNull(csr); uint8_t serialno_byte = 42; CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, &serialno_byte, sizeof(serialno_byte)); SecCertificateRef cert = SecIdentitySignCertificate(ca_identity, serialno, phone_publicKey, subject, extensions); data = SecCertificateCopyData(cert); //write_data("/tmp/iphone_cert.der", data); CFReleaseNull(data); CFReleaseNull(subject); CFReleaseNull(extensions); CFReleaseNull(challenge); const void * email[] = { CFSTR("1.2.840.113549.1.9.1"), CFSTR("*****@*****.**") }; const void * cn[] = { CFSTR("2.5.4.3"), CFSTR("S/MIME Baby") }; CFArrayRef email_dn = CFArrayCreate(kCFAllocatorDefault, email, 2, NULL); CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL); const void *dn_array[2]; dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&email_dn, 1, NULL); dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL); CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, dn_array, 2, NULL); CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("*****@*****.**")); uint8_t random_extension_data[] = { 0xde, 0xad, 0xbe, 0xef }; CFDataRef random_extension_value = CFDataCreate(kCFAllocatorDefault, random_extension_data, sizeof(random_extension_data)); CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.2"), random_extension_value); // APPLE_FDR_ACCESS_OID CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.3"), CFSTR("that guy")); // APPLE_FDR_CLIENT_IDENTIFIER_OID CFReleaseNull(random_extension_value); csr = SecGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey); isnt(csr, NULL, "csr w/ params"); //write_data("/tmp/csr_neu", csr); CFReleaseNull(csr); CFReleaseNull(subject_alt_names); CFDictionaryRemoveAllValues(random_extensions); #if TARGET_OS_IPHONE CFDataRef scep_request = SecSCEPGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey, NULL, ca_cert); isnt(scep_request, NULL, "got scep blob"); //write_data("/tmp/scep_request.der", scep_request); #endif CFReleaseNull(email_dn); CFReleaseNull(cn_dn); CFReleaseNull(dn_array[0]); CFReleaseNull(dn_array[1]); CFReleaseNull(rdns); #if TARGET_OS_IPHONE CFDataRef scep_reply = SecSCEPCertifyRequest(scep_request, ca_identity, serialno, false); isnt(scep_reply, NULL, "produced scep reply"); //write_data("/tmp/scep_reply.der", scep_reply); CFArrayRef issued_certs = NULL; ok(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, ca_cert, NULL), "verify scep reply"); // take the issued cert and CA cert and pretend it's a RA/CA couple CFMutableArrayRef scep_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, issued_certs); CFArrayAppendValue(scep_certs, ca_cert); SecCertificateRef ca_certificate = NULL, ra_signing_certificate = NULL, ra_encryption_certificate = NULL; ok_status(SecSCEPValidateCACertMessage(scep_certs, NULL, &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), "pull apart array again"); ok(CFEqual(ca_cert, ca_certificate), "found ca"); ok(CFArrayContainsValue(issued_certs, CFRangeMake(0, CFArrayGetCount(issued_certs)), ra_signing_certificate), "found ra"); ok(!ra_encryption_certificate, "no separate encryption cert"); CFReleaseSafe(ca_certificate); CFReleaseSafe(ra_signing_certificate); CFReleaseSafe(scep_certs); CFReleaseSafe(scep_request); CFReleaseSafe(scep_reply); CFReleaseSafe(issued_certs); #endif // cleanups dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL); ok_status(SecItemDelete(dict), "delete ca identity"); CFReleaseSafe(dict); dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&phone_privateKey, 1, NULL, NULL); ok_status(SecItemDelete(dict), "delete phone private key"); CFReleaseSafe(dict); CFReleaseSafe(serialno); CFReleaseSafe(cert); CFReleaseSafe(ca_identity); CFReleaseSafe(ca_cert); CFReleaseSafe(ca_identity_phone_key); CFReleaseSafe(ca_cert_phone_key); CFReleaseSafe(csr_parameters); CFReleaseSafe(random_extensions); CFReleaseSafe(parameters); CFReleaseSafe(ca_publicKey); CFReleaseSafe(ca_privateKey); CFReleaseSafe(phone_publicKey); CFReleaseSafe(phone_privateKey); } static void test_ec_csr(void) { SecKeyRef ecPublicKey = NULL, ecPrivateKey = NULL; int keysize = 256; CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize); const void *keyParamsKeys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; const void *keyParamsValues[] = { kSecAttrKeyTypeECSECPrimeRandom, key_size_num}; CFDictionaryRef keyParameters = CFDictionaryCreate(NULL, keyParamsKeys, keyParamsValues, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok_status(SecKeyGeneratePair(keyParameters, &ecPublicKey, &ecPrivateKey), "unable to generate EC key"); SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} }; SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} }; SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} }; SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} }; SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} }; SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL }; CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl")); int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions }; const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions }; CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault, key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, ecPublicKey, ecPrivateKey); isnt(csr, NULL, "csr w/ params"); //write_data("/tmp/csr", csr); CFDataRef subject, extensions; CFStringRef challenge; ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr"); CFReleaseNull(csr); CFReleaseNull(key_size_num); CFReleaseNull(keyParameters); CFReleaseNull(ecPublicKey); CFReleaseNull(ecPrivateKey); CFReleaseNull(subject_alt_names); CFReleaseNull(key_usage_num); CFReleaseNull(random_extensions); CFReleaseNull(csr_parameters); CFReleaseNull(subject); CFReleaseNull(extensions); CFReleaseNull(challenge); }
bool MP4Metadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, FALSE, buf, PATH_MAX)) return false; // Open the file for reading MP4FileHandle file = MP4Read(reinterpret_cast<const char *>(buf)); if(MP4_INVALID_FILE_HANDLE == file) { if(error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 32, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MPEG-4 file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not an MPEG-4 file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; *error = CFErrorCreate(kCFAllocatorDefault, AudioMetadataErrorDomain, AudioMetadataFileFormatNotRecognizedError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } return false; } // Read the properties if(0 < MP4GetNumberOfTracks(file)) { // Should be type 'soun', media data name'mp4a' MP4TrackId trackID = MP4FindTrackId(file, 0); // Verify this is an MPEG-4 audio file if(MP4_INVALID_TRACK_ID == trackID || strncmp("soun", MP4GetTrackType(file, trackID), 4)) { MP4Close(file), file = NULL; if(error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 32, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MPEG-4 file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not an MPEG-4 file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; *error = CFErrorCreate(kCFAllocatorDefault, AudioMetadataErrorDomain, AudioMetadataFileFormatNotSupportedError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } return false; } MP4Duration mp4Duration = MP4GetTrackDuration(file, trackID); uint32_t mp4TimeScale = MP4GetTrackTimeScale(file, trackID); CFNumberRef totalFrames = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &mp4Duration); CFDictionarySetValue(mMetadata, kPropertiesTotalFramesKey, totalFrames); CFRelease(totalFrames), totalFrames = NULL; CFNumberRef sampleRate = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &mp4TimeScale); CFDictionarySetValue(mMetadata, kPropertiesSampleRateKey, sampleRate); CFRelease(sampleRate), sampleRate = NULL; double length = static_cast<double>(mp4Duration / mp4TimeScale); CFNumberRef duration = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &length); CFDictionarySetValue(mMetadata, kPropertiesDurationKey, duration); CFRelease(duration), duration = NULL; // "mdia.minf.stbl.stsd.*[0].channels" int channels = MP4GetTrackAudioChannels(file, trackID); CFNumberRef channelsPerFrame = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &channels); CFDictionaryAddValue(mMetadata, kPropertiesChannelsPerFrameKey, channelsPerFrame); CFRelease(channelsPerFrame), channelsPerFrame = NULL; // ALAC files if(MP4HaveTrackAtom(file, trackID, "mdia.minf.stbl.stsd.alac")) { CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("Apple Lossless")); uint64_t sampleSize; uint8_t *decoderConfig; uint32_t decoderConfigSize; if(MP4GetTrackBytesProperty(file, trackID, "mdia.minf.stbl.stsd.alac.alac.decoderConfig", &decoderConfig, &decoderConfigSize) && 28 <= decoderConfigSize) { // The ALAC magic cookie seems to have the following layout (28 bytes, BE): // Byte 10: Sample size // Bytes 25-28: Sample rate CFNumberRef bitsPerChannel = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, decoderConfig + 9); CFDictionaryAddValue(mMetadata, kPropertiesBitsPerChannelKey, bitsPerChannel); CFRelease(bitsPerChannel), bitsPerChannel = NULL; double losslessBitrate = static_cast<double>(mp4TimeScale * channels * sampleSize) / 1000; CFNumberRef bitrate = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &losslessBitrate); CFDictionarySetValue(mMetadata, kPropertiesBitrateKey, bitrate); CFRelease(bitrate), bitrate = NULL; free(decoderConfig), decoderConfig = NULL; } else if(MP4GetTrackIntegerProperty(file, trackID, "mdia.minf.stbl.stsd.alac.sampleSize", &sampleSize)) { CFNumberRef bitsPerChannel = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &sampleSize); CFDictionaryAddValue(mMetadata, kPropertiesBitsPerChannelKey, bitsPerChannel); CFRelease(bitsPerChannel), bitsPerChannel = NULL; double losslessBitrate = static_cast<double>(mp4TimeScale * channels * sampleSize) / 1000; CFNumberRef bitrate = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &losslessBitrate); CFDictionarySetValue(mMetadata, kPropertiesBitrateKey, bitrate); CFRelease(bitrate), bitrate = NULL; } } // AAC files if(MP4HaveTrackAtom(file, trackID, "mdia.minf.stbl.stsd.mp4a")) { CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("AAC")); // "mdia.minf.stbl.stsd.*.esds.decConfigDescr.avgBitrate" uint32_t trackBitrate = MP4GetTrackBitRate(file, trackID) / 1000; CFNumberRef bitrate = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &trackBitrate); CFDictionaryAddValue(mMetadata, kPropertiesBitrateKey, bitrate); CFRelease(bitrate), bitrate = NULL; } } // No valid tracks in file else { MP4Close(file), file = NULL; if(error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 32, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MPEG-4 file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not an MPEG-4 file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; *error = CFErrorCreate(kCFAllocatorDefault, AudioMetadataErrorDomain, AudioMetadataFileFormatNotSupportedError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } return false; } // Read the tags const MP4Tags *tags = MP4TagsAlloc(); if(NULL == tags) { MP4Close(file), file = NULL; if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, NULL); return false; } MP4TagsFetch(tags, file); // Album title if(tags->album) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->album, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataAlbumTitleKey, str); CFRelease(str), str = NULL; } // Artist if(tags->artist) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->artist, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataArtistKey, str); CFRelease(str), str = NULL; } // Album Artist if(tags->albumArtist) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->albumArtist, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataAlbumArtistKey, str); CFRelease(str), str = NULL; } // Genre if(tags->genre) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->genre, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataGenreKey, str); CFRelease(str), str = NULL; } // Release date if(tags->releaseDate) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->releaseDate, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataReleaseDateKey, str); CFRelease(str), str = NULL; } // Composer if(tags->composer) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->composer, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataComposerKey, str); CFRelease(str), str = NULL; } // Comment if(tags->comments) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->comments, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataCommentKey, str); CFRelease(str), str = NULL; } // Track title if(tags->name) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->name, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataTitleKey, str); CFRelease(str), str = NULL; } // Track number if(tags->track) { if(tags->track->index) { CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &tags->track->index); CFDictionarySetValue(mMetadata, kMetadataTrackNumberKey, num); CFRelease(num), num = NULL; } if(tags->track->total) { CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &tags->track->total); CFDictionarySetValue(mMetadata, kMetadataTrackTotalKey, num); CFRelease(num), num = NULL; } } // Disc number if(tags->disk) { if(tags->disk->index) { CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &tags->disk->index); CFDictionarySetValue(mMetadata, kMetadataDiscNumberKey, num); CFRelease(num), num = NULL; } if(tags->disk->total) { CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &tags->disk->total); CFDictionarySetValue(mMetadata, kMetadataDiscTotalKey, num); CFRelease(num), num = NULL; } } // Compilation if(tags->compilation) CFDictionarySetValue(mMetadata, kMetadataCompilationKey, *(tags->compilation) ? kCFBooleanTrue : kCFBooleanFalse); // BPM if(tags->tempo) { } // Lyrics if(tags->lyrics) { CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, tags->lyrics, kCFStringEncodingUTF8); CFDictionarySetValue(mMetadata, kMetadataLyricsKey, str); CFRelease(str), str = NULL; } // Album art if(tags->artworkCount) { for(uint32_t i = 0; i < tags->artworkCount; ++i) { CFDataRef data = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(tags->artwork[i].data), tags->artwork[i].size); CFDictionarySetValue(mMetadata, kAlbumArtFrontCoverKey, data); CFRelease(data), data = NULL; } } // ReplayGain // Reference loudness MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_reference_loudness"); if(NULL != items) { float referenceLoudnessValue; if(1 <= items->size && 1 <= items->elements[0].dataList.size && sscanf(reinterpret_cast<const char *>(items->elements[0].dataList.elements[0].value), "%f", &referenceLoudnessValue)) { CFNumberRef referenceLoudness = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &referenceLoudnessValue); CFDictionaryAddValue(mMetadata, kReplayGainReferenceLoudnessKey, referenceLoudness); CFRelease(referenceLoudness), referenceLoudness = NULL; } MP4ItmfItemListFree(items), items = NULL; } // Track gain items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_track_gain"); if(NULL != items) { float trackGainValue; if(1 <= items->size && 1 <= items->elements[0].dataList.size && sscanf(reinterpret_cast<const char *>(items->elements[0].dataList.elements[0].value), "%f", &trackGainValue)) { CFNumberRef trackGain = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &trackGainValue); CFDictionaryAddValue(mMetadata, kReplayGainTrackGainKey, trackGain); CFRelease(trackGain), trackGain = NULL; } MP4ItmfItemListFree(items), items = NULL; } // Track peak items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_track_peak"); if(NULL != items) { float trackPeakValue; if(1 <= items->size && 1 <= items->elements[0].dataList.size && sscanf(reinterpret_cast<const char *>(items->elements[0].dataList.elements[0].value), "%f", &trackPeakValue)) { CFNumberRef trackPeak = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &trackPeakValue); CFDictionaryAddValue(mMetadata, kReplayGainTrackPeakKey, trackPeak); CFRelease(trackPeak), trackPeak = NULL; } MP4ItmfItemListFree(items), items = NULL; } // Album gain items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_album_gain"); if(NULL != items) { float albumGainValue; if(1 <= items->size && 1 <= items->elements[0].dataList.size && sscanf(reinterpret_cast<const char *>(items->elements[0].dataList.elements[0].value), "%f", &albumGainValue)) { CFNumberRef albumGain = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &albumGainValue); CFDictionaryAddValue(mMetadata, kReplayGainAlbumGainKey, albumGain); CFRelease(albumGain), albumGain = NULL; } MP4ItmfItemListFree(items), items = NULL; } // Album peak items = MP4ItmfGetItemsByMeaning(file, "com.apple.iTunes", "replaygain_album_peak"); if(NULL != items) { float albumPeakValue; if(1 <= items->size && 1 <= items->elements[0].dataList.size && sscanf(reinterpret_cast<const char *>(items->elements[0].dataList.elements[0].value), "%f", &albumPeakValue)) { CFNumberRef albumPeak = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &albumPeakValue); CFDictionaryAddValue(mMetadata, kReplayGainAlbumPeakKey, albumPeak); CFRelease(albumPeak), albumPeak = NULL; } MP4ItmfItemListFree(items), items = NULL; } // Clean up MP4TagsFree(tags), tags = NULL; MP4Close(file), file = NULL; return true; }
void SFB::Audio::Metadata::ClearAllMetadata() { CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); mPictures.clear(); }
/// The call deallocate all allocated data, close all opened desckriptors. void task_info_manager_free(void) { CFDictionaryRemoveAllValues(tasks_dict); man_info_free(); }
//----------------------------------------------------------------------------------- // TitleChanged //----------------------------------------------------------------------------------- void TValuePictControl::TitleChanged() { CFDictionaryRemoveAllValues(mImageCache); ValueChanged(); }
bool MODMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; CFStringRef pathExtension = CFURLCopyPathExtension(mURL); if(nullptr == pathExtension) return false; bool fileIsValid = false; if(kCFCompareEqualTo == CFStringCompare(pathExtension, CFSTR("it"), kCFCompareCaseInsensitive)) { auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::IT::File file(stream); if(file.isValid()) { fileIsValid = true; CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MOD (Impulse Tracker)")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) AddTagToDictionary(mMetadata, file.tag()); } } else if(kCFCompareEqualTo == CFStringCompare(pathExtension, CFSTR("xm"), kCFCompareCaseInsensitive)) { auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::XM::File file(stream); if(file.isValid()) { fileIsValid = true; CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MOD (Extended Module)")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) AddTagToDictionary(mMetadata, file.tag()); } } else if(kCFCompareEqualTo == CFStringCompare(pathExtension, CFSTR("s3m"), kCFCompareCaseInsensitive)) { auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::S3M::File file(stream); if(file.isValid()) { fileIsValid = true; CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MOD (ScreamTracker III)")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) AddTagToDictionary(mMetadata, file.tag()); } } else if(kCFCompareEqualTo == CFStringCompare(pathExtension, CFSTR("mod"), kCFCompareCaseInsensitive)) { auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::Mod::File file(stream); if(file.isValid()) { fileIsValid = true; CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("MOD (Protracker)")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) AddTagToDictionary(mMetadata, file.tag()); } } CFRelease(pathExtension), pathExtension = nullptr; if(!fileIsValid) { if(error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MOD file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not a MOD file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } return true; }
bool MonkeysAudioMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; TagLib::IOStream *stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::APE::File file(stream); if(!file.isValid()) { if(NULL != error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Monkey's Audio file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not a Monkey's Audio file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; *error = CFErrorCreate(kCFAllocatorDefault, AudioMetadataErrorDomain, AudioMetadataInputOutputError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("Monkey's Audio")); if(file.audioProperties()) { AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(0 != file.audioProperties()->bitsPerSample()) { int value = file.audioProperties()->bitsPerSample(); CFNumberRef bitsPerChannel = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value); CFDictionarySetValue(mMetadata, kPropertiesBitsPerChannelKey, bitsPerChannel); CFRelease(bitsPerChannel), bitsPerChannel = NULL; } } if(file.ID3v1Tag()) AddID3v1TagToDictionary(mMetadata, file.ID3v1Tag()); if(file.APETag()) AddAPETagToDictionary(mMetadata, file.APETag()); return true; }
int pSendDiscover( CFUUIDBytes pHostGuid, PNDAS_HIX_UNITDEVICE_ENTRY_DATA data, struct sockaddr_lpx *host ) { NDAS_HIX_DISCOVER_REQUEST request; CFDataRef cfdRequest = NULL; // Build Request. pBuildNHIXHeader( &request.Header, pHostGuid, 0, NHIX_TYPE_DISCOVER, sizeof(NDAS_HIX_SURRENDER_ACCESS_REQUEST) ); request.Data.EntryCount = 1; memcpy(&request.Data.Entry[0], data, sizeof(NDAS_HIX_UNITDEVICE_ENTRY_DATA)); cfdRequest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *) &request, sizeof(NDAS_HIX_SURRENDER_ACCESS_REQUEST), kCFAllocatorNull); // Send Request. // Per Interface. CFSocketRef sockets[4]; int numInterfaces = 0; for(int i = 0; i < numberOfNics; i++) { CFDataRef address = 0; struct sockaddr_lpx addr = { 0 }; // Build Socket. sockets[numInterfaces] = CFSocketCreate ( kCFAllocatorDefault, PF_LPX, SOCK_DGRAM, 0, 0, 0, NULL ); if(sockets[numInterfaces] == NULL) { syslog(LOG_ERR, "pSendSurrenderAccess: Can't Create socket for surrender Access request."); return -1; } // Bind Interface Address. addr.slpx_family = AF_LPX; addr.slpx_len = sizeof(struct sockaddr_lpx); addr.slpx_port = 0; memcpy(addr.slpx_node, ethernetData[i].macAddress, 6); address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *) &addr, sizeof(struct sockaddr_lpx), kCFAllocatorNull); CFSocketError socketError = CFSocketSetAddress ( sockets[numInterfaces], address ); if(socketError != kCFSocketSuccess) { syslog(LOG_ERR, "pSendSurrenderAccess: Can't Bind."); continue; } if(address) CFRelease(address); address= NULL; // Create Broadcast address. addr.slpx_family = AF_LPX; addr.slpx_len = sizeof(struct sockaddr_lpx); memset(addr.slpx_node, 0xff, 6); addr.slpx_port = htons(NDAS_HIX_LISTEN_PORT); address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *) &addr, sizeof(struct sockaddr_lpx), kCFAllocatorNull); // Set Broadcast Flag. int on = 1; if(setsockopt(CFSocketGetNative(sockets[numInterfaces]), SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) != 0) { syslog(LOG_ERR, "pSendSurrenderAccess: Error when set option."); return false; } // Send Request. socketError = CFSocketSendData ( sockets[numInterfaces], address, cfdRequest, 0 ); if(socketError != kCFSocketSuccess) { syslog(LOG_ERR, "pSendSurrenderAccess: Error when send reply."); return false; } numInterfaces++; if(address) CFRelease(address); } if(cfdRequest) CFRelease(cfdRequest); // Receive Reply. int maxfdp1; socklen_t fromlen; fd_set rset; struct timeval timeout; int bResult; struct sockaddr_lpx addr = { 0 }; int count; int numberOfHosts = 0; // HostID Dictionary. CFMutableDictionaryRef HostIDs = CFDictionaryCreateMutable ( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); if (NULL == HostIDs) { return -1; } retry: FD_ZERO(&rset); maxfdp1 = 0; for(count = 0; count < numInterfaces; count++) { FD_SET( CFSocketGetNative(sockets[count]), &rset); maxfdp1 = (maxfdp1 > CFSocketGetNative(sockets[count])) ? maxfdp1 : CFSocketGetNative(sockets[count]); } maxfdp1++; timeout.tv_sec = 2; // 2 sec. timeout.tv_usec = 0; int result = select(maxfdp1, &rset, NULL, NULL, &timeout); if(result > 0) { NDAS_HIX_DISCOVER_REPLY reply; int len; fromlen = sizeof(struct sockaddr_lpx); // Find socket. for(count = 0; count < numInterfaces; count++) { if (FD_ISSET( CFSocketGetNative(sockets[count]), &rset)) { len = recvfrom(CFSocketGetNative(sockets[count]), &reply, sizeof(NDAS_HIX_DISCOVER_REPLY), 0, (sockaddr *)&addr, &fromlen); if ( len < sizeof(NDAS_HIX_DISCOVER_REPLY) ) { syslog(LOG_WARNING, "pSendDiscover: Too short HIX Discover reply len : %d\n", len); continue; } // syslog(LOG_ERR, "pSendDiscover: Host %2x:%2x:%2x:%2x:%2x:%2x %d\n", // addr.slpx_node[0], addr.slpx_node[1], addr.slpx_node[2], // addr.slpx_node[3], addr.slpx_node[4], addr.slpx_node[5], fromlen); // syslog(LOG_ERR, "pSendDiscover: Access : %x", reply.Data.Entry[0].AccessType); if ( len >= sizeof(NDAS_HIX_DISCOVER_REPLY) ) { if (reply.Data.EntryCount == 1 && memcmp(data->DeviceId, reply.Data.Entry[0].DeviceId, 6) == 0 && data->UnitNo == reply.Data.Entry[0].UnitNo) { // Check Duplecation. CFDataRef hostID = CFDataCreate( kCFAllocatorDefault, reply.Header.HostId, 16 ); if (NULL == hostID) { goto Out; } if (0 == CFDictionaryGetCountOfKey(HostIDs, hostID)) { // New Host. CFDictionarySetValue( HostIDs, hostID, hostID); syslog(LOG_DEBUG, "[%s] HIX Replay Type : %d\n", __FUNCTION__, reply.Data.Entry[0].AccessType); switch (reply.Data.Entry[0].AccessType) { case NHIX_UDA_WRITE_ACCESS: case NHIX_UDA_READ_WRITE_ACCESS: case NHIX_UDA_SHARED_READ_WRITE_SECONDARY_ACCESS: case NHIX_UDA_SHARED_READ_WRITE_PRIMARY_ACCESS: { numberOfHosts++; // Copy Address. if (host) { memcpy(host, &addr, sizeof(struct sockaddr_lpx)); } } break; default: break; } } else { syslog(LOG_INFO, "pSendDiscover: Duplicated replay."); } CFRelease(hostID); } } } } goto retry; } else { // Error or timeout. // syslog(LOG_ERR, "pSendDiscover: select error or timeout %d Hosts %d\n", result, numberOfHosts); bResult = numberOfHosts; } //if(socketSurrender) CFRelease(socketSurrender); Out: if (HostIDs) { CFDictionaryRemoveAllValues(HostIDs); CFRelease(HostIDs); } for(count = 0; count < numInterfaces; count++) { if(sockets[count]) CFRelease(sockets[count]); } return bResult; }