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 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 return true; | 52 return true; |
53 } | 53 } |
54 | 54 |
55 // Gets the content interface of the portable |device|. On success, returns | 55 // Gets the content interface of the portable |device|. On success, returns |
56 // the IPortableDeviceContent interface. On failure, returns NULL. | 56 // the IPortableDeviceContent interface. On failure, returns NULL. |
57 base::win::ScopedComPtr<IPortableDeviceContent> GetDeviceContent( | 57 base::win::ScopedComPtr<IPortableDeviceContent> GetDeviceContent( |
58 IPortableDevice* device) { | 58 IPortableDevice* device) { |
59 base::ThreadRestrictions::AssertIOAllowed(); | 59 base::ThreadRestrictions::AssertIOAllowed(); |
60 DCHECK(device); | 60 DCHECK(device); |
61 base::win::ScopedComPtr<IPortableDeviceContent> content; | 61 base::win::ScopedComPtr<IPortableDeviceContent> content; |
62 if (SUCCEEDED(device->Content(content.Receive()))) | 62 if (SUCCEEDED(device->Content(content.GetAddressOf()))) |
63 return content; | 63 return content; |
64 return base::win::ScopedComPtr<IPortableDeviceContent>(); | 64 return base::win::ScopedComPtr<IPortableDeviceContent>(); |
65 } | 65 } |
66 | 66 |
67 // On success, returns IEnumPortableDeviceObjectIDs interface to enumerate | 67 // On success, returns IEnumPortableDeviceObjectIDs interface to enumerate |
68 // the device objects. On failure, returns NULL. | 68 // the device objects. On failure, returns NULL. |
69 // |parent_id| specifies the parent object identifier. | 69 // |parent_id| specifies the parent object identifier. |
70 base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs> GetDeviceObjectEnumerator( | 70 base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs> GetDeviceObjectEnumerator( |
71 IPortableDevice* device, | 71 IPortableDevice* device, |
72 const base::string16& parent_id) { | 72 const base::string16& parent_id) { |
73 base::ThreadRestrictions::AssertIOAllowed(); | 73 base::ThreadRestrictions::AssertIOAllowed(); |
74 DCHECK(device); | 74 DCHECK(device); |
75 DCHECK(!parent_id.empty()); | 75 DCHECK(!parent_id.empty()); |
76 base::win::ScopedComPtr<IPortableDeviceContent> content = | 76 base::win::ScopedComPtr<IPortableDeviceContent> content = |
77 GetDeviceContent(device); | 77 GetDeviceContent(device); |
78 if (!content.Get()) | 78 if (!content.Get()) |
79 return base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs>(); | 79 return base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs>(); |
80 | 80 |
81 base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs> enum_object_ids; | 81 base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs> enum_object_ids; |
82 if (SUCCEEDED(content->EnumObjects(0, parent_id.c_str(), NULL, | 82 if (SUCCEEDED(content->EnumObjects(0, parent_id.c_str(), NULL, |
83 enum_object_ids.Receive()))) | 83 enum_object_ids.GetAddressOf()))) |
84 return enum_object_ids; | 84 return enum_object_ids; |
85 return base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs>(); | 85 return base::win::ScopedComPtr<IEnumPortableDeviceObjectIDs>(); |
86 } | 86 } |
87 | 87 |
88 // Returns whether the object is a directory/folder/album. |properties_values| | 88 // Returns whether the object is a directory/folder/album. |properties_values| |
89 // contains the object property key values. | 89 // contains the object property key values. |
90 bool IsDirectory(IPortableDeviceValues* properties_values) { | 90 bool IsDirectory(IPortableDeviceValues* properties_values) { |
91 DCHECK(properties_values); | 91 DCHECK(properties_values); |
92 GUID content_type; | 92 GUID content_type; |
93 HRESULT hr = properties_values->GetGuidValue(WPD_OBJECT_CONTENT_TYPE, | 93 HRESULT hr = properties_values->GetGuidValue(WPD_OBJECT_CONTENT_TYPE, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 DCHECK(name); | 179 DCHECK(name); |
180 DCHECK(is_directory); | 180 DCHECK(is_directory); |
181 DCHECK(size); | 181 DCHECK(size); |
182 DCHECK(last_modified_time); | 182 DCHECK(last_modified_time); |
183 base::win::ScopedComPtr<IPortableDeviceContent> content = | 183 base::win::ScopedComPtr<IPortableDeviceContent> content = |
184 GetDeviceContent(device); | 184 GetDeviceContent(device); |
185 if (!content.Get()) | 185 if (!content.Get()) |
186 return false; | 186 return false; |
187 | 187 |
188 base::win::ScopedComPtr<IPortableDeviceProperties> properties; | 188 base::win::ScopedComPtr<IPortableDeviceProperties> properties; |
189 HRESULT hr = content->Properties(properties.Receive()); | 189 HRESULT hr = content->Properties(properties.GetAddressOf()); |
190 if (FAILED(hr)) | 190 if (FAILED(hr)) |
191 return false; | 191 return false; |
192 | 192 |
193 base::win::ScopedComPtr<IPortableDeviceKeyCollection> properties_to_read; | 193 base::win::ScopedComPtr<IPortableDeviceKeyCollection> properties_to_read; |
194 hr = properties_to_read.CreateInstance(__uuidof(PortableDeviceKeyCollection), | 194 hr = properties_to_read.CreateInstance(__uuidof(PortableDeviceKeyCollection), |
195 NULL, | 195 NULL, |
196 CLSCTX_INPROC_SERVER); | 196 CLSCTX_INPROC_SERVER); |
197 if (FAILED(hr)) | 197 if (FAILED(hr)) |
198 return false; | 198 return false; |
199 | 199 |
200 if (FAILED(properties_to_read->Add(WPD_OBJECT_CONTENT_TYPE)) || | 200 if (FAILED(properties_to_read->Add(WPD_OBJECT_CONTENT_TYPE)) || |
201 FAILED(properties_to_read->Add(WPD_OBJECT_FORMAT)) || | 201 FAILED(properties_to_read->Add(WPD_OBJECT_FORMAT)) || |
202 FAILED(properties_to_read->Add(WPD_OBJECT_ORIGINAL_FILE_NAME)) || | 202 FAILED(properties_to_read->Add(WPD_OBJECT_ORIGINAL_FILE_NAME)) || |
203 FAILED(properties_to_read->Add(WPD_OBJECT_NAME)) || | 203 FAILED(properties_to_read->Add(WPD_OBJECT_NAME)) || |
204 FAILED(properties_to_read->Add(WPD_OBJECT_DATE_MODIFIED)) || | 204 FAILED(properties_to_read->Add(WPD_OBJECT_DATE_MODIFIED)) || |
205 FAILED(properties_to_read->Add(WPD_OBJECT_DATE_CREATED)) || | 205 FAILED(properties_to_read->Add(WPD_OBJECT_DATE_CREATED)) || |
206 FAILED(properties_to_read->Add(WPD_OBJECT_SIZE))) | 206 FAILED(properties_to_read->Add(WPD_OBJECT_SIZE))) |
207 return false; | 207 return false; |
208 | 208 |
209 base::win::ScopedComPtr<IPortableDeviceValues> properties_values; | 209 base::win::ScopedComPtr<IPortableDeviceValues> properties_values; |
210 hr = properties->GetValues(object_id.c_str(), | 210 hr = properties->GetValues(object_id.c_str(), properties_to_read.Get(), |
211 properties_to_read.Get(), | 211 properties_values.GetAddressOf()); |
212 properties_values.Receive()); | |
213 if (FAILED(hr)) | 212 if (FAILED(hr)) |
214 return false; | 213 return false; |
215 | 214 |
216 *is_directory = IsDirectory(properties_values.Get()); | 215 *is_directory = IsDirectory(properties_values.Get()); |
217 *name = GetObjectName(properties_values.Get()); | 216 *name = GetObjectName(properties_values.Get()); |
218 if (name->empty()) | 217 if (name->empty()) |
219 return false; | 218 return false; |
220 | 219 |
221 if (*is_directory) { | 220 if (*is_directory) { |
222 // 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 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 DWORD* optimal_transfer_size) { | 356 DWORD* optimal_transfer_size) { |
358 base::ThreadRestrictions::AssertIOAllowed(); | 357 base::ThreadRestrictions::AssertIOAllowed(); |
359 DCHECK(device); | 358 DCHECK(device); |
360 DCHECK(!file_object_id.empty()); | 359 DCHECK(!file_object_id.empty()); |
361 base::win::ScopedComPtr<IPortableDeviceContent> content = | 360 base::win::ScopedComPtr<IPortableDeviceContent> content = |
362 GetDeviceContent(device); | 361 GetDeviceContent(device); |
363 if (!content.Get()) | 362 if (!content.Get()) |
364 return E_FAIL; | 363 return E_FAIL; |
365 | 364 |
366 base::win::ScopedComPtr<IPortableDeviceResources> resources; | 365 base::win::ScopedComPtr<IPortableDeviceResources> resources; |
367 HRESULT hr = content->Transfer(resources.Receive()); | 366 HRESULT hr = content->Transfer(resources.GetAddressOf()); |
368 if (FAILED(hr)) | 367 if (FAILED(hr)) |
369 return hr; | 368 return hr; |
370 return resources->GetStream(file_object_id.c_str(), WPD_RESOURCE_DEFAULT, | 369 return resources->GetStream(file_object_id.c_str(), WPD_RESOURCE_DEFAULT, |
371 STGM_READ, optimal_transfer_size, | 370 STGM_READ, optimal_transfer_size, |
372 file_stream); | 371 file_stream); |
373 } | 372 } |
374 | 373 |
375 DWORD CopyDataChunkToLocalFile(IStream* stream, | 374 DWORD CopyDataChunkToLocalFile(IStream* stream, |
376 const base::FilePath& local_path, | 375 const base::FilePath& local_path, |
377 size_t optimal_transfer_size) { | 376 size_t optimal_transfer_size) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 object_entries.empty()) | 408 object_entries.empty()) |
410 return base::string16(); | 409 return base::string16(); |
411 // TODO(thestig): This DCHECK can fail. Multiple MTP objects can have | 410 // TODO(thestig): This DCHECK can fail. Multiple MTP objects can have |
412 // 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 |
413 // for more details. | 412 // for more details. |
414 DCHECK_EQ(1U, object_entries.size()); | 413 DCHECK_EQ(1U, object_entries.size()); |
415 return object_entries[0].object_id; | 414 return object_entries[0].object_id; |
416 } | 415 } |
417 | 416 |
418 } // namespace media_transfer_protocol | 417 } // namespace media_transfer_protocol |
OLD | NEW |