// Copyright (c) 2012 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/browser/mac/install_from_dmg.h"

#import <AppKit/AppKit.h>
#include <ApplicationServices/ApplicationServices.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <DiskArbitration/DiskArbitration.h>
#include <IOKit/IOKitLib.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/mount.h>

#include "base/auto_reset.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/mac/authorization_util.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/mac_logging.h"
#import "base/mac/mac_util.h"
#include "base/mac/scoped_authorizationref.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_ioobject.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/mac/dock.h"
#import "chrome/browser/mac/keystone_glue.h"
#include "chrome/browser/mac/relauncher.h"
#include "chrome/common/chrome_constants.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"

// When C++ exceptions are disabled, the C++ library defines |try| and
// |catch| so as to allow exception-expecting C++ code to build properly when
// language support for exceptions is not present.  These macros interfere
// with the use of |@try| and |@catch| in Objective-C files such as this one.
// Undefine these macros here, after everything has been #included, since
// there will be no C++ uses and only Objective-C uses from this point on.
#undef try
#undef catch

namespace {

// Given an io_service_t (expected to be of class IOMedia), walks the ancestor
// chain, returning the closest ancestor that implements class IOHDIXHDDrive,
// if any. If no such ancestor is found, returns NULL. Following the "copy"
// rule, the caller assumes ownership of the returned value.
//
// Note that this looks for a class that inherits from IOHDIXHDDrive, but it
// will not likely find a concrete IOHDIXHDDrive. It will be
// IOHDIXHDDriveOutKernel for disk images mounted "out-of-kernel" or
// IOHDIXHDDriveInKernel for disk images mounted "in-kernel." Out-of-kernel is
// the default as of Mac OS X 10.5. See the documentation for "hdiutil attach
// -kernel" for more information.
io_service_t CopyHDIXDriveServiceForMedia(io_service_t media) {
  const char disk_image_class[] = "IOHDIXHDDrive";

  // This is highly unlikely. media as passed in is expected to be of class
  // IOMedia. Since the media service's entire ancestor chain will be checked,
  // though, check it as well.
  if (IOObjectConformsTo(media, disk_image_class)) {
    IOObjectRetain(media);
    return media;
  }

  io_iterator_t iterator_ref;
  kern_return_t kr =
      IORegistryEntryCreateIterator(media,
                                    kIOServicePlane,
                                    kIORegistryIterateRecursively |
                                        kIORegistryIterateParents,
                                    &iterator_ref);
  if (kr != KERN_SUCCESS) {
    LOG(ERROR) << "IORegistryEntryCreateIterator: " << kr;
    return IO_OBJECT_NULL;
  }
  base::mac::ScopedIOObject<io_iterator_t> iterator(iterator_ref);
  iterator_ref = IO_OBJECT_NULL;

  // Look at each of the ancestor services, beginning with the parent,
  // iterating all the way up to the device tree's root. If any ancestor
  // service matches the class used for disk images, the media resides on a
  // disk image, and the disk image file's path can be determined by examining
  // the image-path property.
  for (base::mac::ScopedIOObject<io_service_t> ancestor(
           IOIteratorNext(iterator));
       ancestor;
       ancestor.reset(IOIteratorNext(iterator))) {
    if (IOObjectConformsTo(ancestor, disk_image_class)) {
      return ancestor.release();
    }
  }

  // The media does not reside on a disk image.
  return IO_OBJECT_NULL;
}

// Given an io_service_t (expected to be of class IOMedia), determines whether
// that service is on a disk image. If it is, returns true. If image_path is
// present, it will be set to the pathname of the disk image file, encoded in
// filesystem encoding.
bool MediaResidesOnDiskImage(io_service_t media, std::string* image_path) {
  if (image_path) {
    image_path->clear();
  }

  base::mac::ScopedIOObject<io_service_t> hdix_drive(
      CopyHDIXDriveServiceForMedia(media));
  if (!hdix_drive) {
    return false;
  }

  if (image_path) {
    base::ScopedCFTypeRef<CFTypeRef> image_path_cftyperef(
        IORegistryEntryCreateCFProperty(
            hdix_drive, CFSTR("image-path"), NULL, 0));
    if (!image_path_cftyperef) {
      LOG(ERROR) << "IORegistryEntryCreateCFProperty";
      return true;
    }
    if (CFGetTypeID(image_path_cftyperef) != CFDataGetTypeID()) {
      base::ScopedCFTypeRef<CFStringRef> observed_type_cf(
          CFCopyTypeIDDescription(CFGetTypeID(image_path_cftyperef)));
      std::string observed_type;
      if (observed_type_cf) {
        observed_type.assign(", observed ");
        observed_type.append(base::SysCFStringRefToUTF8(observed_type_cf));
      }
      LOG(ERROR) << "image-path: expected CFData, observed " << observed_type;
      return true;
    }

    CFDataRef image_path_data = static_cast<CFDataRef>(
        image_path_cftyperef.get());
    CFIndex length = CFDataGetLength(image_path_data);
    if (length <= 0) {
      LOG(ERROR) << "image_path_data is unexpectedly empty";
      return true;
    }
    char* image_path_c = WriteInto(image_path, length + 1);
    CFDataGetBytes(image_path_data,
                   CFRangeMake(0, length),
                   reinterpret_cast<UInt8*>(image_path_c));
  }

  return true;
}

// Returns true if |path| is located on a read-only filesystem of a disk
// image. Returns false if not, or in the event of an error. If
// out_dmg_bsd_device_name is present, it will be set to the BSD device name
// for the disk image's device, in "diskNsM" form.
bool IsPathOnReadOnlyDiskImage(const char path[],
                               std::string* out_dmg_bsd_device_name) {
  if (out_dmg_bsd_device_name) {
    out_dmg_bsd_device_name->clear();
  }

  struct statfs statfs_buf;
  if (statfs(path, &statfs_buf) != 0) {
    PLOG(ERROR) << "statfs " << path;
    return false;
  }

  if (!(statfs_buf.f_flags & MNT_RDONLY)) {
    // Not on a read-only filesystem.
    return false;
  }

  const char dev_root[] = "/dev/";
  const int dev_root_length = arraysize(dev_root) - 1;
  if (strncmp(statfs_buf.f_mntfromname, dev_root, dev_root_length) != 0) {
    // Not rooted at dev_root, no BSD name to search on.
    return false;
  }

  // BSD names in IOKit don't include dev_root.
  const char* dmg_bsd_device_name = statfs_buf.f_mntfromname + dev_root_length;
  if (out_dmg_bsd_device_name) {
    out_dmg_bsd_device_name->assign(dmg_bsd_device_name);
  }

  const mach_port_t master_port = kIOMasterPortDefault;

  // IOBSDNameMatching gives ownership of match_dict to the caller, but
  // IOServiceGetMatchingServices will assume that reference.
  CFMutableDictionaryRef match_dict = IOBSDNameMatching(master_port,
                                                        0,
                                                        dmg_bsd_device_name);
  if (!match_dict) {
    LOG(ERROR) << "IOBSDNameMatching " << dmg_bsd_device_name;
    return false;
  }

  io_iterator_t iterator_ref;
  kern_return_t kr = IOServiceGetMatchingServices(master_port,
                                                  match_dict,
                                                  &iterator_ref);
  if (kr != KERN_SUCCESS) {
    LOG(ERROR) << "IOServiceGetMatchingServices: " << kr;
    return false;
  }
  base::mac::ScopedIOObject<io_iterator_t> iterator(iterator_ref);
  iterator_ref = IO_OBJECT_NULL;

  // There needs to be exactly one matching service.
  base::mac::ScopedIOObject<io_service_t> media(IOIteratorNext(iterator));
  if (!media) {
    LOG(ERROR) << "IOIteratorNext: no service";
    return false;
  }
  base::mac::ScopedIOObject<io_service_t> unexpected_service(
      IOIteratorNext(iterator));
  if (unexpected_service) {
    LOG(ERROR) << "IOIteratorNext: too many services";
    return false;
  }

  iterator.reset();

  return MediaResidesOnDiskImage(media, NULL);
}

// Returns true if the application is located on a read-only filesystem of a
// disk image. Returns false if not, or in the event of an error. If
// dmg_bsd_device_name is present, it will be set to the BSD device name for
// the disk image's device, in "diskNsM" form.
bool IsAppRunningFromReadOnlyDiskImage(std::string* dmg_bsd_device_name) {
  return IsPathOnReadOnlyDiskImage(
      [[base::mac::OuterBundle() bundlePath] fileSystemRepresentation],
      dmg_bsd_device_name);
}

// Shows a dialog asking the user whether or not to install from the disk
// image.  Returns true if the user approves installation.
bool ShouldInstallDialog() {
  NSString* title = l10n_util::GetNSStringFWithFixup(
      IDS_INSTALL_FROM_DMG_TITLE, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
  NSString* prompt = l10n_util::GetNSStringFWithFixup(
      IDS_INSTALL_FROM_DMG_PROMPT, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
  NSString* yes = l10n_util::GetNSStringWithFixup(IDS_INSTALL_FROM_DMG_YES);
  NSString* no = l10n_util::GetNSStringWithFixup(IDS_INSTALL_FROM_DMG_NO);

  NSAlert* alert = [[[NSAlert alloc] init] autorelease];

  [alert setAlertStyle:NSInformationalAlertStyle];
  [alert setMessageText:title];
  [alert setInformativeText:prompt];
  [alert addButtonWithTitle:yes];
  NSButton* cancel_button = [alert addButtonWithTitle:no];
  [cancel_button setKeyEquivalent:@"\e"];

  NSInteger result = [alert runModal];

  return result == NSAlertFirstButtonReturn;
}

// Potentially shows an authorization dialog to request authentication to
// copy.  If application_directory appears to be unwritable, attempts to
// obtain authorization, which may result in the display of the dialog.
// Returns NULL if authorization is not performed because it does not appear
// to be necessary because the user has permission to write to
// application_directory.  Returns NULL if authorization fails.
AuthorizationRef MaybeShowAuthorizationDialog(NSString* application_directory) {
  NSFileManager* file_manager = [NSFileManager defaultManager];
  if ([file_manager isWritableFileAtPath:application_directory]) {
    return NULL;
  }

  NSString* prompt = l10n_util::GetNSStringFWithFixup(
      IDS_INSTALL_FROM_DMG_AUTHENTICATION_PROMPT,
      l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
  return base::mac::AuthorizationCreateToRunAsRoot(
      base::mac::NSToCFCast(prompt));
}

// Invokes the installer program at installer_path to copy source_path to
// target_path and perform any additional on-disk bookkeeping needed to be
// able to launch target_path properly.  If authorization_arg is non-NULL,
// function will assume ownership of it, will invoke the installer with that
// authorization reference, and will attempt Keystone ticket promotion.
bool InstallFromDiskImage(AuthorizationRef authorization_arg,
                          NSString* installer_path,
                          NSString* source_path,
                          NSString* target_path) {
  base::mac::ScopedAuthorizationRef authorization(authorization_arg);
  authorization_arg = NULL;
  int exit_status;
  if (authorization) {
    const char* installer_path_c = [installer_path fileSystemRepresentation];
    const char* source_path_c = [source_path fileSystemRepresentation];
    const char* target_path_c = [target_path fileSystemRepresentation];
    const char* arguments[] = {source_path_c, target_path_c, NULL};

    OSStatus status = base::mac::ExecuteWithPrivilegesAndWait(
        authorization,
        installer_path_c,
        kAuthorizationFlagDefaults,
        arguments,
        NULL,  // pipe
        &exit_status);
    if (status != errAuthorizationSuccess) {
      OSSTATUS_LOG(ERROR, status)
          << "AuthorizationExecuteWithPrivileges install";
      return false;
    }
  } else {
    NSArray* arguments = [NSArray arrayWithObjects:source_path,
                                                   target_path,
                                                   nil];

    NSTask* task;
    @try {
      task = [NSTask launchedTaskWithLaunchPath:installer_path
                                      arguments:arguments];
    } @catch(NSException* exception) {
      LOG(ERROR) << "+[NSTask launchedTaskWithLaunchPath:arguments:]: "
                 << [[exception description] UTF8String];
      return false;
    }

    [task waitUntilExit];
    exit_status = [task terminationStatus];
  }

  if (exit_status != 0) {
    LOG(ERROR) << "install.sh: exit status " << exit_status;
    return false;
  }

  if (authorization) {
    // As long as an AuthorizationRef is available, promote the Keystone
    // ticket.  Inform KeystoneGlue of the new path to use.
    KeystoneGlue* keystone_glue = [KeystoneGlue defaultKeystoneGlue];
    [keystone_glue setAppPath:target_path];
    [keystone_glue promoteTicketWithAuthorization:authorization.release()
                                      synchronous:YES];
  }

  return true;
}

// Launches the application at installed_path. The helper application
// contained within install_path will be used for the relauncher process. This
// keeps Launch Services from ever having to see or think about the helper
// application on the disk image. The relauncher process will be asked to
// call EjectAndTrashDiskImage on dmg_bsd_device_name.
bool LaunchInstalledApp(NSString* installed_path,
                        const std::string& dmg_bsd_device_name) {
  base::FilePath browser_path([installed_path fileSystemRepresentation]);

  base::FilePath helper_path = browser_path.Append("Contents/Versions");
  helper_path = helper_path.Append(chrome::kChromeVersion);
  helper_path = helper_path.Append(chrome::kHelperProcessExecutablePath);

  std::vector<std::string> args =
      CommandLine::ForCurrentProcess()->argv();
  args[0] = browser_path.value();

  std::vector<std::string> relauncher_args;
  if (!dmg_bsd_device_name.empty()) {
    std::string dmg_arg(mac_relauncher::kRelauncherDMGDeviceArg);
    dmg_arg.append(dmg_bsd_device_name);
    relauncher_args.push_back(dmg_arg);
  }

  return mac_relauncher::RelaunchAppWithHelper(helper_path.value(),
                                               relauncher_args,
                                               args);
}

void ShowErrorDialog() {
  NSString* title = l10n_util::GetNSStringWithFixup(
      IDS_INSTALL_FROM_DMG_ERROR_TITLE);
  NSString* error = l10n_util::GetNSStringFWithFixup(
      IDS_INSTALL_FROM_DMG_ERROR, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
  NSString* ok = l10n_util::GetNSStringWithFixup(IDS_OK);

  NSAlert* alert = [[[NSAlert alloc] init] autorelease];

  [alert setAlertStyle:NSWarningAlertStyle];
  [alert setMessageText:title];
  [alert setInformativeText:error];
  [alert addButtonWithTitle:ok];

  [alert runModal];
}

}  // namespace

bool MaybeInstallFromDiskImage() {
  base::mac::ScopedNSAutoreleasePool autorelease_pool;

  std::string dmg_bsd_device_name;
  if (!IsAppRunningFromReadOnlyDiskImage(&dmg_bsd_device_name)) {
    return false;
  }

  NSArray* application_directories =
      NSSearchPathForDirectoriesInDomains(NSApplicationDirectory,
                                          NSLocalDomainMask,
                                          YES);
  if ([application_directories count] == 0) {
    LOG(ERROR) << "NSSearchPathForDirectoriesInDomains: "
               << "no local application directories";
    return false;
  }
  NSString* application_directory = [application_directories objectAtIndex:0];

  NSFileManager* file_manager = [NSFileManager defaultManager];

  BOOL is_directory;
  if (![file_manager fileExistsAtPath:application_directory
                          isDirectory:&is_directory] ||
      !is_directory) {
    VLOG(1) << "No application directory at "
            << [application_directory UTF8String];
    return false;
  }

  NSString* source_path = [base::mac::OuterBundle() bundlePath];
  NSString* application_name = [source_path lastPathComponent];
  NSString* target_path =
      [application_directory stringByAppendingPathComponent:application_name];

  if ([file_manager fileExistsAtPath:target_path]) {
    VLOG(1) << "Something already exists at " << [target_path UTF8String];
    return false;
  }

  NSString* installer_path =
      [base::mac::FrameworkBundle() pathForResource:@"install" ofType:@"sh"];
  if (!installer_path) {
    VLOG(1) << "Could not locate install.sh";
    return false;
  }

  if (!ShouldInstallDialog()) {
    return false;
  }

  base::mac::ScopedAuthorizationRef authorization(
      MaybeShowAuthorizationDialog(application_directory));
  // authorization will be NULL if it's deemed unnecessary or if
  // authentication fails.  In either case, try to install without privilege
  // escalation.

  if (!InstallFromDiskImage(authorization.release(),
                            installer_path,
                            source_path,
                            target_path)) {
    ShowErrorDialog();
    return false;
  }

  dock::AddIcon(target_path, source_path);

  if (dmg_bsd_device_name.empty()) {
    // Not fatal, just diagnostic.
    LOG(ERROR) << "Could not determine disk image BSD device name";
  }

  if (!LaunchInstalledApp(target_path, dmg_bsd_device_name)) {
    ShowErrorDialog();
    return false;
  }

  return true;
}

namespace {

// A simple scoper that calls DASessionScheduleWithRunLoop when created and
// DASessionUnscheduleFromRunLoop when destroyed.
class ScopedDASessionScheduleWithRunLoop {
 public:
  ScopedDASessionScheduleWithRunLoop(DASessionRef session,
                                     CFRunLoopRef run_loop,
                                     CFStringRef run_loop_mode)
      : session_(session),
        run_loop_(run_loop),
        run_loop_mode_(run_loop_mode) {
    DASessionScheduleWithRunLoop(session_, run_loop_, run_loop_mode_);
  }

  ~ScopedDASessionScheduleWithRunLoop() {
    DASessionUnscheduleFromRunLoop(session_, run_loop_, run_loop_mode_);
  }

 private:
  DASessionRef session_;
  CFRunLoopRef run_loop_;
  CFStringRef run_loop_mode_;

  DISALLOW_COPY_AND_ASSIGN(ScopedDASessionScheduleWithRunLoop);
};

// A small structure used to ferry data between SynchronousDAOperation and
// SynchronousDACallbackAdapter.
struct SynchronousDACallbackData {
 public:
  SynchronousDACallbackData()
      : callback_called(false),
        run_loop_running(false) {
  }

  base::ScopedCFTypeRef<DADissenterRef> dissenter;
  bool callback_called;
  bool run_loop_running;

 private:
  DISALLOW_COPY_AND_ASSIGN(SynchronousDACallbackData);
};

// The callback target for SynchronousDAOperation. Set the fields in
// SynchronousDACallbackData properly and then stops the run loop so that
// SynchronousDAOperation may proceed.
void SynchronousDACallbackAdapter(DADiskRef disk,
                                  DADissenterRef dissenter,
                                  void* context) {
  SynchronousDACallbackData* callback_data =
      static_cast<SynchronousDACallbackData*>(context);
  callback_data->callback_called = true;

  if (dissenter) {
    CFRetain(dissenter);
    callback_data->dissenter.reset(dissenter);
  }

  // Only stop the run loop if SynchronousDAOperation started it. Don't stop
  // anything if this callback was reached synchronously from DADiskUnmount or
  // DADiskEject.
  if (callback_data->run_loop_running) {
    CFRunLoopStop(CFRunLoopGetCurrent());
  }
}

// Performs a DiskArbitration operation synchronously. After the operation is
// requested by SynchronousDADiskUnmount or SynchronousDADiskEject, those
// functions will call this one to run a run loop for a period of time,
// waiting for the callback to be called. When the callback is called, the
// run loop will be stopped, and this function will examine the result. If
// a dissenter prevented the operation from completing, or if the run loop
// timed out without the callback being called, this function will return
// false. When the callback completes successfully with no dissenters within
// the time allotted, this function returns true. This function requires that
// the DASession being used for the operation being performed has been added
// to the current run loop with DASessionScheduleWithRunLoop.
bool SynchronousDAOperation(const char* name,
                            SynchronousDACallbackData* callback_data) {
  // The callback may already have been called synchronously. In that case,
  // avoid spinning the run loop at all.
  if (!callback_data->callback_called) {
    const CFTimeInterval kOperationTimeoutSeconds = 15;
    base::AutoReset<bool> running_reset(&callback_data->run_loop_running, true);
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, kOperationTimeoutSeconds, FALSE);
  }

  if (!callback_data->callback_called) {
    LOG(ERROR) << name << ": timed out";
    return false;
  } else if (callback_data->dissenter) {
    CFStringRef status_string_cf =
        DADissenterGetStatusString(callback_data->dissenter);
    std::string status_string;
    if (status_string_cf) {
      status_string.assign(" ");
      status_string.append(base::SysCFStringRefToUTF8(status_string_cf));
    }
    LOG(ERROR) << name << ": dissenter: "
               << DADissenterGetStatus(callback_data->dissenter)
               << status_string;
    return false;
  }

  return true;
}

// Calls DADiskUnmount synchronously, returning the result.
bool SynchronousDADiskUnmount(DADiskRef disk, DADiskUnmountOptions options) {
  SynchronousDACallbackData callback_data;
  DADiskUnmount(disk, options, SynchronousDACallbackAdapter, &callback_data);
  return SynchronousDAOperation("DADiskUnmount", &callback_data);
}

// Calls DADiskEject synchronously, returning the result.
bool SynchronousDADiskEject(DADiskRef disk, DADiskEjectOptions options) {
  SynchronousDACallbackData callback_data;
  DADiskEject(disk, options, SynchronousDACallbackAdapter, &callback_data);
  return SynchronousDAOperation("DADiskEject", &callback_data);
}

}  // namespace

void EjectAndTrashDiskImage(const std::string& dmg_bsd_device_name) {
  base::ScopedCFTypeRef<DASessionRef> session(DASessionCreate(NULL));
  if (!session.get()) {
    LOG(ERROR) << "DASessionCreate";
    return;
  }

  base::ScopedCFTypeRef<DADiskRef> disk(
      DADiskCreateFromBSDName(NULL, session, dmg_bsd_device_name.c_str()));
  if (!disk.get()) {
    LOG(ERROR) << "DADiskCreateFromBSDName";
    return;
  }

  // dmg_bsd_device_name may only refer to part of the disk: it may be a
  // single filesystem on a larger disk. Use the "whole disk" object to
  // be able to unmount all mounted filesystems from the disk image, and eject
  // the image. This is harmless if dmg_bsd_device_name already referred to a
  // "whole disk."
  disk.reset(DADiskCopyWholeDisk(disk));
  if (!disk.get()) {
    LOG(ERROR) << "DADiskCopyWholeDisk";
    return;
  }

  base::mac::ScopedIOObject<io_service_t> media(DADiskCopyIOMedia(disk));
  if (!media.get()) {
    LOG(ERROR) << "DADiskCopyIOMedia";
    return;
  }

  // Make sure the device is a disk image, and get the path to its disk image
  // file.
  std::string disk_image_path;
  if (!MediaResidesOnDiskImage(media, &disk_image_path)) {
    LOG(ERROR) << "MediaResidesOnDiskImage";
    return;
  }

  // SynchronousDADiskUnmount and SynchronousDADiskEject require that the
  // session be scheduled with the current run loop.
  ScopedDASessionScheduleWithRunLoop session_run_loop(session,
                                                      CFRunLoopGetCurrent(),
                                                      kCFRunLoopCommonModes);

  if (!SynchronousDADiskUnmount(disk, kDADiskUnmountOptionWhole)) {
    LOG(ERROR) << "SynchronousDADiskUnmount";
    return;
  }

  if (!SynchronousDADiskEject(disk, kDADiskEjectOptionDefault)) {
    LOG(ERROR) << "SynchronousDADiskEject";
    return;
  }

  char* disk_image_path_in_trash_c;
  OSStatus status = FSPathMoveObjectToTrashSync(disk_image_path.c_str(),
                                                &disk_image_path_in_trash_c,
                                                kFSFileOperationDefaultOptions);
  if (status != noErr) {
    OSSTATUS_LOG(ERROR, status) << "FSPathMoveObjectToTrashSync";
    return;
  }

  // FSPathMoveObjectToTrashSync alone doesn't result in the Trash icon in the
  // Dock indicating that any garbage has been placed within it. Using the
  // trash path that FSPathMoveObjectToTrashSync claims to have used, call
  // FNNotifyByPath to fatten up the icon.
  base::FilePath disk_image_path_in_trash(disk_image_path_in_trash_c);
  free(disk_image_path_in_trash_c);

  base::FilePath trash_path = disk_image_path_in_trash.DirName();
  const UInt8* trash_path_u8 = reinterpret_cast<const UInt8*>(
      trash_path.value().c_str());
  status = FNNotifyByPath(trash_path_u8,
                          kFNDirectoryModifiedMessage,
                          kNilOptions);
  if (status != noErr) {
    OSSTATUS_LOG(ERROR, status) << "FNNotifyByPath";
    return;
  }
}
