Index: patches/19_raw_read_directory.patch |
diff --git a/patches/19_raw_read_directory.patch b/patches/19_raw_read_directory.patch |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1d8e67451c676630c2eacb972e1285ee2aa1a312 |
--- /dev/null |
+++ b/patches/19_raw_read_directory.patch |
@@ -0,0 +1,125 @@ |
+diff --git src/libmtp.c src/libmtp.c |
+index b91f246..bbe2642 100644 |
+--- src/libmtp.c |
++++ src/libmtp.c |
+@@ -4415,6 +4415,78 @@ LIBMTP_file_t * LIBMTP_Get_Files_And_Folders(LIBMTP_mtpdevice_t *device, |
+ return retfiles; |
+ } |
+ |
++/** |
++ * This function retrieves the list of ids of files and folders in a certain |
++ * folder with id parent on a certain storage on a certain device. |
++ * The device used with this operations must have been opened with |
++ * LIBMTP_Open_Raw_Device_Uncached() or it will fail. |
++ * |
++ * NOTE: the request will always perform I/O with the device. |
++ * @param device a pointer to the MTP device to report info from. |
++ * @param storage a storage on the device to report info from. If |
++ * 0 is passed in, the files for the given parent will be |
++ * searched across all available storages. |
++ * @param parent the parent folder id. |
++ * @param out the pointer where the array of ids is returned. It is |
++ * set only when the returned value > 0. The caller takes the |
++ * ownership of the array and has to free() it. |
++ * @return the length of the returned array or -1 in case of failure. |
++ */ |
++ |
++int LIBMTP_Get_Children(LIBMTP_mtpdevice_t *device, |
++ uint32_t const storage, |
++ uint32_t const parent, |
++ uint32_t **out) |
++{ |
++ PTPParams *params = (PTPParams *) device->params; |
++ PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; |
++ LIBMTP_file_t *retfiles = NULL; |
++ LIBMTP_file_t *curfile = NULL; |
++ PTPObjectHandles currentHandles; |
++ uint32_t storageid; |
++ uint16_t ret; |
++ int i = 0; |
++ |
++ if (device->cached) { |
++ // This function is only supposed to be used by devices |
++ // opened as uncached! |
++ LIBMTP_ERROR("tried to use %s on a cached device!\n", __func__); |
++ return -1; |
++ } |
++ |
++ if (FLAG_BROKEN_GET_OBJECT_PROPVAL(ptp_usb)) { |
++ // These devices cannot handle the commands needed for |
++ // Uncached access! |
++ LIBMTP_ERROR("tried to use %s on an unsupported device, " |
++ "this command does not work on all devices " |
++ "due to missing low-level support to read " |
++ "information on individual tracks\n", |
++ __func__); |
++ return -1; |
++ } |
++ |
++ if (storage == 0) |
++ storageid = PTP_GOH_ALL_STORAGE; |
++ else |
++ storageid = storage; |
++ |
++ ret = ptp_getobjecthandles(params, |
++ storageid, |
++ PTP_GOH_ALL_FORMATS, |
++ parent, |
++ ¤tHandles); |
++ |
++ if (ret != PTP_RC_OK) { |
++ add_ptp_error_to_errorstack(device, ret, |
++ "LIBMTP_Get_Children(): could not get object handles."); |
++ return -1; |
++ } |
++ |
++ if (currentHandles.Handler == NULL || currentHandles.n == 0) |
++ return 0; |
++ *out = currentHandles.Handler; |
++ return currentHandles.n; |
++} |
+ |
+ /** |
+ * This creates a new track metadata structure and allocates memory |
+diff --git src/libmtp.h src/libmtp.h |
+index 33fac41..f923cc1 100644 |
+--- src/libmtp.h |
++++ src/libmtp.h |
+@@ -875,6 +875,10 @@ LIBMTP_file_t *LIBMTP_Get_Filelisting_With_Callback(LIBMTP_mtpdevice_t *, |
+ LIBMTP_file_t * LIBMTP_Get_Files_And_Folders(LIBMTP_mtpdevice_t *, |
+ uint32_t const, |
+ uint32_t const); |
++int LIBMTP_Get_Children(LIBMTP_mtpdevice_t *, |
++ uint32_t const, |
++ uint32_t const, |
++ uint32_t **); |
+ LIBMTP_file_t *LIBMTP_Get_Filemetadata(LIBMTP_mtpdevice_t *, uint32_t const); |
+ int LIBMTP_Get_File_Chunk(LIBMTP_mtpdevice_t*, uint32_t, uint32_t, uint32_t, |
+ unsigned char**, uint32_t*); |
+diff --git src/libmtp.h.in src/libmtp.h.in |
+index b49d449..2b2f0bb 100644 |
+--- src/libmtp.h.in |
++++ src/libmtp.h.in |
+@@ -875,6 +875,10 @@ LIBMTP_file_t *LIBMTP_Get_Filelisting_With_Callback(LIBMTP_mtpdevice_t *, |
+ LIBMTP_file_t * LIBMTP_Get_Files_And_Folders(LIBMTP_mtpdevice_t *, |
+ uint32_t const, |
+ uint32_t const); |
++int LIBMTP_Get_Children(LIBMTP_mtpdevice_t *, |
++ uint32_t const, |
++ uint32_t const, |
++ uint32_t**); |
+ LIBMTP_file_t *LIBMTP_Get_Filemetadata(LIBMTP_mtpdevice_t *, uint32_t const); |
+ int LIBMTP_Get_File_Chunk(LIBMTP_mtpdevice_t*, uint32_t, uint32_t, uint32_t, |
+ unsigned char**, uint32_t*); |
+diff --git src/libmtp.sym src/libmtp.sym |
+index b6951b2..4130fe8 100644 |
+--- src/libmtp.sym |
++++ src/libmtp.sym |
+@@ -48,6 +48,7 @@ LIBMTP_Get_Filetype_Description |
+ LIBMTP_Get_Filelisting |
+ LIBMTP_Get_Filelisting_With_Callback |
+ LIBMTP_Get_Files_And_Folders |
++LIBMTP_Get_Children |
+ LIBMTP_Get_Filemetadata |
+ LIBMTP_Get_File_Chunk |
+ LIBMTP_Get_File_To_File |