Skip to content
Newer
Older
100644 112 lines (93 sloc) 3.55 KB
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
1 //
2 // SUDiskImageUnarchiver.m
3 // Sparkle
4 //
5 // Created by Andy Matuschak on 6/16/08.
6 // Copyright 2008 Andy Matuschak. All rights reserved.
7 //
8
9 #import "SUDiskImageUnarchiver.h"
10 #import "SUUnarchiver_Private.h"
11 #import "NTSynchronousTask.h"
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
12 #import "SULog.h"
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
13 #import <CoreServices/CoreServices.h>
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
14
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
15
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
16 @implementation SUDiskImageUnarchiver
17
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
18 + (BOOL)canUnarchivePath:(NSString *)path
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
19 {
58a05e2 @andymatuschak Fixes 243533 (for real this time, I hope)
andymatuschak authored
20 return [[path pathExtension] isEqualToString:@"dmg"];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
21 }
22
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
23 - (void)extractDMG
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
24 {
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
25 // GETS CALLED ON NON-MAIN THREAD!!!
26
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
27 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
28 BOOL mountedSuccessfully = NO;
29
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
30 SULog(@"Extracting %@ as a DMG", archivePath);
31
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
32 // get a unique mount point path
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
33 NSString *mountPointName = nil;
34 NSString *mountPoint = nil;
35 FSRef tmpRef;
36 do
37 {
38 CFUUIDRef uuid = CFUUIDCreate(NULL);
d7774c0 performed a code review, specifically:
Sean McBride authored
39 if (uuid)
40 {
41 CFStringRef uuidString = CFUUIDCreateString(NULL, uuid);
756b37d code review of CFRelease usage, minor changes
Sean McBride authored
42 if (uuidString)
43 {
44 mountPoint = [@"/Volumes" stringByAppendingPathComponent:(NSString*)uuidString];
45 CFRelease(uuidString);
46 }
d7774c0 performed a code review, specifically:
Sean McBride authored
47 CFRelease(uuid);
48 }
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
49 }
50 while (noErr == FSPathMakeRefWithOptions((UInt8 *)[mountPoint fileSystemRepresentation], kFSPathMakeRefDoNotFollowLeafSymlink, &tmpRef, NULL));
51
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
52 NSArray* arguments = [NSArray arrayWithObjects:@"attach", archivePath, @"-mountpoint", mountPoint, /*@"-noverify",*/ @"-nobrowse", @"-noautoopen", nil];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
53 // set up a pipe and push "yes" (y works too), this will accept any license agreement crap
54 // not every .dmg needs this, but this will make sure it works with everyone
55 NSData* yesData = [[[NSData alloc] initWithBytes:"yes\n" length:4] autorelease];
56
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
57 NSData *output = nil;
58 int returnCode = [NTSynchronousTask task:@"/usr/bin/hdiutil" directory:@"/" withArgs:arguments input:yesData output: &output];
59 if ( returnCode != 0 )
60 {
61 NSString* resultStr = output ? [[[NSString alloc] initWithData: output encoding: NSUTF8StringEncoding] autorelease] : nil;
62 SULog( @"hdiutil failed with code: %d data: <<%@>>", returnCode, resultStr );
63 goto reportError;
64 }
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
65 mountedSuccessfully = YES;
66
67 // Now that we've mounted it, we need to copy out its contents.
613b759 @cocoabythefire Fixed issues that led to crashes on Mac OS X 10.7 Lion.
cocoabythefire authored
68 if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
69 // On 10.6 and later we don't want to use the File Manager API and instead want to use NSFileManager (fixes #827357).
70 NSFileManager *manager = [[NSFileManager alloc] init];
71 if (![manager copyItemAtPath:mountPoint toPath:[archivePath stringByDeletingLastPathComponent] error:NULL]) {
72 goto reportError;
73 }
74 }
75 else {
76 FSRef srcRef, dstRef;
77 OSStatus err;
78 err = FSPathMakeRef((UInt8 *)[mountPoint fileSystemRepresentation], &srcRef, NULL);
79 if (err != noErr) goto reportError;
80 err = FSPathMakeRef((UInt8 *)[[archivePath stringByDeletingLastPathComponent] fileSystemRepresentation], &dstRef, NULL);
81 if (err != noErr) goto reportError;
82
83 err = FSCopyObjectSync(&srcRef, &dstRef, (CFStringRef)mountPointName, NULL, kFSFileOperationSkipSourcePermissionErrors);
84 if (err != noErr) goto reportError;
85 }
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
86
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
87 [self performSelectorOnMainThread:@selector(notifyDelegateOfSuccess) withObject:nil waitUntilDone:NO];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
88 goto finally;
89
90 reportError:
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
91 [self performSelectorOnMainThread:@selector(notifyDelegateOfFailure) withObject:nil waitUntilDone:NO];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
92
93 finally:
94 if (mountedSuccessfully)
dc249c1 @andymatuschak Fixes 246805
andymatuschak authored
95 [NSTask launchedTaskWithLaunchPath:@"/usr/bin/hdiutil" arguments:[NSArray arrayWithObjects:@"detach", mountPoint, @"-force", nil]];
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
96 else
97 SULog(@"Can't mount DMG %@",archivePath);
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
98 [pool drain];
99 }
100
d726066 fixed warning by moving private methods higher in the source file
Sean McBride authored
101 - (void)start
102 {
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
103 [NSThread detachNewThreadSelector:@selector(extractDMG) toTarget:self withObject:nil];
d726066 fixed warning by moving private methods higher in the source file
Sean McBride authored
104 }
105
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
106 + (void)load
107 {
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
108 [self registerImplementation:self];
93ea93d @andymatuschak Fixes 236695
andymatuschak authored
109 }
110
111 @end
Something went wrong with that request. Please try again.