| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/storage_monitor/volume_mount_watcher_win.h" | 5 #include "components/storage_monitor/volume_mount_watcher_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include <dbt.h> | 9 #include <dbt.h> |
| 10 #include <fileapi.h> | 10 #include <fileapi.h> |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 return FLOPPY; | 68 return FLOPPY; |
| 69 | 69 |
| 70 // Check device strings of the form "X:" and "\\.\X:" | 70 // Check device strings of the form "X:" and "\\.\X:" |
| 71 // For floppy drives, these will return strings like "/Device/Floppy0" | 71 // For floppy drives, these will return strings like "/Device/Floppy0" |
| 72 base::string16 device = mount_point; | 72 base::string16 device = mount_point; |
| 73 if (base::EndsWith(mount_point, L"\\", false)) | 73 if (base::EndsWith(mount_point, L"\\", false)) |
| 74 device = mount_point.substr(0, mount_point.length() - 1); | 74 device = mount_point.substr(0, mount_point.length() - 1); |
| 75 base::string16 device_path; | 75 base::string16 device_path; |
| 76 base::string16 device_path_slash; | 76 base::string16 device_path_slash; |
| 77 DWORD dos_device = QueryDosDevice( | 77 DWORD dos_device = QueryDosDevice( |
| 78 device.c_str(), WriteInto(&device_path, kMaxPathBufLen), kMaxPathBufLen); | 78 device.c_str(), base::WriteInto(&device_path, kMaxPathBufLen), |
| 79 kMaxPathBufLen); |
| 79 base::string16 device_slash = base::string16(L"\\\\.\\"); | 80 base::string16 device_slash = base::string16(L"\\\\.\\"); |
| 80 device_slash += device; | 81 device_slash += device; |
| 81 DWORD dos_device_slash = QueryDosDevice( | 82 DWORD dos_device_slash = QueryDosDevice( |
| 82 device_slash.c_str(), WriteInto(&device_path_slash, kMaxPathBufLen), | 83 device_slash.c_str(), base::WriteInto(&device_path_slash, kMaxPathBufLen), |
| 83 kMaxPathBufLen); | 84 kMaxPathBufLen); |
| 84 if (dos_device == 0 && dos_device_slash == 0) | 85 if (dos_device == 0 && dos_device_slash == 0) |
| 85 return FLOPPY; | 86 return FLOPPY; |
| 86 if (device_path.find(L"Floppy") != base::string16::npos || | 87 if (device_path.find(L"Floppy") != base::string16::npos || |
| 87 device_path_slash.find(L"Floppy") != base::string16::npos) { | 88 device_path_slash.find(L"Floppy") != base::string16::npos) { |
| 88 return FLOPPY; | 89 return FLOPPY; |
| 89 } | 90 } |
| 90 | 91 |
| 91 return REMOVABLE; | 92 return REMOVABLE; |
| 92 } | 93 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 119 // Gets mass storage device information given a |device_path|. On success, | 120 // Gets mass storage device information given a |device_path|. On success, |
| 120 // returns true and fills in |info|. | 121 // returns true and fills in |info|. |
| 121 // The following msdn blog entry is helpful for understanding disk volumes | 122 // The following msdn blog entry is helpful for understanding disk volumes |
| 122 // and how they are treated in Windows: | 123 // and how they are treated in Windows: |
| 123 // http://blogs.msdn.com/b/adioltean/archive/2005/04/16/408947.aspx. | 124 // http://blogs.msdn.com/b/adioltean/archive/2005/04/16/408947.aspx. |
| 124 bool GetDeviceDetails(const base::FilePath& device_path, StorageInfo* info) { | 125 bool GetDeviceDetails(const base::FilePath& device_path, StorageInfo* info) { |
| 125 DCHECK(info); | 126 DCHECK(info); |
| 126 | 127 |
| 127 base::string16 mount_point; | 128 base::string16 mount_point; |
| 128 if (!GetVolumePathName(device_path.value().c_str(), | 129 if (!GetVolumePathName(device_path.value().c_str(), |
| 129 WriteInto(&mount_point, kMaxPathBufLen), | 130 base::WriteInto(&mount_point, kMaxPathBufLen), |
| 130 kMaxPathBufLen)) { | 131 kMaxPathBufLen)) { |
| 131 return false; | 132 return false; |
| 132 } | 133 } |
| 133 mount_point.resize(wcslen(mount_point.c_str())); | 134 mount_point.resize(wcslen(mount_point.c_str())); |
| 134 | 135 |
| 135 // Note: experimentally this code does not spin a floppy drive. It | 136 // Note: experimentally this code does not spin a floppy drive. It |
| 136 // returns a GUID associated with the device, not the volume. | 137 // returns a GUID associated with the device, not the volume. |
| 137 base::string16 guid; | 138 base::string16 guid; |
| 138 if (!GetVolumeNameForVolumeMountPoint(mount_point.c_str(), | 139 if (!GetVolumeNameForVolumeMountPoint(mount_point.c_str(), |
| 139 WriteInto(&guid, kMaxPathBufLen), | 140 base::WriteInto(&guid, kMaxPathBufLen), |
| 140 kMaxPathBufLen)) { | 141 kMaxPathBufLen)) { |
| 141 return false; | 142 return false; |
| 142 } | 143 } |
| 143 // In case it has two GUID's (see above mentioned blog), do it again. | 144 // In case it has two GUID's (see above mentioned blog), do it again. |
| 144 if (!GetVolumeNameForVolumeMountPoint(guid.c_str(), | 145 if (!GetVolumeNameForVolumeMountPoint(guid.c_str(), |
| 145 WriteInto(&guid, kMaxPathBufLen), | 146 base::WriteInto(&guid, kMaxPathBufLen), |
| 146 kMaxPathBufLen)) { | 147 kMaxPathBufLen)) { |
| 147 return false; | 148 return false; |
| 148 } | 149 } |
| 149 | 150 |
| 150 // If we're adding a floppy drive, return without querying any more | 151 // If we're adding a floppy drive, return without querying any more |
| 151 // drive metadata -- it will cause the floppy drive to seek. | 152 // drive metadata -- it will cause the floppy drive to seek. |
| 152 // Note: treats FLOPPY as FIXED_MASS_STORAGE. This is intentional. | 153 // Note: treats FLOPPY as FIXED_MASS_STORAGE. This is intentional. |
| 153 DeviceType device_type = GetDeviceType(mount_point); | 154 DeviceType device_type = GetDeviceType(mount_point); |
| 154 if (device_type == FLOPPY) { | 155 if (device_type == FLOPPY) { |
| 155 info->set_device_id(StorageInfo::MakeDeviceId( | 156 info->set_device_id(StorageInfo::MakeDeviceId( |
| 156 StorageInfo::FIXED_MASS_STORAGE, base::UTF16ToUTF8(guid))); | 157 StorageInfo::FIXED_MASS_STORAGE, base::UTF16ToUTF8(guid))); |
| 157 return true; | 158 return true; |
| 158 } | 159 } |
| 159 | 160 |
| 160 StorageInfo::Type type = StorageInfo::FIXED_MASS_STORAGE; | 161 StorageInfo::Type type = StorageInfo::FIXED_MASS_STORAGE; |
| 161 if (device_type == REMOVABLE) { | 162 if (device_type == REMOVABLE) { |
| 162 type = StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM; | 163 type = StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM; |
| 163 if (MediaStorageUtil::HasDcim(base::FilePath(mount_point))) | 164 if (MediaStorageUtil::HasDcim(base::FilePath(mount_point))) |
| 164 type = StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM; | 165 type = StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM; |
| 165 } | 166 } |
| 166 | 167 |
| 167 // NOTE: experimentally, this function returns false if there is no volume | 168 // NOTE: experimentally, this function returns false if there is no volume |
| 168 // name set. | 169 // name set. |
| 169 base::string16 volume_label; | 170 base::string16 volume_label; |
| 170 GetVolumeInformationW(device_path.value().c_str(), | 171 GetVolumeInformationW(device_path.value().c_str(), |
| 171 WriteInto(&volume_label, kMaxPathBufLen), | 172 base::WriteInto(&volume_label, kMaxPathBufLen), |
| 172 kMaxPathBufLen, NULL, NULL, NULL, NULL, 0); | 173 kMaxPathBufLen, NULL, NULL, NULL, NULL, 0); |
| 173 | 174 |
| 174 uint64 total_size_in_bytes = GetVolumeSize(mount_point); | 175 uint64 total_size_in_bytes = GetVolumeSize(mount_point); |
| 175 std::string device_id = | 176 std::string device_id = |
| 176 StorageInfo::MakeDeviceId(type, base::UTF16ToUTF8(guid)); | 177 StorageInfo::MakeDeviceId(type, base::UTF16ToUTF8(guid)); |
| 177 | 178 |
| 178 // TODO(gbillock): if volume_label.empty(), get the vendor/model information | 179 // TODO(gbillock): if volume_label.empty(), get the vendor/model information |
| 179 // for the volume. | 180 // for the volume. |
| 180 *info = StorageInfo(device_id, mount_point, volume_label, base::string16(), | 181 *info = StorageInfo(device_id, mount_point, volume_label, base::string16(), |
| 181 base::string16(), total_size_in_bytes); | 182 base::string16(), total_size_in_bytes); |
| 182 return true; | 183 return true; |
| 183 } | 184 } |
| 184 | 185 |
| 185 // Returns a vector of all the removable mass storage devices that are | 186 // Returns a vector of all the removable mass storage devices that are |
| 186 // connected. | 187 // connected. |
| 187 std::vector<base::FilePath> GetAttachedDevices() { | 188 std::vector<base::FilePath> GetAttachedDevices() { |
| 188 std::vector<base::FilePath> result; | 189 std::vector<base::FilePath> result; |
| 189 base::string16 volume_name; | 190 base::string16 volume_name; |
| 190 HANDLE find_handle = FindFirstVolume(WriteInto(&volume_name, kMaxPathBufLen), | 191 HANDLE find_handle = FindFirstVolume( |
| 191 kMaxPathBufLen); | 192 base::WriteInto(&volume_name, kMaxPathBufLen), kMaxPathBufLen); |
| 192 if (find_handle == INVALID_HANDLE_VALUE) | 193 if (find_handle == INVALID_HANDLE_VALUE) |
| 193 return result; | 194 return result; |
| 194 | 195 |
| 195 while (true) { | 196 while (true) { |
| 196 base::string16 volume_path; | 197 base::string16 volume_path; |
| 197 DWORD return_count; | 198 DWORD return_count; |
| 198 if (GetVolumePathNamesForVolumeName(volume_name.c_str(), | 199 if (GetVolumePathNamesForVolumeName( |
| 199 WriteInto(&volume_path, kMaxPathBufLen), | 200 volume_name.c_str(), base::WriteInto(&volume_path, kMaxPathBufLen), |
| 200 kMaxPathBufLen, &return_count)) { | 201 kMaxPathBufLen, &return_count)) { |
| 201 result.push_back(base::FilePath(volume_path)); | 202 result.push_back(base::FilePath(volume_path)); |
| 202 } | 203 } |
| 203 if (!FindNextVolume(find_handle, WriteInto(&volume_name, kMaxPathBufLen), | 204 if (!FindNextVolume(find_handle, |
| 205 base::WriteInto(&volume_name, kMaxPathBufLen), |
| 204 kMaxPathBufLen)) { | 206 kMaxPathBufLen)) { |
| 205 if (GetLastError() != ERROR_NO_MORE_FILES) | 207 if (GetLastError() != ERROR_NO_MORE_FILES) |
| 206 DPLOG(ERROR); | 208 DPLOG(ERROR); |
| 207 break; | 209 break; |
| 208 } | 210 } |
| 209 } | 211 } |
| 210 | 212 |
| 211 FindVolumeClose(find_handle); | 213 FindVolumeClose(find_handle); |
| 212 return result; | 214 return result; |
| 213 } | 215 } |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 callback.Run(StorageMonitor::EJECT_FAILURE); | 544 callback.Run(StorageMonitor::EJECT_FAILURE); |
| 543 return; | 545 return; |
| 544 } | 546 } |
| 545 | 547 |
| 546 device_info_task_runner_->PostTask( | 548 device_info_task_runner_->PostTask( |
| 547 FROM_HERE, base::Bind(&EjectDeviceInThreadPool, device, callback, | 549 FROM_HERE, base::Bind(&EjectDeviceInThreadPool, device, callback, |
| 548 device_info_task_runner_, 0)); | 550 device_info_task_runner_, 0)); |
| 549 } | 551 } |
| 550 | 552 |
| 551 } // namespace storage_monitor | 553 } // namespace storage_monitor |
| OLD | NEW |