Merge lp:~phablet-team/mtp/aosp-update into lp:mtp
- aosp-update
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Konrad Zapałowicz | ||||
Approved revision: | 74 | ||||
Merged at revision: | 70 | ||||
Proposed branch: | lp:~phablet-team/mtp/aosp-update | ||||
Merge into: | lp:mtp | ||||
Diff against target: |
2258 lines (+634/-357) 25 files modified
CMakeLists.txt (+1/-1) include/MtpDataPacket.h (+13/-12) include/MtpDevice.h (+1/-1) include/MtpDeviceInfo.h (+2/-2) include/MtpObjectInfo.h (+1/-1) include/MtpPacket.h (+4/-4) include/MtpProperty.h (+7/-7) include/MtpRequestPacket.h (+4/-0) include/MtpServer.h (+1/-0) include/MtpStorageInfo.h (+1/-1) include/MtpStringBuffer.h (+5/-2) server/UbuntuMtpDatabase.h (+48/-37) server/server.cpp (+25/-23) src/MtpDataPacket.cpp (+129/-55) src/MtpDevice.cpp (+33/-14) src/MtpDeviceInfo.cpp (+19/-12) src/MtpObjectInfo.cpp (+22/-20) src/MtpPacket.cpp (+1/-1) src/MtpProperty.cpp (+63/-42) src/MtpRequestPacket.cpp (+17/-4) src/MtpServer.cpp (+170/-64) src/MtpStorageInfo.cpp (+11/-9) src/MtpStringBuffer.cpp (+36/-24) src/MtpUtils.cpp (+19/-20) tests/TestMtpUtils.cpp (+1/-1) |
||||
To merge this branch: | bzr merge lp:~phablet-team/mtp/aosp-update | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Konrad Zapałowicz (community) | code | Approve | |
Simon Fels | Approve | ||
Review via email: mp+291626@code.launchpad.net |
Commit message
* Update to latest AOSP code (Marshallow)
* Make MTP work for file > 4GB (LP: #1472789). This involved adding O_LARGEFILE flag when opening a file (the flag is automatically added by bionic, but not by glibc) and fixing parts of the MTP database implementation.
Description of the change
* Update to latest AOSP code (Marshallow)
* Make MTP work for file > 4GB (LP: #1472789). This involved adding O_LARGEFILE flag when opening a file (the flag is automatically added by bionic, but not by glibc) and fixing parts of the MTP database implementation.
Konrad Zapałowicz (kzapalowicz) wrote : | # |
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
Thanks for the thorough review. However, most of the code comes directly from AOSP, and I have preferred in many cases to minimize the difference between our project and "upstream" to ease future merges. AOSP code can be found in:
- 74. By Alfonso Sanchez-Beato
-
Address review comments
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
Branch refreshed after addressing review comments.
Konrad Zapałowicz (kzapalowicz) wrote : | # |
Approved
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-09-04 01:11:14 +0000 |
3 | +++ CMakeLists.txt 2016-04-12 16:15:02 +0000 |
4 | @@ -7,7 +7,7 @@ |
5 | |
6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") |
7 | |
8 | -add_definitions(-DMTP_DEVICE -DMTP_HOST) |
9 | +add_definitions(-DMTP_DEVICE -DMTP_HOST -D_FILE_OFFSET_BITS=64) |
10 | |
11 | set(MTP_VERSION_MAJOR 1) |
12 | set(MTP_VERSION_MINOR 0) |
13 | |
14 | === modified file 'include/MtpDataPacket.h' |
15 | --- include/MtpDataPacket.h 2013-06-13 10:22:21 +0000 |
16 | +++ include/MtpDataPacket.h 2016-04-12 16:15:02 +0000 |
17 | @@ -30,7 +30,7 @@ |
18 | class MtpDataPacket : public MtpPacket { |
19 | private: |
20 | // current offset for get/put methods |
21 | - int mOffset; |
22 | + size_t mOffset; |
23 | |
24 | public: |
25 | MtpDataPacket(); |
26 | @@ -42,17 +42,18 @@ |
27 | void setTransactionID(MtpTransactionID id); |
28 | |
29 | inline const uint8_t* getData() const { return mBuffer + MTP_CONTAINER_HEADER_SIZE; } |
30 | - inline uint8_t getUInt8() { return (uint8_t)mBuffer[mOffset++]; } |
31 | - inline int8_t getInt8() { return (int8_t)mBuffer[mOffset++]; } |
32 | - uint16_t getUInt16(); |
33 | - inline int16_t getInt16() { return (int16_t)getUInt16(); } |
34 | - uint32_t getUInt32(); |
35 | - inline int32_t getInt32() { return (int32_t)getUInt32(); } |
36 | - uint64_t getUInt64(); |
37 | - inline int64_t getInt64() { return (int64_t)getUInt64(); } |
38 | - void getUInt128(uint128_t& value); |
39 | - inline void getInt128(int128_t& value) { getUInt128((uint128_t&)value); } |
40 | - void getString(MtpStringBuffer& string); |
41 | + |
42 | + bool getUInt8(uint8_t& value); |
43 | + inline bool getInt8(int8_t& value) { return getUInt8((uint8_t&)value); } |
44 | + bool getUInt16(uint16_t& value); |
45 | + inline bool getInt16(int16_t& value) { return getUInt16((uint16_t&)value); } |
46 | + bool getUInt32(uint32_t& value); |
47 | + inline bool getInt32(int32_t& value) { return getUInt32((uint32_t&)value); } |
48 | + bool getUInt64(uint64_t& value); |
49 | + inline bool getInt64(int64_t& value) { return getUInt64((uint64_t&)value); } |
50 | + bool getUInt128(uint128_t& value); |
51 | + inline bool getInt128(int128_t& value) { return getUInt128((uint128_t&)value); } |
52 | + bool getString(MtpStringBuffer& string); |
53 | |
54 | Int8List* getAInt8(); |
55 | UInt8List* getAUInt8(); |
56 | |
57 | === modified file 'include/MtpDevice.h' |
58 | --- include/MtpDevice.h 2013-06-13 10:22:21 +0000 |
59 | +++ include/MtpDevice.h 2016-04-12 16:15:02 +0000 |
60 | @@ -96,7 +96,7 @@ |
61 | bool readObject(MtpObjectHandle handle, |
62 | bool (* callback)(void* data, int offset, |
63 | int length, void* clientData), |
64 | - int objectSize, void* clientData); |
65 | + size_t objectSize, void* clientData); |
66 | bool readObject(MtpObjectHandle handle, const char* destPath, int group, |
67 | int perm); |
68 | |
69 | |
70 | === modified file 'include/MtpDeviceInfo.h' |
71 | --- include/MtpDeviceInfo.h 2013-06-13 10:22:21 +0000 |
72 | +++ include/MtpDeviceInfo.h 2016-04-12 16:15:02 +0000 |
73 | @@ -29,7 +29,7 @@ |
74 | uint32_t mVendorExtensionID; |
75 | uint16_t mVendorExtensionVersion; |
76 | char* mVendorExtensionDesc; |
77 | - uint16_t mFunctionalCode; |
78 | + uint16_t mFunctionalMode; |
79 | UInt16List* mOperations; |
80 | UInt16List* mEvents; |
81 | MtpDevicePropertyList* mDeviceProperties; |
82 | @@ -44,7 +44,7 @@ |
83 | MtpDeviceInfo(); |
84 | virtual ~MtpDeviceInfo(); |
85 | |
86 | - void read(MtpDataPacket& packet); |
87 | + bool read(MtpDataPacket& packet); |
88 | |
89 | void print(); |
90 | }; |
91 | |
92 | === modified file 'include/MtpObjectInfo.h' |
93 | --- include/MtpObjectInfo.h 2013-06-13 10:22:21 +0000 |
94 | +++ include/MtpObjectInfo.h 2016-04-12 16:15:02 +0000 |
95 | @@ -50,7 +50,7 @@ |
96 | MtpObjectInfo(MtpObjectHandle handle); |
97 | virtual ~MtpObjectInfo(); |
98 | |
99 | - void read(MtpDataPacket& packet); |
100 | + bool read(MtpDataPacket& packet); |
101 | |
102 | void print(); |
103 | }; |
104 | |
105 | === modified file 'include/MtpPacket.h' |
106 | --- include/MtpPacket.h 2013-06-13 10:22:21 +0000 |
107 | +++ include/MtpPacket.h 2016-04-12 16:15:02 +0000 |
108 | @@ -28,11 +28,11 @@ |
109 | protected: |
110 | uint8_t* mBuffer; |
111 | // current size of the buffer |
112 | - int mBufferSize; |
113 | + size_t mBufferSize; |
114 | // number of bytes to add when resizing the buffer |
115 | - int mAllocationIncrement; |
116 | + size_t mAllocationIncrement; |
117 | // size of the data in the packet |
118 | - int mPacketSize; |
119 | + size_t mPacketSize; |
120 | |
121 | public: |
122 | MtpPacket(int bufferSize); |
123 | @@ -41,7 +41,7 @@ |
124 | // sets packet size to the default container size and sets buffer to zero |
125 | virtual void reset(); |
126 | |
127 | - void allocate(int length); |
128 | + void allocate(size_t length); |
129 | void dump(); |
130 | void copyFrom(const MtpPacket& src); |
131 | |
132 | |
133 | === modified file 'include/MtpProperty.h' |
134 | --- include/MtpProperty.h 2013-06-13 10:22:21 +0000 |
135 | +++ include/MtpProperty.h 2016-04-12 16:15:02 +0000 |
136 | @@ -49,9 +49,9 @@ |
137 | MtpPropertyValue mCurrentValue; |
138 | |
139 | // for array types |
140 | - int mDefaultArrayLength; |
141 | + uint32_t mDefaultArrayLength; |
142 | MtpPropertyValue* mDefaultArrayValues; |
143 | - int mCurrentArrayLength; |
144 | + uint32_t mCurrentArrayLength; |
145 | MtpPropertyValue* mCurrentArrayValues; |
146 | |
147 | enum { |
148 | @@ -70,7 +70,7 @@ |
149 | MtpPropertyValue mStepSize; |
150 | |
151 | // for enum form |
152 | - int mEnumLength; |
153 | + uint16_t mEnumLength; |
154 | MtpPropertyValue* mEnumValues; |
155 | |
156 | public: |
157 | @@ -83,7 +83,7 @@ |
158 | |
159 | inline MtpPropertyCode getPropertyCode() const { return mCode; } |
160 | |
161 | - void read(MtpDataPacket& packet); |
162 | + bool read(MtpDataPacket& packet); |
163 | void write(MtpDataPacket& packet); |
164 | |
165 | void setDefaultValue(const uint16_t* string); |
166 | @@ -102,11 +102,11 @@ |
167 | } |
168 | |
169 | private: |
170 | - void readValue(MtpDataPacket& packet, MtpPropertyValue& value); |
171 | + bool readValue(MtpDataPacket& packet, MtpPropertyValue& value); |
172 | void writeValue(MtpDataPacket& packet, MtpPropertyValue& value); |
173 | - MtpPropertyValue* readArrayValues(MtpDataPacket& packet, int& length); |
174 | + MtpPropertyValue* readArrayValues(MtpDataPacket& packet, uint32_t& length); |
175 | void writeArrayValues(MtpDataPacket& packet, |
176 | - MtpPropertyValue* values, int length); |
177 | + MtpPropertyValue* values, uint32_t length); |
178 | }; |
179 | |
180 | }; // namespace android |
181 | |
182 | === modified file 'include/MtpRequestPacket.h' |
183 | --- include/MtpRequestPacket.h 2013-06-13 10:22:21 +0000 |
184 | +++ include/MtpRequestPacket.h 2016-04-12 16:15:02 +0000 |
185 | @@ -43,6 +43,10 @@ |
186 | inline MtpOperationCode getOperationCode() const { return getContainerCode(); } |
187 | inline void setOperationCode(MtpOperationCode code) |
188 | { return setContainerCode(code); } |
189 | + inline int getParameterCount() const { return mParameterCount; } |
190 | + |
191 | +private: |
192 | + int mParameterCount; |
193 | }; |
194 | |
195 | }; // namespace android |
196 | |
197 | === modified file 'include/MtpServer.h' |
198 | --- include/MtpServer.h 2014-10-29 18:46:35 +0000 |
199 | +++ include/MtpServer.h 2016-04-12 16:15:02 +0000 |
200 | @@ -108,6 +108,7 @@ |
201 | |
202 | void sendObjectAdded(MtpObjectHandle handle); |
203 | void sendObjectRemoved(MtpObjectHandle handle); |
204 | + void sendDevicePropertyChanged(MtpDeviceProperty property); |
205 | void sendObjectInfoChanged(MtpObjectHandle handle); |
206 | void sendObjectPropChanged(MtpObjectHandle handle, |
207 | MtpObjectProperty prop); |
208 | |
209 | === modified file 'include/MtpStorageInfo.h' |
210 | --- include/MtpStorageInfo.h 2013-06-13 10:22:21 +0000 |
211 | +++ include/MtpStorageInfo.h 2016-04-12 16:15:02 +0000 |
212 | @@ -39,7 +39,7 @@ |
213 | MtpStorageInfo(MtpStorageID id); |
214 | virtual ~MtpStorageInfo(); |
215 | |
216 | - void read(MtpDataPacket& packet); |
217 | + bool read(MtpDataPacket& packet); |
218 | |
219 | void print(); |
220 | }; |
221 | |
222 | === modified file 'include/MtpStringBuffer.h' |
223 | --- include/MtpStringBuffer.h 2013-06-13 10:22:21 +0000 |
224 | +++ include/MtpStringBuffer.h 2016-04-12 16:15:02 +0000 |
225 | @@ -19,6 +19,9 @@ |
226 | |
227 | #include <stdint.h> |
228 | |
229 | +// Max Character number of a MTP String |
230 | +#define MTP_STRING_MAX_CHARACTER_NUMBER 255 |
231 | + |
232 | namespace android { |
233 | |
234 | class MtpDataPacket; |
235 | @@ -29,7 +32,7 @@ |
236 | private: |
237 | // mBuffer contains string in UTF8 format |
238 | // maximum 3 bytes/character, with 1 extra for zero termination |
239 | - uint8_t mBuffer[255 * 3 + 1]; |
240 | + uint8_t mBuffer[MTP_STRING_MAX_CHARACTER_NUMBER * 3 + 1]; |
241 | int mCharCount; |
242 | int mByteCount; |
243 | |
244 | @@ -43,7 +46,7 @@ |
245 | void set(const char* src); |
246 | void set(const uint16_t* src); |
247 | |
248 | - void readFromPacket(MtpDataPacket* packet); |
249 | + bool readFromPacket(MtpDataPacket* packet); |
250 | void writeToPacket(MtpDataPacket* packet) const; |
251 | |
252 | inline int getCharCount() const { return mCharCount; } |
253 | |
254 | === modified file 'server/UbuntuMtpDatabase.h' |
255 | --- server/UbuntuMtpDatabase.h 2015-01-26 19:35:23 +0000 |
256 | +++ server/UbuntuMtpDatabase.h 2016-04-12 16:15:02 +0000 |
257 | @@ -63,7 +63,7 @@ |
258 | MtpStorageID storage_id; |
259 | MtpObjectFormat object_format; |
260 | MtpObjectHandle parent; |
261 | - size_t object_size; |
262 | + uint64_t object_size; |
263 | std::string display_name; |
264 | std::string path; |
265 | int watch_fd; |
266 | @@ -117,7 +117,7 @@ |
267 | IN_MODIFY | IN_CREATE | IN_DELETE); |
268 | } |
269 | |
270 | - |
271 | + |
272 | void add_file_entry(path p, MtpObjectHandle parent, MtpStorageID storage) |
273 | { |
274 | MtpObjectHandle handle = counter; |
275 | @@ -246,16 +246,16 @@ |
276 | std::size_t transferred) |
277 | { |
278 | size_t processed = 0; |
279 | - |
280 | + |
281 | while(transferred - processed >= sizeof(inotify_event)) |
282 | { |
283 | const char* cdata = processed + asio::buffer_cast<const char*>(buf.data()); |
284 | const inotify_event* ievent = reinterpret_cast<const inotify_event*>(cdata); |
285 | MtpObjectHandle parent; |
286 | path p; |
287 | - |
288 | + |
289 | processed += sizeof(inotify_event) + ievent->len; |
290 | - |
291 | + |
292 | BOOST_FOREACH(MtpObjectHandle i, db | boost::adaptors::map_keys) { |
293 | if (db.at(i).watch_fd == ievent->wd) { |
294 | parent = i; |
295 | @@ -329,7 +329,7 @@ |
296 | } |
297 | } |
298 | } |
299 | - |
300 | + |
301 | read_more_notify(); |
302 | } |
303 | |
304 | @@ -411,7 +411,7 @@ |
305 | |
306 | counter++; |
307 | |
308 | - return handle; |
309 | + return handle; |
310 | } |
311 | |
312 | // called to report success or failure of the SendObject file transfer |
313 | @@ -470,7 +470,7 @@ |
314 | { |
315 | list = new MtpObjectHandleList(); |
316 | } |
317 | - |
318 | + |
319 | return list; |
320 | } |
321 | |
322 | @@ -491,7 +491,7 @@ |
323 | } catch(...) |
324 | { |
325 | } |
326 | - |
327 | + |
328 | return result; |
329 | } |
330 | |
331 | @@ -540,14 +540,14 @@ |
332 | |
333 | return new MtpObjectFormatList{list}; |
334 | } |
335 | - |
336 | + |
337 | virtual MtpObjectFormatList* getSupportedCaptureFormats() |
338 | { |
339 | VLOG(1) << __PRETTY_FUNCTION__; |
340 | static const MtpObjectFormatList list = {MTP_FORMAT_ASSOCIATION, MTP_FORMAT_PNG}; |
341 | return new MtpObjectFormatList{list}; |
342 | } |
343 | - |
344 | + |
345 | virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format) |
346 | { |
347 | VLOG(1) << __PRETTY_FUNCTION__; |
348 | @@ -555,8 +555,8 @@ |
349 | if (format != MTP_FORMAT_PNG) |
350 | return nullptr; |
351 | */ |
352 | - |
353 | - static const MtpObjectPropertyList list = |
354 | + |
355 | + static const MtpObjectPropertyList list = |
356 | { |
357 | MTP_PROPERTY_STORAGE_ID, |
358 | MTP_PROPERTY_PARENT_OBJECT, |
359 | @@ -574,16 +574,16 @@ |
360 | MTP_PROPERTY_NON_CONSUMABLE, |
361 | |
362 | }; |
363 | - |
364 | + |
365 | return new MtpObjectPropertyList{list}; |
366 | } |
367 | - |
368 | + |
369 | virtual MtpDevicePropertyList* getSupportedDeviceProperties() |
370 | { |
371 | VLOG(1) << __PRETTY_FUNCTION__; |
372 | static const MtpDevicePropertyList list = { |
373 | MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, |
374 | - MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, |
375 | + MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, |
376 | }; |
377 | return new MtpDevicePropertyList{list}; |
378 | } |
379 | @@ -592,7 +592,7 @@ |
380 | MtpObjectHandle handle, |
381 | MtpObjectProperty property, |
382 | MtpDataPacket& packet) |
383 | - { |
384 | + { |
385 | char date[20]; |
386 | |
387 | VLOG(1) << __PRETTY_FUNCTION__ |
388 | @@ -605,10 +605,10 @@ |
389 | try { |
390 | switch(property) |
391 | { |
392 | - case MTP_PROPERTY_STORAGE_ID: packet.putUInt32(db.at(handle).storage_id); break; |
393 | - case MTP_PROPERTY_PARENT_OBJECT: packet.putUInt32(db.at(handle).parent); break; |
394 | + case MTP_PROPERTY_STORAGE_ID: packet.putUInt32(db.at(handle).storage_id); break; |
395 | + case MTP_PROPERTY_PARENT_OBJECT: packet.putUInt32(db.at(handle).parent); break; |
396 | case MTP_PROPERTY_OBJECT_FORMAT: packet.putUInt16(db.at(handle).object_format); break; |
397 | - case MTP_PROPERTY_OBJECT_SIZE: packet.putUInt32(db.at(handle).object_size); break; |
398 | + case MTP_PROPERTY_OBJECT_SIZE: packet.putUInt64(db.at(handle).object_size); break; |
399 | case MTP_PROPERTY_DISPLAY_NAME: packet.putString(db.at(handle).display_name.c_str()); break; |
400 | case MTP_PROPERTY_OBJECT_FILE_NAME: packet.putString(db.at(handle).display_name.c_str()); break; |
401 | case MTP_PROPERTY_PERSISTENT_UID: packet.putUInt128(handle); break; |
402 | @@ -637,9 +637,9 @@ |
403 | else |
404 | packet.putUInt16(1); // files can usually be played. |
405 | break; |
406 | - default: return MTP_RESPONSE_GENERAL_ERROR; break; |
407 | + default: return MTP_RESPONSE_GENERAL_ERROR; break; |
408 | } |
409 | - |
410 | + |
411 | return MTP_RESPONSE_OK; |
412 | } |
413 | catch (...) { |
414 | @@ -676,7 +676,10 @@ |
415 | try { |
416 | entry = db.at(handle); |
417 | |
418 | - packet.getString(buffer); |
419 | + if (!packet.getString(buffer)) { |
420 | + LOG(ERROR) << "Cannot read packet"; |
421 | + return MTP_RESPONSE_GENERAL_ERROR; |
422 | + } |
423 | newname = strdup(buffer); |
424 | |
425 | oldpath /= entry.path; |
426 | @@ -701,7 +704,10 @@ |
427 | case MTP_PROPERTY_PARENT_OBJECT: |
428 | try { |
429 | entry = db.at(handle); |
430 | - entry.parent = packet.getUInt32(); |
431 | + if (!packet.getUInt32(entry.parent)) { |
432 | + LOG(ERROR) << "Cannot read packet"; |
433 | + return MTP_RESPONSE_GENERAL_ERROR; |
434 | + } |
435 | } |
436 | catch (...) { |
437 | LOG(ERROR) << "Could not change parent object for handle " |
438 | @@ -710,7 +716,7 @@ |
439 | } |
440 | default: return MTP_RESPONSE_OPERATION_NOT_SUPPORTED; break; |
441 | } |
442 | - |
443 | + |
444 | return MTP_RESPONSE_OK; |
445 | } |
446 | |
447 | @@ -727,7 +733,7 @@ |
448 | break; |
449 | default: return MTP_RESPONSE_OPERATION_NOT_SUPPORTED; break; |
450 | } |
451 | - |
452 | + |
453 | return MTP_RESPONSE_OK; |
454 | } |
455 | |
456 | @@ -748,9 +754,9 @@ |
457 | |
458 | virtual MtpResponseCode getObjectPropertyList( |
459 | MtpObjectHandle handle, |
460 | - uint32_t format, |
461 | + uint32_t format, |
462 | uint32_t property, |
463 | - int groupCode, |
464 | + int groupCode, |
465 | int depth, |
466 | MtpDataPacket& packet) |
467 | { |
468 | @@ -841,8 +847,8 @@ |
469 | if (property == ALL_PROPERTIES || property == MTP_PROPERTY_OBJECT_SIZE) { |
470 | packet.putUInt32(i); |
471 | packet.putUInt16(MTP_PROPERTY_OBJECT_SIZE); |
472 | - packet.putUInt16(MTP_TYPE_UINT32); |
473 | - packet.putUInt32(entry.object_size); |
474 | + packet.putUInt16(MTP_TYPE_UINT64); |
475 | + packet.putUInt64(entry.object_size); |
476 | } |
477 | |
478 | // Object File Name |
479 | @@ -944,11 +950,16 @@ |
480 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
481 | |
482 | try { |
483 | + uint64_t object_size = db.at(handle).object_size; |
484 | + |
485 | info.mHandle = handle; |
486 | info.mStorageID = db.at(handle).storage_id; |
487 | info.mFormat = db.at(handle).object_format; |
488 | info.mProtectionStatus = 0x0; |
489 | - info.mCompressedSize = db.at(handle).object_size; |
490 | + if (object_size > UINT64_C(0xFFFFFFFF)) |
491 | + info.mCompressedSize = UINT64_C(0xFFFFFFFF); |
492 | + else |
493 | + info.mCompressedSize = object_size; |
494 | info.mImagePixWidth = 0; |
495 | info.mImagePixHeight = 0; |
496 | info.mImagePixDepth = 0; |
497 | @@ -1116,7 +1127,7 @@ |
498 | case MTP_PROPERTY_STORAGE_ID: result = new MtpProperty(property, MTP_TYPE_UINT32, false); break; |
499 | case MTP_PROPERTY_PARENT_OBJECT: result = new MtpProperty(property, MTP_TYPE_UINT32, true); break; |
500 | case MTP_PROPERTY_OBJECT_FORMAT: result = new MtpProperty(property, MTP_TYPE_UINT16, false); break; |
501 | - case MTP_PROPERTY_OBJECT_SIZE: result = new MtpProperty(property, MTP_TYPE_UINT32, false); break; |
502 | + case MTP_PROPERTY_OBJECT_SIZE: result = new MtpProperty(property, MTP_TYPE_UINT64, false); break; |
503 | case MTP_PROPERTY_WIDTH: result = new MtpProperty(property, MTP_TYPE_UINT32, false); break; |
504 | case MTP_PROPERTY_HEIGHT: result = new MtpProperty(property, MTP_TYPE_UINT32, false); break; |
505 | case MTP_PROPERTY_IMAGE_BIT_DEPTH: result = new MtpProperty(property, MTP_TYPE_UINT32, false); break; |
506 | @@ -1130,9 +1141,9 @@ |
507 | case MTP_PROPERTY_DATE_MODIFIED: result = new MtpProperty(property, MTP_TYPE_STR, false); break; |
508 | case MTP_PROPERTY_HIDDEN: result = new MtpProperty(property, MTP_TYPE_UINT16, false); break; |
509 | case MTP_PROPERTY_NON_CONSUMABLE: result = new MtpProperty(property, MTP_TYPE_UINT16, false); break; |
510 | - default: break; |
511 | + default: break; |
512 | } |
513 | - |
514 | + |
515 | return result; |
516 | } |
517 | |
518 | @@ -1146,12 +1157,12 @@ |
519 | case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: |
520 | case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: |
521 | result = new MtpProperty(property, MTP_TYPE_STR, false); break; |
522 | - default: break; |
523 | + default: break; |
524 | } |
525 | - |
526 | + |
527 | return result; |
528 | } |
529 | - |
530 | + |
531 | virtual void sessionStarted(MtpServer* server) |
532 | { |
533 | VLOG(1) << __PRETTY_FUNCTION__; |
534 | |
535 | === modified file 'server/server.cpp' |
536 | --- server/server.cpp 2015-02-13 15:19:49 +0000 |
537 | +++ server/server.cpp 2016-04-12 16:15:02 +0000 |
538 | @@ -21,6 +21,7 @@ |
539 | #include <MtpStorage.h> |
540 | |
541 | #include <iostream> |
542 | +#include <stdint.h> |
543 | |
544 | #include <signal.h> |
545 | #include <sys/types.h> |
546 | @@ -39,7 +40,7 @@ |
547 | #include <core/dbus/property.h> |
548 | #include <core/dbus/service.h> |
549 | #include <core/dbus/signal.h> |
550 | - |
551 | + |
552 | #include <core/dbus/asio/executor.h> |
553 | #include <core/dbus/types/stl/tuple.h> |
554 | #include <core/dbus/types/stl/vector.h> |
555 | @@ -76,23 +77,23 @@ |
556 | }; |
557 | } |
558 | |
559 | -namespace core |
560 | -{ |
561 | -namespace dbus |
562 | -{ |
563 | +namespace core |
564 | +{ |
565 | +namespace dbus |
566 | +{ |
567 | namespace traits |
568 | -{ |
569 | -template<> |
570 | -struct Service<core::UnityGreeter> |
571 | -{ |
572 | +{ |
573 | +template<> |
574 | +struct Service<core::UnityGreeter> |
575 | +{ |
576 | inline static const std::string& interface_name() |
577 | { |
578 | static const std::string s |
579 | { |
580 | "com.canonical.UnityGreeter" |
581 | - }; |
582 | + }; |
583 | return s; |
584 | - } |
585 | + } |
586 | }; |
587 | } |
588 | } |
589 | @@ -148,13 +149,14 @@ |
590 | { |
591 | static int storageID = MTP_STORAGE_REMOVABLE_RAM; |
592 | |
593 | + /* TODO check removable file system type to set maximum file size */ |
594 | MtpStorage *removable = new MtpStorage( |
595 | - storageID, |
596 | + storageID, |
597 | path, |
598 | name, |
599 | 1024 * 1024 * 100, /* 100 MB reserved space, to avoid filling the disk */ |
600 | true, |
601 | - 1024 * 1024 * 1024 * 2 /* 2GB arbitrary max file size */); |
602 | + UINT64_C(4294967295) /* 4GB-1, we assume vfat here */); |
603 | |
604 | storageID++; |
605 | |
606 | @@ -195,15 +197,15 @@ |
607 | std::size_t transferred) |
608 | { |
609 | size_t processed = 0; |
610 | - |
611 | + |
612 | while(transferred - processed >= sizeof(inotify_event)) |
613 | { |
614 | const char* cdata = processed + asio::buffer_cast<const char*>(buf.data()); |
615 | const inotify_event* ievent = reinterpret_cast<const inotify_event*>(cdata); |
616 | path storage_path ("/media"); |
617 | - |
618 | + |
619 | processed += sizeof(inotify_event) + ievent->len; |
620 | - |
621 | + |
622 | storage_path /= userdata->pw_name; |
623 | |
624 | if (ievent->len > 0 && ievent->mask & IN_CREATE) |
625 | @@ -277,11 +279,11 @@ |
626 | |
627 | // MTP server |
628 | server = new MtpServer( |
629 | - fd, |
630 | + fd, |
631 | mtp_database, |
632 | - false, |
633 | - userdata->pw_gid, |
634 | - FileSystemConfig::file_perm, |
635 | + false, |
636 | + userdata->pw_gid, |
637 | + FileSystemConfig::file_perm, |
638 | FileSystemConfig::directory_perm); |
639 | |
640 | // security / screen locking |
641 | @@ -302,12 +304,12 @@ |
642 | property_get ("ro.product.model", product_name, "Ubuntu Touch device"); |
643 | |
644 | home_storage = new MtpStorage( |
645 | - MTP_STORAGE_FIXED_RAM, |
646 | + MTP_STORAGE_FIXED_RAM, |
647 | userdata->pw_dir, |
648 | product_name, |
649 | 1024 * 1024 * 100, /* 100 MB reserved space, to avoid filling the disk */ |
650 | false, |
651 | - 1024 * 1024 * 1024 * 2 /* 2GB arbitrary max file size */); |
652 | + 0 /* Do not check sizes for internal storage */); |
653 | mtp_database->addStoragePath(std::string(userdata->pw_dir) + "/Documents", |
654 | gettext("Documents"), |
655 | MTP_STORAGE_FIXED_RAM, false); |
656 | @@ -424,7 +426,7 @@ |
657 | LOG(ERROR) << "Error opening /dev/mtp_usb, aborting now..."; |
658 | return 1; |
659 | } |
660 | - |
661 | + |
662 | try { |
663 | MtpDaemon *d = new MtpDaemon(fd); |
664 | |
665 | |
666 | === modified file 'src/MtpDataPacket.cpp' |
667 | --- src/MtpDataPacket.cpp 2014-03-27 15:45:30 +0000 |
668 | +++ src/MtpDataPacket.cpp 2016-04-12 16:15:02 +0000 |
669 | @@ -53,104 +53,178 @@ |
670 | MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); |
671 | } |
672 | |
673 | -uint16_t MtpDataPacket::getUInt16() { |
674 | - int offset = mOffset; |
675 | - uint16_t result = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); |
676 | - mOffset += 2; |
677 | - return result; |
678 | -} |
679 | - |
680 | -uint32_t MtpDataPacket::getUInt32() { |
681 | - int offset = mOffset; |
682 | - uint32_t result = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | |
683 | +bool MtpDataPacket::getUInt8(uint8_t& value) { |
684 | + if (mPacketSize - mOffset < sizeof(value)) |
685 | + return false; |
686 | + value = mBuffer[mOffset++]; |
687 | + return true; |
688 | +} |
689 | + |
690 | +bool MtpDataPacket::getUInt16(uint16_t& value) { |
691 | + if (mPacketSize - mOffset < sizeof(value)) |
692 | + return false; |
693 | + size_t offset = mOffset; |
694 | + value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); |
695 | + mOffset += sizeof(value); |
696 | + return true; |
697 | +} |
698 | + |
699 | +bool MtpDataPacket::getUInt32(uint32_t& value) { |
700 | + if (mPacketSize - mOffset < sizeof(value)) |
701 | + return false; |
702 | + size_t offset = mOffset; |
703 | + value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | |
704 | ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24); |
705 | - mOffset += 4; |
706 | - return result; |
707 | + mOffset += sizeof(value); |
708 | + return true; |
709 | } |
710 | |
711 | -uint64_t MtpDataPacket::getUInt64() { |
712 | - int offset = mOffset; |
713 | - uint64_t result = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | |
714 | +bool MtpDataPacket::getUInt64(uint64_t& value) { |
715 | + if (mPacketSize - mOffset < sizeof(value)) |
716 | + return false; |
717 | + size_t offset = mOffset; |
718 | + value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | |
719 | ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) | |
720 | ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) | |
721 | ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56); |
722 | - mOffset += 8; |
723 | - return result; |
724 | -} |
725 | - |
726 | -void MtpDataPacket::getUInt128(uint128_t& value) { |
727 | - value[0] = getUInt32(); |
728 | - value[1] = getUInt32(); |
729 | - value[2] = getUInt32(); |
730 | - value[3] = getUInt32(); |
731 | -} |
732 | - |
733 | -void MtpDataPacket::getString(MtpStringBuffer& string) |
734 | + mOffset += sizeof(value); |
735 | + return true; |
736 | +} |
737 | + |
738 | +bool MtpDataPacket::getUInt128(uint128_t& value) { |
739 | + return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]); |
740 | +} |
741 | + |
742 | +bool MtpDataPacket::getString(MtpStringBuffer& string) |
743 | { |
744 | - string.readFromPacket(this); |
745 | + return string.readFromPacket(this); |
746 | } |
747 | |
748 | Int8List* MtpDataPacket::getAInt8() { |
749 | + uint32_t count; |
750 | + if (!getUInt32(count)) |
751 | + return NULL; |
752 | Int8List* result = new Int8List; |
753 | - int count = getUInt32(); |
754 | - for (int i = 0; i < count; i++) |
755 | - result->push_back(getInt8()); |
756 | + for (uint32_t i = 0; i < count; i++) { |
757 | + int8_t value; |
758 | + if (!getInt8(value)) { |
759 | + delete result; |
760 | + return NULL; |
761 | + } |
762 | + result->push_back(value); |
763 | + } |
764 | return result; |
765 | } |
766 | |
767 | UInt8List* MtpDataPacket::getAUInt8() { |
768 | + uint32_t count; |
769 | + if (!getUInt32(count)) |
770 | + return NULL; |
771 | UInt8List* result = new UInt8List; |
772 | - int count = getUInt32(); |
773 | - for (int i = 0; i < count; i++) |
774 | - result->push_back(getUInt8()); |
775 | + for (uint32_t i = 0; i < count; i++) { |
776 | + uint8_t value; |
777 | + if (!getUInt8(value)) { |
778 | + delete result; |
779 | + return NULL; |
780 | + } |
781 | + result->push_back(value); |
782 | + } |
783 | return result; |
784 | } |
785 | |
786 | Int16List* MtpDataPacket::getAInt16() { |
787 | + uint32_t count; |
788 | + if (!getUInt32(count)) |
789 | + return NULL; |
790 | Int16List* result = new Int16List; |
791 | - int count = getUInt32(); |
792 | - for (int i = 0; i < count; i++) |
793 | - result->push_back(getInt16()); |
794 | + for (uint32_t i = 0; i < count; i++) { |
795 | + int16_t value; |
796 | + if (!getInt16(value)) { |
797 | + delete result; |
798 | + return NULL; |
799 | + } |
800 | + result->push_back(value); |
801 | + } |
802 | return result; |
803 | } |
804 | |
805 | UInt16List* MtpDataPacket::getAUInt16() { |
806 | + uint32_t count; |
807 | + if (!getUInt32(count)) |
808 | + return NULL; |
809 | UInt16List* result = new UInt16List; |
810 | - int count = getUInt32(); |
811 | - for (int i = 0; i < count; i++) |
812 | - result->push_back(getUInt16()); |
813 | + for (uint32_t i = 0; i < count; i++) { |
814 | + uint16_t value; |
815 | + if (!getUInt16(value)) { |
816 | + delete result; |
817 | + return NULL; |
818 | + } |
819 | + result->push_back(value); |
820 | + } |
821 | return result; |
822 | } |
823 | |
824 | Int32List* MtpDataPacket::getAInt32() { |
825 | + uint32_t count; |
826 | + if (!getUInt32(count)) |
827 | + return NULL; |
828 | Int32List* result = new Int32List; |
829 | - int count = getUInt32(); |
830 | - for (int i = 0; i < count; i++) |
831 | - result->push_back(getInt32()); |
832 | + for (uint32_t i = 0; i < count; i++) { |
833 | + int32_t value; |
834 | + if (!getInt32(value)) { |
835 | + delete result; |
836 | + return NULL; |
837 | + } |
838 | + result->push_back(value); |
839 | + } |
840 | return result; |
841 | } |
842 | |
843 | UInt32List* MtpDataPacket::getAUInt32() { |
844 | + uint32_t count; |
845 | + if (!getUInt32(count)) |
846 | + return NULL; |
847 | UInt32List* result = new UInt32List; |
848 | - int count = getUInt32(); |
849 | - for (int i = 0; i < count; i++) |
850 | - result->push_back(getUInt32()); |
851 | + for (uint32_t i = 0; i < count; i++) { |
852 | + uint32_t value; |
853 | + if (!getUInt32(value)) { |
854 | + delete result; |
855 | + return NULL; |
856 | + } |
857 | + result->push_back(value); |
858 | + } |
859 | return result; |
860 | } |
861 | |
862 | Int64List* MtpDataPacket::getAInt64() { |
863 | + uint32_t count; |
864 | + if (!getUInt32(count)) |
865 | + return NULL; |
866 | Int64List* result = new Int64List; |
867 | - int count = getUInt32(); |
868 | - for (int i = 0; i < count; i++) |
869 | - result->push_back(getInt64()); |
870 | + for (uint32_t i = 0; i < count; i++) { |
871 | + int64_t value; |
872 | + if (!getInt64(value)) { |
873 | + delete result; |
874 | + return NULL; |
875 | + } |
876 | + result->push_back(value); |
877 | + } |
878 | return result; |
879 | } |
880 | |
881 | UInt64List* MtpDataPacket::getAUInt64() { |
882 | + uint32_t count; |
883 | + if (!getUInt32(count)) |
884 | + return NULL; |
885 | UInt64List* result = new UInt64List; |
886 | - int count = getUInt32(); |
887 | - for (int i = 0; i < count; i++) |
888 | - result->push_back(getUInt64()); |
889 | + for (uint32_t i = 0; i < count; i++) { |
890 | + uint64_t value; |
891 | + if (!getUInt64(value)) { |
892 | + delete result; |
893 | + return NULL; |
894 | + } |
895 | + result->push_back(value); |
896 | + } |
897 | return result; |
898 | } |
899 | |
900 | @@ -333,7 +407,7 @@ |
901 | |
902 | void MtpDataPacket::putString(const uint16_t* string) { |
903 | int count = 0; |
904 | - for (int i = 0; i < 256; i++) { |
905 | + for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) { |
906 | if (string[i]) |
907 | count++; |
908 | else |
909 | @@ -365,7 +439,7 @@ |
910 | } |
911 | |
912 | int MtpDataPacket::writeData(int fd, void* data, uint32_t length) { |
913 | - allocate(length); |
914 | + allocate(length + MTP_CONTAINER_HEADER_SIZE); |
915 | memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length); |
916 | length += MTP_CONTAINER_HEADER_SIZE; |
917 | MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); |
918 | @@ -420,7 +494,7 @@ |
919 | // Queue a read request. Call readDataWait to wait for result |
920 | int MtpDataPacket::readDataAsync(struct usb_request *req) { |
921 | if (usb_request_queue(req)) { |
922 | - PLOG(ERROR) << "usb_endpoint_queue failed"; |
923 | + PLOG(ERROR) << "usb_endpoint_queue failed, errno: " << errno; |
924 | return -1; |
925 | } |
926 | return 0; |
927 | |
928 | === modified file 'src/MtpDevice.cpp' |
929 | --- src/MtpDevice.cpp 2014-03-27 15:45:30 +0000 |
930 | +++ src/MtpDevice.cpp 2016-04-12 16:15:02 +0000 |
931 | @@ -135,13 +135,22 @@ |
932 | struct usb_endpoint_descriptor *ep_in_desc = NULL; |
933 | struct usb_endpoint_descriptor *ep_out_desc = NULL; |
934 | struct usb_endpoint_descriptor *ep_intr_desc = NULL; |
935 | + //USB3 add USB_DT_SS_ENDPOINT_COMP as companion descriptor; |
936 | + struct usb_ss_ep_comp_descriptor *ep_ss_ep_comp_desc = NULL; |
937 | for (int i = 0; i < 3; i++) { |
938 | ep = (struct usb_endpoint_descriptor *)usb_descriptor_iter_next(&iter); |
939 | + if (ep && ep->bDescriptorType == USB_DT_SS_ENDPOINT_COMP) { |
940 | + VLOG(2) << "Descriptor type is USB_DT_SS_ENDPOINT_COMP for USB3 \n"; |
941 | + ep_ss_ep_comp_desc = (usb_ss_ep_comp_descriptor*)ep; |
942 | + ep = (struct usb_endpoint_descriptor *)usb_descriptor_iter_next(&iter); |
943 | + } |
944 | + |
945 | if (!ep || ep->bDescriptorType != USB_DT_ENDPOINT) { |
946 | LOG(ERROR) << "endpoints not found"; |
947 | usb_device_close(device); |
948 | return NULL; |
949 | } |
950 | + |
951 | if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK) { |
952 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
953 | ep_in_desc = ep; |
954 | @@ -199,7 +208,7 @@ |
955 | |
956 | MtpDevice::~MtpDevice() { |
957 | close(); |
958 | - for (int i = 0; i < mDeviceProperties.size(); i++) |
959 | + for (size_t i = 0; i < mDeviceProperties.size(); i++) |
960 | delete mDeviceProperties[i]; |
961 | usb_request_free(mRequestIn1); |
962 | usb_request_free(mRequestIn2); |
963 | @@ -257,7 +266,7 @@ |
964 | VLOG(2) << "*** FORMAT: " << MtpDebug::getFormatCodeName(format); |
965 | MtpObjectPropertyList* props = getObjectPropsSupported(format); |
966 | if (props) { |
967 | - for (int j = 0; j < props->size(); j++) { |
968 | + for (size_t j = 0; j < props->size(); j++) { |
969 | MtpObjectProperty prop = (*props)[j]; |
970 | MtpProperty* property = getObjectPropDesc(prop, format); |
971 | if (property) { |
972 | @@ -317,8 +326,10 @@ |
973 | MtpResponseCode ret = readResponse(); |
974 | if (ret == MTP_RESPONSE_OK) { |
975 | MtpDeviceInfo* info = new MtpDeviceInfo; |
976 | - info->read(mData); |
977 | - return info; |
978 | + if (info->read(mData)) |
979 | + return info; |
980 | + else |
981 | + delete info; |
982 | } |
983 | return NULL; |
984 | } |
985 | @@ -350,8 +361,10 @@ |
986 | MtpResponseCode ret = readResponse(); |
987 | if (ret == MTP_RESPONSE_OK) { |
988 | MtpStorageInfo* info = new MtpStorageInfo(storageID); |
989 | - info->read(mData); |
990 | - return info; |
991 | + if (info->read(mData)) |
992 | + return info; |
993 | + else |
994 | + delete info; |
995 | } |
996 | return NULL; |
997 | } |
998 | @@ -389,8 +402,10 @@ |
999 | MtpResponseCode ret = readResponse(); |
1000 | if (ret == MTP_RESPONSE_OK) { |
1001 | MtpObjectInfo* info = new MtpObjectInfo(handle); |
1002 | - info->read(mData); |
1003 | - return info; |
1004 | + if (info->read(mData)) |
1005 | + return info; |
1006 | + else |
1007 | + delete info; |
1008 | } |
1009 | return NULL; |
1010 | } |
1011 | @@ -551,8 +566,10 @@ |
1012 | MtpResponseCode ret = readResponse(); |
1013 | if (ret == MTP_RESPONSE_OK) { |
1014 | MtpProperty* property = new MtpProperty; |
1015 | - property->read(mData); |
1016 | - return property; |
1017 | + if (property->read(mData)) |
1018 | + return property; |
1019 | + else |
1020 | + delete property; |
1021 | } |
1022 | return NULL; |
1023 | } |
1024 | @@ -570,15 +587,17 @@ |
1025 | MtpResponseCode ret = readResponse(); |
1026 | if (ret == MTP_RESPONSE_OK) { |
1027 | MtpProperty* property = new MtpProperty; |
1028 | - property->read(mData); |
1029 | - return property; |
1030 | + if (property->read(mData)) |
1031 | + return property; |
1032 | + else |
1033 | + delete property; |
1034 | } |
1035 | return NULL; |
1036 | } |
1037 | |
1038 | bool MtpDevice::readObject(MtpObjectHandle handle, |
1039 | bool (* callback)(void* data, int offset, int length, void* clientData), |
1040 | - int objectSize, void* clientData) { |
1041 | + size_t objectSize, void* clientData) { |
1042 | MtpAutolock autoLock(mMutex); |
1043 | bool result = false; |
1044 | |
1045 | @@ -671,7 +690,7 @@ |
1046 | // reads the object's data and writes it to the specified file path |
1047 | bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) { |
1048 | VLOG(2) << "readObject: " << destPath; |
1049 | - int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
1050 | + int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR); |
1051 | if (fd < 0) { |
1052 | LOG(ERROR) << "open failed for " << destPath; |
1053 | return false; |
1054 | |
1055 | === modified file 'src/MtpDeviceInfo.cpp' |
1056 | --- src/MtpDeviceInfo.cpp 2014-03-27 15:45:30 +0000 |
1057 | +++ src/MtpDeviceInfo.cpp 2016-04-12 16:15:02 +0000 |
1058 | @@ -32,7 +32,7 @@ |
1059 | mVendorExtensionID(0), |
1060 | mVendorExtensionVersion(0), |
1061 | mVendorExtensionDesc(NULL), |
1062 | - mFunctionalCode(0), |
1063 | + mFunctionalMode(0), |
1064 | mOperations(NULL), |
1065 | mEvents(NULL), |
1066 | mDeviceProperties(NULL), |
1067 | @@ -63,32 +63,39 @@ |
1068 | free(mSerial); |
1069 | } |
1070 | |
1071 | -void MtpDeviceInfo::read(MtpDataPacket& packet) { |
1072 | +bool MtpDeviceInfo::read(MtpDataPacket& packet) { |
1073 | MtpStringBuffer string; |
1074 | |
1075 | // read the device info |
1076 | - mStandardVersion = packet.getUInt16(); |
1077 | - mVendorExtensionID = packet.getUInt32(); |
1078 | - mVendorExtensionVersion = packet.getUInt16(); |
1079 | + if (!packet.getUInt16(mStandardVersion)) return false; |
1080 | + if (!packet.getUInt32(mVendorExtensionID)) return false; |
1081 | + if (!packet.getUInt16(mVendorExtensionVersion)) return false; |
1082 | |
1083 | - packet.getString(string); |
1084 | + if (!packet.getString(string)) return false; |
1085 | mVendorExtensionDesc = strdup((const char *)string); |
1086 | |
1087 | - mFunctionalCode = packet.getUInt16(); |
1088 | + if (!packet.getUInt16(mFunctionalMode)) return false; |
1089 | mOperations = packet.getAUInt16(); |
1090 | + if (!mOperations) return false; |
1091 | mEvents = packet.getAUInt16(); |
1092 | + if (!mEvents) return false; |
1093 | mDeviceProperties = packet.getAUInt16(); |
1094 | + if (!mDeviceProperties) return false; |
1095 | mCaptureFormats = packet.getAUInt16(); |
1096 | + if (!mCaptureFormats) return false; |
1097 | mPlaybackFormats = packet.getAUInt16(); |
1098 | + if (!mCaptureFormats) return false; |
1099 | |
1100 | - packet.getString(string); |
1101 | + if (!packet.getString(string)) return false; |
1102 | mManufacturer = strdup((const char *)string); |
1103 | - packet.getString(string); |
1104 | + if (!packet.getString(string)) return false; |
1105 | mModel = strdup((const char *)string); |
1106 | - packet.getString(string); |
1107 | + if (!packet.getString(string)) return false; |
1108 | mVersion = strdup((const char *)string); |
1109 | - packet.getString(string); |
1110 | + if (!packet.getString(string)) return false; |
1111 | mSerial = strdup((const char *)string); |
1112 | + |
1113 | + return true; |
1114 | } |
1115 | |
1116 | void MtpDeviceInfo::print() { |
1117 | @@ -97,7 +104,7 @@ |
1118 | << "\n\tmVendorExtensionID: " << mVendorExtensionID |
1119 | << "\n\tmVendorExtensionVersion: " << mVendorExtensionVersion |
1120 | << "\n\tmVendorExtensionDesc: " << mVendorExtensionDesc |
1121 | - << "\n\tmFunctionalCode: " << mFunctionalCode |
1122 | + << "\n\tmFunctionalCode: " << mFunctionalMode |
1123 | << "\n\tmManufacturer: " << mManufacturer |
1124 | << "\n\tmModel: " << mModel |
1125 | << "\n\tmVersion: " << mVersion |
1126 | |
1127 | === modified file 'src/MtpObjectInfo.cpp' |
1128 | --- src/MtpObjectInfo.cpp 2014-03-27 15:45:30 +0000 |
1129 | +++ src/MtpObjectInfo.cpp 2016-04-12 16:15:02 +0000 |
1130 | @@ -60,39 +60,41 @@ |
1131 | free(mKeywords); |
1132 | } |
1133 | |
1134 | -void MtpObjectInfo::read(MtpDataPacket& packet) { |
1135 | +bool MtpObjectInfo::read(MtpDataPacket& packet) { |
1136 | MtpStringBuffer string; |
1137 | time_t time; |
1138 | |
1139 | - mStorageID = packet.getUInt32(); |
1140 | - mFormat = packet.getUInt16(); |
1141 | - mProtectionStatus = packet.getUInt16(); |
1142 | - mCompressedSize = packet.getUInt32(); |
1143 | - mThumbFormat = packet.getUInt16(); |
1144 | - mThumbCompressedSize = packet.getUInt32(); |
1145 | - mThumbPixWidth = packet.getUInt32(); |
1146 | - mThumbPixHeight = packet.getUInt32(); |
1147 | - mImagePixWidth = packet.getUInt32(); |
1148 | - mImagePixHeight = packet.getUInt32(); |
1149 | - mImagePixDepth = packet.getUInt32(); |
1150 | - mParent = packet.getUInt32(); |
1151 | - mAssociationType = packet.getUInt16(); |
1152 | - mAssociationDesc = packet.getUInt32(); |
1153 | - mSequenceNumber = packet.getUInt32(); |
1154 | + if (!packet.getUInt32(mStorageID)) return false; |
1155 | + if (!packet.getUInt16(mFormat)) return false; |
1156 | + if (!packet.getUInt16(mProtectionStatus)) return false; |
1157 | + if (!packet.getUInt32(mCompressedSize)) return false; |
1158 | + if (!packet.getUInt16(mThumbFormat)) return false; |
1159 | + if (!packet.getUInt32(mThumbCompressedSize)) return false; |
1160 | + if (!packet.getUInt32(mThumbPixWidth)) return false; |
1161 | + if (!packet.getUInt32(mThumbPixHeight)) return false; |
1162 | + if (!packet.getUInt32(mImagePixWidth)) return false; |
1163 | + if (!packet.getUInt32(mImagePixHeight)) return false; |
1164 | + if (!packet.getUInt32(mImagePixDepth)) return false; |
1165 | + if (!packet.getUInt32(mParent)) return false; |
1166 | + if (!packet.getUInt16(mAssociationType)) return false; |
1167 | + if (!packet.getUInt32(mAssociationDesc)) return false; |
1168 | + if (!packet.getUInt32(mSequenceNumber)) return false; |
1169 | |
1170 | - packet.getString(string); |
1171 | + if (!packet.getString(string)) return false; |
1172 | mName = strdup((const char *)string); |
1173 | |
1174 | - packet.getString(string); |
1175 | + if (!packet.getString(string)) return false; |
1176 | if (parseDateTime((const char*)string, time)) |
1177 | mDateCreated = time; |
1178 | |
1179 | - packet.getString(string); |
1180 | + if (!packet.getString(string)) return false; |
1181 | if (parseDateTime((const char*)string, time)) |
1182 | mDateModified = time; |
1183 | |
1184 | - packet.getString(string); |
1185 | + if (!packet.getString(string)) return false; |
1186 | mKeywords = strdup((const char *)string); |
1187 | + |
1188 | + return true; |
1189 | } |
1190 | |
1191 | void MtpObjectInfo::print() { |
1192 | |
1193 | === modified file 'src/MtpPacket.cpp' |
1194 | --- src/MtpPacket.cpp 2014-03-27 15:45:30 +0000 |
1195 | +++ src/MtpPacket.cpp 2016-04-12 16:15:02 +0000 |
1196 | @@ -52,7 +52,7 @@ |
1197 | memset(mBuffer, 0, mBufferSize); |
1198 | } |
1199 | |
1200 | -void MtpPacket::allocate(int length) { |
1201 | +void MtpPacket::allocate(size_t length) { |
1202 | if (length > mBufferSize) { |
1203 | int newLength = length + mAllocationIncrement; |
1204 | mBuffer = (uint8_t *)realloc(mBuffer, newLength); |
1205 | |
1206 | === modified file 'src/MtpProperty.cpp' |
1207 | --- src/MtpProperty.cpp 2014-03-27 15:45:30 +0000 |
1208 | +++ src/MtpProperty.cpp 2016-04-12 16:15:02 +0000 |
1209 | @@ -112,15 +112,15 @@ |
1210 | free(mMinimumValue.str); |
1211 | free(mMaximumValue.str); |
1212 | if (mDefaultArrayValues) { |
1213 | - for (int i = 0; i < mDefaultArrayLength; i++) |
1214 | + for (uint32_t i = 0; i < mDefaultArrayLength; i++) |
1215 | free(mDefaultArrayValues[i].str); |
1216 | } |
1217 | if (mCurrentArrayValues) { |
1218 | - for (int i = 0; i < mCurrentArrayLength; i++) |
1219 | + for (uint32_t i = 0; i < mCurrentArrayLength; i++) |
1220 | free(mCurrentArrayValues[i].str); |
1221 | } |
1222 | if (mEnumValues) { |
1223 | - for (int i = 0; i < mEnumLength; i++) |
1224 | + for (uint16_t i = 0; i < mEnumLength; i++) |
1225 | free(mEnumValues[i].str); |
1226 | } |
1227 | } |
1228 | @@ -129,11 +129,14 @@ |
1229 | delete[] mEnumValues; |
1230 | } |
1231 | |
1232 | -void MtpProperty::read(MtpDataPacket& packet) { |
1233 | - mCode = packet.getUInt16(); |
1234 | +bool MtpProperty::read(MtpDataPacket& packet) { |
1235 | + uint8_t temp8; |
1236 | + |
1237 | + if (!packet.getUInt16(mCode)) return false; |
1238 | bool deviceProp = isDeviceProperty(); |
1239 | - mType = packet.getUInt16(); |
1240 | - mWriteable = (packet.getUInt8() == 1); |
1241 | + if (!packet.getUInt16(mType)) return false; |
1242 | + if (!packet.getUInt8(temp8)) return false; |
1243 | + mWriteable = (temp8 == 1); |
1244 | switch (mType) { |
1245 | case MTP_TYPE_AINT8: |
1246 | case MTP_TYPE_AUINT8: |
1247 | @@ -146,28 +149,36 @@ |
1248 | case MTP_TYPE_AINT128: |
1249 | case MTP_TYPE_AUINT128: |
1250 | mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength); |
1251 | - if (deviceProp) |
1252 | + if (!mDefaultArrayValues) return false; |
1253 | + if (deviceProp) { |
1254 | mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength); |
1255 | + if (!mCurrentArrayValues) return false; |
1256 | + } |
1257 | break; |
1258 | default: |
1259 | - readValue(packet, mDefaultValue); |
1260 | - if (deviceProp) |
1261 | - readValue(packet, mCurrentValue); |
1262 | - } |
1263 | - if (!deviceProp) |
1264 | - mGroupCode = packet.getUInt32(); |
1265 | - mFormFlag = packet.getUInt8(); |
1266 | + if (!readValue(packet, mDefaultValue)) return false; |
1267 | + if (deviceProp) { |
1268 | + if (!readValue(packet, mCurrentValue)) return false; |
1269 | + } |
1270 | + } |
1271 | + if (!deviceProp) { |
1272 | + if (!packet.getUInt32(mGroupCode)) return false; |
1273 | + } |
1274 | + if (!packet.getUInt8(mFormFlag)) return false; |
1275 | |
1276 | if (mFormFlag == kFormRange) { |
1277 | - readValue(packet, mMinimumValue); |
1278 | - readValue(packet, mMaximumValue); |
1279 | - readValue(packet, mStepSize); |
1280 | + if (!readValue(packet, mMinimumValue)) return false; |
1281 | + if (!readValue(packet, mMaximumValue)) return false; |
1282 | + if (!readValue(packet, mStepSize)) return false; |
1283 | } else if (mFormFlag == kFormEnum) { |
1284 | - mEnumLength = packet.getUInt16(); |
1285 | + if (!packet.getUInt16(mEnumLength)) return false; |
1286 | mEnumValues = new MtpPropertyValue[mEnumLength]; |
1287 | - for (int i = 0; i < mEnumLength; i++) |
1288 | - readValue(packet, mEnumValues[i]); |
1289 | + for (int i = 0; i < mEnumLength; i++) { |
1290 | + if (!readValue(packet, mEnumValues[i])) return false; |
1291 | + } |
1292 | } |
1293 | + |
1294 | + return true; |
1295 | } |
1296 | |
1297 | void MtpProperty::write(MtpDataPacket& packet) { |
1298 | @@ -197,9 +208,9 @@ |
1299 | if (deviceProp) |
1300 | writeValue(packet, mCurrentValue); |
1301 | } |
1302 | - packet.putUInt32(mGroupCode); |
1303 | if (!deviceProp) |
1304 | - packet.putUInt8(mFormFlag); |
1305 | + packet.putUInt32(mGroupCode); |
1306 | + packet.putUInt8(mFormFlag); |
1307 | if (mFormFlag == kFormRange) { |
1308 | writeValue(packet, mMinimumValue); |
1309 | writeValue(packet, mMaximumValue); |
1310 | @@ -423,52 +434,52 @@ |
1311 | buffer += ss.str(); |
1312 | } |
1313 | |
1314 | -void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { |
1315 | +bool MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { |
1316 | MtpStringBuffer stringBuffer; |
1317 | |
1318 | switch (mType) { |
1319 | case MTP_TYPE_INT8: |
1320 | case MTP_TYPE_AINT8: |
1321 | - value.u.i8 = packet.getInt8(); |
1322 | + if (!packet.getInt8(value.u.i8)) return false; |
1323 | break; |
1324 | case MTP_TYPE_UINT8: |
1325 | case MTP_TYPE_AUINT8: |
1326 | - value.u.u8 = packet.getUInt8(); |
1327 | + if (!packet.getUInt8(value.u.u8)) return false; |
1328 | break; |
1329 | case MTP_TYPE_INT16: |
1330 | case MTP_TYPE_AINT16: |
1331 | - value.u.i16 = packet.getInt16(); |
1332 | + if (!packet.getInt16(value.u.i16)) return false; |
1333 | break; |
1334 | case MTP_TYPE_UINT16: |
1335 | case MTP_TYPE_AUINT16: |
1336 | - value.u.u16 = packet.getUInt16(); |
1337 | + if (!packet.getUInt16(value.u.u16)) return false; |
1338 | break; |
1339 | case MTP_TYPE_INT32: |
1340 | case MTP_TYPE_AINT32: |
1341 | - value.u.i32 = packet.getInt32(); |
1342 | + if (!packet.getInt32(value.u.i32)) return false; |
1343 | break; |
1344 | case MTP_TYPE_UINT32: |
1345 | case MTP_TYPE_AUINT32: |
1346 | - value.u.u32 = packet.getUInt32(); |
1347 | + if (!packet.getUInt32(value.u.u32)) return false; |
1348 | break; |
1349 | case MTP_TYPE_INT64: |
1350 | case MTP_TYPE_AINT64: |
1351 | - value.u.i64 = packet.getInt64(); |
1352 | + if (!packet.getInt64(value.u.i64)) return false; |
1353 | break; |
1354 | case MTP_TYPE_UINT64: |
1355 | case MTP_TYPE_AUINT64: |
1356 | - value.u.u64 = packet.getUInt64(); |
1357 | + if (!packet.getUInt64(value.u.u64)) return false; |
1358 | break; |
1359 | case MTP_TYPE_INT128: |
1360 | case MTP_TYPE_AINT128: |
1361 | - packet.getInt128(value.u.i128); |
1362 | + if (!packet.getInt128(value.u.i128)) return false; |
1363 | break; |
1364 | case MTP_TYPE_UINT128: |
1365 | case MTP_TYPE_AUINT128: |
1366 | - packet.getUInt128(value.u.u128); |
1367 | + if (!packet.getUInt128(value.u.u128)) return false; |
1368 | break; |
1369 | case MTP_TYPE_STR: |
1370 | - packet.getString(stringBuffer); |
1371 | + if (!packet.getString(stringBuffer)) return false; |
1372 | value.str = strdup(stringBuffer); |
1373 | break; |
1374 | default: |
1375 | @@ -476,6 +487,7 @@ |
1376 | << std::hex << mType << std::dec |
1377 | << " in MtpProperty::readValue"; |
1378 | } |
1379 | + return true; |
1380 | } |
1381 | |
1382 | void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { |
1383 | @@ -535,19 +547,28 @@ |
1384 | } |
1385 | } |
1386 | |
1387 | -MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { |
1388 | - length = packet.getUInt32(); |
1389 | - if (length == 0) |
1390 | +MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, uint32_t& length) { |
1391 | + if (!packet.getUInt32(length)) return NULL; |
1392 | + |
1393 | + // Fail if resulting array is over 2GB. This is because the maximum array |
1394 | + // size may be less than SIZE_MAX on some platforms. |
1395 | + if (length == 0 || |
1396 | + length >= INT32_MAX / sizeof(MtpPropertyValue)) { |
1397 | + length = 0; |
1398 | return NULL; |
1399 | + } |
1400 | MtpPropertyValue* result = new MtpPropertyValue[length]; |
1401 | - for (int i = 0; i < length; i++) |
1402 | - readValue(packet, result[i]); |
1403 | + for (uint32_t i = 0; i < length; i++) |
1404 | + if (!readValue(packet, result[i])) { |
1405 | + delete result; |
1406 | + return NULL; |
1407 | + } |
1408 | return result; |
1409 | } |
1410 | |
1411 | -void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { |
1412 | +void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, uint32_t length) { |
1413 | packet.putUInt32(length); |
1414 | - for (int i = 0; i < length; i++) |
1415 | + for (uint32_t i = 0; i < length; i++) |
1416 | writeValue(packet, values[i]); |
1417 | } |
1418 | |
1419 | |
1420 | === modified file 'src/MtpRequestPacket.cpp' |
1421 | --- src/MtpRequestPacket.cpp 2013-06-13 10:22:21 +0000 |
1422 | +++ src/MtpRequestPacket.cpp 2016-04-12 16:15:02 +0000 |
1423 | @@ -24,11 +24,13 @@ |
1424 | #include "MtpRequestPacket.h" |
1425 | |
1426 | #include <usbhost/usbhost.h> |
1427 | +#include <glog/logging.h> |
1428 | |
1429 | namespace android { |
1430 | |
1431 | MtpRequestPacket::MtpRequestPacket() |
1432 | - : MtpPacket(512) |
1433 | + : MtpPacket(512), |
1434 | + mParameterCount(0) |
1435 | { |
1436 | } |
1437 | |
1438 | @@ -38,10 +40,21 @@ |
1439 | #ifdef MTP_DEVICE |
1440 | int MtpRequestPacket::read(int fd) { |
1441 | int ret = ::read(fd, mBuffer, mBufferSize); |
1442 | - if (ret >= 0) |
1443 | + if (ret < 0) { |
1444 | + // file read error |
1445 | + return ret; |
1446 | + } |
1447 | + |
1448 | + // request packet should have 12 byte header followed by 0 to 5 32-bit arguments |
1449 | + if (ret >= MTP_CONTAINER_HEADER_SIZE |
1450 | + && ret <= MTP_CONTAINER_HEADER_SIZE + 5 * sizeof(uint32_t) |
1451 | + && ((ret - MTP_CONTAINER_HEADER_SIZE) & 3) == 0) { |
1452 | mPacketSize = ret; |
1453 | - else |
1454 | - mPacketSize = 0; |
1455 | + mParameterCount = (ret - MTP_CONTAINER_HEADER_SIZE) / sizeof(uint32_t); |
1456 | + } else { |
1457 | + PLOG(ERROR) << "Malformed MTP request packet"; |
1458 | + ret = -1; |
1459 | + } |
1460 | return ret; |
1461 | } |
1462 | #endif |
1463 | |
1464 | === modified file 'src/MtpServer.cpp' |
1465 | --- src/MtpServer.cpp 2014-10-31 15:56:55 +0000 |
1466 | +++ src/MtpServer.cpp 2016-04-12 16:15:02 +0000 |
1467 | @@ -27,6 +27,7 @@ |
1468 | #include <sys/stat.h> |
1469 | #include <dirent.h> |
1470 | #include <unistd.h> |
1471 | +#include <errno.h> |
1472 | |
1473 | #define LOG_TAG "MtpServer" |
1474 | |
1475 | @@ -99,6 +100,7 @@ |
1476 | MTP_EVENT_OBJECT_REMOVED, |
1477 | MTP_EVENT_STORE_ADDED, |
1478 | MTP_EVENT_STORE_REMOVED, |
1479 | + MTP_EVENT_DEVICE_PROP_CHANGED, |
1480 | MTP_EVENT_OBJECT_INFO_CHANGED, |
1481 | MTP_EVENT_OBJECT_PROP_CHANGED, |
1482 | }; |
1483 | @@ -132,7 +134,7 @@ |
1484 | void MtpServer::removeStorage(MtpStorage* storage) { |
1485 | MtpAutolock autoLock(mMutex); |
1486 | |
1487 | - for (int i = 0; i < mStorages.size(); i++) { |
1488 | + for (size_t i = 0; i < mStorages.size(); i++) { |
1489 | if (mStorages[i] == storage) { |
1490 | mStorages.erase(mStorages.begin()+i); |
1491 | sendStoreRemoved(storage->getStorageID()); |
1492 | @@ -144,7 +146,7 @@ |
1493 | MtpStorage* MtpServer::getStorage(MtpStorageID id) { |
1494 | if (id == 0) |
1495 | return mStorages[0]; |
1496 | - for (int i = 0; i < mStorages.size(); i++) { |
1497 | + for (size_t i = 0; i < mStorages.size(); i++) { |
1498 | MtpStorage* storage = mStorages[i]; |
1499 | if (storage->getStorageID() == id) |
1500 | return storage; |
1501 | @@ -226,10 +228,12 @@ |
1502 | VLOG(2) << "sending response " |
1503 | << std::hex << mResponse.getResponseCode() << std::dec; |
1504 | ret = mResponse.write(fd); |
1505 | + const int savedErrno = errno; |
1506 | mResponse.dump(); |
1507 | if (ret < 0) { |
1508 | - PLOG(ERROR) << "request write returned " << ret; |
1509 | - if (errno == ECANCELED) { |
1510 | + PLOG(ERROR) << "request write returned " << ret |
1511 | + << ", errno: " << savedErrno; |
1512 | + if (savedErrno == ECANCELED) { |
1513 | // return to top of loop and wait for next command |
1514 | continue; |
1515 | } |
1516 | @@ -348,6 +352,15 @@ |
1517 | mSendObjectHandle = kInvalidObjectHandle; |
1518 | } |
1519 | |
1520 | + int containertype = mRequest.getContainerType(); |
1521 | + if (containertype != MTP_CONTAINER_TYPE_COMMAND) { |
1522 | + LOG(ERROR) << "wrong container type " << containertype; |
1523 | + return false; |
1524 | + } |
1525 | + |
1526 | + VLOG(2) << "got command " << MtpDebug::getOperationCodeName(operation) |
1527 | + << ", " << std::hex << operation << std::dec; |
1528 | + |
1529 | switch (operation) { |
1530 | case MTP_OPERATION_GET_DEVICE_INFO: |
1531 | response = doGetDeviceInfo(); |
1532 | @@ -513,6 +526,9 @@ |
1533 | mResponse.setParameter(1, mSessionID); |
1534 | return MTP_RESPONSE_SESSION_ALREADY_OPEN; |
1535 | } |
1536 | + if (mRequest.getParameterCount() < 1) |
1537 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1538 | + |
1539 | mSessionID = mRequest.getParameter(1); |
1540 | mSessionOpen = true; |
1541 | |
1542 | @@ -547,6 +563,9 @@ |
1543 | |
1544 | if (!mSessionOpen) |
1545 | return MTP_RESPONSE_SESSION_NOT_OPEN; |
1546 | + if (mRequest.getParameterCount() < 1) |
1547 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1548 | + |
1549 | MtpStorageID id = mRequest.getParameter(1); |
1550 | MtpStorage* storage = getStorage(id); |
1551 | if (!storage) |
1552 | @@ -568,6 +587,8 @@ |
1553 | MtpResponseCode MtpServer::doGetObjectPropsSupported() { |
1554 | if (!mSessionOpen) |
1555 | return MTP_RESPONSE_SESSION_NOT_OPEN; |
1556 | + if (mRequest.getParameterCount() < 1) |
1557 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1558 | MtpObjectFormat format = mRequest.getParameter(1); |
1559 | MtpObjectPropertyList* properties = mDatabase->getSupportedObjectProperties(format); |
1560 | mData.putAUInt16(properties); |
1561 | @@ -578,6 +599,8 @@ |
1562 | MtpResponseCode MtpServer::doGetObjectHandles() { |
1563 | if (!mSessionOpen) |
1564 | return MTP_RESPONSE_SESSION_NOT_OPEN; |
1565 | + if (mRequest.getParameterCount() < 3) |
1566 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1567 | MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage |
1568 | MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats |
1569 | MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent |
1570 | @@ -595,6 +618,8 @@ |
1571 | MtpResponseCode MtpServer::doGetNumObjects() { |
1572 | if (!mSessionOpen) |
1573 | return MTP_RESPONSE_SESSION_NOT_OPEN; |
1574 | + if (mRequest.getParameterCount() < 3) |
1575 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1576 | MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage |
1577 | MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats |
1578 | MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent |
1579 | @@ -617,6 +642,8 @@ |
1580 | return MTP_RESPONSE_SESSION_NOT_OPEN; |
1581 | if (!hasStorage()) |
1582 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1583 | + if (mRequest.getParameterCount() < 1) |
1584 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1585 | MtpObjectHandle handle = mRequest.getParameter(1); |
1586 | |
1587 | // FIXME - check for invalid object handle |
1588 | @@ -635,9 +662,13 @@ |
1589 | return MTP_RESPONSE_SESSION_NOT_OPEN; |
1590 | if (!hasStorage()) |
1591 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1592 | + if (mRequest.getParameterCount() < 1) |
1593 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1594 | MtpStorageID handle = mRequest.getParameter(1); |
1595 | |
1596 | MtpObjectHandleList* references = mData.getAUInt32(); |
1597 | + if (!references) |
1598 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1599 | MtpResponseCode result = mDatabase->setObjectReferences(handle, references); |
1600 | delete references; |
1601 | return result; |
1602 | @@ -646,6 +677,8 @@ |
1603 | MtpResponseCode MtpServer::doGetObjectPropValue() { |
1604 | if (!hasStorage()) |
1605 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1606 | + if (mRequest.getParameterCount() < 2) |
1607 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1608 | MtpObjectHandle handle = mRequest.getParameter(1); |
1609 | MtpObjectProperty property = mRequest.getParameter(2); |
1610 | VLOG(2) << "GetObjectPropValue " << handle |
1611 | @@ -659,6 +692,8 @@ |
1612 | |
1613 | if (!hasStorage()) |
1614 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1615 | + if (mRequest.getParameterCount() < 2) |
1616 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1617 | MtpObjectHandle handle = mRequest.getParameter(1); |
1618 | MtpObjectProperty property = mRequest.getParameter(2); |
1619 | VLOG(2) << "SetObjectPropValue " << handle |
1620 | @@ -672,6 +707,8 @@ |
1621 | } |
1622 | |
1623 | MtpResponseCode MtpServer::doGetDevicePropValue() { |
1624 | + if (mRequest.getParameterCount() < 1) |
1625 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1626 | MtpDeviceProperty property = mRequest.getParameter(1); |
1627 | VLOG(1) << "GetDevicePropValue " << MtpDebug::getDevicePropCodeName(property); |
1628 | |
1629 | @@ -679,6 +716,8 @@ |
1630 | } |
1631 | |
1632 | MtpResponseCode MtpServer::doSetDevicePropValue() { |
1633 | + if (mRequest.getParameterCount() < 1) |
1634 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1635 | MtpDeviceProperty property = mRequest.getParameter(1); |
1636 | VLOG(1) << "SetDevicePropValue " << MtpDebug::getDevicePropCodeName(property); |
1637 | |
1638 | @@ -686,6 +725,8 @@ |
1639 | } |
1640 | |
1641 | MtpResponseCode MtpServer::doResetDevicePropValue() { |
1642 | + if (mRequest.getParameterCount() < 1) |
1643 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1644 | MtpDeviceProperty property = mRequest.getParameter(1); |
1645 | VLOG(1) << "ResetDevicePropValue " << MtpDebug::getDevicePropCodeName(property); |
1646 | |
1647 | @@ -695,6 +736,8 @@ |
1648 | MtpResponseCode MtpServer::doGetObjectPropList() { |
1649 | if (!hasStorage()) |
1650 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1651 | + if (mRequest.getParameterCount() < 5) |
1652 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1653 | |
1654 | MtpObjectHandle handle = mRequest.getParameter(1); |
1655 | // use uint32_t so we can support 0xFFFFFFFF |
1656 | @@ -714,6 +757,8 @@ |
1657 | MtpResponseCode MtpServer::doGetObjectInfo() { |
1658 | if (!hasStorage()) |
1659 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1660 | + if (mRequest.getParameterCount() < 1) |
1661 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1662 | MtpObjectHandle handle = mRequest.getParameter(1); |
1663 | MtpObjectInfo info(handle); |
1664 | MtpResponseCode result = mDatabase->getObjectInfo(handle, info); |
1665 | @@ -754,6 +799,8 @@ |
1666 | MtpResponseCode MtpServer::doGetObject() { |
1667 | if (!hasStorage()) |
1668 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1669 | + if (mRequest.getParameterCount() < 1) |
1670 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1671 | MtpObjectHandle handle = mRequest.getParameter(1); |
1672 | MtpString pathBuf; |
1673 | int64_t fileLength; |
1674 | @@ -763,7 +810,7 @@ |
1675 | return result; |
1676 | |
1677 | mtp_file_range mfr; |
1678 | - mfr.fd = open(pathBuf.c_str(), O_RDONLY); |
1679 | + mfr.fd = open(pathBuf.c_str(), O_RDONLY | O_LARGEFILE); |
1680 | if (mfr.fd < 0) { |
1681 | return MTP_RESPONSE_GENERAL_ERROR; |
1682 | } |
1683 | @@ -774,18 +821,24 @@ |
1684 | |
1685 | // then transfer the file |
1686 | int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr); |
1687 | + if (ret < 0) { |
1688 | + if (errno == ECANCELED) { |
1689 | + result = MTP_RESPONSE_TRANSACTION_CANCELLED; |
1690 | + } else { |
1691 | + result = MTP_RESPONSE_GENERAL_ERROR; |
1692 | + } |
1693 | + } else { |
1694 | + result = MTP_RESPONSE_OK; |
1695 | + } |
1696 | + |
1697 | VLOG(2) << "MTP_SEND_FILE_WITH_HEADER returned " << ret; |
1698 | close(mfr.fd); |
1699 | - if (ret < 0) { |
1700 | - if (errno == ECANCELED) |
1701 | - return MTP_RESPONSE_TRANSACTION_CANCELLED; |
1702 | - else |
1703 | - return MTP_RESPONSE_GENERAL_ERROR; |
1704 | - } |
1705 | - return MTP_RESPONSE_OK; |
1706 | + return result; |
1707 | } |
1708 | |
1709 | MtpResponseCode MtpServer::doGetThumb() { |
1710 | + if (mRequest.getParameterCount() < 1) |
1711 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1712 | MtpObjectHandle handle = mRequest.getParameter(1); |
1713 | size_t thumbSize; |
1714 | void* thumb = mDatabase->getThumbnail(handle, thumbSize); |
1715 | @@ -809,11 +862,19 @@ |
1716 | uint32_t length; |
1717 | offset = mRequest.getParameter(2); |
1718 | if (operation == MTP_OPERATION_GET_PARTIAL_OBJECT_64) { |
1719 | + // MTP_OPERATION_GET_PARTIAL_OBJECT_64 takes 4 arguments |
1720 | + if (mRequest.getParameterCount() < 4) |
1721 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1722 | + |
1723 | // android extension with 64 bit offset |
1724 | uint64_t offset2 = mRequest.getParameter(3); |
1725 | offset = offset | (offset2 << 32); |
1726 | length = mRequest.getParameter(4); |
1727 | } else { |
1728 | + // MTP_OPERATION_GET_PARTIAL_OBJECT takes 3 arguments |
1729 | + if (mRequest.getParameterCount() < 3) |
1730 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1731 | + |
1732 | // standard GetPartialObject |
1733 | length = mRequest.getParameter(3); |
1734 | } |
1735 | @@ -823,11 +884,11 @@ |
1736 | int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format); |
1737 | if (result != MTP_RESPONSE_OK) |
1738 | return result; |
1739 | - if (offset + length > fileLength) |
1740 | + if (offset + length > (uint64_t)fileLength) |
1741 | length = fileLength - offset; |
1742 | |
1743 | mtp_file_range mfr; |
1744 | - mfr.fd = open(pathBuf.c_str(), O_RDONLY); |
1745 | + mfr.fd = open(pathBuf.c_str(), O_RDONLY | O_LARGEFILE); |
1746 | if (mfr.fd < 0) { |
1747 | return MTP_RESPONSE_GENERAL_ERROR; |
1748 | } |
1749 | @@ -840,18 +901,24 @@ |
1750 | // transfer the file |
1751 | int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr); |
1752 | VLOG(2) << "MTP_SEND_FILE_WITH_HEADER returned " << ret; |
1753 | - close(mfr.fd); |
1754 | + result = MTP_RESPONSE_OK; |
1755 | if (ret < 0) { |
1756 | if (errno == ECANCELED) |
1757 | - return MTP_RESPONSE_TRANSACTION_CANCELLED; |
1758 | + result = MTP_RESPONSE_TRANSACTION_CANCELLED; |
1759 | else |
1760 | - return MTP_RESPONSE_GENERAL_ERROR; |
1761 | + result = MTP_RESPONSE_GENERAL_ERROR; |
1762 | } |
1763 | - return MTP_RESPONSE_OK; |
1764 | + close(mfr.fd); |
1765 | + return result; |
1766 | } |
1767 | |
1768 | MtpResponseCode MtpServer::doSendObjectInfo() { |
1769 | MtpString path; |
1770 | + uint16_t temp16; |
1771 | + uint32_t temp32; |
1772 | + |
1773 | + if (mRequest.getParameterCount() < 2) |
1774 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1775 | MtpStorageID storageID = mRequest.getParameter(1); |
1776 | MtpStorage* storage = getStorage(storageID); |
1777 | MtpObjectHandle parent = mRequest.getParameter(2); |
1778 | @@ -873,25 +940,29 @@ |
1779 | } |
1780 | |
1781 | // read only the fields we need |
1782 | - mData.getUInt32(); // storage ID |
1783 | - MtpObjectFormat format = mData.getUInt16(); |
1784 | - mData.getUInt16(); // protection status |
1785 | - mSendObjectFileSize = mData.getUInt32(); |
1786 | - mData.getUInt16(); // thumb format |
1787 | - mData.getUInt32(); // thumb compressed size |
1788 | - mData.getUInt32(); // thumb pix width |
1789 | - mData.getUInt32(); // thumb pix height |
1790 | - mData.getUInt32(); // image pix width |
1791 | - mData.getUInt32(); // image pix height |
1792 | - mData.getUInt32(); // image bit depth |
1793 | - mData.getUInt32(); // parent |
1794 | - uint16_t associationType = mData.getUInt16(); |
1795 | - uint32_t associationDesc = mData.getUInt32(); // association desc |
1796 | - mData.getUInt32(); // sequence number |
1797 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // storage ID |
1798 | + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; |
1799 | + MtpObjectFormat format = temp16; |
1800 | + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; // protection status |
1801 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; |
1802 | + mSendObjectFileSize = temp32; |
1803 | + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb format |
1804 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb compressed size |
1805 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb pix width |
1806 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb pix height |
1807 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // image pix width |
1808 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // image pix height |
1809 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // image bit depth |
1810 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // parent |
1811 | + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; |
1812 | + uint16_t associationType = temp16; |
1813 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; |
1814 | + uint32_t associationDesc = temp32; // association desc |
1815 | + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // sequence number |
1816 | MtpStringBuffer name, created, modified; |
1817 | - mData.getString(name); // file name |
1818 | - mData.getString(created); // date created |
1819 | - mData.getString(modified); // date modified |
1820 | + if (!mData.getString(name)) return MTP_RESPONSE_INVALID_PARAMETER; // file name |
1821 | + if (!mData.getString(created)) return MTP_RESPONSE_INVALID_PARAMETER; // date created |
1822 | + if (!mData.getString(modified)) return MTP_RESPONSE_INVALID_PARAMETER; // date modified |
1823 | // keywords follow |
1824 | |
1825 | VLOG(2) << "name: " << (const char *) name |
1826 | @@ -954,6 +1025,7 @@ |
1827 | MtpResponseCode result = MTP_RESPONSE_OK; |
1828 | mode_t mask; |
1829 | int ret, initialData; |
1830 | + bool isCanceled = false; |
1831 | |
1832 | if (mSendObjectHandle == kInvalidObjectHandle) { |
1833 | LOG(ERROR) << "Expected SendObjectInfo before SendObject"; |
1834 | @@ -970,7 +1042,9 @@ |
1835 | initialData = ret - MTP_CONTAINER_HEADER_SIZE; |
1836 | |
1837 | mtp_file_range mfr; |
1838 | - mfr.fd = open(mSendObjectFilePath.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
1839 | + mfr.fd = open(mSendObjectFilePath.c_str(), |
1840 | + O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, |
1841 | + S_IRUSR | S_IWUSR); |
1842 | if (mfr.fd < 0) { |
1843 | result = MTP_RESPONSE_GENERAL_ERROR; |
1844 | goto done; |
1845 | @@ -981,28 +1055,38 @@ |
1846 | fchmod(mfr.fd, mFilePermission); |
1847 | umask(mask); |
1848 | |
1849 | - if (initialData > 0) |
1850 | + if (initialData > 0) { |
1851 | ret = write(mfr.fd, mData.getData(), initialData); |
1852 | - |
1853 | - if (mSendObjectFileSize - initialData > 0) { |
1854 | - mfr.offset = initialData; |
1855 | - if (mSendObjectFileSize == 0xFFFFFFFF) { |
1856 | - // tell driver to read until it receives a short packet |
1857 | - mfr.length = 0xFFFFFFFF; |
1858 | - } else { |
1859 | - mfr.length = mSendObjectFileSize - initialData; |
1860 | + } |
1861 | + |
1862 | + if (ret < 0) { |
1863 | + LOG(ERROR) << "failed to write initial data"; |
1864 | + result = MTP_RESPONSE_GENERAL_ERROR; |
1865 | + } else { |
1866 | + if (mSendObjectFileSize - initialData > 0) { |
1867 | + mfr.offset = initialData; |
1868 | + if (mSendObjectFileSize == 0xFFFFFFFF) { |
1869 | + // tell driver to read until it receives a short packet |
1870 | + mfr.length = 0xFFFFFFFF; |
1871 | + } else { |
1872 | + mfr.length = mSendObjectFileSize - initialData; |
1873 | + } |
1874 | + |
1875 | + VLOG(2) << "receiving " << mSendObjectFilePath.c_str(); |
1876 | + // transfer the file |
1877 | + ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); |
1878 | + if ((ret < 0) && (errno == ECANCELED)) { |
1879 | + isCanceled = true; |
1880 | + } |
1881 | + |
1882 | + VLOG(2) << "MTP_RECEIVE_FILE returned " << ret; |
1883 | } |
1884 | - |
1885 | - VLOG(2) << "receiving " << mSendObjectFilePath.c_str(); |
1886 | - // transfer the file |
1887 | - ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); |
1888 | - VLOG(2) << "MTP_RECEIVE_FILE returned " << ret; |
1889 | } |
1890 | close(mfr.fd); |
1891 | |
1892 | if (ret < 0) { |
1893 | unlink(mSendObjectFilePath.c_str()); |
1894 | - if (errno == ECANCELED) |
1895 | + if (isCanceled) |
1896 | result = MTP_RESPONSE_TRANSACTION_CANCELLED; |
1897 | else |
1898 | result = MTP_RESPONSE_GENERAL_ERROR; |
1899 | @@ -1021,7 +1105,7 @@ |
1900 | |
1901 | static void deleteRecursive(const char* path) { |
1902 | char pathbuf[PATH_MAX]; |
1903 | - int pathLength = strlen(path); |
1904 | + size_t pathLength = strlen(path); |
1905 | if (pathLength >= sizeof(pathbuf) - 1) { |
1906 | LOG(ERROR) << "path too long: " << path; |
1907 | } |
1908 | @@ -1082,8 +1166,10 @@ |
1909 | MtpResponseCode MtpServer::doDeleteObject() { |
1910 | if (!hasStorage()) |
1911 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1912 | + if (mRequest.getParameterCount() < 1) |
1913 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1914 | MtpObjectHandle handle = mRequest.getParameter(1); |
1915 | - MtpObjectFormat format = mRequest.getParameter(2); |
1916 | + MtpObjectFormat format; |
1917 | // FIXME - support deleting all objects if handle is 0xFFFFFFFF |
1918 | // FIXME - implement deleting objects by format |
1919 | |
1920 | @@ -1127,6 +1213,8 @@ |
1921 | } |
1922 | |
1923 | MtpResponseCode MtpServer::doGetObjectPropDesc() { |
1924 | + if (mRequest.getParameterCount() < 2) |
1925 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1926 | MtpObjectProperty propCode = mRequest.getParameter(1); |
1927 | MtpObjectFormat format = mRequest.getParameter(2); |
1928 | VLOG(2) << "GetObjectPropDesc " << MtpDebug::getObjectPropCodeName(propCode) |
1929 | @@ -1140,6 +1228,8 @@ |
1930 | } |
1931 | |
1932 | MtpResponseCode MtpServer::doGetDevicePropDesc() { |
1933 | + if (mRequest.getParameterCount() < 1) |
1934 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1935 | MtpDeviceProperty propCode = mRequest.getParameter(1); |
1936 | VLOG(1) << "GetDevicePropDesc " << MtpDebug::getDevicePropCodeName(propCode); |
1937 | MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode); |
1938 | @@ -1153,6 +1243,8 @@ |
1939 | MtpResponseCode MtpServer::doSendPartialObject() { |
1940 | if (!hasStorage()) |
1941 | return MTP_RESPONSE_INVALID_OBJECT_HANDLE; |
1942 | + if (mRequest.getParameterCount() < 4) |
1943 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1944 | MtpObjectHandle handle = mRequest.getParameter(1); |
1945 | uint64_t offset = mRequest.getParameter(2); |
1946 | uint64_t offset2 = mRequest.getParameter(3); |
1947 | @@ -1188,19 +1280,27 @@ |
1948 | length -= initialData; |
1949 | } |
1950 | |
1951 | - if (length > 0) { |
1952 | - mtp_file_range mfr; |
1953 | - mfr.fd = edit->mFD; |
1954 | - mfr.offset = offset; |
1955 | - mfr.length = length; |
1956 | + bool isCanceled = false; |
1957 | + if (ret < 0) { |
1958 | + PLOG(ERROR) << "failed to write initial data"; |
1959 | + } else { |
1960 | + if (length > 0) { |
1961 | + mtp_file_range mfr; |
1962 | + mfr.fd = edit->mFD; |
1963 | + mfr.offset = offset; |
1964 | + mfr.length = length; |
1965 | |
1966 | - // transfer the file |
1967 | - ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); |
1968 | - VLOG(2) << "MTP_RECEIVE_FILE returned " << ret; |
1969 | + // transfer the file |
1970 | + ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); |
1971 | + if ((ret < 0) && (errno == ECANCELED)) { |
1972 | + isCanceled = true; |
1973 | + } |
1974 | + VLOG(2) << "MTP_RECEIVE_FILE returned " << ret << " errno " << errno; |
1975 | + } |
1976 | } |
1977 | if (ret < 0) { |
1978 | mResponse.setParameter(1, 0); |
1979 | - if (errno == ECANCELED) |
1980 | + if (isCanceled) |
1981 | return MTP_RESPONSE_TRANSACTION_CANCELLED; |
1982 | else |
1983 | return MTP_RESPONSE_GENERAL_ERROR; |
1984 | @@ -1217,6 +1317,8 @@ |
1985 | } |
1986 | |
1987 | MtpResponseCode MtpServer::doTruncateObject() { |
1988 | + if (mRequest.getParameterCount() < 3) |
1989 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1990 | MtpObjectHandle handle = mRequest.getParameter(1); |
1991 | ObjectEdit* edit = getEditObject(handle); |
1992 | if (!edit) { |
1993 | @@ -1236,6 +1338,8 @@ |
1994 | } |
1995 | |
1996 | MtpResponseCode MtpServer::doBeginEditObject() { |
1997 | + if (mRequest.getParameterCount() < 1) |
1998 | + return MTP_RESPONSE_INVALID_PARAMETER; |
1999 | MtpObjectHandle handle = mRequest.getParameter(1); |
2000 | if (getEditObject(handle)) { |
2001 | LOG(ERROR) << "object already open for edit in doBeginEditObject"; |
2002 | @@ -1249,7 +1353,7 @@ |
2003 | if (result != MTP_RESPONSE_OK) |
2004 | return result; |
2005 | |
2006 | - int fd = open(path.c_str(), O_RDWR | O_EXCL); |
2007 | + int fd = open(path.c_str(), O_RDWR | O_EXCL | O_LARGEFILE); |
2008 | if (fd < 0) { |
2009 | PLOG(ERROR) << "open failed for " << path.c_str() << " in doBeginEditObject"; |
2010 | return MTP_RESPONSE_GENERAL_ERROR; |
2011 | @@ -1260,6 +1364,8 @@ |
2012 | } |
2013 | |
2014 | MtpResponseCode MtpServer::doEndEditObject() { |
2015 | + if (mRequest.getParameterCount() < 1) |
2016 | + return MTP_RESPONSE_INVALID_PARAMETER; |
2017 | MtpObjectHandle handle = mRequest.getParameter(1); |
2018 | ObjectEdit* edit = getEditObject(handle); |
2019 | if (!edit) { |
2020 | |
2021 | === modified file 'src/MtpStorageInfo.cpp' |
2022 | --- src/MtpStorageInfo.cpp 2014-03-27 15:45:30 +0000 |
2023 | +++ src/MtpStorageInfo.cpp 2016-04-12 16:15:02 +0000 |
2024 | @@ -48,21 +48,23 @@ |
2025 | free(mVolumeIdentifier); |
2026 | } |
2027 | |
2028 | -void MtpStorageInfo::read(MtpDataPacket& packet) { |
2029 | +bool MtpStorageInfo::read(MtpDataPacket& packet) { |
2030 | MtpStringBuffer string; |
2031 | |
2032 | // read the device info |
2033 | - mStorageType = packet.getUInt16(); |
2034 | - mFileSystemType = packet.getUInt16(); |
2035 | - mAccessCapability = packet.getUInt16(); |
2036 | - mMaxCapacity = packet.getUInt64(); |
2037 | - mFreeSpaceBytes = packet.getUInt64(); |
2038 | - mFreeSpaceObjects = packet.getUInt32(); |
2039 | + if (!packet.getUInt16(mStorageType)) return false; |
2040 | + if (!packet.getUInt16(mFileSystemType)) return false; |
2041 | + if (!packet.getUInt16(mAccessCapability)) return false; |
2042 | + if (!packet.getUInt64(mMaxCapacity)) return false; |
2043 | + if (!packet.getUInt64(mFreeSpaceBytes)) return false; |
2044 | + if (!packet.getUInt32(mFreeSpaceObjects)) return false; |
2045 | |
2046 | - packet.getString(string); |
2047 | + if (!packet.getString(string)) return false; |
2048 | mStorageDescription = strdup((const char *)string); |
2049 | - packet.getString(string); |
2050 | + if (!packet.getString(string)) return false; |
2051 | mVolumeIdentifier = strdup((const char *)string); |
2052 | + |
2053 | + return true; |
2054 | } |
2055 | |
2056 | void MtpStorageInfo::print() { |
2057 | |
2058 | === modified file 'src/MtpStringBuffer.cpp' |
2059 | --- src/MtpStringBuffer.cpp 2013-06-13 10:22:21 +0000 |
2060 | +++ src/MtpStringBuffer.cpp 2016-04-12 16:15:02 +0000 |
2061 | @@ -56,42 +56,47 @@ |
2062 | } |
2063 | |
2064 | void MtpStringBuffer::set(const char* src) { |
2065 | - int length = strlen(src); |
2066 | - if (length >= sizeof(mBuffer)) |
2067 | - length = sizeof(mBuffer) - 1; |
2068 | - memcpy(mBuffer, src, length); |
2069 | - |
2070 | // count the characters |
2071 | int count = 0; |
2072 | char ch; |
2073 | - while ((ch = *src++) != 0) { |
2074 | + char* dest = (char*)mBuffer; |
2075 | + |
2076 | + while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) { |
2077 | if ((ch & 0x80) == 0) { |
2078 | // single byte character |
2079 | + *dest++ = ch; |
2080 | } else if ((ch & 0xE0) == 0xC0) { |
2081 | // two byte character |
2082 | - if (! *src++) { |
2083 | + char ch1 = *src++; |
2084 | + if (! ch1) { |
2085 | // last character was truncated, so ignore last byte |
2086 | - length--; |
2087 | break; |
2088 | } |
2089 | + |
2090 | + *dest++ = ch; |
2091 | + *dest++ = ch1; |
2092 | } else if ((ch & 0xF0) == 0xE0) { |
2093 | // 3 byte char |
2094 | - if (! *src++) { |
2095 | - // last character was truncated, so ignore last byte |
2096 | - length--; |
2097 | - break; |
2098 | - } |
2099 | - if (! *src++) { |
2100 | - // last character was truncated, so ignore last two bytes |
2101 | - length -= 2; |
2102 | - break; |
2103 | - } |
2104 | + char ch1 = *src++; |
2105 | + if (! ch1) { |
2106 | + // last character was truncated, so ignore last byte |
2107 | + break; |
2108 | + } |
2109 | + char ch2 = *src++; |
2110 | + if (! ch2) { |
2111 | + // last character was truncated, so ignore last byte |
2112 | + break; |
2113 | + } |
2114 | + |
2115 | + *dest++ = ch; |
2116 | + *dest++ = ch1; |
2117 | + *dest++ = ch2; |
2118 | } |
2119 | count++; |
2120 | } |
2121 | |
2122 | - mByteCount = length + 1; |
2123 | - mBuffer[length] = 0; |
2124 | + *dest++ = 0; |
2125 | + mByteCount = dest - (char*)mBuffer; |
2126 | mCharCount = count; |
2127 | } |
2128 | |
2129 | @@ -100,7 +105,7 @@ |
2130 | uint16_t ch; |
2131 | uint8_t* dest = mBuffer; |
2132 | |
2133 | - while ((ch = *src++) != 0 && count < 255) { |
2134 | + while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) { |
2135 | if (ch >= 0x0800) { |
2136 | *dest++ = (uint8_t)(0xE0 | (ch >> 12)); |
2137 | *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F)); |
2138 | @@ -118,11 +123,17 @@ |
2139 | mByteCount = dest - mBuffer; |
2140 | } |
2141 | |
2142 | -void MtpStringBuffer::readFromPacket(MtpDataPacket* packet) { |
2143 | - int count = packet->getUInt8(); |
2144 | +bool MtpStringBuffer::readFromPacket(MtpDataPacket* packet) { |
2145 | + uint8_t count; |
2146 | + if (!packet->getUInt8(count)) |
2147 | + return false; |
2148 | + |
2149 | uint8_t* dest = mBuffer; |
2150 | for (int i = 0; i < count; i++) { |
2151 | - uint16_t ch = packet->getUInt16(); |
2152 | + uint16_t ch; |
2153 | + |
2154 | + if (!packet->getUInt16(ch)) |
2155 | + return false; |
2156 | if (ch >= 0x0800) { |
2157 | *dest++ = (uint8_t)(0xE0 | (ch >> 12)); |
2158 | *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F)); |
2159 | @@ -137,6 +148,7 @@ |
2160 | *dest++ = 0; |
2161 | mCharCount = count; |
2162 | mByteCount = dest - mBuffer; |
2163 | + return true; |
2164 | } |
2165 | |
2166 | void MtpStringBuffer::writeToPacket(MtpDataPacket* packet) const { |
2167 | |
2168 | === modified file 'src/MtpUtils.cpp' |
2169 | --- src/MtpUtils.cpp 2013-09-10 15:54:14 +0000 |
2170 | +++ src/MtpUtils.cpp 2016-04-12 16:15:02 +0000 |
2171 | @@ -19,7 +19,6 @@ |
2172 | #include <stdio.h> |
2173 | #include <time.h> |
2174 | |
2175 | -// #include <cutils/tztime.h> |
2176 | #include "MtpUtils.h" |
2177 | |
2178 | namespace android { |
2179 | @@ -31,40 +30,40 @@ |
2180 | DD replaced by the day (01-31), T is a constant character 'T' delimiting time from date, |
2181 | hh is replaced by the hour (00-23), mm is replaced by the minute (00-59), and ss by the |
2182 | second (00-59). The ".s" is optional, and represents tenths of a second. |
2183 | +This is followed by a UTC offset given as "[+-]zzzz" or the literal "Z", meaning UTC. |
2184 | */ |
2185 | |
2186 | bool parseDateTime(const char* dateTime, time_t& outSeconds) { |
2187 | int year, month, day, hour, minute, second; |
2188 | - struct tm tm; |
2189 | - |
2190 | if (sscanf(dateTime, "%04d%02d%02dT%02d%02d%02d", |
2191 | - &year, &month, &day, &hour, &minute, &second) != 6) |
2192 | + &year, &month, &day, &hour, &minute, &second) != 6) |
2193 | return false; |
2194 | + |
2195 | + // skip optional tenth of second |
2196 | const char* tail = dateTime + 15; |
2197 | - // skip optional tenth of second |
2198 | - if (tail[0] == '.' && tail[1]) |
2199 | - tail += 2; |
2200 | - //FIXME - support +/-hhmm |
2201 | + if (tail[0] == '.' && tail[1]) tail += 2; |
2202 | + |
2203 | + // FIXME: "Z" means UTC, but non-"Z" doesn't mean local time. |
2204 | + // It might be that you're in Asia/Seoul on vacation and your Android |
2205 | + // device has noticed this via the network, but your camera was set to |
2206 | + // America/Los_Angeles once when you bought it and doesn't know where |
2207 | + // it is right now, so the camera says "20160106T081700-0800" but we |
2208 | + // just ignore the "-0800" and assume local time which is actually "+0900". |
2209 | + // I think to support this (without switching to Java or using icu4c) |
2210 | + // you'd want to always use timegm(3) and then manually add/subtract |
2211 | + // the UTC offset parsed from the string (taking care of wrapping). |
2212 | + // mktime(3) ignores the tm_gmtoff field, so you can't let it do the work. |
2213 | bool useUTC = (tail[0] == 'Z'); |
2214 | |
2215 | - // hack to compute timezone |
2216 | - time_t dummy; |
2217 | - tzset(); |
2218 | - localtime_r(&dummy, &tm); |
2219 | - |
2220 | + struct tm tm = {}; |
2221 | tm.tm_sec = second; |
2222 | tm.tm_min = minute; |
2223 | tm.tm_hour = hour; |
2224 | tm.tm_mday = day; |
2225 | tm.tm_mon = month - 1; // mktime uses months in 0 - 11 range |
2226 | tm.tm_year = year - 1900; |
2227 | - tm.tm_wday = 0; |
2228 | tm.tm_isdst = -1; |
2229 | - outSeconds = mktime(&tm); |
2230 | - /*if (useUTC) |
2231 | - outSeconds = mktime(&tm); |
2232 | - else |
2233 | - outSeconds = mktime_tz(&tm, tm.tm_zone);*/ |
2234 | + outSeconds = useUTC ? timegm(&tm) : mktime(&tm); |
2235 | |
2236 | return true; |
2237 | } |
2238 | @@ -74,7 +73,7 @@ |
2239 | |
2240 | localtime_r(&seconds, &tm); |
2241 | snprintf(buffer, bufferLength, "%04d%02d%02dT%02d%02d%02d", |
2242 | - tm.tm_year + 1900, |
2243 | + tm.tm_year + 1900, |
2244 | tm.tm_mon + 1, // localtime_r uses months in 0 - 11 range |
2245 | tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); |
2246 | } |
2247 | |
2248 | === modified file 'tests/TestMtpUtils.cpp' |
2249 | --- tests/TestMtpUtils.cpp 2013-09-13 14:21:51 +0000 |
2250 | +++ tests/TestMtpUtils.cpp 2016-04-12 16:15:02 +0000 |
2251 | @@ -40,7 +40,7 @@ |
2252 | { |
2253 | time_t seconds = 1378726903; |
2254 | char buffer[25]; |
2255 | - char *expected = "20130909T114143"; |
2256 | + const char *expected = "20130909T114143"; |
2257 | |
2258 | setenv("TZ", "UTC", 1); |
2259 |
Minor issues mostly related to type-safety