OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chrome/browser/media_galleries/win/mtp_device_operations_util.h" | 5 #include "chrome/browser/media_galleries/win/mtp_device_operations_util.h" |
6 | 6 |
7 #include <portabledevice.h> | 7 #include <portabledevice.h> |
| 8 #include <stdint.h> |
8 | 9 |
9 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <limits> |
10 | 12 |
11 #include "base/basictypes.h" | |
12 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
13 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/numerics/safe_conversions.h" | 16 #include "base/numerics/safe_conversions.h" |
16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
17 #include "base/threading/thread_restrictions.h" | 18 #include "base/threading/thread_restrictions.h" |
18 #include "base/time/time.h" | 19 #include "base/time/time.h" |
19 #include "base/win/scoped_co_mem.h" | 20 #include "base/win/scoped_co_mem.h" |
20 #include "base/win/scoped_propvariant.h" | 21 #include "base/win/scoped_propvariant.h" |
21 #include "chrome/common/chrome_constants.h" | 22 #include "chrome/common/chrome_constants.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 FILETIME file_time; | 144 FILETIME file_time; |
144 if (last_modified_date.get().vt == VT_DATE && | 145 if (last_modified_date.get().vt == VT_DATE && |
145 VariantTimeToSystemTime(last_modified_date.get().date, &system_time) && | 146 VariantTimeToSystemTime(last_modified_date.get().date, &system_time) && |
146 SystemTimeToFileTime(&system_time, &file_time)) { | 147 SystemTimeToFileTime(&system_time, &file_time)) { |
147 *last_modified_time = base::Time::FromFileTime(file_time); | 148 *last_modified_time = base::Time::FromFileTime(file_time); |
148 } | 149 } |
149 } | 150 } |
150 | 151 |
151 // Gets the size of the file object in bytes from the property key values | 152 // Gets the size of the file object in bytes from the property key values |
152 // specified by the |properties_values|. On failure, return -1. | 153 // specified by the |properties_values|. On failure, return -1. |
153 int64 GetObjectSize(IPortableDeviceValues* properties_values) { | 154 int64_t GetObjectSize(IPortableDeviceValues* properties_values) { |
154 DCHECK(properties_values); | 155 DCHECK(properties_values); |
155 ULONGLONG actual_size; | 156 ULONGLONG actual_size; |
156 HRESULT hr = properties_values->GetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, | 157 HRESULT hr = properties_values->GetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, |
157 &actual_size); | 158 &actual_size); |
158 bool success = SUCCEEDED(hr) && (actual_size <= kint64max); | 159 bool success = SUCCEEDED(hr) && |
159 return success ? static_cast<int64>(actual_size) : -1; | 160 (actual_size <= |
| 161 static_cast<ULONGLONG>(std::numeric_limits<int64_t>::max())); |
| 162 return success ? static_cast<int64_t>(actual_size) : -1; |
160 } | 163 } |
161 | 164 |
162 // Gets the details of the object specified by the |object_id| given the media | 165 // Gets the details of the object specified by the |object_id| given the media |
163 // transfer protocol |device|. On success, returns true and fills in |name|, | 166 // transfer protocol |device|. On success, returns true and fills in |name|, |
164 // |is_directory|, |size|. |last_modified_time| will be filled in if possible, | 167 // |is_directory|, |size|. |last_modified_time| will be filled in if possible, |
165 // but failure to get it doesn't prevent success. | 168 // but failure to get it doesn't prevent success. |
166 bool GetObjectDetails(IPortableDevice* device, | 169 bool GetObjectDetails(IPortableDevice* device, |
167 const base::string16 object_id, | 170 const base::string16 object_id, |
168 base::string16* name, | 171 base::string16* name, |
169 bool* is_directory, | 172 bool* is_directory, |
170 int64* size, | 173 int64_t* size, |
171 base::Time* last_modified_time) { | 174 base::Time* last_modified_time) { |
172 base::ThreadRestrictions::AssertIOAllowed(); | 175 base::ThreadRestrictions::AssertIOAllowed(); |
173 DCHECK(device); | 176 DCHECK(device); |
174 DCHECK(!object_id.empty()); | 177 DCHECK(!object_id.empty()); |
175 DCHECK(name); | 178 DCHECK(name); |
176 DCHECK(is_directory); | 179 DCHECK(is_directory); |
177 DCHECK(size); | 180 DCHECK(size); |
178 DCHECK(last_modified_time); | 181 DCHECK(last_modified_time); |
179 base::win::ScopedComPtr<IPortableDeviceContent> content = | 182 base::win::ScopedComPtr<IPortableDeviceContent> content = |
180 GetDeviceContent(device); | 183 GetDeviceContent(device); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 // Directory entry does not have size and last modified date property key | 221 // Directory entry does not have size and last modified date property key |
219 // values. | 222 // values. |
220 *size = 0; | 223 *size = 0; |
221 *last_modified_time = base::Time(); | 224 *last_modified_time = base::Time(); |
222 return true; | 225 return true; |
223 } | 226 } |
224 | 227 |
225 // Try to get the last modified time, but don't fail if we can't. | 228 // Try to get the last modified time, but don't fail if we can't. |
226 GetLastModifiedTime(properties_values.get(), last_modified_time); | 229 GetLastModifiedTime(properties_values.get(), last_modified_time); |
227 | 230 |
228 int64 object_size = GetObjectSize(properties_values.get()); | 231 int64_t object_size = GetObjectSize(properties_values.get()); |
229 if (object_size < 0) | 232 if (object_size < 0) |
230 return false; | 233 return false; |
231 *size = object_size; | 234 *size = object_size; |
232 return true; | 235 return true; |
233 } | 236 } |
234 | 237 |
235 // Creates an MTP device object entry for the given |device| and |object_id|. | 238 // Creates an MTP device object entry for the given |device| and |object_id|. |
236 // On success, returns true and fills in |entry|. | 239 // On success, returns true and fills in |entry|. |
237 MTPDeviceObjectEntry GetMTPDeviceObjectEntry(IPortableDevice* device, | 240 MTPDeviceObjectEntry GetMTPDeviceObjectEntry(IPortableDevice* device, |
238 const base::string16& object_id) { | 241 const base::string16& object_id) { |
239 base::ThreadRestrictions::AssertIOAllowed(); | 242 base::ThreadRestrictions::AssertIOAllowed(); |
240 DCHECK(device); | 243 DCHECK(device); |
241 DCHECK(!object_id.empty()); | 244 DCHECK(!object_id.empty()); |
242 base::string16 name; | 245 base::string16 name; |
243 bool is_directory; | 246 bool is_directory; |
244 int64 size; | 247 int64_t size; |
245 base::Time last_modified_time; | 248 base::Time last_modified_time; |
246 MTPDeviceObjectEntry entry; | 249 MTPDeviceObjectEntry entry; |
247 if (GetObjectDetails(device, object_id, &name, &is_directory, &size, | 250 if (GetObjectDetails(device, object_id, &name, &is_directory, &size, |
248 &last_modified_time)) { | 251 &last_modified_time)) { |
249 entry = MTPDeviceObjectEntry(object_id, name, is_directory, size, | 252 entry = MTPDeviceObjectEntry(object_id, name, is_directory, size, |
250 last_modified_time); | 253 last_modified_time); |
251 } | 254 } |
252 return entry; | 255 return entry; |
253 } | 256 } |
254 | 257 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 object_entries.empty()) | 408 object_entries.empty()) |
406 return base::string16(); | 409 return base::string16(); |
407 // TODO(thestig): This DCHECK can fail. Multiple MTP objects can have | 410 // TODO(thestig): This DCHECK can fail. Multiple MTP objects can have |
408 // the same name. Handle the situation gracefully. Refer to crbug.com/169930 | 411 // the same name. Handle the situation gracefully. Refer to crbug.com/169930 |
409 // for more details. | 412 // for more details. |
410 DCHECK_EQ(1U, object_entries.size()); | 413 DCHECK_EQ(1U, object_entries.size()); |
411 return object_entries[0].object_id; | 414 return object_entries[0].object_id; |
412 } | 415 } |
413 | 416 |
414 } // namespace media_transfer_protocol | 417 } // namespace media_transfer_protocol |
OLD | NEW |