OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/utility/image_writer/disk_unmounter_mac.h" | |
6 | |
7 #include <sys/socket.h> | |
8 #include <IOKit/storage/IOStorageProtocolCharacteristics.h> | |
9 | |
10 #include "base/message_loop/message_loop_proxy.h" | |
11 #include "base/message_loop/message_pump_mac.h" | |
12 #include "base/posix/eintr_wrapper.h" | |
13 #include "chrome/utility/image_writer/error_messages.h" | |
14 #include "chrome/utility/image_writer/image_writer.h" | |
15 | |
16 namespace image_writer { | |
17 | |
18 DiskUnmounterMac::DiskUnmounterMac() : cf_thread_("ImageWriterDiskArb") { | |
19 base::Thread::Options options; | |
20 options.message_pump_factory = base::Bind(&CreateMessagePump); | |
21 | |
22 cf_thread_.StartWithOptions(options); | |
23 } | |
24 | |
25 DiskUnmounterMac::~DiskUnmounterMac() { | |
26 if (disk_) | |
27 DADiskUnclaim(disk_); | |
28 } | |
29 | |
30 void DiskUnmounterMac::Unmount(const std::string& device_path, | |
31 const base::Closure& success_continuation, | |
32 const base::Closure& failure_continuation) { | |
Robert Sesek
2014/06/16 19:32:53
Maybe DCHECK(!original_thread_)?
Drew Haven
2014/06/16 21:51:39
I forget that we use these debug assertions to enf
| |
33 original_thread_ = base::MessageLoopProxy::current(); | |
34 success_continuation_ = success_continuation; | |
35 failure_continuation_ = failure_continuation; | |
36 | |
37 cf_thread_.message_loop()->PostTask( | |
38 FROM_HERE, | |
39 base::Bind(&DiskUnmounterMac::UnmountOnWorker, | |
40 base::Unretained(this), | |
41 device_path)); | |
42 } | |
43 | |
44 // static | |
45 void DiskUnmounterMac::DiskClaimed(DADiskRef disk, | |
46 DADissenterRef dissenter, | |
47 void* context) { | |
48 DiskUnmounterMac* disk_unmounter = static_cast<DiskUnmounterMac*>(context); | |
49 | |
50 if (dissenter) { | |
51 LOG(ERROR) << "Unable to claim disk."; | |
52 disk_unmounter->Error(); | |
53 return; | |
54 } | |
55 | |
56 DADiskUnmount(disk, | |
57 kDADiskUnmountOptionForce | kDADiskUnmountOptionWhole, | |
58 DiskUnmounted, | |
59 disk_unmounter); | |
60 } | |
61 | |
62 // static | |
63 DADissenterRef DiskUnmounterMac::DiskClaimRevoked(DADiskRef disk, | |
64 void* context) { | |
65 CFStringRef reason = CFSTR( | |
66 "Hi. Sorry to bother you, but I'm busy overwriting the entire disk " | |
67 "here. There's nothing to claim but the smoldering ruins of bytes " | |
68 "that were in flash memory. Trust me, it's nothing that you want. " | |
69 "All the best. Toodles!"); | |
70 return DADissenterCreate(kCFAllocatorDefault, kDAReturnBusy, reason); | |
71 } | |
72 | |
73 // static | |
74 void DiskUnmounterMac::DiskUnmounted(DADiskRef disk, | |
75 DADissenterRef dissenter, | |
76 void* context) { | |
77 DiskUnmounterMac* disk_unmounter = static_cast<DiskUnmounterMac*>(context); | |
78 | |
79 if (dissenter) { | |
80 LOG(ERROR) << "Unable to unmount disk."; | |
81 disk_unmounter->Error(); | |
82 return; | |
83 } | |
84 | |
85 disk_unmounter->original_thread_->PostTask( | |
86 FROM_HERE, disk_unmounter->success_continuation_); | |
87 } | |
88 | |
89 void DiskUnmounterMac::UnmountOnWorker(const std::string& device_path) { | |
90 DCHECK(cf_thread_.message_loop() == base::MessageLoop::current()); | |
91 | |
92 session_.reset(DASessionCreate(NULL)); | |
93 | |
94 DASessionScheduleWithRunLoop( | |
95 session_, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); | |
96 | |
97 disk_.reset(DADiskCreateFromBSDName( | |
98 kCFAllocatorDefault, session_, device_path.c_str())); | |
99 | |
100 if (!disk_) { | |
101 LOG(ERROR) << "Unable to get disk reference."; | |
102 Error(); | |
103 return; | |
104 } | |
105 | |
106 DADiskClaim(disk_, | |
107 kDADiskClaimOptionDefault, | |
108 DiskClaimRevoked, | |
109 this, | |
110 DiskClaimed, | |
111 this); | |
112 } | |
113 | |
114 // static | |
115 scoped_ptr<base::MessagePump> DiskUnmounterMac::CreateMessagePump() { | |
Robert Sesek
2014/06/16 19:32:53
nit: implementation order should match header orde
Drew Haven
2014/06/16 21:51:39
Done.
| |
116 return scoped_ptr<base::MessagePump>(new base::MessagePumpCFRunLoop); | |
117 } | |
118 | |
119 void DiskUnmounterMac::Error() { | |
120 original_thread_->PostTask(FROM_HERE, failure_continuation_); | |
121 } | |
122 | |
123 } // namespace image_writer | |
OLD | NEW |