Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(920)

Side by Side Diff: chrome/browser/media_galleries/win/mtp_device_operations_util.cc

Issue 322333005: Media Galleries: Fix PTP Devices on Windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 HRESULT hr = properties_values->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, 111 HRESULT hr = properties_values->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME,
112 &buffer); 112 &buffer);
113 if (FAILED(hr)) 113 if (FAILED(hr))
114 hr = properties_values->GetStringValue(WPD_OBJECT_NAME, &buffer); 114 hr = properties_values->GetStringValue(WPD_OBJECT_NAME, &buffer);
115 if (SUCCEEDED(hr)) 115 if (SUCCEEDED(hr))
116 result.assign(buffer); 116 result.assign(buffer);
117 return result; 117 return result;
118 } 118 }
119 119
120 // Gets the last modified time of the object from the property key values 120 // Gets the last modified time of the object from the property key values
121 // specified by the |properties_values|. On success, returns true and fills in 121 // specified by the |properties_values|. On success, fills in
122 // |last_modified_time|. 122 // |last_modified_time|.
123 bool GetLastModifiedTime(IPortableDeviceValues* properties_values, 123 void GetLastModifiedTime(IPortableDeviceValues* properties_values,
124 base::Time* last_modified_time) { 124 base::Time* last_modified_time) {
125 DCHECK(properties_values); 125 DCHECK(properties_values);
126 DCHECK(last_modified_time); 126 DCHECK(last_modified_time);
127 base::win::ScopedPropVariant last_modified_date; 127 base::win::ScopedPropVariant last_modified_date;
128 HRESULT hr = properties_values->GetValue(WPD_OBJECT_DATE_MODIFIED, 128 HRESULT hr = properties_values->GetValue(WPD_OBJECT_DATE_MODIFIED,
129 last_modified_date.Receive()); 129 last_modified_date.Receive());
130 if (FAILED(hr)) 130 if (FAILED(hr))
131 return false; 131 return;
132 132
133 bool last_modified_time_set = (last_modified_date.get().vt == VT_DATE); 133 // Some PTP devices don't provide an mtime. Try using the ctime instead.
134 if (last_modified_time_set) { 134 if (last_modified_date.get().vt != VT_DATE) {
135 SYSTEMTIME system_time; 135 last_modified_date.Reset();
136 FILETIME file_time; 136 HRESULT hr = properties_values->GetValue(WPD_OBJECT_DATE_CREATED,
137 if (VariantTimeToSystemTime(last_modified_date.get().date, &system_time) && 137 last_modified_date.Receive());
138 SystemTimeToFileTime(&system_time, &file_time)) { 138 if (FAILED(hr))
139 *last_modified_time = base::Time::FromFileTime(file_time); 139 return;
140 } else {
141 last_modified_time_set = false;
142 }
143 } 140 }
144 return last_modified_time_set; 141
142 SYSTEMTIME system_time;
143 FILETIME file_time;
144 if (last_modified_date.get().vt == VT_DATE &&
145 VariantTimeToSystemTime(last_modified_date.get().date, &system_time) &&
146 SystemTimeToFileTime(&system_time, &file_time)) {
147 *last_modified_time = base::Time::FromFileTime(file_time);
148 }
145 } 149 }
146 150
147 // Gets the size of the file object in bytes from the property key values 151 // Gets the size of the file object in bytes from the property key values
148 // specified by the |properties_values|. On success, returns true and fills 152 // specified by the |properties_values|. On success, returns true and fills
149 // in |size|. 153 // in |size|.
150 bool GetObjectSize(IPortableDeviceValues* properties_values, int64* size) { 154 bool GetObjectSize(IPortableDeviceValues* properties_values, int64* size) {
151 DCHECK(properties_values); 155 DCHECK(properties_values);
152 DCHECK(size); 156 DCHECK(size);
153 ULONGLONG actual_size; 157 ULONGLONG actual_size;
154 HRESULT hr = properties_values->GetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, 158 HRESULT hr = properties_values->GetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE,
155 &actual_size); 159 &actual_size);
156 bool success = SUCCEEDED(hr) && (actual_size <= kint64max); 160 bool success = SUCCEEDED(hr) && (actual_size <= kint64max);
157 if (success) 161 if (success)
158 *size = static_cast<int64>(actual_size); 162 *size = static_cast<int64>(actual_size);
159 return success; 163 return success;
160 } 164 }
161 165
162 // Gets the details of the object specified by the |object_id| given the media 166 // 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|, 167 // transfer protocol |device|. On success, returns true and fills in |name|,
164 // |is_directory|, |size| and |last_modified_time|. 168 // |is_directory|, |size|. |last_modified_time| will be filled in if possible,
169 // but failure to get it doesn't prevent success.
165 bool GetObjectDetails(IPortableDevice* device, 170 bool GetObjectDetails(IPortableDevice* device,
166 const base::string16 object_id, 171 const base::string16 object_id,
167 base::string16* name, 172 base::string16* name,
168 bool* is_directory, 173 bool* is_directory,
169 int64* size, 174 int64* size,
170 base::Time* last_modified_time) { 175 base::Time* last_modified_time) {
171 base::ThreadRestrictions::AssertIOAllowed(); 176 base::ThreadRestrictions::AssertIOAllowed();
172 DCHECK(device); 177 DCHECK(device);
173 DCHECK(!object_id.empty()); 178 DCHECK(!object_id.empty());
174 DCHECK(name); 179 DCHECK(name);
(...skipping 15 matching lines...) Expand all
190 NULL, 195 NULL,
191 CLSCTX_INPROC_SERVER); 196 CLSCTX_INPROC_SERVER);
192 if (FAILED(hr)) 197 if (FAILED(hr))
193 return false; 198 return false;
194 199
195 if (FAILED(properties_to_read->Add(WPD_OBJECT_CONTENT_TYPE)) || 200 if (FAILED(properties_to_read->Add(WPD_OBJECT_CONTENT_TYPE)) ||
196 FAILED(properties_to_read->Add(WPD_OBJECT_FORMAT)) || 201 FAILED(properties_to_read->Add(WPD_OBJECT_FORMAT)) ||
197 FAILED(properties_to_read->Add(WPD_OBJECT_ORIGINAL_FILE_NAME)) || 202 FAILED(properties_to_read->Add(WPD_OBJECT_ORIGINAL_FILE_NAME)) ||
198 FAILED(properties_to_read->Add(WPD_OBJECT_NAME)) || 203 FAILED(properties_to_read->Add(WPD_OBJECT_NAME)) ||
199 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)) ||
200 FAILED(properties_to_read->Add(WPD_OBJECT_SIZE))) 206 FAILED(properties_to_read->Add(WPD_OBJECT_SIZE)))
201 return false; 207 return false;
202 208
203 base::win::ScopedComPtr<IPortableDeviceValues> properties_values; 209 base::win::ScopedComPtr<IPortableDeviceValues> properties_values;
204 hr = properties->GetValues(object_id.c_str(), 210 hr = properties->GetValues(object_id.c_str(),
205 properties_to_read.get(), 211 properties_to_read.get(),
206 properties_values.Receive()); 212 properties_values.Receive());
207 if (FAILED(hr)) 213 if (FAILED(hr))
208 return false; 214 return false;
209 215
210 *is_directory = IsDirectory(properties_values.get()); 216 *is_directory = IsDirectory(properties_values.get());
211 *name = GetObjectName(properties_values.get()); 217 *name = GetObjectName(properties_values.get());
212 if (name->empty()) 218 if (name->empty())
213 return false; 219 return false;
214 220
215 if (*is_directory) { 221 if (*is_directory) {
216 // Directory entry does not have size and last modified date property key 222 // Directory entry does not have size and last modified date property key
217 // values. 223 // values.
218 *size = 0; 224 *size = 0;
219 *last_modified_time = base::Time(); 225 *last_modified_time = base::Time();
220 return true; 226 return true;
221 } 227 }
222 return (GetObjectSize(properties_values.get(), size) && 228
223 GetLastModifiedTime(properties_values.get(), last_modified_time)); 229 // Try to get the last modified time, but don't fail if we can't.
230 GetLastModifiedTime(properties_values.get(), last_modified_time);
231
232 return GetObjectSize(properties_values.get(), size);
224 } 233 }
225 234
226 // Creates an MTP device object entry for the given |device| and |object_id|. 235 // Creates an MTP device object entry for the given |device| and |object_id|.
227 // On success, returns true and fills in |entry|. 236 // On success, returns true and fills in |entry|.
228 bool GetMTPDeviceObjectEntry(IPortableDevice* device, 237 bool GetMTPDeviceObjectEntry(IPortableDevice* device,
229 const base::string16& object_id, 238 const base::string16& object_id,
230 MTPDeviceObjectEntry* entry) { 239 MTPDeviceObjectEntry* entry) {
231 base::ThreadRestrictions::AssertIOAllowed(); 240 base::ThreadRestrictions::AssertIOAllowed();
232 DCHECK(device); 241 DCHECK(device);
233 DCHECK(!object_id.empty()); 242 DCHECK(!object_id.empty());
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 object_entries.empty()) 408 object_entries.empty())
400 return base::string16(); 409 return base::string16();
401 // TODO(thestig): This DCHECK can fail. Multiple MTP objects can have 410 // TODO(thestig): This DCHECK can fail. Multiple MTP objects can have
402 // 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
403 // for more details. 412 // for more details.
404 DCHECK_EQ(1U, object_entries.size()); 413 DCHECK_EQ(1U, object_entries.size());
405 return object_entries[0].object_id; 414 return object_entries[0].object_id;
406 } 415 }
407 416
408 } // namespace media_transfer_protocol 417 } // namespace media_transfer_protocol
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698