From 5531ff37fcd107198b72db396ac22b007cfcbc32 Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Sun, 12 Oct 2008 19:58:47 +0000 Subject: [PATCH] 2008-10-12 Marcus Meissner * library.c: Adjusted summary output a bit. * library.c: Handle "wrong parent" or "no root parent" devices every time, so when we autodetect new ones we do not need to add them to the list. Should avoid releasing libgphoto2 for new iPhones etc. * library.c: If a filename is empty or not set, replace it by the 8 char hexcode. (Should enable movie retrieval on Panasonics). git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@11378 67ed7778-7388-44ab-90cf-0a291f65f57c --- camlibs/ptp2/ChangeLog | 9 +++ camlibs/ptp2/library.c | 141 +++++++++++++++++++++++----------------- camlibs/ptp2/ptp-bugs.h | 3 - 3 files changed, 90 insertions(+), 63 deletions(-) diff --git a/camlibs/ptp2/ChangeLog b/camlibs/ptp2/ChangeLog index 9b58c1760..923d4e607 100644 --- a/camlibs/ptp2/ChangeLog +++ b/camlibs/ptp2/ChangeLog @@ -2,6 +2,15 @@ * library.c: Adjusted summary output a bit. + * library.c: Handle "wrong parent" or "no root parent" + devices every time, so when we autodetect new ones + we do not need to add them to the list. + Should avoid releasing libgphoto2 for new iPhones etc. + + * library.c: If a filename is empty or not set, replace it by + the 8 char hexcode. (Should enable movie retrieval on + Panasonics). + 2008-10-09 Marcus Meissner * ptp-pack.c: factored out ptp time string parser diff --git a/camlibs/ptp2/library.c b/camlibs/ptp2/library.c index 1c4b04462..1fc1a4f8f 100644 --- a/camlibs/ptp2/library.c +++ b/camlibs/ptp2/library.c @@ -331,7 +331,7 @@ static struct { /* Giulio Salani */ {"Kodak:C310", 0x040a, 0x058a, 0}, /* Brandon Sharitt */ - {"Kodak:C330", 0x040a, 0x058c, PTPBUG_DCIM_WRONG_PARENT}, + {"Kodak:C330", 0x040a, 0x058c, 0}, /* c340 Maurizio Daniele */ {"Kodak:C340", 0x040a, 0x058d, 0}, {"Kodak:V530", 0x040a, 0x058e, 0}, @@ -678,9 +678,9 @@ static struct { {"Canon:Elura 50 (PTP mode)", 0x04a9, 0x3087, PTPBUG_DELETE_SENDS_EVENT}, {"Canon:MVX3i (PTP mode)", 0x04a9, 0x308d, PTPBUG_DELETE_SENDS_EVENT}, /* 0x3084 is the EOS 300D/Digital Rebel in normal (canon) mode */ - {"Canon:EOS 300D (PTP mode)", 0x04a9, 0x3099, PTPBUG_DCIM_WRONG_PARENT}, - {"Canon:EOS Digital Rebel (PTP mode)", 0x04a9, 0x3099, PTPBUG_DCIM_WRONG_PARENT}, - {"Canon:EOS Kiss Digital (PTP mode)", 0x04a9, 0x3099, PTPBUG_DCIM_WRONG_PARENT}, + {"Canon:EOS 300D (PTP mode)", 0x04a9, 0x3099, 0}, + {"Canon:EOS Digital Rebel (PTP mode)", 0x04a9, 0x3099, 0}, + {"Canon:EOS Kiss Digital (PTP mode)", 0x04a9, 0x3099, 0}, {"Canon:PowerShot A80 (PTP)", 0x04a9, 0x309a, PTPBUG_DELETE_SENDS_EVENT|PTP_CAP|PTP_CAP_PREVIEW}, {"Canon:Digital IXUS i (PTP mode)", 0x04a9, 0x309b, PTPBUG_DELETE_SENDS_EVENT}, {"Canon:PowerShot S1 IS (PTP mode)", 0x04a9, 0x309c, PTPBUG_DELETE_SENDS_EVENT|PTP_CAP|PTP_CAP_PREVIEW}, @@ -706,16 +706,16 @@ static struct { {"Canon:Digital IXUS 30 (PTP mode)", 0x04a9, 0x30c0, PTPBUG_DELETE_SENDS_EVENT}, {"Canon:PowerShot A520 (PTP mode)", 0x04a9, 0x30c1, PTPBUG_DELETE_SENDS_EVENT|PTP_CAP|PTP_CAP_PREVIEW}, {"Canon:PowerShot A510 (PTP mode)", 0x04a9, 0x30c2, PTPBUG_DELETE_SENDS_EVENT}, - {"Canon:EOS 1D Mark II (PTP mode)", 0x04a9, 0x30ea, PTPBUG_DCIM_WRONG_PARENT}, - {"Canon:EOS 20D (PTP mode)", 0x04a9, 0x30ec, PTPBUG_DCIM_WRONG_PARENT}, + {"Canon:EOS 1D Mark II (PTP mode)", 0x04a9, 0x30ea, 0}, + {"Canon:EOS 20D (PTP mode)", 0x04a9, 0x30ec, 0}, /* 30ef is the ID in explicit PTP mode. * 30ee is the ID with the camera in Canon mode, but the camera reacts to * PTP commands according to: * https://sourceforge.net/tracker/?func=detail&atid=108874&aid=1394326&group_id=8874 * They need to have different names. */ - {"Canon:EOS 350D (PTP mode)", 0x04a9, 0x30ee, PTPBUG_DCIM_WRONG_PARENT}, - {"Canon:EOS 350D", 0x04a9, 0x30ef, PTPBUG_DCIM_WRONG_PARENT}, + {"Canon:EOS 350D (PTP mode)", 0x04a9, 0x30ee, 0}, + {"Canon:EOS 350D", 0x04a9, 0x30ef, 0}, {"Canon:PowerShot S2 IS (PTP mode)", 0x04a9, 0x30f0, PTPBUG_DELETE_SENDS_EVENT|PTP_CAP|PTP_CAP_PREVIEW}, {"Canon:PowerShot SD430 (PTP mode)", 0x04a9, 0x30f1, PTPBUG_DELETE_SENDS_EVENT|PTP_CAP|PTP_CAP_PREVIEW}, {"Canon:Digital IXUS Wireless (PTP mode)",0x04a9, 0x30f1, PTPBUG_DELETE_SENDS_EVENT|PTP_CAP|PTP_CAP_PREVIEW}, @@ -741,18 +741,18 @@ static struct { {"Canon:PowerShot SD450 (PTP mode)", 0x04a9, 0x30ff, 0}, {"Canon:Optura 600 (PTP mode)", 0x04a9, 0x3105, 0}, /* Jeff Mock */ - {"Canon:EOS 5D (PTP mode)", 0x04a9, 0x3102, PTPBUG_DCIM_WRONG_PARENT}, + {"Canon:EOS 5D (PTP mode)", 0x04a9, 0x3102, 0}, /* Nick Richards */ {"Canon:Digital IXUS 50 (PTP mode)", 0x04a9, 0x310e, PTPBUG_DELETE_SENDS_EVENT}, /* http://sourceforge.net/tracker/index.php?func=detail&aid=1640547&group_id=8874&atid=358874 */ {"Canon:PowerShot A420 (PTP mode)", 0x04a9, 0x310f, PTPBUG_DELETE_SENDS_EVENT}, /* Some Canon 400D do not have the infamous PTP bug, but some do. * see http://bugs.kde.org/show_bug.cgi?id=141577 -Marcus */ - {"Canon:EOS 400D (PTP mode)", 0x04a9, 0x3110, PTPBUG_DCIM_WRONG_PARENT|PTP_CAP}, + {"Canon:EOS 400D (PTP mode)", 0x04a9, 0x3110, PTP_CAP}, /* https://sourceforge.net/tracker/?func=detail&atid=358874&aid=1456391&group_id=8874 */ - {"Canon:EOS 30D (PTP mode)", 0x04a9, 0x3113, PTPBUG_DCIM_WRONG_PARENT}, - {"Canon:Digital IXUS 900Ti (PTP mode)", 0x04a9, 0x3115, PTPBUG_DCIM_WRONG_PARENT}, - {"Canon:PowerShot SD900 (PTP mode)", 0x04a9, 0x3115, PTPBUG_DCIM_WRONG_PARENT}, + {"Canon:EOS 30D (PTP mode)", 0x04a9, 0x3113, 0}, + {"Canon:Digital IXUS 900Ti (PTP mode)", 0x04a9, 0x3115, 0}, + {"Canon:PowerShot SD900 (PTP mode)", 0x04a9, 0x3115, 0}, {"Canon:Digital IXUS 750 (PTP mode)", 0x04a9, 0x3116, PTPBUG_DELETE_SENDS_EVENT}, {"Canon:PowerShot A700 (PTP mode)", 0x04a9, 0x3117, PTPBUG_DELETE_SENDS_EVENT}, /* http://sourceforge.net/tracker/index.php?func=detail&aid=1498577&group_id=8874&atid=358874 */ @@ -783,7 +783,7 @@ static struct { {"Canon:EOS 40D (PTP mode)", 0x04a9, 0x3146, PTP_CAP}, /* user had it working without problem */ /* reported by: gphoto@lunkwill.org */ - {"Canon:EOS 1D Mark III (PTP mode)", 0x04a9, 0x3147, PTPBUG_DCIM_WRONG_PARENT|PTP_CAP}, + {"Canon:EOS 1D Mark III (PTP mode)", 0x04a9, 0x3147, PTP_CAP}, {"Canon:PowerShot S5 IS (PTP mode)", 0x04a9, 0x3148, PTP_CAP|PTP_CAP_PREVIEW}, /* AlannY */ @@ -876,9 +876,9 @@ static struct { {"Sanyo:VPC-C5 (PTP mode)", 0x0474, 0x0230, 0}, /* from Mike Meyer */ - {"Apple:iPhone (PTP mode)", 0x05ac, 0x1290, PTPBUG_DCIM_WRONG_PARENT}, + {"Apple:iPhone (PTP mode)", 0x05ac, 0x1290, 0}, /* irc reporter */ - {"Apple:iPhone 3G (PTP mode)", 0x05ac, 0x1292, PTPBUG_DCIM_WRONG_PARENT}, + {"Apple:iPhone 3G (PTP mode)", 0x05ac, 0x1292, 0}, /* https://sourceforge.net/tracker/index.php?func=detail&aid=1869653&group_id=158745&atid=809061 */ {"Pioneer:DVR-LX60D", 0x08e4, 0x0142, 0}, }; @@ -3800,7 +3800,7 @@ storage_info_func (CameraFilesystem *fs, static int init_ptp_fs (Camera *camera, GPContext *context) { - int i,id,nroot; + int i, id, nroot = 0; PTPParams *params = &camera->pl->params; char buf[1024]; uint16_t ret; @@ -3880,6 +3880,7 @@ init_ptp_fs (Camera *camera, GPContext *context) roothandle = curhandle; params->handles.Handler[curhandle] = rootoid; params->objectinfo[curhandle].ParentObject = 0; + nroot = 1; } else { if (roothandle == -1) { /* We must synthesize /DCIM... */ roothandle = curhandle; @@ -4048,6 +4049,8 @@ init_ptp_fs (Camera *camera, GPContext *context) break; } oinfos[i].ParentObject = xpl->propval.u32; + if (xpl->propval.u32 == 0) + nroot++; gp_log (GP_LOG_DEBUG, "ptp2/mtpfast", "parent 0x%x", xpl->propval.u32); break; case PTP_OPC_ObjectFormat: @@ -4167,6 +4170,17 @@ fallback: GP_DEBUG (" SequenceNumber: 0x%08x", oi->SequenceNumber); } #endif + if (params->objectinfo[i].ParentObject == 0) + nroot++; + + if ( !params->objectinfo[i].Filename || + !strlen (params->objectinfo[i].Filename) + ) { + params->objectinfo[i].Filename = malloc(8+1); + sprintf (params->objectinfo[i].Filename, "%08x", params->handles.Handler[i]); + gp_log (GP_LOG_ERROR, "ptp2/std_getobjectinfo", "Replaced empty dirname by '%08x'", params->handles.Handler[i]); + } + gp_context_progress_update (context, id, 10+(90*i)/params->handles.n); } @@ -4212,52 +4226,56 @@ fallback: } } - if (DCIM_WRONG_PARENT_BUG(camera->pl)) - { - GP_DEBUG("PTPBUG_DCIM_WRONG_PARENT bug workaround"); - /* Count number of root directory objects */ - nroot = 0; - for (i = 0; i < params->handles.n; i++) - if (params->objectinfo[i].ParentObject == 0) - nroot++; + /* If there are no root directory objects, look for "DCIM" directories. + * This way, we can handle cameras that report the wrong ParentObject ID for + * root. + * + * FIXME: If DCIM is there, it will not look for other root directories. + */ + if (nroot == 0 && params->handles.n > 0) { + uint32_t badroothandle; - GP_DEBUG("Found %d root directory objects", nroot); + GP_DEBUG("Bug workaround: Found no root directory objects, looking for some."); + for (i = 0; i < params->handles.n; i++) { + PTPObjectInfo *oi = ¶ms->objectinfo[i]; - /* If no root directory objects, look for "DCIM". This way, we can - * handle cameras that report the wrong ParentObject ID for root - */ - if (nroot == 0 && params->handles.n > 0) { - for (i = 0; i < params->handles.n; i++) - { - PTPObjectInfo *oi = ¶ms->objectinfo[i]; - - if (strcmp(oi->Filename, "DCIM") == 0) - { - GP_DEBUG("Changing DCIM ParentObject ID from 0x%x to 0", - oi->ParentObject); - oi->ParentObject = 0; - nroot++; - } + if (strcmp(oi->Filename, "DCIM") == 0) { + GP_DEBUG("Changing DCIM ParentObject ID from 0x%x to 0", + oi->ParentObject); + badroothandle = oi->ParentObject; + oi->ParentObject = 0; + nroot++; + } } - } - /* Some cameras do not have a directory at all, just files or unattached - * directories. In this case associate all unattached to the 0 object. - */ - if (nroot == 0) { - /* look for entries with parentobjects that do not exist */ - for (i = 0; i < params->handles.n; i++) - { - int j; - PTPObjectInfo *oi = ¶ms->objectinfo[i]; - - for (j = 0;j < params->handles.n; j++) - if (oi->ParentObject == params->handles.Handler[j]) - break; - if (j == params->handles.n) - oi->ParentObject = 0; + for (i = 0; i < params->handles.n; i++) { + PTPObjectInfo *oi = ¶ms->objectinfo[i]; + if (oi->ParentObject == badroothandle) { + GP_DEBUG("Changing %s ParentObject ID from 0x%x to 0", + oi->Filename, oi->ParentObject); + oi->ParentObject = 0; + nroot++; + } } - } - } + /* Some cameras do not have a directory at all, just files or unattached + * directories. In this case associate all unattached to the 0 object. + * + * O(n^2) search. Be careful. + */ + if (nroot == 0) { + GP_DEBUG("Bug workaround: Found no root dir entries and no DCIM dir, looking for some."); + /* look for entries with parentobjects that do not exist */ + for (i = 0; i < params->handles.n; i++) { + int j; + PTPObjectInfo *oi = ¶ms->objectinfo[i]; + + for (j = 0;j < params->handles.n; j++) + if (oi->ParentObject == params->handles.Handler[j]) + break; + if (j == params->handles.n) + oi->ParentObject = 0; + } + } + } #if 0 add_dir (camera, 0x00000000, 0xff000000, "DIR1"); add_dir (camera, 0x00000000, 0xff000001, "DIR20"); @@ -4453,11 +4471,14 @@ camera_init (Camera *camera, GPContext *context) GP_DEBUG ("Device info:"); GP_DEBUG ("Manufacturer: %s",camera->pl->params.deviceinfo.Manufacturer); - GP_DEBUG (" model: %s", camera->pl->params.deviceinfo.Model); + GP_DEBUG (" Model: %s", camera->pl->params.deviceinfo.Model); GP_DEBUG (" device version: %s", camera->pl->params.deviceinfo.DeviceVersion); GP_DEBUG (" serial number: '%s'",camera->pl->params.deviceinfo.SerialNumber); GP_DEBUG ("Vendor extension ID: 0x%08x",camera->pl->params.deviceinfo.VendorExtensionID); + GP_DEBUG ("Vendor extension version: %d",camera->pl->params.deviceinfo.VendorExtensionVersion); GP_DEBUG ("Vendor extension description: %s",camera->pl->params.deviceinfo.VendorExtensionDesc); + GP_DEBUG ("Functional Mode: 0x%04x",camera->pl->params.deviceinfo.FunctionalMode); + GP_DEBUG ("PTP Standard Version: %d",camera->pl->params.deviceinfo.StandardVersion); GP_DEBUG ("Supported operations:"); for (i=0; ipl->params.deviceinfo.OperationsSupported_len; i++) GP_DEBUG (" 0x%04x", diff --git a/camlibs/ptp2/ptp-bugs.h b/camlibs/ptp2/ptp-bugs.h index 51cac9c30..df82817c2 100644 --- a/camlibs/ptp2/ptp-bugs.h +++ b/camlibs/ptp2/ptp-bugs.h @@ -23,7 +23,6 @@ #define __PTP_BUGS_H_ -#define PTPBUG_DCIM_WRONG_PARENT (1<<0) #define PTPBUG_DELETE_SENDS_EVENT (1<<1) #define PTPBUG_DUPE_FILE (1<<2) #define PTP_MTP (1<<3) @@ -33,8 +32,6 @@ #define PTP_NIKON_BROKEN_CAP (1<<7) #define PTP_MTP_ZEN_BROKEN_HEADER (1<<8) -#define DCIM_WRONG_PARENT_BUG(x) \ - ((x)->bugs & PTPBUG_DCIM_WRONG_PARENT) #define DELETE_SENDS_EVENT(x) \ ((x)->bugs & PTPBUG_DELETE_SENDS_EVENT) #define CAN_HAVE_DUPE_FILE(x) \