1

So, I've been trying to deserialize the IPXDefaultLibraryURLBookmark of the com.apple.Photos defaults (defaults read com.apple.Photos IPXDefaultLibraryURLBookmark) but no luck. Ideally I'd like a programmatic way in c++ to deserialize that value to retrieve the last known location of the photo

bookd0xUsersmateuscbPicturesPhotos Library.photoslibrary 0@˜ì5$r$Éò|åú¨A∫˙æJ   file:///Macintosh HDÇ1tA∫‘}•$6465C0A4-1771-3C89-9055-147CEDFBBF2EÅÔ/∆72cd528f2dcfb4b3434986cf3caa02cc946333b8;00000000;00000000;0000000000000020;com.apple.app-sandbox.read-write;00000001;01000004;0000000002980783;/users/mateuscb/pictures/photos library.photoslibrary¥˛ˇˇˇdº‰@‘ î   H ( 8  t0 †–Ä®

I know its not a bplist, since the first format specifier denotes bookd.

But I have no clue what that is. I'm somewhat new to OSX development, so this may be something very basic I'm missing.

I want to retrieve the: /users/mateuscb/pictures/photos library.photoslibrary portion so I can find the defaults photoslibrary.

Unless there is another way to retrieve the default photoslibrary path?

mateuscb
  • 10,150
  • 3
  • 52
  • 76

1 Answers1

0

I figured out how to retrieve the path to the .photoslibrary. I used CFURLCreateByResolvingBookmarkData to get a CFURLRef from the plist then used CFURLGetFileSystemRepresentation to get the full path as a string.

Help from this sample to retrieve sandbox preferences: https://gist.github.com/glebd/4759724

Here is my full solution:

int main(int argc, const char * argv[]) {
    bool success = FALSE;
    UInt8 photosUrlString[PATH_MAX];

    struct passwd *pwd = getpwuid(getuid());
    if (pwd ==  NULL){
        Log("Unable to retrieve current user");
        return 0;
    }

    const char *home = pwd->pw_dir;
    if (home ==  NULL){
        Log("Unable to retrieve current user directory");
        return 0;
    }


    CFMutableStringRef preferencesPath = CFStringCreateMutable(NULL, 0);
    if (preferencesPath) {
        CFStringAppend(preferencesPath, CFStringCreateWithCStringNoCopy(NULL, home, kCFStringEncodingUTF8, NULL));
        CFStringAppend(preferencesPath, CFSTR("/Library/Containers/com.apple.Photos/Data/Library/Preferences/com.apple.Photos"));
    } else {
        Log("Unable to create CFString of user directory");
        return 0;
    }

    CFPropertyListRef photosUrlPrefs = CFPreferencesCopyValue(CFSTR("IPXDefaultLibraryURLBookmark"), preferencesPath, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    CFRelease(preferencesPath);

    if (photosUrlPrefs) {
        CFTypeID prefsType = CFGetTypeID(photosUrlPrefs);
        if (CFDataGetTypeID() == prefsType) {
            CFDataRef photosUrlData = (CFDataRef) photosUrlPrefs;
            CFErrorRef urlResolveError = nil;
            CFURLRef photosUrl = CFURLCreateByResolvingBookmarkData(kCFAllocatorDefault, photosUrlData, NULL, NULL, NULL, NULL, &urlResolveError);
            if (photosUrl == NULL) {
                if(urlResolveError != NULL) {
                    CFStringRef resolveErrorString = CFErrorCopyDescription(urlResolveError);
                    if (resolveErrorString != NULL) {
                        char resolveErrorCString[PATH_MAX];
                        if (CFStringGetCString((CFStringRef) resolveErrorString, resolveErrorCString, sizeof(resolveErrorCString), kCFStringEncodingUTF8)) {
                            Log("Error resolving URL: %s", resolveErrorCString);
                        }
                        CFRelease(resolveErrorString);
                    }
                } else {
                    Log("Error resolving URL, no resolveError");
                }
            } else {
                success = CFURLGetFileSystemRepresentation(photosUrl, false, photosUrlString, sizeof(photosUrlString));
                CFRelease(photosUrl);
            }
        } else {
            Log("Url plist value is not CFData");
        }

        if (photosUrlPrefs != NULL) {
            CFRelease(photosUrlPrefs);
        }
    }

    if(success) {
        Log("path: %s", photosUrlString);
    }

    return 0;
}
mateuscb
  • 10,150
  • 3
  • 52
  • 76