- Timestamp:
- Oct 24, 2013 5:56:56 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/UIDesktopServices_darwin_cocoa.mm
r34411 r49280 25 25 #import <AppKit/NSWorkspace.h> 26 26 27 /* It's crazy how hard it is to create an Alias file on Mac OS X. You could try 28 to write such files yourself, with all the resource fork fun (and the 29 understanding what to write in) or you could kindly ask Finder for doing 30 this job. We take the second approach, which is hard enough. */ 27 /* Create desktop alias using a bookmark stuff. */ 31 28 bool darwinCreateMachineShortcut(NativeNSStringRef pstrSrcFile, NativeNSStringRef pstrDstPath, NativeNSStringRef pstrName, NativeNSStringRef /* pstrUuid */) 32 29 { 33 /* First of all we need to figure out which process Id the Finder currently has. */ 34 NSWorkspace *pWS = [NSWorkspace sharedWorkspace]; 35 NSArray *pApps = [pWS launchedApplications]; 36 bool fFFound = false; 37 ProcessSerialNumber psn; 38 for (NSDictionary *pDict in pApps) 39 { 40 if ([[pDict valueForKey:@"NSApplicationBundleIdentifier"] isEqualToString:@"com.apple.finder"]) 41 { 42 psn.highLongOfPSN = [[pDict valueForKey:@"NSApplicationProcessSerialNumberHigh"] intValue]; 43 psn.lowLongOfPSN = [[pDict valueForKey:@"NSApplicationProcessSerialNumberLow"] intValue]; 44 fFFound = true; 45 break; 46 } 47 } 48 if (!fFFound) 30 if (!pstrSrcFile || !pstrDstPath) 49 31 return false; 50 32 51 /* Now the event fun begins. */ 52 OSErr err = noErr; 53 AliasHandle hSrcAlias = 0; 54 AliasHandle hDstAlias = 0; 55 do 33 NSError *pErr = nil; 34 NSURL *pSrcUrl = [NSURL fileURLWithPath:pstrSrcFile]; 35 36 NSString *pVmFileName = [pSrcUrl lastPathComponent]; 37 NSString *pSrcPath = [NSString stringWithFormat:@"%@/%@", pstrDstPath, [pVmFileName stringByDeletingPathExtension]]; 38 NSURL *pDstUrl = [NSURL fileURLWithPath:pSrcPath]; 39 40 bool rc = false; 41 42 if (!pSrcUrl || !pDstUrl) 43 return false; 44 45 NSData *pBookmark = [pSrcUrl bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile 46 includingResourceValuesForKeys:nil 47 relativeToURL:nil 48 error:&pErr]; 49 50 if (pBookmark) 56 51 { 57 /* Create a descriptor which contains the target psn. */ 58 NSAppleEventDescriptor *finderPSNDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber bytes:&psn length:sizeof(psn)]; 59 if (!finderPSNDesc) 60 break; 61 /* Create the Apple event descriptor which points to the Finder target already. */ 62 NSAppleEventDescriptor *finderEventDesc = [NSAppleEventDescriptor 63 appleEventWithEventClass:kAECoreSuite 64 eventID:kAECreateElement 65 targetDescriptor:finderPSNDesc 66 returnID:kAutoGenerateReturnID 67 transactionID:kAnyTransactionID]; 68 if (!finderEventDesc) 69 break; 70 /* Create and add an event type descriptor: Alias */ 71 NSAppleEventDescriptor *osTypeDesc = [NSAppleEventDescriptor descriptorWithTypeCode:typeAlias]; 72 if (!osTypeDesc) 73 break; 74 [finderEventDesc setParamDescriptor:osTypeDesc forKeyword:keyAEObjectClass]; 75 /* Now create the source Alias, which will be attached to the event. */ 76 err = FSNewAliasFromPath(nil, [pstrSrcFile fileSystemRepresentation], 0, &hSrcAlias, 0); 77 if (err != noErr) 78 break; 79 char handleState; 80 handleState = HGetState((Handle)hSrcAlias); 81 HLock((Handle)hSrcAlias); 82 NSAppleEventDescriptor *srcAliasDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeAlias bytes:*hSrcAlias length:GetAliasSize(hSrcAlias)]; 83 if (!srcAliasDesc) 84 break; 85 [finderEventDesc setParamDescriptor:srcAliasDesc forKeyword:keyASPrepositionTo]; 86 HSetState((Handle)hSrcAlias, handleState); 87 /* Next create the target Alias and attach it to the event. */ 88 err = FSNewAliasFromPath(nil, [pstrDstPath fileSystemRepresentation], 0, &hDstAlias, 0); 89 if (err != noErr) 90 break; 91 handleState = HGetState((Handle)hDstAlias); 92 HLock((Handle)hDstAlias); 93 NSAppleEventDescriptor *dstAliasDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeAlias bytes:*hDstAlias length:GetAliasSize(hDstAlias)]; 94 if (!dstAliasDesc) 95 break; 96 [finderEventDesc setParamDescriptor:dstAliasDesc forKeyword:keyAEInsertHere]; 97 HSetState((Handle)hDstAlias, handleState); 98 /* Finally a property descriptor containing the target Alias name. */ 99 NSAppleEventDescriptor *finderPropDesc = [NSAppleEventDescriptor recordDescriptor]; 100 if (!finderPropDesc) 101 break; 102 [finderPropDesc setDescriptor:[NSAppleEventDescriptor descriptorWithString:pstrName] forKeyword:keyAEName]; 103 [finderEventDesc setParamDescriptor:finderPropDesc forKeyword:keyAEPropData]; 104 /* Now send the event to the Finder. */ 105 err = AESend([finderEventDesc aeDesc], NULL, kAENoReply, kAENormalPriority, kNoTimeOut, 0, nil); 106 if (err != noErr) 107 break; 108 } while(0); 52 rc = [NSURL writeBookmarkData:pBookmark 53 toURL:pDstUrl 54 options:0 55 error:&pErr]; 56 } 109 57 110 /* Cleanup */ 111 if (hSrcAlias) 112 DisposeHandle((Handle)hSrcAlias); 113 if (hDstAlias) 114 DisposeHandle((Handle)hDstAlias); 115 116 return err == noErr ? true : false; 58 return rc; 117 59 } 118 60
Note:
See TracChangeset
for help on using the changeset viewer.