5 // Created by Karl Adam on Fri May 28 2004.
6 // Copyright 2004-2006 The Growl Project. All rights reserved.
8 // This file is under the BSD License, refer to License.txt for details
10 #include "CFURLAdditions.h"
11 #include "CFGrowlAdditions.h"
12 #include "CFMutableDictionaryAdditions.h"
13 #include <Carbon/Carbon.h>
16 #include <sys/types.h>
19 #define _CFURLAliasDataKey CFSTR("_CFURLAliasData")
20 #define _CFURLStringKey CFSTR("_CFURLString")
21 #define _CFURLStringTypeKey CFSTR("_CFURLStringType")
23 //'alias' as in the Alias Manager.
24 URL_TYPE createFileURLWithAliasData(DATA_TYPE aliasData) {
26 NSLog(CFSTR("WARNING: createFileURLWithAliasData called with NULL aliasData"));
32 AliasHandle alias = NULL;
33 OSStatus err = PtrToHand(CFDataGetBytePtr(aliasData), (Handle *)&alias, CFDataGetLength(aliasData));
35 NSLog(CFSTR("in createFileURLWithAliasData: Could not allocate an alias handle from %u bytes of alias data (data follows) because PtrToHand returned %li\n%@"), CFDataGetLength(aliasData), aliasData, (long)err);
37 CFStringRef path = NULL;
39 * FSResolveAlias mounts disk images or network shares to resolve
40 * aliases, thus we resort to FSCopyAliasInfo.
42 err = FSCopyAliasInfo(alias,
43 /* targetName */ NULL,
44 /* volumeName */ NULL,
48 DisposeHandle((Handle)alias);
50 if (err != fnfErr) //ignore file-not-found; it's harmless
51 NSLog(CFSTR("in createFileURLWithAliasData: Could not resolve alias (alias data follows) because FSResolveAlias returned %li - will try path\n%@"), (long)err, aliasData);
53 url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, true);
55 NSLog(CFSTR("in createFileURLWithAliasData: FSCopyAliasInfo returned a NULL path"));
63 DATA_TYPE createAliasDataWithURL(URL_TYPE theURL) {
64 //return NULL for non-file: URLs.
65 CFStringRef scheme = CFURLCopyScheme(theURL);
66 CFComparisonResult isFileURL = CFStringCompare(scheme, CFSTR("file"), kCFCompareCaseInsensitive);
68 if (isFileURL != kCFCompareEqualTo)
71 CFDataRef aliasData = NULL;
74 if (CFURLGetFSRef(theURL, &fsref)) {
75 AliasHandle alias = NULL;
76 OSStatus err = FSNewAlias(/*fromFile*/ NULL, &fsref, &alias);
78 NSLog(CFSTR("in createAliasDataForURL: FSNewAlias for %@ returned %li"), theURL, (long)err);
82 aliasData = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)*alias, GetHandleSize((Handle)alias));
84 HUnlock((Handle)alias);
85 DisposeHandle((Handle)alias);
92 //these are the type of external representations used by Dock.app.
93 URL_TYPE createFileURLWithDockDescription(DICTIONARY_TYPE dict) {
96 CFStringRef path = CFDictionaryGetValue(dict, _CFURLStringKey);
97 CFDataRef aliasData = CFDictionaryGetValue(dict, _CFURLAliasDataKey);
100 url = createFileURLWithAliasData(aliasData);
104 CFNumberRef pathStyleNum = CFDictionaryGetValue(dict, _CFURLStringTypeKey);
105 CFURLPathStyle pathStyle = kCFURLPOSIXPathStyle;
108 CFNumberGetValue(pathStyleNum, kCFNumberIntType, &pathStyle);
110 char *filename = createFileSystemRepresentationOfString(path);
111 int fd = open(filename, O_RDONLY, 0);
117 url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, pathStyle, /*isDirectory*/ (sb.st_mode & S_IFDIR));
125 DICTIONARY_TYPE createDockDescriptionWithURL(URL_TYPE theURL) {
126 CFMutableDictionaryRef dict;
129 NSLog(CFSTR("%@"), CFSTR("in createDockDescriptionWithURL: Cannot copy Dock description for a NULL URL"));
133 CFStringRef path = CFURLCopyFileSystemPath(theURL, kCFURLPOSIXPathStyle);
134 CFDataRef aliasData = createAliasDataWithURL(theURL);
136 if (path || aliasData) {
137 dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
140 CFDictionarySetValue(dict, _CFURLStringKey, path);
142 setIntegerForKey(dict, _CFURLStringTypeKey, kCFURLPOSIXPathStyle);
146 CFDictionarySetValue(dict, _CFURLAliasDataKey, aliasData);
147 CFRelease(aliasData);