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