summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhaven@chromium.org <haven@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-09 23:11:14 +0000
committerhaven@chromium.org <haven@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-09 23:11:14 +0000
commit6f584585d97c0ecc5ec0a5071f6e70cae3291e61 (patch)
treefd99f5be972768ccf5a54d9a5a4310d8bac9d6b5
parent8589e7d6a49c2af9872d84bd8511998b5f436ed3 (diff)
downloadchromium_src-6f584585d97c0ecc5ec0a5071f6e70cae3291e61.zip
chromium_src-6f584585d97c0ecc5ec0a5071f6e70cae3291e61.tar.gz
chromium_src-6f584585d97c0ecc5ec0a5071f6e70cae3291e61.tar.bz2
Changes Mac removable device listing to include all attached USB drives.
Some drives do not report themselves as removable despite appearing to a user to be a removable drive. Particularly this is the case for some USB sticks. We are fixing this by changing the device listing to list all drives that are either removable or attached via USB. We have already done a similar change for Chrome OS due to some SD card readers listing themselves as non-removable. Chrome OS lists all SD or USB drives. However, we do not have a reliable way to detect SD cards on Windows and Mac so we will continue to use the removable flag. BUG=391998 Review URL: https://codereview.chromium.org/375703004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282166 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc15
-rw-r--r--chrome/chrome_common.gypi2
-rw-r--r--chrome/common/extensions/image_writer/OWNERS2
-rw-r--r--chrome/common/extensions/image_writer/image_writer_util_mac.cc42
-rw-r--r--chrome/common/extensions/image_writer/image_writer_util_mac.h19
-rw-r--r--chrome/utility/image_writer/image_writer_mac.cc66
6 files changed, 114 insertions, 32 deletions
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc
index 67c8ab6..a47c63c 100644
--- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc
+++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc
@@ -16,6 +16,7 @@
#include "base/mac/scoped_ioobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
+#include "chrome/common/extensions/image_writer/image_writer_util_mac.h"
namespace extensions {
@@ -23,11 +24,9 @@ namespace extensions {
bool RemovableStorageProvider::PopulateDeviceList(
scoped_refptr<StorageDeviceList> device_list) {
base::ThreadRestrictions::AssertIOAllowed();
- // Match only removable, ejectable, non-internal, whole disks.
+ // Match only writable whole-disks.
CFMutableDictionaryRef matching = IOServiceMatching(kIOMediaClass);
CFDictionaryAddValue(matching, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
- CFDictionaryAddValue(matching, CFSTR(kIOMediaEjectableKey), kCFBooleanTrue);
- CFDictionaryAddValue(matching, CFSTR(kIOMediaRemovableKey), kCFBooleanTrue);
CFDictionaryAddValue(matching, CFSTR(kIOMediaWritableKey), kCFBooleanTrue);
io_service_t disk_iterator;
@@ -60,6 +59,16 @@ bool RemovableStorageProvider::PopulateDeviceList(
if (size_number)
CFNumberGetValue(size_number, kCFNumberLongLongType, &size_in_bytes);
+ CFBooleanRef cf_removable = base::mac::GetValueFromDictionary<CFBooleanRef>(
+ dict, CFSTR(kIOMediaRemovableKey));
+ bool removable = CFBooleanGetValue(cf_removable);
+
+ bool is_usb = IsUsbDevice(disk_obj);
+
+ if (!removable && !is_usb) {
+ continue;
+ }
+
base::ScopedCFTypeRef<CFDictionaryRef> characteristics(
static_cast<CFDictionaryRef>(IORegistryEntrySearchCFProperty(
disk_obj,
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 11a1afc..fd3380d 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -91,6 +91,8 @@
'common/extensions/features/chrome_channel_feature_filter.h',
'common/extensions/features/feature_channel.cc',
'common/extensions/features/feature_channel.h',
+ 'common/extensions/image_writer/image_writer_util_mac.cc',
+ 'common/extensions/image_writer/image_writer_util_mac.h',
'common/extensions/manifest_handlers/app_isolation_info.cc',
'common/extensions/manifest_handlers/app_isolation_info.h',
'common/extensions/manifest_handlers/app_launch_info.cc',
diff --git a/chrome/common/extensions/image_writer/OWNERS b/chrome/common/extensions/image_writer/OWNERS
new file mode 100644
index 0000000..0847ff8
--- /dev/null
+++ b/chrome/common/extensions/image_writer/OWNERS
@@ -0,0 +1,2 @@
+haven@chromium.org
+miket@chromium.org
diff --git a/chrome/common/extensions/image_writer/image_writer_util_mac.cc b/chrome/common/extensions/image_writer/image_writer_util_mac.cc
new file mode 100644
index 0000000..70f4460
--- /dev/null
+++ b/chrome/common/extensions/image_writer/image_writer_util_mac.cc
@@ -0,0 +1,42 @@
+// 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/common/extensions/image_writer/image_writer_util_mac.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_ioobject.h"
+
+namespace extensions {
+
+bool IsUsbDevice(io_object_t disk_obj) {
+ io_object_t current_obj = disk_obj;
+ io_object_t parent_obj = 0;
+ // Keep scoped object outside the loop so the object lives to the next
+ // GetParentEntry.
+ base::mac::ScopedIOObject<io_object_t> parent_obj_ref(parent_obj);
+
+ while ((IORegistryEntryGetParentEntry(
+ current_obj, kIOServicePlane, &parent_obj)) == KERN_SUCCESS) {
+ current_obj = parent_obj;
+ parent_obj_ref.reset(parent_obj);
+
+ base::ScopedCFTypeRef<CFStringRef> class_name(
+ IOObjectCopyClass(current_obj));
+ if (!class_name) {
+ LOG(ERROR) << "Could not get object class of IO Registry Entry.";
+ continue;
+ }
+
+ if (CFStringCompare(class_name.get(), CFSTR("IOUSBMassStorageClass"), 0) ==
+ kCFCompareEqualTo) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/image_writer/image_writer_util_mac.h b/chrome/common/extensions/image_writer/image_writer_util_mac.h
new file mode 100644
index 0000000..5b1c82c
--- /dev/null
+++ b/chrome/common/extensions/image_writer/image_writer_util_mac.h
@@ -0,0 +1,19 @@
+// 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.
+
+#ifndef CHROME_COMMON_EXTENSIONS_IMAGE_WRITER_IMAGE_WRITER_UTIL_MAC_H
+#define CHROME_COMMON_EXTENSIONS_IMAGE_WRITER_IMAGE_WRITER_UTIL_MAC_H
+
+#include <IOKit/IOKitLib.h>
+
+namespace extensions {
+
+// Determines whether the object from the IO registry is a USB mass storage
+// device. It does this by reading the ancestors of the object to see if any
+// is of the USB mass-storage class.
+bool IsUsbDevice(io_object_t disk_obj);
+
+} // namespace extensions
+
+#endif // CHROME_COMMON_EXTENSIONS_IMAGE_WRITER_IMAGE_WRITER_UTIL_MAC_H
diff --git a/chrome/utility/image_writer/image_writer_mac.cc b/chrome/utility/image_writer/image_writer_mac.cc
index 0935a5a..c572d14 100644
--- a/chrome/utility/image_writer/image_writer_mac.cc
+++ b/chrome/utility/image_writer/image_writer_mac.cc
@@ -2,15 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOBSD.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/storage/IOBlockStorageDevice.h>
+#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
#include <sys/socket.h>
#include "base/command_line.h"
#include "base/files/scoped_file.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_ioobject.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/strings/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
+#include "chrome/common/extensions/image_writer/image_writer_util_mac.h"
#include "chrome/utility/image_writer/disk_unmounter_mac.h"
#include "chrome/utility/image_writer/error_messages.h"
#include "chrome/utility/image_writer/image_writer.h"
@@ -20,37 +29,36 @@ namespace image_writer {
static const char kAuthOpenPath[] = "/usr/libexec/authopen";
bool ImageWriter::IsValidDevice() {
- base::ScopedCFTypeRef<DASessionRef> session(DASessionCreate(NULL));
- base::ScopedCFTypeRef<DADiskRef> disk(DADiskCreateFromBSDName(
- kCFAllocatorDefault, session, device_path_.value().c_str()));
+ base::ScopedCFTypeRef<CFStringRef> cf_bsd_name(
+ base::SysUTF8ToCFStringRef(device_path_.value()));
+ CFMutableDictionaryRef matching = IOServiceMatching(kIOMediaClass);
+ CFDictionaryAddValue(matching, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
+ CFDictionaryAddValue(matching, CFSTR(kIOMediaWritableKey), kCFBooleanTrue);
+ CFDictionaryAddValue(matching, CFSTR(kIOBSDNameKey), cf_bsd_name);
+
+ io_service_t disk_obj =
+ IOServiceGetMatchingService(kIOMasterPortDefault, matching);
+ base::mac::ScopedIOObject<io_service_t> iterator_ref(disk_obj);
+
+ if (disk_obj) {
+ CFMutableDictionaryRef dict;
+ if (IORegistryEntryCreateCFProperties(
+ disk_obj, &dict, kCFAllocatorDefault, 0) != KERN_SUCCESS) {
+ LOG(ERROR) << "Unable to get properties of disk object.";
+ return false;
+ }
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> dict_ref(dict);
- if (!disk)
- return false;
+ CFBooleanRef cf_removable = base::mac::GetValueFromDictionary<CFBooleanRef>(
+ dict, CFSTR(kIOMediaRemovableKey));
+ bool removable = CFBooleanGetValue(cf_removable);
+
+ bool is_usb = extensions::IsUsbDevice(disk_obj);
+
+ return removable || is_usb;
+ }
- base::ScopedCFTypeRef<CFDictionaryRef> disk_description(
- DADiskCopyDescription(disk));
-
- CFBooleanRef ejectable = base::mac::GetValueFromDictionary<CFBooleanRef>(
- disk_description, kDADiskDescriptionMediaEjectableKey);
- CFBooleanRef removable = base::mac::GetValueFromDictionary<CFBooleanRef>(
- disk_description, kDADiskDescriptionMediaRemovableKey);
- CFBooleanRef writable = base::mac::GetValueFromDictionary<CFBooleanRef>(
- disk_description, kDADiskDescriptionMediaWritableKey);
- CFBooleanRef whole = base::mac::GetValueFromDictionary<CFBooleanRef>(
- disk_description, kDADiskDescriptionMediaWholeKey);
- CFStringRef kind = base::mac::GetValueFromDictionary<CFStringRef>(
- disk_description, kDADiskDescriptionMediaKindKey);
-
- // A drive is valid if it is
- // - ejectable
- // - removable
- // - writable
- // - a whole drive
- // - it is of type IOMedia (external DVD drives and the like are IOCDMedia or
- // IODVDMedia)
- return CFBooleanGetValue(ejectable) && CFBooleanGetValue(removable) &&
- CFBooleanGetValue(writable) && CFBooleanGetValue(whole) &&
- CFStringCompare(kind, CFSTR("IOMedia"), 0) == kCFCompareEqualTo;
+ return false;
}
void ImageWriter::UnmountVolumes(const base::Closure& continuation) {