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