Domanda

Sto cercando di entrare in un percorso di file in alcuni file .pref, ma invece di una stringa, il campo vuole una sorta di sequenza esadecimale. Come posso convertire il mio cammino in questo formato esadecimale?

Mac OS 10.6.7

Ecco un esempio di un percorso di file:

<00000000 00010000 009e0003 c94bbb14 0000482b 00000000 000d3ad2 000dfc12 0000c950 e4db0000 00.000.920 fffe0000 00000000 0000ffff ffff0001 0008000d 3ad2000c 9ce1000e 000c0005 0069006e 0062006f 0078000f 001a000c 004d0061 00.630.069 006e0074 006f0073 00680020 00480044 00120015 55736572 732f7263 68.617.265 7474652f 696e626f 78.000.013 00.150.002 00012f00 0010ffff 0000>

È stato utile?

Soluzione

It's alias 'alis' data, which has been the standard way to refer to files in a persistent manner in Mac OS for the last 20 years or more. ;-) The AliasHandle et. al are found in Aliases.h, which is in the CarbonCore.framework of the CoreServices umbrella framework.

Note that it is Property List Editor (or Xcode) that's showing you a hexadecimal representation of NSData. The data tells us that you haven't changed the name of your hard drive (it appears to still be "Macintosh HD") and that the path of the alias was to /Users/rcharette/inbox

The "newfangled" name for this is bookmark data, which was introduced in 10.6.

There are a couple of high-level wrappers around aliases, Nathan Day's NDAlias, I believe.

Otherwise, the following is mine, a category on NSString modeled after the new bookmark APIs available in NSURL (which require 10.6). (This code should work on 10.3+):

MDBookmarks.h:

#import <Foundation/Foundation.h>

//  Constants
//  MDBookmarkResolutionWithoutUI
// Option for specifying that no UI feedback accompany resolution of the bookmark data.
enum {
    MDBookmarkResolutionDefaultOptions      = 1,
    MDBookmarkResolutionWithoutUI = ( 1UL << 8 )
};
typedef NSUInteger MDBookmarkResolutionOptions;


@interface NSString (MDBookmarks)

- (NSData *)bookmarkDataWithError:(NSError **)error;

+ (id)stringByResolvingBookmarkData:(NSData *)bookmarkData 
                            options:(MDBookmarkResolutionOptions)options
       bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error;

@end

MDBookmarks.m:

#import "MDBookmarks.h"
#import <CoreServices/CoreServices.h>
#import <sys/syslimits.h>

@implementation NSString (MDBookmarks)

- (NSData *)bookmarkDataWithError:(NSError **)outError {
    if (outError) *outError = nil;
    NSString *path = [[self stringByResolvingSymlinksInPath]
                               stringByStandardizingPath];
    AliasHandle alias = NULL;
    FSRef itemRef;
    OSStatus status = FSPathMakeRef((const UInt8 *)[path UTF8String], &itemRef, NULL);
    if (status != noErr) {
        if (outError) {
            if (status == fnfErr) *outError = [NSError errorWithDomain:NSCocoaErrorDomain 
              code:NSFileNoSuchFileError userInfo:nil];
            else *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
              code:status userInfo:nil];
        }
        return nil;
    }
    status = FSNewAlias(NULL, &itemRef, &alias);
    if (status != noErr ) {
        if (outError)
        *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
                code:status userInfo:nil];
        return nil;
    }
    HLock((Handle)alias);
    NSData *bookmarkData =
[[[NSData dataWithBytes:*alias length:GetHandleSize((Handle)alias)] retain] autorelease];
    HUnlock((Handle)alias);
    if (alias) DisposeHandle((Handle)alias);
    return bookmarkData;
}

+ (id)stringByResolvingBookmarkData:(NSData *)bookmarkData
        options:(MDBookmarkResolutionOptions)options
         bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)outError {
    if (bookmarkData == nil) return nil;
    if (outError) *outError = nil;
    AliasHandle alias = NULL;
    FSRef resolvedRef;
    Boolean wasChanged = false;
    OSStatus status = PtrToHand([bookmarkData bytes], (Handle *)&alias,
                                              [bookmarkData length]);
    if (status) {
        if (outError) *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
                         code:status userInfo:nil];
        return nil;
    }
    status = FSResolveAliasWithMountFlags(NULL, alias, &resolvedRef, &wasChanged,
             (options & MDBookmarkResolutionWithoutUI ? kResolveAliasFileNoUI : 0));
    if (status) {
        if (outError) *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
                            code:status userInfo:nil];
        return nil;
    }
    UInt8 thePath[PATH_MAX + 1];
    status = FSRefMakePath(&resolvedRef, thePath, PATH_MAX);
    if (status != noErr) {
        if (outError) *outError = [NSError errorWithDomain:NSOSStatusErrorDomain 
                        code:status userInfo:nil];
        return nil;
    }
    if (isStale) *isStale = wasChanged;
    return [NSString stringWithUTF8String:(const char *)thePath];
}
@end

Otherwise, if you can require 10.6, then check out the newer APIs in NSURL.

Altri suggerimenti

Paths in preference files are sometimes base64 encoded. You can use openssl to de/encode the values:

Decode: echo <encoded-path> | openssl enc -d -base64

Encode: echo <path> | openssl enc -e -base64

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top