-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBDDiskArbitrationSession.m
116 lines (99 loc) · 3.35 KB
/
BDDiskArbitrationSession.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//
// BDDiskArbitrationSession.m
// ButteredDisk
//
// Created by Jeremy Knope on 10/17/09.
// Copyright 2009 Buttered Cat Software. All rights reserved.
//
#import "BDDiskArbitrationSession.h"
#import "BDDisk.h"
@implementation BDDiskArbitrationSession {
DASessionRef _session;
CFRunLoopRef _sessionRunLoop;
__weak BDDiskArbitrationSession *_weakSelf; // used for the callbacks
}
void bcDiskAppeared(DADiskRef disk, void *context)
{
BDDiskArbitrationSession *self = *(BDDiskArbitrationSession * __weak *)context;
[self diskDidAppear:disk];
}
void bcDiskDisappeared(DADiskRef disk, void *context)
{
BDDiskArbitrationSession *self = *(BDDiskArbitrationSession * __weak *)context;
[self diskDidDisappear:disk];
}
- (id)initWithDelegate:(NSObject <BDDiskArbitrationSessionDelegate> *)newDelegate
{
if((self = [super init]))
{
_delegate = newDelegate;
_session = DASessionCreate(kCFAllocatorDefault);
_sessionRunLoop = (CFRunLoopRef)CFRetain(CFRunLoopGetCurrent());
DASessionScheduleWithRunLoop(_session, _sessionRunLoop, kCFRunLoopCommonModes);
_weakSelf = self;
[self watchDisks];
}
return self;
}
- (void)dealloc
{
[self unwatchDisks];
DASessionUnscheduleFromRunLoop(_session, _sessionRunLoop, kCFRunLoopCommonModes);
CFRelease(_session);
CFRelease(_sessionRunLoop);
}
- (void)watchDisks
{
DARegisterDiskAppearedCallback(_session, NULL, bcDiskAppeared, (void *)(&_weakSelf));
DARegisterDiskDisappearedCallback(_session, NULL, bcDiskDisappeared, (void *)(&_weakSelf));
// TODO: add support for mount/unmount notifications (do we have to rely on NSWorkspace?)
// [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(diskDidMount:) name:NSWorkspaceDidMountNotification object:nil];
// currently don't care for unmounts
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(diskDidUnmount:) name:NSWorkspaceDidUnmountNotification object:nil];
}
- (void)unwatchDisks
{
DAUnregisterCallback(_session, bcDiskAppeared, (void *)(&_weakSelf));
DAUnregisterCallback(_session, bcDiskDisappeared, (void *)(&_weakSelf));
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
}
- (void)diskDidAppear:(DADiskRef)aDisk
{
BDDisk *disk = [BDDisk diskWithRef:aDisk];
id<BDDiskArbitrationSessionDelegate> delegate = self.delegate;
if([delegate respondsToSelector:@selector(diskDidAppear:)]) {
[delegate diskDidAppear:disk];
}
}
- (void)diskDidDisappear:(DADiskRef)aDisk
{
BDDisk *disk = [BDDisk diskWithRef:aDisk];
id<BDDiskArbitrationSessionDelegate> delegate = self.delegate;
if([delegate respondsToSelector:@selector(diskDidDisappear:)]) {
[delegate diskDidDisappear:disk];
}
}
#pragma mark -
- (BDDisk *)diskForVolumeURL:(NSURL *)url
{
if(url) {
DADiskRef diskRef = DADiskCreateFromVolumePath(kCFAllocatorDefault, _session, (__bridge CFURLRef)url);
if(diskRef) {
BDDisk *disk = [BDDisk diskWithRef:diskRef];
CFRelease(diskRef);
return disk;
}
}
return nil;
}
- (BDDisk *)diskForBSDName:(NSString *)bsdName
{
DADiskRef diskRef = DADiskCreateFromBSDName(kCFAllocatorDefault, _session, [bsdName UTF8String]);
if(diskRef) {
BDDisk *disk = [BDDisk diskWithRef:diskRef];
CFRelease(diskRef);
return disk;
}
return nil;
}
@end