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 |