31# define UINT_MAX 0xFFFFFFFF 
   33#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 
   40        return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var));
 
   46        return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var));
 
   50htod16ap (
PTPParams *params, 
unsigned char *a, uint16_t val)
 
   52        if (params->byteorder==PTP_DL_LE)
 
   59htod32ap (
PTPParams *params, 
unsigned char *a, uint32_t val)
 
   61        if (params->byteorder==PTP_DL_LE)
 
   68htod64ap (
PTPParams *params, 
unsigned char *a, uint64_t val)
 
   70        if (params->byteorder==PTP_DL_LE)
 
   79        return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var));
 
   85        return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var));
 
   91        return ((params->byteorder==PTP_DL_LE)?le64toh(var):be64toh(var));
 
   95dtoh16ap (
PTPParams *params, 
const unsigned char *a)
 
   97        return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a));
 
  100static inline uint32_t
 
  101dtoh32ap (
PTPParams *params, 
const unsigned char *a)
 
  103        return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a));
 
  106static inline uint64_t
 
  107dtoh64ap (
PTPParams *params, 
const unsigned char *a)
 
  109        return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a));
 
  112#define htod8a(a,x)     *(uint8_t*)(a) = x 
  113#define htod16a(a,x)    htod16ap(params,a,x) 
  114#define htod32a(a,x)    htod32ap(params,a,x) 
  115#define htod64a(a,x)    htod64ap(params,a,x) 
  116#define htod16(x)       htod16p(params,x) 
  117#define htod32(x)       htod32p(params,x) 
  118#define htod64(x)       htod64p(params,x) 
  120#define dtoh8a(x)       (*(uint8_t*)(x)) 
  121#define dtoh16a(a)      dtoh16ap(params,a) 
  122#define dtoh32a(a)      dtoh32ap(params,a) 
  123#define dtoh64a(a)      dtoh64ap(params,a) 
  124#define dtoh16(x)       dtoh16p(params,x) 
  125#define dtoh32(x)       dtoh32p(params,x) 
  126#define dtoh64(x)       dtoh64p(params,x) 
  138ptp_unpack_string(
PTPParams *params, 
unsigned char* data, uint32_t offset, uint32_t total, uint8_t *len, 
char **retstr)
 
  141        uint16_t 
string[PTP_MAXSTRLEN+1];
 
  143        char loclstr[PTP_MAXSTRLEN*3+1];
 
  144        size_t nconv, srclen, destlen;
 
  150        if (offset + 1 > total)
 
  153        length = dtoh8a(&data[offset]); 
 
  156                *retstr = strdup(
"");   
 
  160        if (offset + 1 + length*
sizeof(
string[0]) > total)
 
  166        memcpy(
string, &data[offset+1], length * 
sizeof(
string[0]));
 
  167        string[length] = 0x0000U;   
 
  171        src = (
char *)
string;
 
  172        srclen = length * 
sizeof(
string[0]);
 
  174        destlen = 
sizeof(loclstr)-1;
 
  176#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 
  177        if (params->cd_ucs2_to_locale != (iconv_t)-1)
 
  178                nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, &dest, &destlen);
 
  180        if (nconv == (
size_t) -1) { 
 
  183                for (i=0;i<length;i++) {
 
  184                        if (dtoh16a(&data[offset+1+2*i])>127)
 
  187                                loclstr[i] = dtoh16a(&data[offset+1+2*i]);
 
  189                dest = loclstr+length;
 
  192        loclstr[
sizeof(loclstr)-1] = 
'\0';   
 
  193        *retstr = strdup(loclstr);
 
  198ucs2strlen(uint16_t 
const * 
const unicstr)
 
  203        for(length = 0; unicstr[length] != 0x0000U; length ++);
 
  209ptp_pack_string(
PTPParams *params, 
char *
string, 
unsigned char* data, uint16_t offset, uint8_t *len)
 
  212        uint16_t ucs2str[PTP_MAXSTRLEN+1];
 
  213        char *ucs2strp = (
char *) ucs2str;
 
  214        size_t convlen = strlen(
string);
 
  216        if (convlen > PTP_MAXSTRLEN) {
 
  217                convlen = PTP_MAXSTRLEN;
 
  220        memset(ucs2strp, 0, 
sizeof(ucs2str));  
 
  221#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 
  222        if (params->cd_locale_to_ucs2 != (iconv_t)-1) {
 
  224                size_t convmax = PTP_MAXSTRLEN * 2; 
 
  225                char *stringp = string;
 
  227                nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen,
 
  228                        &ucs2strp, &convmax);
 
  229                if (nconv == (
size_t) -1)
 
  230                        ucs2str[0] = 0x0000U;
 
  235                if (convlen > PTP_MAXSTRLEN) {
 
  236                        convlen = PTP_MAXSTRLEN;
 
  238                for (i=0;i<convlen;i++) {
 
  239                        ucs2str[i] = 
string[i];
 
  241                ucs2str[convlen] = 0;
 
  247        packedlen = ucs2strlen(ucs2str);
 
  248        if (packedlen > PTP_MAXSTRLEN-1) {
 
  254        htod8a(&data[offset],packedlen+1);
 
  255        memcpy(&data[offset+1], &ucs2str[0], packedlen * 
sizeof(ucs2str[0]));
 
  256        htod16a(&data[offset+packedlen*2+1], 0x0000);  
 
  259        *len = (uint8_t) packedlen+1;
 
  262static inline unsigned char *
 
  263ptp_get_packed_stringcopy(
PTPParams *params, 
char *
string, uint32_t *packed_size)
 
  265        uint8_t packed[PTP_MAXSTRLEN*2+3], len;
 
  267        unsigned char *retcopy = NULL;
 
  270          ptp_pack_string(params, 
"", (
unsigned char*) packed, 0, &len);
 
  272          ptp_pack_string(params, 
string, (
unsigned char*) packed, 0, &len);
 
  277        retcopy = malloc(plen);
 
  282        memcpy(retcopy, packed, plen);
 
  287static inline uint32_t
 
  288ptp_unpack_uint32_t_array(
PTPParams *params, 
unsigned char* data, 
unsigned int offset, 
unsigned int datalen, uint32_t **array)
 
  295        if (offset >= datalen)
 
  298        if (offset + 
sizeof(uint32_t) > datalen)
 
  302        n=dtoh32a(&data[offset]);
 
  303        if (n >= UINT_MAX/
sizeof(uint32_t))
 
  308        if (offset + 
sizeof(uint32_t)*(n+1) > datalen) {
 
  309                ptp_debug (params ,
"array runs over datalen bufferend (%d vs %d)", offset + 
sizeof(uint32_t)*(n+1) , datalen);
 
  313        *array = malloc (n*
sizeof(uint32_t));
 
  317                (*array)[i]=dtoh32a(&data[offset+(
sizeof(uint32_t)*(i+1))]);
 
  321static inline uint32_t
 
  322ptp_pack_uint32_t_array(
PTPParams *params, uint32_t *array, uint32_t arraylen, 
unsigned char **data )
 
  326        *data = malloc ((arraylen+1)*
sizeof(uint32_t));
 
  329        htod32a(&(*data)[0],arraylen);
 
  330        for (i=0;i<arraylen;i++)
 
  331                htod32a(&(*data)[
sizeof(uint32_t)*(i+1)], array[i]);
 
  332        return (arraylen+1)*
sizeof(uint32_t);
 
  335static inline uint32_t
 
  336ptp_unpack_uint16_t_array(
PTPParams *params, 
unsigned char* data, 
unsigned int offset, 
unsigned int datalen, uint16_t **array)
 
  344        if (datalen - offset < 
sizeof(uint32_t))
 
  346        n=dtoh32a(&data[offset]);
 
  348        if (n >= (UINT_MAX - offset - 
sizeof(uint32_t))/
sizeof(uint16_t))
 
  352        if (offset + 
sizeof(uint32_t) > datalen)
 
  354        if (offset + 
sizeof(uint32_t)+
sizeof(uint16_t)*n > datalen) {
 
  355                ptp_debug (params ,
"array runs over datalen bufferend (%d vs %d)", offset + 
sizeof(uint32_t)+n*
sizeof(uint16_t) , datalen);
 
  358        *array = malloc (n*
sizeof(uint16_t));
 
  362                (*array)[i]=dtoh16a(&data[offset+(
sizeof(uint16_t)*(i+2))]);
 
  368#define PTP_di_StandardVersion           0 
  369#define PTP_di_VendorExtensionID         2 
  370#define PTP_di_VendorExtensionVersion    6 
  371#define PTP_di_VendorExtensionDesc       8 
  372#define PTP_di_FunctionalMode            8 
  373#define PTP_di_OperationsSupported      10 
  379        unsigned int totallen;
 
  382        if (datalen < 12) 
return 0;
 
  383        memset (di, 0, 
sizeof(*di));
 
  384        di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]);
 
  385        di->VendorExtensionID =
 
  386                dtoh32a(&data[PTP_di_VendorExtensionID]);
 
  387        di->VendorExtensionVersion =
 
  388                dtoh16a(&data[PTP_di_VendorExtensionVersion]);
 
  389        if (!ptp_unpack_string(params, data,
 
  390                PTP_di_VendorExtensionDesc,
 
  393                &di->VendorExtensionDesc)
 
  397        if (datalen <= totallen + PTP_di_FunctionalMode + 
sizeof(uint16_t)) {
 
  398                ptp_debug (params, 
"datalen %d <= totallen + PTP_di_FunctionalMode + sizeof(uint16_t) %d", datalen, totallen + PTP_di_FunctionalMode + 
sizeof(uint16_t));
 
  402                dtoh16a(&data[PTP_di_FunctionalMode+totallen]);
 
  403        di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data,
 
  404                PTP_di_OperationsSupported+totallen,
 
  406                &di->OperationsSupported);
 
  407        totallen=totallen+di->OperationsSupported_len*
sizeof(uint16_t)+
sizeof(uint32_t);
 
  408        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  409                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 1", datalen, totallen+PTP_di_OperationsSupported);
 
  412        di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data,
 
  413                PTP_di_OperationsSupported+totallen,
 
  415                &di->EventsSupported);
 
  416        totallen=totallen+di->EventsSupported_len*
sizeof(uint16_t)+
sizeof(uint32_t);
 
  417        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  418                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 2", datalen, totallen+PTP_di_OperationsSupported);
 
  421        di->DevicePropertiesSupported_len =
 
  422                ptp_unpack_uint16_t_array(params, data,
 
  423                PTP_di_OperationsSupported+totallen,
 
  425                &di->DevicePropertiesSupported);
 
  426        totallen=totallen+di->DevicePropertiesSupported_len*
sizeof(uint16_t)+
sizeof(uint32_t);
 
  427        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  428                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 3", datalen, totallen+PTP_di_OperationsSupported);
 
  431        di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data,
 
  432                PTP_di_OperationsSupported+totallen,
 
  434                &di->CaptureFormats);
 
  435        totallen=totallen+di->CaptureFormats_len*
sizeof(uint16_t)+
sizeof(uint32_t);
 
  436        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  437                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 4", datalen, totallen+PTP_di_OperationsSupported);
 
  440        di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data,
 
  441                PTP_di_OperationsSupported+totallen,
 
  444        totallen=totallen+di->ImageFormats_len*
sizeof(uint16_t)+
sizeof(uint32_t);
 
  445        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  446                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 5", datalen, totallen+PTP_di_OperationsSupported);
 
  449        if (!ptp_unpack_string(params, data,
 
  450                PTP_di_OperationsSupported+totallen,
 
  458        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  459                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 6", datalen, totallen+PTP_di_OperationsSupported);
 
  462        if (!ptp_unpack_string(params, data,
 
  463                PTP_di_OperationsSupported+totallen,
 
  471        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  472                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 7", datalen, totallen+PTP_di_OperationsSupported);
 
  475        if (!ptp_unpack_string(params, data,
 
  476                PTP_di_OperationsSupported+totallen,
 
  484        if (datalen <= totallen+PTP_di_OperationsSupported) {
 
  485                ptp_debug (params, 
"datalen %d <= totallen+PTP_di_OperationsSupported %d 8", datalen, totallen+PTP_di_OperationsSupported);
 
  488        if (!ptp_unpack_string(params, data,
 
  489                PTP_di_OperationsSupported+totallen,
 
  500        free (di->SerialNumber);
 
  501        free (di->DeviceVersion);
 
  503        free (di->Manufacturer);
 
  504        free (di->ImageFormats);
 
  505        free (di->CaptureFormats);
 
  506        free (di->VendorExtensionDesc);
 
  507        free (di->OperationsSupported);
 
  508        free (di->EventsSupported);
 
  509        free (di->DevicePropertiesSupported);
 
  510        memset(di, 0, 
sizeof(*di));
 
  517        unsigned int totallen = 4;
 
  519        memset (di,0, 
sizeof(*di));
 
  520        if (datalen < 8) 
return 0;
 
  523        di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data,
 
  524                totallen, datalen, &di->EventsSupported);
 
  525        if (!di->EventsSupported) 
return 0;
 
  526        totallen += di->EventsSupported_len*
sizeof(uint32_t)+4;
 
  527        if (totallen >= datalen) 
return 0;
 
  529        di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data,
 
  530                totallen, datalen, &di->DevicePropertiesSupported);
 
  531        if (!di->DevicePropertiesSupported) 
return 0;
 
  532        totallen += di->DevicePropertiesSupported_len*
sizeof(uint32_t)+4;
 
  533        if (totallen >= datalen) 
return 0;
 
  535        di->unk_len = ptp_unpack_uint32_t_array(params, data,
 
  536                totallen, datalen, &di->unk);
 
  537        if (!di->unk) 
return 0;
 
  538        totallen += di->unk_len*
sizeof(uint32_t)+4;
 
  545        free (di->EventsSupported);
 
  546        free (di->DevicePropertiesSupported);
 
  558                oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, len, &oh->Handler);
 
  573        sids->Storage = NULL;
 
  578        sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, len, &sids->Storage);
 
  583#define PTP_si_StorageType               0 
  584#define PTP_si_FilesystemType            2 
  585#define PTP_si_AccessCapability          4 
  586#define PTP_si_MaxCapability             6 
  587#define PTP_si_FreeSpaceInBytes         14 
  588#define PTP_si_FreeSpaceInImages        22 
  589#define PTP_si_StorageDescription       26 
  594        uint8_t storagedescriptionlen;
 
  596        if (len < 26) 
return 0;
 
  597        si->StorageType=dtoh16a(&data[PTP_si_StorageType]);
 
  598        si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]);
 
  599        si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]);
 
  600        si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]);
 
  601        si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]);
 
  602        si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]);
 
  605        if (!ptp_unpack_string(params, data,
 
  606                PTP_si_StorageDescription,
 
  608                &storagedescriptionlen,
 
  609                &si->StorageDescription)
 
  613        if (!ptp_unpack_string(params, data,
 
  614                PTP_si_StorageDescription+storagedescriptionlen*2+1,
 
  616                &storagedescriptionlen,
 
  618                ptp_debug(params, 
"could not unpack storage description");
 
  626#define PTP_oi_StorageID                 0 
  627#define PTP_oi_ObjectFormat              4 
  628#define PTP_oi_ProtectionStatus          6 
  629#define PTP_oi_ObjectCompressedSize      8 
  630#define PTP_oi_ThumbFormat              12 
  631#define PTP_oi_ThumbCompressedSize      14 
  632#define PTP_oi_ThumbPixWidth            18 
  633#define PTP_oi_ThumbPixHeight           22 
  634#define PTP_oi_ImagePixWidth            26 
  635#define PTP_oi_ImagePixHeight           30 
  636#define PTP_oi_ImageBitDepth            34 
  637#define PTP_oi_ParentObject             38 
  638#define PTP_oi_AssociationType          42 
  639#define PTP_oi_AssociationDesc          44 
  640#define PTP_oi_SequenceNumber           48 
  641#define PTP_oi_filenamelen              52 
  642#define PTP_oi_Filename                 53 
  646#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 
  648static inline uint32_t
 
  651        unsigned char* oidata;
 
  653        uint8_t capturedatelen=0;
 
  655        oidata=malloc(PTP_oi_MaxLen + params->ocs64*4);
 
  659        char *capture_date=
"20020101T010101"; 
 
  661        memset (oidata, 0, PTP_oi_MaxLen + params->ocs64*4);
 
  662        htod32a(&oidata[PTP_oi_StorageID],oi->StorageID);
 
  663        htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat);
 
  664        htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus);
 
  665        htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize);
 
  668        htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat);
 
  669        htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize);
 
  670        htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth);
 
  671        htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight);
 
  672        htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth);
 
  673        htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight);
 
  674        htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth);
 
  675        htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject);
 
  676        htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType);
 
  677        htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc);
 
  678        htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber);
 
  680        ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen);
 
  694        capturedatelen=strlen(capture_date);
 
  695        htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2],
 
  697        for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) {
 
  698                data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i];
 
  700        htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1],
 
  702        for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) {
 
  703                data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]=
 
  708        return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3)+params->ocs64*4;
 
  712ptp_unpack_PTPTIME (
const char *str) {
 
  720        ptpdatelen = strlen(str);
 
  721        if (ptpdatelen >= 
sizeof (ptpdate)) {
 
  729        strncpy (ptpdate, str, 
sizeof(ptpdate));
 
  730        ptpdate[
sizeof(ptpdate) - 1] = 
'\0';
 
  732        memset(&tm,0,
sizeof(tm));
 
  733        strncpy (tmp, ptpdate, 4);
 
  735        tm.tm_year=atoi (tmp) - 1900;
 
  736        strncpy (tmp, ptpdate + 4, 2);
 
  738        tm.tm_mon = atoi (tmp) - 1;
 
  739        strncpy (tmp, ptpdate + 6, 2);
 
  741        tm.tm_mday = atoi (tmp);
 
  742        strncpy (tmp, ptpdate + 9, 2);
 
  744        tm.tm_hour = atoi (tmp);
 
  745        strncpy (tmp, ptpdate + 11, 2);
 
  747        tm.tm_min = atoi (tmp);
 
  748        strncpy (tmp, ptpdate + 13, 2);
 
  750        tm.tm_sec = atoi (tmp);
 
  759        uint8_t capturedatelen;
 
  762        if (len < PTP_oi_SequenceNumber)
 
  765        oi->Filename = oi->Keywords = NULL;
 
  768        oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]);
 
  769        oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]);
 
  770        oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]);
 
  771        oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]);
 
  774        if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) {
 
  775                ptp_debug (params, 
"objectsize 64bit detected!");
 
  780        oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]);
 
  781        oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]);
 
  782        oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]);
 
  783        oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]);
 
  784        oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]);
 
  785        oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]);
 
  786        oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]);
 
  787        oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]);
 
  788        oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]);
 
  789        oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]);
 
  790        oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]);
 
  792        ptp_unpack_string(params, data, PTP_oi_filenamelen, len, &filenamelen, &oi->Filename);
 
  793        ptp_unpack_string(params, data, PTP_oi_filenamelen+filenamelen*2+1, len, &capturedatelen, &capture_date);
 
  797        oi->CaptureDate = ptp_unpack_PTPTIME(capture_date);
 
  801        ptp_unpack_string(params, data,
 
  802                PTP_oi_filenamelen+filenamelen*2
 
  803                +capturedatelen*2+2, len, &capturedatelen, &capture_date
 
  805        oi->ModificationDate = ptp_unpack_PTPTIME(capture_date);
 
  810#define CTVAL(target,func) {                    \ 
  811        if (total - *offset < sizeof(target))   \ 
  813        target = func(&data[*offset]);          \ 
  814        *offset += sizeof(target);              \ 
  817#define RARR(val,member,func)   {                       \ 
  819        if (total - *offset < sizeof(uint32_t))         \ 
  821        n = dtoh32a (&data[*offset]);                   \ 
  822        *offset += sizeof(uint32_t);                    \ 
  824        if (n >= UINT_MAX/sizeof(val->a.v[0]))          \ 
  826        if (n > (total - (*offset))/sizeof(val->a.v[0].member))\ 
  829        val->a.v = malloc(sizeof(val->a.v[0])*n);       \ 
  830        if (!val->a.v) return 0;                        \ 
  832                CTVAL(val->a.v[j].member, func);        \ 
  835static inline unsigned int 
  837        PTPParams *params, 
unsigned char* data, 
unsigned int *offset, 
unsigned int total,
 
  840        if (*offset >= total)   
 
  845                CTVAL(value->i8,dtoh8a);
 
  848                CTVAL(value->u8,dtoh8a);
 
  851                CTVAL(value->i16,dtoh16a);
 
  854                CTVAL(value->u16,dtoh16a);
 
  857                CTVAL(value->i32,dtoh32a);
 
  860                CTVAL(value->u32,dtoh32a);
 
  863                CTVAL(value->i64,dtoh64a);
 
  866                CTVAL(value->u64,dtoh64a);
 
  869        case PTP_DTC_UINT128:
 
  881                RARR(value,i8,dtoh8a);
 
  884                RARR(value,u8,dtoh8a);
 
  886        case PTP_DTC_AUINT16:
 
  887                RARR(value,u16,dtoh16a);
 
  890                RARR(value,i16,dtoh16a);
 
  892        case PTP_DTC_AUINT32:
 
  893                RARR(value,u32,dtoh32a);
 
  896                RARR(value,i32,dtoh32a);
 
  898        case PTP_DTC_AUINT64:
 
  899                RARR(value,u64,dtoh64a);
 
  902                RARR(value,i64,dtoh64a);
 
  910                if (*offset >= total+1)
 
  913                if (!ptp_unpack_string(params,data,*offset,total,&len,&value->str))
 
  925#define PTP_dpd_DevicePropertyCode      0 
  926#define PTP_dpd_DataType                2 
  927#define PTP_dpd_GetSet                  4 
  928#define PTP_dpd_FactoryDefaultValue     5 
  933        unsigned int offset = 0, ret;
 
  937        memset (dpd, 0, 
sizeof(*dpd));
 
  940        dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]);
 
  941        dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]);
 
  942        dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]);
 
  943        dpd->FormFlag=PTP_DPFF_None;
 
  945        offset = PTP_dpd_FactoryDefaultValue;
 
  946        ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType);
 
  947        if (!ret) 
goto outofmemory;
 
  948        if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) {
 
  952        ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType);
 
  953        if (!ret) 
goto outofmemory;
 
  960        if (offset + 
sizeof(uint8_t) > dpdlen) {
 
  965        dpd->FormFlag=dtoh8a(&data[offset]);
 
  966        offset+=
sizeof(uint8_t);
 
  968        switch (dpd->FormFlag) {
 
  970                ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType);
 
  971                if (!ret) 
goto outofmemory;
 
  972                ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType);
 
  973                if (!ret) 
goto outofmemory;
 
  974                ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType);
 
  975                if (!ret) 
goto outofmemory;
 
  977        case PTP_DPFF_Enumeration: {
 
  979#define N       dpd->FORM.Enum.NumberOfValues 
  981                if (offset + 
sizeof(uint16_t) > dpdlen) 
goto outofmemory;
 
  983                N = dtoh16a(&data[offset]);
 
  984                offset+=
sizeof(uint16_t);
 
  985                dpd->FORM.Enum.SupportedValue = malloc(N*
sizeof(dpd->FORM.Enum.SupportedValue[0]));
 
  986                if (!dpd->FORM.Enum.SupportedValue)
 
  989                memset (dpd->FORM.Enum.SupportedValue,0 , N*
sizeof(dpd->FORM.Enum.SupportedValue[0]));
 
  991                        ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType);
 
 1001                                dpd->FORM.Enum.NumberOfValues = i;
 
 1008        *newoffset = offset;
 
 1011        ptp_free_devicepropdesc(dpd);
 
 1016#define PTP_dpd_Sony_DevicePropertyCode         0 
 1017#define PTP_dpd_Sony_DataType                   2 
 1018#define PTP_dpd_Sony_ChangeMethod               4 
 1019#define PTP_dpd_Sony_GetSet                     5 
 1020#define PTP_dpd_Sony_FactoryDefaultValue        6 
 1023ptp_unpack_Sony_DPD (
PTPParams *params, 
unsigned char* data, 
PTPDevicePropDesc *dpd, 
unsigned int dpdlen, 
unsigned int *poffset)
 
 1026        unsigned int changemethod, getset;
 
 1028        memset (dpd, 0, 
sizeof(*dpd));
 
 1029        dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_Sony_DevicePropertyCode]);
 
 1030        dpd->DataType=dtoh16a(&data[PTP_dpd_Sony_DataType]);
 
 1032        changemethod = dtoh8a(&data[PTP_dpd_Sony_ChangeMethod]);
 
 1033        getset = dtoh8a(&data[PTP_dpd_Sony_GetSet]);
 
 1035        ptp_debug (params, 
"prop 0x%04x, datatype 0x%04x, changemethod %d getset %d", dpd->DevicePropertyCode, dpd->DataType, changemethod, getset);
 
 1048        dpd->FormFlag=PTP_DPFF_None;
 
 1050        *poffset = PTP_dpd_Sony_FactoryDefaultValue;
 
 1051        ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType);
 
 1052        if (!ret) 
goto outofmemory;
 
 1053        if ((dpd->DataType == PTP_DTC_STR) && (*poffset == dpdlen))
 
 1055        ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->CurrentValue, dpd->DataType);
 
 1056        if (!ret) 
goto outofmemory;
 
 1063        if (*poffset==PTP_dpd_Sony_FactoryDefaultValue)
 
 1066        dpd->FormFlag=dtoh8a(&data[*poffset]);
 
 1067        *poffset+=
sizeof(uint8_t);
 
 1069        switch (dpd->FormFlag) {
 
 1070        case PTP_DPFF_Range:
 
 1071                ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType);
 
 1072                if (!ret) 
goto outofmemory;
 
 1073                ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType);
 
 1074                if (!ret) 
goto outofmemory;
 
 1075                ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType);
 
 1076                if (!ret) 
goto outofmemory;
 
 1078        case PTP_DPFF_Enumeration: {
 
 1080#define N       dpd->FORM.Enum.NumberOfValues 
 1081                N = dtoh16a(&data[*poffset]);
 
 1082                *poffset+=
sizeof(uint16_t);
 
 1083                dpd->FORM.Enum.SupportedValue = malloc(N*
sizeof(dpd->FORM.Enum.SupportedValue[0]));
 
 1084                if (!dpd->FORM.Enum.SupportedValue)
 
 1087                memset (dpd->FORM.Enum.SupportedValue,0 , N*
sizeof(dpd->FORM.Enum.SupportedValue[0]));
 
 1089                        ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType);
 
 1099                                dpd->FORM.Enum.NumberOfValues = i;
 
 1108        ptp_free_devicepropdesc(dpd);
 
 1114        if (type == PTP_DTC_STR) {
 
 1116                        dst->str = strdup(src->str);
 
 1122        if (type & PTP_DTC_ARRAY_MASK) {
 
 1125                dst->a.count = src->a.count;
 
 1126                dst->a.v = malloc (
sizeof(src->a.v[0])*src->a.count);
 
 1127                for (i=0;i<src->a.count;i++)
 
 1128                        duplicate_PropertyValue (&src->a.v[i], &dst->a.v[i], type & ~PTP_DTC_ARRAY_MASK);
 
 1131        switch (type & ~PTP_DTC_ARRAY_MASK) {
 
 1132        case PTP_DTC_INT8:      dst->i8 = src->i8; 
break;
 
 1133        case PTP_DTC_UINT8:     dst->u8 = src->u8; 
break;
 
 1134        case PTP_DTC_INT16:     dst->i16 = src->i16; 
break;
 
 1135        case PTP_DTC_UINT16:    dst->u16 = src->u16; 
break;
 
 1136        case PTP_DTC_INT32:     dst->i32 = src->i32; 
break;
 
 1137        case PTP_DTC_UINT32:    dst->u32 = src->u32; 
break;
 
 1138        case PTP_DTC_UINT64:    dst->u64 = src->u64; 
break;
 
 1139        case PTP_DTC_INT64:     dst->i64 = src->i64; 
break;
 
 1141        case PTP_DTC_INT128:    dst->i128 = src->i128; 
break;
 
 1142        case PTP_DTC_UINT128:   dst->u128 = src->u128; 
break;
 
 1153        dst->DevicePropertyCode = src->DevicePropertyCode;
 
 1154        dst->DataType           = src->DataType;
 
 1155        dst->GetSet             = src->GetSet;
 
 1157        duplicate_PropertyValue (&src->FactoryDefaultValue, &dst->FactoryDefaultValue, src->DataType);
 
 1158        duplicate_PropertyValue (&src->CurrentValue, &dst->CurrentValue, src->DataType);
 
 1160        dst->FormFlag           = src->FormFlag;
 
 1161        switch (src->FormFlag) {
 
 1162        case PTP_DPFF_Range:
 
 1163                duplicate_PropertyValue (&src->FORM.Range.MinimumValue, &dst->FORM.Range.MinimumValue, src->DataType);
 
 1164                duplicate_PropertyValue (&src->FORM.Range.MaximumValue, &dst->FORM.Range.MaximumValue, src->DataType);
 
 1165                duplicate_PropertyValue (&src->FORM.Range.StepSize,     &dst->FORM.Range.StepSize,     src->DataType);
 
 1167        case PTP_DPFF_Enumeration:
 
 1168                dst->FORM.Enum.NumberOfValues = src->FORM.Enum.NumberOfValues;
 
 1169                dst->FORM.Enum.SupportedValue = malloc (
sizeof(dst->FORM.Enum.SupportedValue[0])*src->FORM.Enum.NumberOfValues);
 
 1170                for (i = 0; i<src->FORM.Enum.NumberOfValues ; i++)
 
 1171                        duplicate_PropertyValue (&src->FORM.Enum.SupportedValue[i], &dst->FORM.Enum.SupportedValue[i], src->DataType);
 
 1178#define PTP_opd_ObjectPropertyCode      0 
 1179#define PTP_opd_DataType                2 
 1180#define PTP_opd_GetSet                  4 
 1181#define PTP_opd_FactoryDefaultValue     5 
 1186        unsigned int offset=0, ret;
 
 1189        memset (opd, 0, 
sizeof(*opd));
 
 1194        opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]);
 
 1195        opd->DataType=dtoh16a(&data[PTP_opd_DataType]);
 
 1196        opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]);
 
 1198        offset = PTP_opd_FactoryDefaultValue;
 
 1199        ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType);
 
 1200        if (!ret) 
goto outofmemory;
 
 1202        if (offset + 
sizeof(uint32_t) > opdlen) 
goto outofmemory;
 
 1203        opd->GroupCode=dtoh32a(&data[offset]);
 
 1204        offset+=
sizeof(uint32_t);
 
 1206        if (offset + 
sizeof(uint8_t) > opdlen) 
goto outofmemory;
 
 1207        opd->FormFlag=dtoh8a(&data[offset]);
 
 1208        offset+=
sizeof(uint8_t);
 
 1210        switch (opd->FormFlag) {
 
 1211        case PTP_OPFF_Range:
 
 1212                ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType);
 
 1213                if (!ret) 
goto outofmemory;
 
 1214                ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType);
 
 1215                if (!ret) 
goto outofmemory;
 
 1216                ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType);
 
 1217                if (!ret) 
goto outofmemory;
 
 1219        case PTP_OPFF_Enumeration: {
 
 1221#define N       opd->FORM.Enum.NumberOfValues 
 1223                if (offset + 
sizeof(uint16_t) > opdlen) 
goto outofmemory;
 
 1224                N = dtoh16a(&data[offset]);
 
 1225                offset+=
sizeof(uint16_t);
 
 1227                opd->FORM.Enum.SupportedValue = malloc(N*
sizeof(opd->FORM.Enum.SupportedValue[0]));
 
 1228                if (!opd->FORM.Enum.SupportedValue)
 
 1231                memset (opd->FORM.Enum.SupportedValue,0 , N*
sizeof(opd->FORM.Enum.SupportedValue[0]));
 
 1233                        ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType);
 
 1243                                opd->FORM.Enum.NumberOfValues = i;
 
 1250        case PTP_OPFF_DateTime:
 
 1251                if (!ptp_unpack_string(params, data, offset, opdlen, &len, &opd->FORM.DateTime.String))
 
 1252                        opd->FORM.DateTime.String = NULL;
 
 1255        case PTP_OPFF_RegularExpression:
 
 1256                if (!ptp_unpack_string(params, data, offset, opdlen, &len, &opd->FORM.RegularExpression.String))
 
 1257                        opd->FORM.RegularExpression.String = NULL;
 
 1260        case PTP_OPFF_FixedLengthArray:
 
 1261                if (offset + 
sizeof(uint16_t) > opdlen) 
goto outofmemory;
 
 1262                opd->FORM.FixedLengthArray.NumberOfValues = dtoh16a(&data[offset]);
 
 1263                offset += 
sizeof(uint16_t); 
 
 1265        case PTP_OPFF_ByteArray:
 
 1266                if (offset + 
sizeof(uint16_t) > opdlen) 
goto outofmemory;
 
 1267                opd->FORM.ByteArray.NumberOfValues = dtoh16a(&data[offset]);
 
 1268                offset += 
sizeof(uint16_t); 
 
 1270        case PTP_OPFF_LongString:
 
 1275        ptp_free_objectpropdesc(opd);
 
 1279static inline uint32_t
 
 1282        unsigned char* dpv=NULL;
 
 1288                size=
sizeof(int8_t);
 
 1290                htod8a(dpv,value->i8);
 
 1293                size=
sizeof(uint8_t);
 
 1295                htod8a(dpv,value->u8);
 
 1298                size=
sizeof(int16_t);
 
 1300                htod16a(dpv,value->i16);
 
 1302        case PTP_DTC_UINT16:
 
 1303                size=
sizeof(uint16_t);
 
 1305                htod16a(dpv,value->u16);
 
 1308                size=
sizeof(int32_t);
 
 1310                htod32a(dpv,value->i32);
 
 1312        case PTP_DTC_UINT32:
 
 1313                size=
sizeof(uint32_t);
 
 1315                htod32a(dpv,value->u32);
 
 1318                size=
sizeof(int64_t);
 
 1320                htod64a(dpv,value->i64);
 
 1322        case PTP_DTC_UINT64:
 
 1323                size=
sizeof(uint64_t);
 
 1325                htod64a(dpv,value->u64);
 
 1327        case PTP_DTC_AUINT8:
 
 1328                size=
sizeof(uint32_t)+value->a.count*
sizeof(uint8_t);
 
 1330                htod32a(dpv,value->a.count);
 
 1331                for (i=0;i<value->a.count;i++)
 
 1332                        htod8a(&dpv[
sizeof(uint32_t)+i*
sizeof(uint8_t)],value->a.v[i].u8);
 
 1335                size=
sizeof(uint32_t)+value->a.count*
sizeof(int8_t);
 
 1337                htod32a(dpv,value->a.count);
 
 1338                for (i=0;i<value->a.count;i++)
 
 1339                        htod8a(&dpv[
sizeof(uint32_t)+i*
sizeof(int8_t)],value->a.v[i].i8);
 
 1341        case PTP_DTC_AUINT16:
 
 1342                size=
sizeof(uint32_t)+value->a.count*
sizeof(uint16_t);
 
 1344                htod32a(dpv,value->a.count);
 
 1345                for (i=0;i<value->a.count;i++)
 
 1346                        htod16a(&dpv[
sizeof(uint32_t)+i*
sizeof(uint16_t)],value->a.v[i].u16);
 
 1348        case PTP_DTC_AINT16:
 
 1349                size=
sizeof(uint32_t)+value->a.count*
sizeof(int16_t);
 
 1351                htod32a(dpv,value->a.count);
 
 1352                for (i=0;i<value->a.count;i++)
 
 1353                        htod16a(&dpv[
sizeof(uint32_t)+i*
sizeof(int16_t)],value->a.v[i].i16);
 
 1355        case PTP_DTC_AUINT32:
 
 1356                size=
sizeof(uint32_t)+value->a.count*
sizeof(uint32_t);
 
 1358                htod32a(dpv,value->a.count);
 
 1359                for (i=0;i<value->a.count;i++)
 
 1360                        htod32a(&dpv[
sizeof(uint32_t)+i*
sizeof(uint32_t)],value->a.v[i].u32);
 
 1362        case PTP_DTC_AINT32:
 
 1363                size=
sizeof(uint32_t)+value->a.count*
sizeof(int32_t);
 
 1365                htod32a(dpv,value->a.count);
 
 1366                for (i=0;i<value->a.count;i++)
 
 1367                        htod32a(&dpv[
sizeof(uint32_t)+i*
sizeof(int32_t)],value->a.v[i].i32);
 
 1369        case PTP_DTC_AUINT64:
 
 1370                size=
sizeof(uint32_t)+value->a.count*
sizeof(uint64_t);
 
 1372                htod32a(dpv,value->a.count);
 
 1373                for (i=0;i<value->a.count;i++)
 
 1374                        htod64a(&dpv[
sizeof(uint32_t)+i*
sizeof(uint64_t)],value->a.v[i].u64);
 
 1376        case PTP_DTC_AINT64:
 
 1377                size=
sizeof(uint32_t)+value->a.count*
sizeof(int64_t);
 
 1379                htod32a(dpv,value->a.count);
 
 1380                for (i=0;i<value->a.count;i++)
 
 1381                        htod64a(&dpv[
sizeof(uint32_t)+i*
sizeof(int64_t)],value->a.v[i].i64);
 
 1385                dpv=ptp_get_packed_stringcopy(params, value->str, &size);
 
 1393#define MAX_MTP_PROPS 127 
 1394static inline uint32_t
 
 1397        unsigned char* opldata;
 
 1399        unsigned char *packedprops[MAX_MTP_PROPS];
 
 1400        uint32_t packedpropslens[MAX_MTP_PROPS];
 
 1401        uint32_t packedobjecthandles[MAX_MTP_PROPS];
 
 1402        uint16_t packedpropsids[MAX_MTP_PROPS];
 
 1403        uint16_t packedpropstypes[MAX_MTP_PROPS];
 
 1404        uint32_t totalsize = 0;
 
 1406        uint32_t noitems = 0;
 
 1409        totalsize = 
sizeof(uint32_t); 
 
 1411        while (nrofprops-- && noitems < MAX_MTP_PROPS) {
 
 1413                packedobjecthandles[noitems]=propitr->ObjectHandle;
 
 1414                totalsize += 
sizeof(uint32_t); 
 
 1416                packedpropsids[noitems]=propitr->property;
 
 1417                totalsize += 
sizeof(uint16_t);
 
 1419                packedpropstypes[noitems]= propitr->datatype;
 
 1420                totalsize += 
sizeof(uint16_t);
 
 1422                packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype);
 
 1423                totalsize += packedpropslens[noitems];
 
 1429        opldata = malloc(totalsize);
 
 1431        htod32a(&opldata[bufp],noitems);
 
 1435        for (i = 0; i < noitems; i++) {
 
 1437                htod32a(&opldata[bufp],packedobjecthandles[i]);
 
 1438                bufp += 
sizeof(uint32_t);
 
 1439                htod16a(&opldata[bufp],packedpropsids[i]);
 
 1440                bufp += 
sizeof(uint16_t);
 
 1441                htod16a(&opldata[bufp],packedpropstypes[i]);
 
 1442                bufp += 
sizeof(uint16_t);
 
 1444                memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]);
 
 1445                bufp += packedpropslens[i];
 
 1446                free(packedprops[i]);
 
 1448        *opldataptr = opldata;
 
 1453_compare_func(
const void* x, 
const void *y) {
 
 1457        return px->ObjectHandle - py->ObjectHandle;
 
 1463        uint32_t prop_count;
 
 1465        unsigned int offset = 0, i;
 
 1467        if (len < 
sizeof(uint32_t)) {
 
 1468                ptp_debug (params ,
"must have at least 4 bytes data, not %d", len);
 
 1472        prop_count = dtoh32a(data);
 
 1474        if (prop_count == 0)
 
 1478                ptp_debug (params ,
"prop_count %d is too large", prop_count);
 
 1481        ptp_debug (params ,
"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count);
 
 1483        data += 
sizeof(uint32_t);
 
 1484        len -= 
sizeof(uint32_t);
 
 1486        if (!props) 
return 0;
 
 1487        for (i = 0; i < prop_count; i++) {
 
 1488                if (len <= (
sizeof(uint32_t) + 
sizeof(uint16_t) + 
sizeof(uint16_t))) {
 
 1489                        ptp_debug (params ,
"short MTP Object Property List at property %d (of %d)", i, prop_count);
 
 1490                        ptp_debug (params ,
"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL");
 
 1491                        ptp_debug (params ,
"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST", i);
 
 1498                props[i].ObjectHandle = dtoh32a(data);
 
 1499                data += 
sizeof(uint32_t);
 
 1500                len -= 
sizeof(uint32_t);
 
 1502                props[i].property = dtoh16a(data);
 
 1503                data += 
sizeof(uint16_t);
 
 1504                len -= 
sizeof(uint16_t);
 
 1506                props[i].datatype = dtoh16a(data);
 
 1507                data += 
sizeof(uint16_t);
 
 1508                len -= 
sizeof(uint16_t);
 
 1511                if (!ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype)) {
 
 1512                        ptp_debug (params ,
"unpacking DPV of property %d encountered insufficient buffer. attack?", i);
 
 1520        qsort (props, prop_count, 
sizeof(
MTPProperties),_compare_func);
 
 1530#define PTP_ec_Length           0 
 1531#define PTP_ec_Type             4 
 1532#define PTP_ec_Code             6 
 1533#define PTP_ec_TransId          8 
 1534#define PTP_ec_Param1           12 
 1535#define PTP_ec_Param2           16 
 1536#define PTP_ec_Param3           20 
 1541        unsigned int    length;
 
 1546        memset(ec,0,
sizeof(*ec));
 
 1548        length=dtoh32a(&data[PTP_ec_Length]);
 
 1550                ptp_debug (params, 
"length %d in container, but data only %d bytes?!", length, len);
 
 1553        type = dtoh16a(&data[PTP_ec_Type]);
 
 1555        ec->Code=dtoh16a(&data[PTP_ec_Code]);
 
 1556        ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]);
 
 1558        if (type!=PTP_USB_CONTAINER_EVENT) {
 
 1559                ptp_debug (params, 
"Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID);
 
 1562        if (length>=(PTP_ec_Param1+4)) {
 
 1563                ec->Param1=dtoh32a(&data[PTP_ec_Param1]);
 
 1566        if (length>=(PTP_ec_Param2+4)) {
 
 1567                ec->Param2=dtoh32a(&data[PTP_ec_Param2]);
 
 1570        if (length>=(PTP_ec_Param3+4)) {
 
 1571                ec->Param3=dtoh32a(&data[PTP_ec_Param3]);
 
 1580#define PTP_cfe_ObjectHandle            0 
 1581#define PTP_cfe_ObjectFormatCode        4 
 1582#define PTP_cfe_Flags                   6 
 1583#define PTP_cfe_ObjectSize              7 
 1584#define PTP_cfe_Time                    11 
 1585#define PTP_cfe_Filename                15 
 1593        fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]);
 
 1594        fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]);
 
 1595        fe->Flags=dtoh8a(&data[PTP_cfe_Flags]);
 
 1596        fe->ObjectSize=dtoh32a((
unsigned char*)&data[PTP_cfe_ObjectSize]);
 
 1597        fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]);
 
 1598        for (i=0; i<PTP_CANON_FilenameBufferLen; i++)
 
 1599                fe->Filename[i]=(
char)dtoh8a(&data[PTP_cfe_Filename+i]);
 
 1654#define PTP_cefe_ObjectHandle           0 
 1655#define PTP_cefe_StorageID              4 
 1656#define PTP_cefe_ObjectFormatCode       8 
 1657#define PTP_cefe_Flags                  16 
 1658#define PTP_cefe_ObjectSize             20 
 1659#define PTP_cefe_Filename               32 
 1660#define PTP_cefe_Time                   48 
 1667        if (size < PTP_cefe_Time + 4) 
return;
 
 1669        fe->ObjectHandle=dtoh32a(&data[PTP_cefe_ObjectHandle]);
 
 1670        fe->ObjectFormatCode=dtoh16a(&data[PTP_cefe_ObjectFormatCode]);
 
 1671        fe->Flags=dtoh8a(&data[PTP_cefe_Flags]);
 
 1672        fe->ObjectSize=dtoh32a((
unsigned char*)&data[PTP_cefe_ObjectSize]);
 
 1673        fe->Time=(time_t)dtoh32a(&data[PTP_cefe_Time]);
 
 1674        for (i=0; i<PTP_CANON_FilenameBufferLen; i++)
 
 1675                fe->Filename[i]=(
char)data[PTP_cefe_Filename+i];
 
 1676        fe->Filename[PTP_CANON_FilenameBufferLen-1] = 0;
 
 1680static inline uint16_t
 
 1681ptp_unpack_EOS_ImageFormat (
PTPParams* params, 
unsigned char** data )
 
 1713        const unsigned char* d = *data;
 
 1714        uint32_t n = dtoh32a( d );
 
 1715        uint32_t l, t1, s1, c1, t2 = 0, s2 = 0, c2 = 0;
 
 1717        if (n != 1 && n !=2) {
 
 1718                ptp_debug (params, 
"parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n);
 
 1722        l = dtoh32a( d+=4 );
 
 1724                ptp_debug (params, 
"parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l);
 
 1728        t1 = dtoh32a( d+=4 );
 
 1729        s1 = dtoh32a( d+=4 );
 
 1730        c1 = dtoh32a( d+=4 );
 
 1733                l = dtoh32a( d+=4 );
 
 1735                        ptp_debug (params, 
"parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l);
 
 1738                t2 = dtoh32a( d+=4 );
 
 1739                s2 = dtoh32a( d+=4 );
 
 1740                c2 = dtoh32a( d+=4 );
 
 1743        *data = (
unsigned char*) d+4;
 
 1752        c1 |= (t1 == 6) ? 8 : 0;
 
 1753        c2 |= (t2 == 6) ? 8 : 0;
 
 1755        return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0);
 
 1758static inline uint32_t
 
 1759ptp_pack_EOS_ImageFormat (
PTPParams* params, 
unsigned char* data, uint16_t value)
 
 1761        uint32_t n = (value & 0xFF) ? 2 : 1;
 
 1762        uint32_t s = 4 + 0x10 * n;
 
 1767#define PACK_5DM3_SMALL_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X) 
 1769        htod32a(data+=0, n);
 
 1770        htod32a(data+=4, 0x10);
 
 1771        htod32a(data+=4, (((value >> 8) & 0xF) >> 3) ? 6 : 1);
 
 1772        htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 12) & 0xF));
 
 1773        htod32a(data+=4, ((value >> 8) & 0xF) & ~8);
 
 1776                htod32a(data+=4, 0x10);
 
 1777                htod32a(data+=4, (((value >> 0) & 0xF) >> 3) ? 6 : 1);
 
 1778                htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 4) & 0xF));
 
 1779                htod32a(data+=4, ((value >> 0) & 0xF) & ~8);
 
 1782#undef PACK_5DM3_SMALL_JPEG_SIZE 
 1806ptp_unpack_EOS_FocusInfoEx (
PTPParams* params, 
unsigned char** data, uint32_t datasize )
 
 1808        uint32_t size                   = dtoh32a( *data );
 
 1809        uint32_t halfsize               = dtoh16a( (*data) + 4);
 
 1810        uint32_t version                = dtoh16a( (*data) + 6);
 
 1811        uint32_t focus_points_in_struct = dtoh16a( (*data) + 8);
 
 1812        uint32_t focus_points_in_use    = dtoh16a( (*data) + 10);
 
 1813        uint32_t sizeX                  = dtoh16a( (*data) + 12);
 
 1814        uint32_t sizeY                  = dtoh16a( (*data) + 14);
 
 1815        uint32_t size2X                 = dtoh16a( (*data) + 16);
 
 1816        uint32_t size2Y                 = dtoh16a( (*data) + 18);
 
 1821        if ((size >= datasize) || (size < 20))
 
 1822                return strdup(
"bad size 1");
 
 1825        if (!focus_points_in_struct || !focus_points_in_use) {
 
 1826                ptp_debug(params, 
"skipped FocusInfoEx data (zero filled)");
 
 1827                return strdup(
"no focus points returned by camera");
 
 1834        if (size < focus_points_in_struct*8) {
 
 1835                ptp_error(params, 
"focus_points_in_struct %d is too large vs size %d", focus_points_in_struct, size);
 
 1836                return strdup(
"bad size 2");
 
 1838        if (focus_points_in_use > focus_points_in_struct) {
 
 1839                ptp_error(params, 
"focus_points_in_use %d is larger than focus_points_in_struct %d", focus_points_in_use, focus_points_in_struct);
 
 1840                return strdup(
"bad size 3");
 
 1843        maxlen = focus_points_in_use*32 + 100 + (size - focus_points_in_struct*8)*2;
 
 1844        if (halfsize != size-4) {
 
 1845                ptp_error(params, 
"halfsize %d is not expected %d", halfsize, size-4);
 
 1846                return strdup(
"bad size 4");
 
 1848        if (20 + focus_points_in_struct*8 + (focus_points_in_struct+7)/8 > size) {
 
 1849                ptp_error(params, 
"size %d is too large for fp in struct %d", focus_points_in_struct*8 + 20 + (focus_points_in_struct+7)/8, size);
 
 1850                return strdup(
"bad size 5");
 
 1853        ptp_debug(params,
"d1d3 content:");
 
 1854        for (i=0;i<size;i+=2)
 
 1855                ptp_debug(params,
"%d: %02x %02x", i, (*data)[i], (*data)[i+1]);
 
 1857        ptp_debug(params,
"d1d3 version %d", version);
 
 1858        ptp_debug(params,
"d1d3 size %d", size);
 
 1859        ptp_debug(params,
"d1d3 focus points in struct %d, in use %d", focus_points_in_struct, focus_points_in_use);
 
 1861        str = (
char*)malloc( maxlen );
 
 1866        p += sprintf(p,
"eosversion=%u,size=%ux%u,size2=%ux%u,points={", version, sizeX, sizeY, size2X, size2Y);
 
 1867        for (i=0;i<focus_points_in_use;i++) {
 
 1868                int16_t x = dtoh16a((*data) + focus_points_in_struct*4 + 20 + 2*i);
 
 1869                int16_t y = dtoh16a((*data) + focus_points_in_struct*6 + 20 + 2*i);
 
 1870                int16_t w = dtoh16a((*data) + focus_points_in_struct*2 + 20 + 2*i);
 
 1871                int16_t h = dtoh16a((*data) + focus_points_in_struct*0 + 20 + 2*i);
 
 1873                p += sprintf(p,
"{%d,%d,%d,%d}",x,y,w,h);
 
 1875                if (i<focus_points_in_use-1)
 
 1876                        p += sprintf(p,
",");
 
 1878        p += sprintf(p,
"},select={");
 
 1879        for (i=0;i<focus_points_in_use;i++) {
 
 1880                if ((1<<(i%8)) & ((*data)[focus_points_in_struct*8+20+i/8]))
 
 1881                        p+=sprintf(p,
"%u,", i);
 
 1884        p += sprintf(p,
"},unknown={");
 
 1885        for (i=focus_points_in_struct*8+(focus_points_in_struct+7)/8+20;i<size;i++) {
 
 1886                if ((p-str) > maxlen - 4)
 
 1888                p+=sprintf(p,
"%02x", (*data)[i]);
 
 1890        p += sprintf(p,
"}");
 
 1896ptp_unpack_EOS_CustomFuncEx (
PTPParams* params, 
unsigned char** data )
 
 1898        uint32_t s = dtoh32a( *data );
 
 1899        uint32_t n = s/4, i;
 
 1903                ptp_debug (params, 
"customfuncex data is larger than 1k / %d... unexpected?", s);
 
 1904                return strdup(
"bad length");
 
 1906        str = (
char*)malloc( s*2+s/4+1 ); 
 
 1908                return strdup(
"malloc failed");
 
 1911        for (i=0; i < n; ++i)
 
 1912                p += sprintf(p, 
"%x,", dtoh32a( *data + 4*i ));
 
 1916static inline uint32_t
 
 1917ptp_pack_EOS_CustomFuncEx (
PTPParams* params, 
unsigned char* data, 
char* str)
 
 1919        uint32_t s = strtoul(str, NULL, 16);
 
 1920        uint32_t n = s/4, i, v;
 
 1927                v = strtoul(str, &str, 16);
 
 1929                htod32a(data + i*4, v);
 
 1938#define PTP_ece_Size            0 
 1939#define PTP_ece_Type            4 
 1941#define PTP_ece_Prop_Subtype    8        
 1942#define PTP_ece_Prop_Val_Data   0xc      
 1943#define PTP_ece_Prop_Desc_Type  0xc      
 1944#define PTP_ece_Prop_Desc_Count 0x10     
 1945#define PTP_ece_Prop_Desc_Data  0x14     
 1948#define PTP_ece_OI_ObjectID     8 
 1949#define PTP_ece_OI_OFC          0x0c 
 1950#define PTP_ece_OI_Size         0x14 
 1951#define PTP_ece_OI_Name         0x1c 
 1954#define PTP_ece_OA_ObjectID     8 
 1955#define PTP_ece_OA_StorageID    0x0c 
 1956#define PTP_ece_OA_OFC          0x10 
 1957#define PTP_ece_OA_Size         0x1c 
 1958#define PTP_ece_OA_Parent       0x20 
 1959#define PTP_ece_OA_Name         0x28 
 1961#define PTP_ece2_OA_ObjectID    8        
 1962#define PTP_ece2_OA_StorageID   0x0c     
 1963#define PTP_ece2_OA_OFC         0x10     
 1964#define PTP_ece2_OA_Size        0x1c     
 1965#define PTP_ece2_OA_Parent      0x24 
 1966#define PTP_ece2_OA_2ndOID      0x28 
 1967#define PTP_ece2_OA_Name        0x2c     
 1970#define PTP_ece_OAN_OFC         0x0c 
 1971#define PTP_ece_OAN_Size        0x14 
 1974_lookup_or_allocate_canon_prop(
PTPParams *params, uint16_t proptype)
 
 1978        for (j=0;j<params->nrofcanon_props;j++)
 
 1979                if (params->canon_props[j].proptype == proptype)
 
 1981        if (j<params->nrofcanon_props)
 
 1982                return ¶ms->canon_props[j].dpd;
 
 1985                params->canon_props = realloc(params->canon_props, 
sizeof(params->canon_props[0])*(j+1));
 
 1987                params->canon_props = malloc(
sizeof(params->canon_props[0]));
 
 1988        params->canon_props[j].proptype = proptype;
 
 1989        params->canon_props[j].size = 0;
 
 1990        params->canon_props[j].data = NULL;
 
 1991        memset (¶ms->canon_props[j].dpd,0,
sizeof(params->canon_props[j].dpd));
 
 1992        params->canon_props[j].dpd.GetSet = 1;
 
 1993        params->canon_props[j].dpd.FormFlag = PTP_DPFF_None;
 
 1994        params->nrofcanon_props = j+1;
 
 1995        return ¶ms->canon_props[j].dpd;
 
 2002        int     i = 0, entries = 0;
 
 2003        unsigned char   *curdata = data;
 
 2008        while (curdata - data + 8 < datasize) {
 
 2009                uint32_t        size = dtoh32a(&curdata[PTP_ece_Size]);
 
 2010                uint32_t        type = dtoh32a(&curdata[PTP_ece_Type]);
 
 2012                if (size > datasize) {
 
 2013                        ptp_debug (params, 
"size %d is larger than datasize %d", size, datasize);
 
 2017                        ptp_debug (params, 
"size %d is smaller than 8.", size);
 
 2020                if ((size == 8) && (type == 0))
 
 2022                if ((curdata - data) + size >= datasize) {
 
 2023                        ptp_debug (params, 
"canon eos event decoder ran over supplied data, skipping entries");
 
 2026                if (type == PTP_EC_CANON_EOS_OLCInfoChanged) {
 
 2032                                        if (dtoh16a(curdata+12) & (1<<j))
 
 2043        while (curdata - data  + 8 < datasize) {
 
 2044                uint32_t        size = dtoh32a(&curdata[PTP_ece_Size]);
 
 2045                uint32_t        type = dtoh32a(&curdata[PTP_ece_Type]);
 
 2047                if (size > datasize) {
 
 2048                        ptp_debug (params, 
"size %d is larger than datasize %d", size, datasize);
 
 2052                        ptp_debug (params, 
"size %d is smaller than 8", size);
 
 2056                if ((size == 8) && (type == 0))
 
 2059                if ((curdata - data) + size >= datasize) {
 
 2060                        ptp_debug (params, 
"canon eos event decoder ran over supplied data, skipping entries");
 
 2064                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2065                ce[i].u.info = NULL;
 
 2067                case PTP_EC_CANON_EOS_ObjectContentChanged:
 
 2068                        if (size < PTP_ece_OA_ObjectID+1) {
 
 2069                                ptp_debug (params, 
"size %d is smaller than %d", size, PTP_ece_OA_ObjectID+1);
 
 2072                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTCONTENT_CHANGE;
 
 2073                        ce[i].u.object.oid              = dtoh32a(&curdata[PTP_ece_OA_ObjectID]);
 
 2075                case PTP_EC_CANON_EOS_ObjectInfoChangedEx:
 
 2076                case PTP_EC_CANON_EOS_ObjectAddedEx:
 
 2077                        if (size < PTP_ece_OA_Name+1) {
 
 2078                                ptp_debug (params, 
"size %d is smaller than %d", size, PTP_ece_OA_Name+1);
 
 2081                        ce[i].type = ((type == PTP_EC_CANON_EOS_ObjectAddedEx) ? PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO : PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO_CHANGE);
 
 2082                        ce[i].u.object.oid              = dtoh32a(&curdata[PTP_ece_OA_ObjectID]);
 
 2083                        ce[i].u.object.oi.StorageID     = dtoh32a(&curdata[PTP_ece_OA_StorageID]);
 
 2084                        ce[i].u.object.oi.ParentObject  = dtoh32a(&curdata[PTP_ece_OA_Parent]);
 
 2085                        ce[i].u.object.oi.ObjectFormat  = dtoh16a(&curdata[PTP_ece_OA_OFC]);
 
 2086                        ce[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]);
 
 2087                        ce[i].u.object.oi.Filename      = strdup(((
char*)&curdata[PTP_ece_OA_Name]));
 
 2088                        if (type == PTP_EC_CANON_EOS_ObjectAddedEx) {
 
 2089                                ptp_debug (params, 
"event %d: objectinfo added oid %08lx, parent %08lx, ofc %04x, size %d, filename %s", i, ce[i].u.object.oid, ce[i].u.object.oi.ParentObject, ce[i].u.object.oi.ObjectFormat, ce[i].u.object.oi.ObjectCompressedSize, ce[i].u.object.oi.Filename);
 
 2091                                ptp_debug (params, 
"event %d: objectinfo changed oid %08lx, parent %08lx, ofc %04x, size %d, filename %s", i, ce[i].u.object.oid, ce[i].u.object.oi.ParentObject, ce[i].u.object.oi.ObjectFormat, ce[i].u.object.oi.ObjectCompressedSize, ce[i].u.object.oi.Filename);
 
 2094                case PTP_EC_CANON_EOS_ObjectAddedEx64:  
 
 2095                        if (size < PTP_ece2_OA_Name+1) {
 
 2096                                ptp_debug (params, 
"size %d is smaller than %d", size, PTP_ece2_OA_Name+1);
 
 2099                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO;
 
 2100                        ce[i].u.object.oid              = dtoh32a(&curdata[PTP_ece2_OA_ObjectID]);
 
 2101                        ce[i].u.object.oi.StorageID     = dtoh32a(&curdata[PTP_ece2_OA_StorageID]);
 
 2102                        ce[i].u.object.oi.ParentObject  = dtoh32a(&curdata[PTP_ece2_OA_Parent]);
 
 2103                        ce[i].u.object.oi.ObjectFormat  = dtoh16a(&curdata[PTP_ece2_OA_OFC]);
 
 2104                        ce[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece2_OA_Size]);    
 
 2105                        ce[i].u.object.oi.Filename      = strdup(((
char*)&curdata[PTP_ece2_OA_Name]));
 
 2106                        ptp_debug (params, 
"event %d: objectinfo added oid %08lx, parent %08lx, ofc %04x, size %d, filename %s", i, ce[i].u.object.oid, ce[i].u.object.oi.ParentObject, ce[i].u.object.oi.ObjectFormat, ce[i].u.object.oi.ObjectCompressedSize, ce[i].u.object.oi.Filename);
 
 2108                case PTP_EC_CANON_EOS_RequestObjectTransfer:
 
 2109                case PTP_EC_CANON_EOS_RequestObjectTransfer64:
 
 2110                        if (size < PTP_ece_OI_Name+1) {
 
 2111                                ptp_debug (params, 
"size %d is smaller than %d", size, PTP_ece_OI_Name+1);
 
 2114                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER;
 
 2115                        ce[i].u.object.oid              = dtoh32a(&curdata[PTP_ece_OI_ObjectID]);
 
 2116                        ce[i].u.object.oi.StorageID     = 0; 
 
 2117                        ce[i].u.object.oi.ObjectFormat  = dtoh16a(&curdata[PTP_ece_OI_OFC]);
 
 2118                        ce[i].u.object.oi.ParentObject  = 0; 
 
 2119                        ce[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]);
 
 2120                        ce[i].u.object.oi.Filename      = strdup(((
char*)&curdata[PTP_ece_OI_Name]));
 
 2122                        ptp_debug (params, 
"event %d: request object transfer oid %08lx, ofc %04x, size %d, filename %p", i, ce[i].u.object.oid, ce[i].u.object.oi.ObjectFormat, ce[i].u.object.oi.ObjectCompressedSize, ce[i].u.object.oi.Filename);
 
 2124                case PTP_EC_CANON_EOS_AvailListChanged: {       
 
 2125                        uint32_t        proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]);
 
 2126                        uint32_t        propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]);
 
 2127                        uint32_t        propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]);
 
 2128                        unsigned char   *xdata = &curdata[PTP_ece_Prop_Desc_Data];
 
 2132                        if (size < PTP_ece_Prop_Desc_Data) {
 
 2133                                ptp_debug (params, 
"size %d is smaller than %d", size, PTP_ece_Prop_Desc_Data);
 
 2137                        ptp_debug (params, 
"event %d: EOS prop %04x (%s) desc record, datasize %d, propxtype %d", i, proptype, ptp_get_property_description (params, proptype), size-PTP_ece_Prop_Desc_Data, propxtype);
 
 2138                        for (j=0;j<params->nrofcanon_props;j++)
 
 2139                                if (params->canon_props[j].proptype == proptype)
 
 2141                        if (j==params->nrofcanon_props) {
 
 2142                                ptp_debug (params, 
"event %d: propdesc %x, default value not found.", i, proptype);
 
 2145                        dpd = ¶ms->canon_props[j].dpd;
 
 2150                        if (propxtype != 3) {
 
 2151                                ptp_debug (params, 
"event %d: propxtype is %x for %04x, unhandled, size %d", i, propxtype, proptype, size);
 
 2152                                for (j=0;j<size-PTP_ece_Prop_Desc_Data;j++)
 
 2153                                        ptp_debug (params, 
"    %d: %02x", j, xdata[j]);
 
 2158                        if (propxcnt >= 2<<16) 
 
 2161                        ptp_debug (params, 
"event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.",
 
 2162                                   i, propxtype, proptype, dpd->DataType, propxcnt);
 
 2163                        dpd->FormFlag = PTP_DPFF_Enumeration;
 
 2164                        dpd->FORM.Enum.NumberOfValues = propxcnt;
 
 2165                        free (dpd->FORM.Enum.SupportedValue);
 
 2166                        dpd->FORM.Enum.SupportedValue = malloc (
sizeof (
PTPPropertyValue)*propxcnt);
 
 2169                        case PTP_DPC_CANON_EOS_ImageFormat:
 
 2170                        case PTP_DPC_CANON_EOS_ImageFormatCF:
 
 2171                        case PTP_DPC_CANON_EOS_ImageFormatSD:
 
 2172                        case PTP_DPC_CANON_EOS_ImageFormatExtHD:
 
 2174                                for (j=0;j<propxcnt;j++) {
 
 2175                                        dpd->FORM.Enum.SupportedValue[j].u16 =
 
 2176                                                        ptp_unpack_EOS_ImageFormat( params, &xdata );
 
 2177                                        ptp_debug (params, 
"event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16);
 
 2182                                switch (dpd->DataType) {
 
 2183#define XX( TYPE, CONV )\ 
 2184                                        if (sizeof(dpd->FORM.Enum.SupportedValue[j].TYPE)*propxcnt + PTP_ece_Prop_Desc_Data > size) {   \ 
 2185                                                ptp_debug (params, "size %lu does not match needed %u", sizeof(dpd->FORM.Enum.SupportedValue[j].TYPE)*propxcnt + PTP_ece_Prop_Desc_Data, size); \ 
 2188                                        for (j=0;j<propxcnt;j++) {                                      \ 
 2189                                                dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(xdata);    \ 
 2190                                                ptp_debug (params, "event %u: suppval[%u] of %x is 0x%x.", i, j, proptype, CONV(xdata)); \ 
 2195                                case PTP_DTC_INT16:     XX( i16, dtoh16a );
 
 2196                                case PTP_DTC_UINT16:    XX( u16, dtoh16a );
 
 2197                                case PTP_DTC_UINT32:    XX( u32, dtoh32a );
 
 2198                                case PTP_DTC_INT32:     XX( i32, dtoh32a );
 
 2199                                case PTP_DTC_UINT8:     XX( u8,  dtoh8a );
 
 2200                                case PTP_DTC_INT8:      XX( i8,  dtoh8a );
 
 2203                                        free (dpd->FORM.Enum.SupportedValue);
 
 2204                                        dpd->FORM.Enum.SupportedValue = NULL;
 
 2205                                        dpd->FORM.Enum.NumberOfValues = 0;
 
 2206                                        ptp_debug (params ,
"event %d: data type 0x%04x of %x unhandled, size %d, raw values:", i, dpd->DataType, proptype, dtoh32a(xdata), size);
 
 2207                                        for (j=0;j<(size-PTP_ece_Prop_Desc_Data)/4;j++, xdata+=4) 
 
 2208                                                ptp_debug (params, 
"    %3d: 0x%8x", j, dtoh32a(xdata));
 
 2214                case PTP_EC_CANON_EOS_PropValueChanged:
 
 2217                                uint32_t        proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]);
 
 2218                                unsigned char   *xdata = &curdata[PTP_ece_Prop_Val_Data];
 
 2221                                if (size < PTP_ece_Prop_Val_Data) {
 
 2222                                        ptp_debug (params, 
"size %d is smaller than %d", size, PTP_ece_Prop_Val_Data);
 
 2225                                ptp_debug (params, 
"event %d: EOS prop %04x (%s) info record, datasize is %d", i, proptype, ptp_get_property_description(params,proptype), size-PTP_ece_Prop_Val_Data);
 
 2226                                for (j=0;j<params->nrofcanon_props;j++)
 
 2227                                        if (params->canon_props[j].proptype == proptype)
 
 2229                                if (j<params->nrofcanon_props) {
 
 2230                                        if (    (params->canon_props[j].size != size) ||
 
 2231                                                (memcmp(params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data))) {
 
 2232                                                params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data);
 
 2233                                                params->canon_props[j].size = size;
 
 2234                                                memcpy (params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data);
 
 2238                                                params->canon_props = realloc(params->canon_props, 
sizeof(params->canon_props[0])*(j+1));
 
 2240                                                params->canon_props = malloc(
sizeof(params->canon_props[0]));
 
 2241                                        params->canon_props[j].proptype = proptype;
 
 2242                                        params->canon_props[j].size = size;
 
 2243                                        params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data);
 
 2244                                        memcpy(params->canon_props[j].data, xdata, size-PTP_ece_Prop_Val_Data);
 
 2245                                        memset (¶ms->canon_props[j].dpd,0,
sizeof(params->canon_props[j].dpd));
 
 2246                                        params->canon_props[j].dpd.GetSet = 1;
 
 2247                                        params->canon_props[j].dpd.FormFlag = PTP_DPFF_None;
 
 2248                                        params->nrofcanon_props = j+1;
 
 2250                                dpd = ¶ms->canon_props[j].dpd;
 
 2252                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 
 2253                                ce[i].u.propid = proptype;
 
 2257#define XX(x) case PTP_DPC_CANON_##x: 
 2259                                        XX(EOS_BatteryPower)
 
 2260                                        XX(EOS_BatterySelect)
 
 2262                                        XX(EOS_PTPExtensionVersion)
 
 2264                                        XX(EOS_AvailableShots)
 
 2265                                        XX(EOS_CurrentStorage)
 
 2266                                        XX(EOS_CurrentFolder)
 
 2269                                        XX(EOS_HDDirectoryStructure)
 
 2273                                        XX(EOS_CardExtension)
 
 2275                                        XX(EOS_ShutterCounter)
 
 2276                                        XX(EOS_SerialNumber)
 
 2277                                        XX(EOS_DepthOfFieldPreview)
 
 2278                                        XX(EOS_EVFRecordStatus)
 
 2281                                        XX(EOS_DepthOfField)
 
 2288                                                dpd->GetSet = PTP_DPGS_Get;
 
 2294                                case PTP_DPC_CANON_EOS_CameraTime:
 
 2295                                case PTP_DPC_CANON_EOS_UTCTime:
 
 2296                                case PTP_DPC_CANON_EOS_Summertime: 
 
 2297                                case PTP_DPC_CANON_EOS_AvailableShots:
 
 2298                                case PTP_DPC_CANON_EOS_CaptureDestination:
 
 2299                                case PTP_DPC_CANON_EOS_WhiteBalanceXA:
 
 2300                                case PTP_DPC_CANON_EOS_WhiteBalanceXB:
 
 2301                                case PTP_DPC_CANON_EOS_CurrentStorage:
 
 2302                                case PTP_DPC_CANON_EOS_CurrentFolder:
 
 2303                                case PTP_DPC_CANON_EOS_ShutterCounter:
 
 2304                                case PTP_DPC_CANON_EOS_ModelID:
 
 2305                                case PTP_DPC_CANON_EOS_LensID:
 
 2306                                case PTP_DPC_CANON_EOS_StroboFiring:
 
 2307                                case PTP_DPC_CANON_EOS_AFSelectFocusArea:
 
 2308                                case PTP_DPC_CANON_EOS_ContinousAFMode:
 
 2309                                case PTP_DPC_CANON_EOS_MirrorUpSetting:
 
 2310                                case PTP_DPC_CANON_EOS_OLCInfoVersion:
 
 2311                                case PTP_DPC_CANON_EOS_PowerZoomPosition:
 
 2312                                case PTP_DPC_CANON_EOS_PowerZoomSpeed:
 
 2313                                case PTP_DPC_CANON_EOS_BuiltinStroboMode:
 
 2314                                case PTP_DPC_CANON_EOS_StroboETTL2Metering:
 
 2315                                case PTP_DPC_CANON_EOS_ColorTemperature:
 
 2316                                case PTP_DPC_CANON_EOS_FixedMovie:
 
 2317                                        dpd->DataType = PTP_DTC_UINT32;
 
 2320                                case PTP_DPC_CANON_EOS_AutoExposureMode:
 
 2321                                        dpd->DataType = PTP_DTC_UINT16;
 
 2322                                        dpd->FormFlag = PTP_DPFF_Enumeration;
 
 2323                                        dpd->FORM.Enum.NumberOfValues = 0;
 
 2325                                case PTP_DPC_CANON_EOS_Aperture:
 
 2326                                case PTP_DPC_CANON_EOS_ShutterSpeed:
 
 2327                                case PTP_DPC_CANON_EOS_ISOSpeed:
 
 2328                                case PTP_DPC_CANON_EOS_FocusMode:
 
 2329                                case PTP_DPC_CANON_EOS_ColorSpace:
 
 2330                                case PTP_DPC_CANON_EOS_BatteryPower:
 
 2331                                case PTP_DPC_CANON_EOS_BatterySelect:
 
 2332                                case PTP_DPC_CANON_EOS_PTPExtensionVersion:
 
 2333                                case PTP_DPC_CANON_EOS_DriveMode:
 
 2334                                case PTP_DPC_CANON_EOS_AEB:
 
 2335                                case PTP_DPC_CANON_EOS_BracketMode:
 
 2336                                case PTP_DPC_CANON_EOS_QuickReviewTime:
 
 2337                                case PTP_DPC_CANON_EOS_EVFMode:
 
 2338                                case PTP_DPC_CANON_EOS_EVFOutputDevice:
 
 2339                                case PTP_DPC_CANON_EOS_AutoPowerOff:
 
 2340                                case PTP_DPC_CANON_EOS_EVFRecordStatus:
 
 2341                                case PTP_DPC_CANON_EOS_HighISOSettingNoiseReduction:
 
 2342                                case PTP_DPC_CANON_EOS_MultiAspect: 
 
 2343                                        dpd->DataType = PTP_DTC_UINT16;
 
 2345                                case PTP_DPC_CANON_EOS_PictureStyle:
 
 2346                                case PTP_DPC_CANON_EOS_WhiteBalance:
 
 2347                                case PTP_DPC_CANON_EOS_MeteringMode:
 
 2348                                case PTP_DPC_CANON_EOS_ExpCompensation:
 
 2349                                        dpd->DataType = PTP_DTC_UINT8;
 
 2351                                case PTP_DPC_CANON_EOS_Owner:
 
 2352                                case PTP_DPC_CANON_EOS_Artist:
 
 2353                                case PTP_DPC_CANON_EOS_Copyright:
 
 2354                                case PTP_DPC_CANON_EOS_SerialNumber:
 
 2355                                case PTP_DPC_CANON_EOS_LensName:
 
 2356                                        dpd->DataType = PTP_DTC_STR;
 
 2358                                case PTP_DPC_CANON_EOS_WhiteBalanceAdjustA:
 
 2359                                case PTP_DPC_CANON_EOS_WhiteBalanceAdjustB:
 
 2360                                        dpd->DataType = PTP_DTC_INT32;
 
 2363                                case PTP_DPC_CANON_EOS_DPOFVersion:
 
 2364                                        dpd->DataType = PTP_DTC_UINT16;
 
 2365                                        ptp_debug (params, 
"event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data);
 
 2366                                        for (j=0;j<size-PTP_ece_Prop_Val_Data;j++)
 
 2367                                                ptp_debug (params, 
"    %d: %02x", j, xdata[j]);
 
 2369                                case PTP_DPC_CANON_EOS_CustomFunc1:
 
 2370                                case PTP_DPC_CANON_EOS_CustomFunc2:
 
 2371                                case PTP_DPC_CANON_EOS_CustomFunc3:
 
 2372                                case PTP_DPC_CANON_EOS_CustomFunc4:
 
 2373                                case PTP_DPC_CANON_EOS_CustomFunc5:
 
 2374                                case PTP_DPC_CANON_EOS_CustomFunc6:
 
 2375                                case PTP_DPC_CANON_EOS_CustomFunc7:
 
 2376                                case PTP_DPC_CANON_EOS_CustomFunc8:
 
 2377                                case PTP_DPC_CANON_EOS_CustomFunc9:
 
 2378                                case PTP_DPC_CANON_EOS_CustomFunc10:
 
 2379                                case PTP_DPC_CANON_EOS_CustomFunc11:
 
 2380                                        dpd->DataType = PTP_DTC_UINT8;
 
 2381                                        ptp_debug (params, 
"event %d: Unknown EOS property %04x, datasize is %d, using uint8", i ,proptype, size-PTP_ece_Prop_Val_Data);
 
 2382                                        for (j=0;j<size-PTP_ece_Prop_Val_Data;j++)
 
 2383                                                ptp_debug (params, 
"    %d: %02x", j, xdata[j]);
 
 2388                                case PTP_DPC_CANON_EOS_WftStatus:
 
 2389                                case PTP_DPC_CANON_EOS_LensStatus:
 
 2390                                case PTP_DPC_CANON_EOS_CardExtension:
 
 2391                                case PTP_DPC_CANON_EOS_TempStatus:
 
 2392                                case PTP_DPC_CANON_EOS_PhotoStudioMode:
 
 2393                                case PTP_DPC_CANON_EOS_DepthOfFieldPreview:
 
 2394                                case PTP_DPC_CANON_EOS_EVFSharpness:
 
 2395                                case PTP_DPC_CANON_EOS_EVFWBMode:
 
 2396                                case PTP_DPC_CANON_EOS_EVFClickWBCoeffs:
 
 2397                                case PTP_DPC_CANON_EOS_EVFColorTemp:
 
 2398                                case PTP_DPC_CANON_EOS_ExposureSimMode:
 
 2399                                case PTP_DPC_CANON_EOS_LvAfSystem:
 
 2400                                case PTP_DPC_CANON_EOS_MovSize:
 
 2401                                case PTP_DPC_CANON_EOS_DepthOfField:
 
 2402                                case PTP_DPC_CANON_EOS_LvViewTypeSelect:
 
 2403                                case PTP_DPC_CANON_EOS_AloMode:
 
 2404                                case PTP_DPC_CANON_EOS_Brightness:
 
 2405                                case PTP_DPC_CANON_EOS_GPSLogCtrl:
 
 2406                                case PTP_DPC_CANON_EOS_GPSDeviceActive:
 
 2407                                        dpd->DataType = PTP_DTC_UINT32;
 
 2408                                        ptp_debug (params, 
"event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data);
 
 2409                                        if ((size-PTP_ece_Prop_Val_Data) % 
sizeof(uint32_t) != 0)
 
 2410                                                ptp_debug (params, 
"event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % 
sizeof(uint32_t) );
 
 2411                                        for (j=0;j<(size-PTP_ece_Prop_Val_Data)/
sizeof(uint32_t);j++)
 
 2412                                                ptp_debug (params, 
"    %d: 0x%8x", j, dtoh32a(xdata+j*4));
 
 2415                                case PTP_DPC_CANON_EOS_ImageFormat:
 
 2416                                case PTP_DPC_CANON_EOS_ImageFormatCF:
 
 2417                                case PTP_DPC_CANON_EOS_ImageFormatSD:
 
 2418                                case PTP_DPC_CANON_EOS_ImageFormatExtHD:
 
 2419                                case PTP_DPC_CANON_EOS_CustomFuncEx:
 
 2420                                case PTP_DPC_CANON_EOS_FocusInfoEx:
 
 2423                                        ptp_debug (params, 
"event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data);
 
 2424                                        for (j=0;j<size-PTP_ece_Prop_Val_Data;j++)
 
 2425                                                ptp_debug (params, 
"    %d: %02x", j, xdata[j]);
 
 2428                                switch (dpd->DataType) {
 
 2429                                case PTP_DTC_UINT32:
 
 2430                                        dpd->FactoryDefaultValue.u32    = dtoh32a(xdata);
 
 2431                                        dpd->CurrentValue.u32           = dtoh32a(xdata);
 
 2432                                        ptp_debug (params ,
"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32);
 
 2435                                        dpd->FactoryDefaultValue.i16    = dtoh16a(xdata);
 
 2436                                        dpd->CurrentValue.i16           = dtoh16a(xdata);
 
 2437                                        ptp_debug (params,
"event %d: currentvalue of %x is %d", i, proptype, dpd->CurrentValue.i16);
 
 2439                                case PTP_DTC_UINT16:
 
 2440                                        dpd->FactoryDefaultValue.u16    = dtoh16a(xdata);
 
 2441                                        dpd->CurrentValue.u16           = dtoh16a(xdata);
 
 2442                                        ptp_debug (params,
"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16);
 
 2445                                        dpd->FactoryDefaultValue.u8     = dtoh8a(xdata);
 
 2446                                        dpd->CurrentValue.u8            = dtoh8a(xdata);
 
 2447                                        ptp_debug (params,
"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8);
 
 2450                                        dpd->FactoryDefaultValue.i8     = dtoh8a(xdata);
 
 2451                                        dpd->CurrentValue.i8            = dtoh8a(xdata);
 
 2452                                        ptp_debug (params,
"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.i8);
 
 2457                                        dpd->FactoryDefaultValue.str    = ptp_unpack_string(params, data, 0, &len);
 
 2458                                        dpd->CurrentValue.str           = ptp_unpack_string(params, data, 0, &len);
 
 2460                                        free (dpd->FactoryDefaultValue.str);
 
 2461                                        dpd->FactoryDefaultValue.str    = strdup( (
char*)xdata );
 
 2463                                        free (dpd->CurrentValue.str);
 
 2464                                        dpd->CurrentValue.str           = strdup( (
char*)xdata );
 
 2466                                        ptp_debug (params,
"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str);
 
 2476                                case PTP_DPC_CANON_EOS_ImageFormat:
 
 2477                                case PTP_DPC_CANON_EOS_ImageFormatCF:
 
 2478                                case PTP_DPC_CANON_EOS_ImageFormatSD:
 
 2479                                case PTP_DPC_CANON_EOS_ImageFormatExtHD:
 
 2480                                        dpd->DataType = PTP_DTC_UINT16;
 
 2481                                        dpd->FactoryDefaultValue.u16    = ptp_unpack_EOS_ImageFormat( params, &xdata );
 
 2482                                        dpd->CurrentValue.u16           = dpd->FactoryDefaultValue.u16;
 
 2483                                        ptp_debug (params,
"event %d: decoded imageformat, currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16);
 
 2485                                case PTP_DPC_CANON_EOS_CustomFuncEx:
 
 2486                                        dpd->DataType = PTP_DTC_STR;
 
 2487                                        free (dpd->FactoryDefaultValue.str);
 
 2488                                        free (dpd->CurrentValue.str);
 
 2489                                        dpd->FactoryDefaultValue.str    = ptp_unpack_EOS_CustomFuncEx( params, &xdata );
 
 2490                                        dpd->CurrentValue.str           = strdup( (
char*)dpd->FactoryDefaultValue.str );
 
 2491                                        ptp_debug (params,
"event %d: decoded custom function, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str);
 
 2493                                case PTP_DPC_CANON_EOS_FocusInfoEx:
 
 2494                                        dpd->DataType = PTP_DTC_STR;
 
 2495                                        free (dpd->FactoryDefaultValue.str);
 
 2496                                        free (dpd->CurrentValue.str);
 
 2497                                        dpd->FactoryDefaultValue.str    = ptp_unpack_EOS_FocusInfoEx( params, &xdata, size );
 
 2498                                        dpd->CurrentValue.str           = strdup( (
char*)dpd->FactoryDefaultValue.str );
 
 2499                                        ptp_debug (params,
"event %d: decoded focus info, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str);
 
 2516                case PTP_EC_CANON_EOS_OLCInfoChanged: {
 
 2517                        uint32_t                len, curoff;
 
 2518                        uint16_t                mask,proptype;
 
 2522                        dpd = _lookup_or_allocate_canon_prop(params, PTP_DPC_CANON_EOS_OLCInfoVersion);
 
 2524                                ptp_debug (params, 
"olcinfoversion is %d", dpd->CurrentValue.u32);
 
 2525                                olcver = dpd->CurrentValue.u32;
 
 2529                        ptp_debug (params, 
"event %d: EOS event OLCInfoChanged (size %d)", i, size);
 
 2532                                for (k=8;k<size;k++)
 
 2533                                        ptp_debug (params, 
"    %d: %02x", k-8, curdata[k]);
 
 2535                        len = dtoh32a(curdata+8);
 
 2536                        if ((len != size-8) && (len != size-4)) {
 
 2537                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2538                                ce[i].u.info = strdup(
"OLC size unexpected");
 
 2539                                ptp_debug (params, 
"event %d: OLC unexpected size %d for blob len %d (not -4 nor -8)", i, size, len);
 
 2542                        mask = dtoh16a(curdata+8+4);
 
 2544                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2545                                ce[i].u.info = strdup(
"OLC size too small");
 
 2546                                ptp_debug (params, 
"event %d: OLC unexpected size %d", i, size);
 
 2550                        if (mask & CANON_EOS_OLC_BUTTON) {
 
 2551                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2552                                ce[i].u.info = malloc(strlen(
"Button 1234567"));
 
 2553                                sprintf(ce[i].u.info, 
"Button %d",  dtoh16a(curdata+curoff));
 
 2558                        if (mask & CANON_EOS_OLC_SHUTTERSPEED) {
 
 2566                                proptype = PTP_DPC_CANON_EOS_ShutterSpeed;
 
 2567                                dpd = _lookup_or_allocate_canon_prop(params, proptype);
 
 2568                                dpd->CurrentValue.u16 = curdata[curoff+5]; 
 
 2570                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 
 2571                                ce[i].u.propid = proptype;
 
 2592                        if (mask & CANON_EOS_OLC_APERTURE) {
 
 2598                                proptype = PTP_DPC_CANON_EOS_Aperture;
 
 2599                                dpd = _lookup_or_allocate_canon_prop(params, proptype);
 
 2600                                dpd->CurrentValue.u16 = curdata[curoff+4]; 
 
 2602                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 
 2603                                ce[i].u.propid = proptype;
 
 2604                                if (olcver >= 0xf) {
 
 2611                        if (mask & CANON_EOS_OLC_ISO) {
 
 2614                                proptype = PTP_DPC_CANON_EOS_ISOSpeed;
 
 2615                                dpd = _lookup_or_allocate_canon_prop(params, proptype);
 
 2616                                dpd->CurrentValue.u16 = curdata[curoff+3]; 
 
 2618                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 
 2619                                ce[i].u.propid = proptype;
 
 2623                        if (mask & 0x0010) {
 
 2625                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2626                                ce[i].u.info = malloc(strlen(
"OLCInfo event 0x0010 content 01234567")+1);
 
 2627                                sprintf(ce[i].u.info,
"OLCInfo event 0x0010 content %02x%02x%02x%02x",
 
 2636                        if (mask & 0x0020) {
 
 2641                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2642                                ce[i].u.info = malloc(strlen(
"OLCInfo event 0x0020 content 0123456789ab")+1);
 
 2643                                sprintf(ce[i].u.info,
"OLCInfo event 0x0020 content %02x%02x%02x%02x%02x%02x",
 
 2654                        if (mask & 0x0040) {
 
 2655                                int     value = (
signed char)curdata[curoff+2];
 
 2658                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2659                                ce[i].u.info = malloc(strlen(
"OLCInfo exposure indicator 012345678901234567890123456789abcd")+1);
 
 2660                                sprintf(ce[i].u.info,
"OLCInfo exposure indicator %d,%d,%d.%d (%02x%02x%02x%02x)",
 
 2663                                        value/10,abs(value)%10,
 
 2672                        if (mask & 0x0080) {
 
 2674                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2675                                ce[i].u.info = malloc(strlen(
"OLCInfo event 0x0080 content 01234567")+1);
 
 2676                                sprintf(ce[i].u.info,
"OLCInfo event 0x0080 content %02x%02x%02x%02x",
 
 2685                        if (mask & 0x0100) {
 
 2687                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO;
 
 2688                                ce[i].u.info = malloc(strlen(
"0123456789ab")+1);
 
 2689                                sprintf(ce[i].u.info,
"%02x%02x%02x%02x%02x%02x",
 
 2700                        if (mask & 0x0200) {
 
 2702                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSMASK;
 
 2703                                ce[i].u.info = malloc(strlen(
"0123456789abcd0123456789abcdef")+1);
 
 2704                                sprintf(ce[i].u.info,
"%02x%02x%02x%02x%02x%02x%02x",
 
 2716                        if (mask & 0x0400) {
 
 2718                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2719                                ce[i].u.info = malloc(strlen(
"OLCInfo event 0x0400 content 0123456789abcd")+1);
 
 2720                                sprintf(ce[i].u.info,
"OLCInfo event 0x0400 content %02x%02x%02x%02x%02x%02x%02x",
 
 2732                        if (mask & 0x0800) {
 
 2735                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2736                                ce[i].u.info = malloc(strlen(
"OLCInfo event 0x0800 content 0123456789abcdef")+1);
 
 2737                                sprintf(ce[i].u.info,
"OLCInfo event 0x0800 content %02x%02x%02x%02x%02x%02x%02x%02x",
 
 2750                        if (mask & 0x1000) {
 
 2752                                ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2753                                ce[i].u.info = malloc(strlen(
"OLCInfo event 0x1000 content 01")+1);
 
 2754                                sprintf(ce[i].u.info,
"OLCInfo event 0x1000 content %02x",
 
 2761                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2762                        ce[i].u.info = malloc(strlen(
"OLCInfo event mask 0123456789")+1);
 
 2763                        sprintf(ce[i].u.info, 
"OLCInfo event mask=%x",  mask);
 
 2766                case PTP_EC_CANON_EOS_CameraStatusChanged:
 
 2767                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS;
 
 2768                        ce[i].u.status =  dtoh32a(curdata+8);
 
 2769                        ptp_debug (params, 
"event %d: EOS event CameraStatusChanged (size %d) = %d", i, size, dtoh32a(curdata+8));
 
 2770                        params->eos_camerastatus = dtoh32a(curdata+8);
 
 2775                        ptp_debug (params, 
"event %d: EOS event 0, but size %d", i, size);
 
 2777                case PTP_EC_CANON_EOS_BulbExposureTime:
 
 2778                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2779                        ce[i].u.info = malloc(strlen(
"BulbExposureTime 123456789012345678"));
 
 2780                        sprintf (ce[i].u.info, 
"BulbExposureTime %u",  dtoh32a(curdata+8));
 
 2782                case PTP_EC_CANON_EOS_ObjectRemoved:
 
 2783                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTREMOVED;
 
 2784                        ce[i].u.object.oid = dtoh32a(curdata+8);
 
 2788#define XX(x)           case PTP_EC_CANON_EOS_##x:                                                              \ 
 2789                                ptp_debug (params, "event %u: unhandled EOS event "#x" (size %u)", i, size);    \ 
 2790                                ce[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 12345678901)")+1); \ 
 2791                                sprintf (ce[i].u.info, "unhandled EOS event "#x" (size %u)",  size);            \ 
 2794                        XX(RequestGetObjectInfoEx)
 
 2795                        XX(StorageStatusChanged)
 
 2796                        XX(StorageInfoChanged)
 
 2797                        XX(ObjectInfoChangedEx)
 
 2798                        XX(ObjectContentChanged)
 
 2799                        XX(WillSoonShutdown)
 
 2800                        XX(ShutdownTimerUpdated)
 
 2801                        XX(RequestCancelTransfer)
 
 2802                        XX(RequestObjectTransferDT)
 
 2803                        XX(RequestCancelTransferDT)
 
 2806                        XX(BulbExposureTime)
 
 2808                        XX(RequestObjectTransferTS)
 
 2810                        XX(PowerZoomInfoChanged)
 
 2811                        XX(CTGInfoCheckComplete)
 
 2814                                ptp_debug (params, 
"event %d: unknown EOS event %04x", i, type);
 
 2820                                for (j=8;j<size;j++)
 
 2821                                        ptp_debug (params, 
"    %d: %02x", j, curdata[j]);
 
 2823                        ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 
 2829                        ptp_debug (params, 
"BAD: i %d, entries %d", i, entries);
 
 2843#define PTP_nikon_ec_Length             0 
 2844#define PTP_nikon_ec_Code               2 
 2845#define PTP_nikon_ec_Param1             4 
 2846#define PTP_nikon_ec_Size               6 
 2848ptp_unpack_Nikon_EC (
PTPParams *params, 
unsigned char* data, 
unsigned int len, 
PTPContainer **ec, 
unsigned int *cnt)
 
 2855        if (len < PTP_nikon_ec_Code)
 
 2857        *cnt = dtoh16a(&data[PTP_nikon_ec_Length]);
 
 2858        if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) { 
 
 2867        for (i=0;i<*cnt;i++) {
 
 2869                (*ec)[i].Code   = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]);
 
 2870                (*ec)[i].Param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]);
 
 2871                (*ec)[i].Nparam = 1;
 
 2878#define PTP_nikon_ec_ex_Length          0 
 2879#define PTP_nikon_ec_ex_Code            2 
 2882ptp_unpack_Nikon_EC_EX (
PTPParams *params, 
unsigned char* data, 
unsigned int len, 
PTPContainer **ec, 
unsigned int *cnt)
 
 2884        unsigned int i, offset;
 
 2889        if (len < PTP_nikon_ec_ex_Code)
 
 2891        *cnt = dtoh16a(&data[PTP_nikon_ec_ex_Length]);
 
 2892        if (*cnt > (len-PTP_nikon_ec_ex_Code)/4) { 
 
 2900        offset = PTP_nikon_ec_ex_Code+
sizeof(uint16_t);
 
 2902        for (i=0;i<*cnt;i++) {
 
 2904                if (len - offset < 4) {
 
 2910                (*ec)[i].Code   = dtoh16a(&data[offset]);
 
 2911                (*ec)[i].Nparam = dtoh16a(&data[offset+2]);
 
 2912                ptp_debug (params, 
"nikon eventex %d: code 0x%04x, params %d", i, (*ec)[i].Code, (*ec)[i].Nparam);
 
 2913                if (    ((*ec)[i].Nparam > 5)                                   ||
 
 2914                        (len < ((*ec)[i].Nparam*
sizeof(uint32_t)) + 4 + offset)
 
 2921                switch ((*ec)[i].Nparam) {
 
 2922                case 5: (*ec)[i].Param5 = dtoh32a(&data[offset+4+
sizeof(uint32_t)*4]);
 
 2923                case 4: (*ec)[i].Param4 = dtoh32a(&data[offset+4+
sizeof(uint32_t)*3]);
 
 2924                case 3: (*ec)[i].Param3 = dtoh32a(&data[offset+4+
sizeof(uint32_t)*2]);
 
 2925                case 2: (*ec)[i].Param2 = dtoh32a(&data[offset+4+
sizeof(uint32_t)*1]);
 
 2926                case 1: (*ec)[i].Param1 = dtoh32a(&data[offset+4]);
 
 2930                offset += (*ec)[i].Nparam*
sizeof(uint32_t) + 4;
 
 2935static inline uint32_t
 
 2939        unsigned char *curdata;
 
 2941        len =   2*(strlen(text->title)+1)+1+
 
 2942                2*(strlen(text->line[0])+1)+1+
 
 2943                2*(strlen(text->line[1])+1)+1+
 
 2944                2*(strlen(text->line[2])+1)+1+
 
 2945                2*(strlen(text->line[3])+1)+1+
 
 2946                2*(strlen(text->line[4])+1)+1+
 
 2947                4*2+2*4+2+4+2+5*4*2;
 
 2948        *data = malloc(len);
 
 2949        if (!*data) 
return 0;
 
 2952        htod16a(curdata,100);curdata+=2;
 
 2953        htod16a(curdata,1);curdata+=2;
 
 2954        htod16a(curdata,0);curdata+=2;
 
 2955        htod16a(curdata,1000);curdata+=2;
 
 2957        htod32a(curdata,0);curdata+=4;
 
 2958        htod32a(curdata,0);curdata+=4;
 
 2960        htod16a(curdata,6);curdata+=2;
 
 2961        htod32a(curdata,0);curdata+=4;
 
 2963        ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2;
 
 2964        htod16a(curdata,0x10);curdata+=2;
 
 2967                ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2;
 
 2968                htod16a(curdata,0x10);curdata+=2;
 
 2969                htod16a(curdata,0x01);curdata+=2;
 
 2970                htod16a(curdata,0x02);curdata+=2;
 
 2971                htod16a(curdata,0x06);curdata+=2;
 
 2976#define ptp_canon_dir_version   0x00 
 2977#define ptp_canon_dir_ofc       0x02 
 2978#define ptp_canon_dir_unk1      0x04 
 2979#define ptp_canon_dir_objectid  0x08 
 2980#define ptp_canon_dir_parentid  0x0c 
 2981#define ptp_canon_dir_previd    0x10     
 2982#define ptp_canon_dir_nextid    0x14     
 2983#define ptp_canon_dir_nextchild 0x18     
 2984#define ptp_canon_dir_storageid 0x1c     
 2985#define ptp_canon_dir_name      0x20 
 2986#define ptp_canon_dir_flags     0x2c 
 2987#define ptp_canon_dir_size      0x30 
 2988#define ptp_canon_dir_unixtime  0x34 
 2989#define ptp_canon_dir_year      0x38 
 2990#define ptp_canon_dir_month     0x39 
 2991#define ptp_canon_dir_mday      0x3a 
 2992#define ptp_canon_dir_hour      0x3b 
 2993#define ptp_canon_dir_minute    0x3c 
 2994#define ptp_canon_dir_second    0x3d 
 2995#define ptp_canon_dir_unk2      0x3e 
 2996#define ptp_canon_dir_thumbsize 0x40 
 2997#define ptp_canon_dir_width     0x44 
 2998#define ptp_canon_dir_height    0x48 
 3000static inline uint16_t
 
 3001ptp_unpack_canon_directory (
 
 3009        unsigned int    i, j, nrofobs = 0, curob = 0;
 
 3011#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 
 3013                if (ISOBJECT(dir+i*0x4c)) nrofobs++;
 
 3014        handles->n = nrofobs;
 
 3015        handles->Handler = calloc(nrofobs,
sizeof(handles->Handler[0]));
 
 3016        if (!handles->Handler) 
return PTP_RC_GeneralError;
 
 3017        *oinfos = calloc(nrofobs,
sizeof((*oinfos)[0]));
 
 3018        if (!*oinfos) 
return PTP_RC_GeneralError;
 
 3019        *flags  = calloc(nrofobs,
sizeof((*flags)[0]));
 
 3020        if (!*flags) 
return PTP_RC_GeneralError;
 
 3026        for (i=0;i<cnt;i++) {
 
 3027                unsigned char   *cur = dir+i*0x4c;
 
 3033                handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid);
 
 3034                oi->StorageID           = 0xffffffff;
 
 3035                oi->ObjectFormat        = dtoh16a(cur + ptp_canon_dir_ofc);
 
 3036                oi->ParentObject        = dtoh32a(cur + ptp_canon_dir_parentid);
 
 3037                oi->Filename            = strdup((
char*)(cur + ptp_canon_dir_name));
 
 3038                oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size);
 
 3039                oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize);
 
 3040                oi->ImagePixWidth       = dtoh32a(cur + ptp_canon_dir_width);
 
 3041                oi->ImagePixHeight      = dtoh32a(cur + ptp_canon_dir_height);
 
 3042                oi->CaptureDate         = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime);
 
 3043                (*flags)[curob]         = dtoh32a(cur + ptp_canon_dir_flags);
 
 3048        for (i=0;i<cnt;i++) {
 
 3049                unsigned char   *cur = dir+i*0x4c;
 
 3050                uint32_t        nextchild = dtoh32a(cur + ptp_canon_dir_nextchild);
 
 3054                for (j=0;j<handles->n;j++) 
if (nextchild == handles->Handler[j]) 
break;
 
 3055                if (j == handles->n) 
continue;
 
 3056                (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid);
 
 3060                unsigned int changed = 0;
 
 3061                for (i=0;i<cnt;i++) {
 
 3062                        unsigned char   *cur = dir+i*0x4c;
 
 3063                        uint32_t        oid = dtoh32a(cur + ptp_canon_dir_objectid);
 
 3064                        uint32_t        nextoid = dtoh32a(cur + ptp_canon_dir_nextid);
 
 3065                        uint32_t        nextchild = dtoh32a(cur + ptp_canon_dir_nextchild);
 
 3070                        for (j=0;j<handles->n;j++) 
if (oid == handles->Handler[j]) 
break;
 
 3071                        if (j == handles->n) {
 
 3075                        storageid = (*oinfos)[j].StorageID;
 
 3076                        if (storageid == 0xffffffff) 
continue;
 
 3077                        if (nextoid != 0xffffffff) {
 
 3078                                for (j=0;j<handles->n;j++) 
if (nextoid == handles->Handler[j]) 
break;
 
 3079                                if (j == handles->n) {
 
 3083                                if ((*oinfos)[j].StorageID == 0xffffffff) {
 
 3084                                        (*oinfos)[j].StorageID = storageid;
 
 3088                        if (nextchild != 0xffffffff) {
 
 3089                                for (j=0;j<handles->n;j++) 
if (nextchild == handles->Handler[j]) 
break;
 
 3090                                if (j == handles->n) {
 
 3094                                if ((*oinfos)[j].StorageID == 0xffffffff) {
 
 3095                                        (*oinfos)[j].StorageID = storageid;
 
 3105                if (!changed || (changed==nrofobs-1))
 
 3113ptp_unpack_ptp11_manifest (
 
 3115        unsigned char           *data,
 
 3116        unsigned int            datalen,
 
 3120        uint64_t                numberoifs, i;
 
 3121        unsigned int            curoffset;
 
 3126        numberoifs = dtoh64ap(params,data);
 
 3132        for (i = 0; i < numberoifs; i++) {
 
 3137                if (curoffset + 34 + 2 > datalen)
 
 3140                oif->ObjectHandle               = dtoh32ap(params,data+curoffset);
 
 3141                oif->StorageID                  = dtoh32ap(params,data+curoffset+4);
 
 3142                oif->ObjectFormat               = dtoh16ap(params,data+curoffset+8);
 
 3143                oif->ProtectionStatus           = dtoh16ap(params,data+curoffset+10);
 
 3144                oif->ObjectCompressedSize64     = dtoh64ap(params,data+curoffset+12);
 
 3145                oif->ParentObject               = dtoh32ap(params,data+curoffset+20);
 
 3146                oif->AssociationType            = dtoh16ap(params,data+curoffset+24);
 
 3147                oif->AssociationDesc            = dtoh32ap(params,data+curoffset+26);
 
 3148                oif->SequenceNumber             = dtoh32ap(params,data+curoffset+30);
 
 3149                if (!ptp_unpack_string(params, data, curoffset+34, datalen, &len, &oif->Filename))
 
 3151                if (curoffset+34+len*2+1 > datalen)
 
 3154                if (!ptp_unpack_string(params, data, curoffset+len*2+1+34, datalen, &dlen, &modify_date))
 
 3157                oif->ModificationDate           = ptp_unpack_PTPTIME(modify_date);
 
 3159                curoffset += 34+len*2+dlen*2+2;
 
 3161        *numoifs = numberoifs;
 
 3165        for (i = 0; i < numberoifs; i++)
 
 3166                if (xoifs[i].Filename) free (xoifs[i].Filename);
 
 3177        header->version_major = dtoh32a(&data[off]);
 
 3178        header->version_minor = dtoh32a(&data[off+=4]);
 
 3179        header->lcd_aspect_ratio = dtoh32a(&data[off+=4]);
 
 3180        header->palette_type = dtoh32a(&data[off+=4]);
 
 3181        header->palette_data_start = dtoh32a(&data[off+=4]);
 
 3182        header->vp_desc_start = dtoh32a(&data[off+=4]);
 
 3183        header->bm_desc_start = dtoh32a(&data[off+=4]);
 
 3184        if (header->version_minor > 1)
 
 3185                header->bmo_desc_start = dtoh32a(&data[off+=4]);
 
 3194        fd->fb_type = dtoh32a(&data[off]);
 
 3195        fd->data_start = dtoh32a(&data[off+=4]);
 
 3196        fd->buffer_width = dtoh32a(&data[off+=4]);
 
 3197        fd->visible_width = dtoh32a(&data[off+=4]);
 
 3198        fd->visible_height = dtoh32a(&data[off+=4]);
 
 3199        fd->margin_left = dtoh32a(&data[off+=4]);
 
 3200        fd->margin_top = dtoh32a(&data[off+=4]);
 
 3201        fd->margin_right = dtoh32a(&data[off+=4]);
 
 3202        fd->margin_bot = dtoh32a(&data[off+=4]);
 
 3207        if (!data) 
return PTP_RC_GeneralError;
 
 3208        if (size < 36) 
return PTP_RC_GeneralError;
 
 3210        si->DatasetSize         = dtoh64ap(params,data+0);
 
 3211        si->TimeResolution      = dtoh64ap(params,data+8);
 
 3212        si->FrameHeaderSize     = dtoh32ap(params,data+16);
 
 3213        si->FrameMaxSize        = dtoh32ap(params,data+20);
 
 3214        si->PacketHeaderSize    = dtoh32ap(params,data+24);
 
 3215        si->PacketMaxSize       = dtoh32ap(params,data+28);
 
 3216        si->PacketAlignment     = dtoh32ap(params,data+32);
 
Definition chdk_live_view.h:65