| Index: chrome/utility/image_writer/disk_unmounter_mac.cc
|
| diff --git a/chrome/utility/image_writer/disk_unmounter_mac.cc b/chrome/utility/image_writer/disk_unmounter_mac.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8da5975f780417bf689411ad119d73ecc707b074
|
| --- /dev/null
|
| +++ b/chrome/utility/image_writer/disk_unmounter_mac.cc
|
| @@ -0,0 +1,123 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/utility/image_writer/disk_unmounter_mac.h"
|
| +
|
| +#include <sys/socket.h>
|
| +#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
|
| +
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +#include "base/message_loop/message_pump_mac.h"
|
| +#include "base/posix/eintr_wrapper.h"
|
| +#include "chrome/utility/image_writer/error_messages.h"
|
| +#include "chrome/utility/image_writer/image_writer.h"
|
| +
|
| +namespace image_writer {
|
| +
|
| +DiskUnmounterMac::DiskUnmounterMac() : cf_thread_("ImageWriterDiskArb") {
|
| + base::Thread::Options options;
|
| + options.message_pump_factory = base::Bind(&CreateMessagePump);
|
| +
|
| + cf_thread_.StartWithOptions(options);
|
| +}
|
| +
|
| +DiskUnmounterMac::~DiskUnmounterMac() {
|
| + if (disk_)
|
| + DADiskUnclaim(disk_);
|
| +}
|
| +
|
| +void DiskUnmounterMac::Unmount(const std::string& device_path,
|
| + const base::Closure& success_continuation,
|
| + const base::Closure& failure_continuation) {
|
| + original_thread_ = base::MessageLoopProxy::current();
|
| + success_continuation_ = success_continuation;
|
| + failure_continuation_ = failure_continuation;
|
| +
|
| + cf_thread_.message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&DiskUnmounterMac::UnmountOnWorker,
|
| + base::Unretained(this),
|
| + device_path));
|
| +}
|
| +
|
| +// static
|
| +void DiskUnmounterMac::DiskClaimed(DADiskRef disk,
|
| + DADissenterRef dissenter,
|
| + void* context) {
|
| + DiskUnmounterMac* disk_unmounter = static_cast<DiskUnmounterMac*>(context);
|
| +
|
| + if (dissenter) {
|
| + LOG(ERROR) << "Unable to claim disk.";
|
| + disk_unmounter->Error();
|
| + return;
|
| + }
|
| +
|
| + DADiskUnmount(disk,
|
| + kDADiskUnmountOptionForce | kDADiskUnmountOptionWhole,
|
| + DiskUnmounted,
|
| + disk_unmounter);
|
| +}
|
| +
|
| +// static
|
| +DADissenterRef DiskUnmounterMac::DiskClaimRevoked(DADiskRef disk,
|
| + void* context) {
|
| + CFStringRef reason = CFSTR(
|
| + "Hi. Sorry to bother you, but I'm busy overwriting the entire disk "
|
| + "here. There's nothing to claim but the smoldering ruins of bytes "
|
| + "that were in flash memory. Trust me, it's nothing that you want. "
|
| + "All the best. Toodles!");
|
| + return DADissenterCreate(kCFAllocatorDefault, kDAReturnBusy, reason);
|
| +}
|
| +
|
| +// static
|
| +void DiskUnmounterMac::DiskUnmounted(DADiskRef disk,
|
| + DADissenterRef dissenter,
|
| + void* context) {
|
| + DiskUnmounterMac* disk_unmounter = static_cast<DiskUnmounterMac*>(context);
|
| +
|
| + if (dissenter) {
|
| + LOG(ERROR) << "Unable to unmount disk.";
|
| + disk_unmounter->Error();
|
| + return;
|
| + }
|
| +
|
| + disk_unmounter->original_thread_->PostTask(
|
| + FROM_HERE, disk_unmounter->success_continuation_);
|
| +}
|
| +
|
| +void DiskUnmounterMac::UnmountOnWorker(const std::string& device_path) {
|
| + DCHECK(cf_thread_.message_loop() == base::MessageLoop::current());
|
| +
|
| + session_.reset(DASessionCreate(NULL));
|
| +
|
| + DASessionScheduleWithRunLoop(
|
| + session_, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
| +
|
| + disk_.reset(DADiskCreateFromBSDName(
|
| + kCFAllocatorDefault, session_, device_path.c_str()));
|
| +
|
| + if (!disk_) {
|
| + LOG(ERROR) << "Unable to get disk reference.";
|
| + Error();
|
| + return;
|
| + }
|
| +
|
| + DADiskClaim(disk_,
|
| + kDADiskClaimOptionDefault,
|
| + DiskClaimRevoked,
|
| + this,
|
| + DiskClaimed,
|
| + this);
|
| +}
|
| +
|
| +// static
|
| +scoped_ptr<base::MessagePump> DiskUnmounterMac::CreateMessagePump() {
|
| + return scoped_ptr<base::MessagePump>(new base::MessagePumpCFRunLoop);
|
| +}
|
| +
|
| +void DiskUnmounterMac::Error() {
|
| + original_thread_->PostTask(FROM_HERE, failure_continuation_);
|
| +}
|
| +
|
| +} // namespace image_writer
|
|
|