| Index: src/ptp-pack.c
 | 
| diff --git a/src/ptp-pack.c b/src/ptp-pack.c
 | 
| index ea6bfc92fba5fef79fd1d628c4b3d324824e6084..5bf90e095b923c366bcfd36b81ae8c456b091edf 100644
 | 
| --- a/src/ptp-pack.c
 | 
| +++ b/src/ptp-pack.c
 | 
| @@ -1,7 +1,7 @@
 | 
|  /* ptp-pack.c
 | 
|   *
 | 
|   * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl>
 | 
| - * Copyright (C) 2003-2014 Marcus Meissner <marcus@jet.franken.de>
 | 
| + * Copyright (C) 2003-2012 Marcus Meissner <marcus@jet.franken.de>
 | 
|   * Copyright (C) 2006-2008 Linus Walleij <triad@df.lth.se>
 | 
|   * Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com>
 | 
|   * Copyright (C) 2009 Axel Waggershauser <awagger@web.de>
 | 
| @@ -18,19 +18,13 @@
 | 
|   *
 | 
|   * You should have received a copy of the GNU Lesser General Public
 | 
|   * License along with this library; if not, write to the
 | 
| - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 | 
| - * Boston, MA  02110-1301  USA
 | 
| + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
| + * Boston, MA 02111-1307, USA.
 | 
|   */
 | 
|  
 | 
|  /* currently this file is included into ptp.c */
 | 
|  
 | 
| -#ifdef HAVE_LIMITS_H
 | 
| -#include <limits.h>
 | 
| -#endif
 | 
| -#ifndef UINT_MAX
 | 
| -# define UINT_MAX 0xFFFFFFFF
 | 
| -#endif
 | 
| -#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H)
 | 
| +#ifdef HAVE_ICONV
 | 
|  #include <iconv.h>
 | 
|  #endif
 | 
|  
 | 
| @@ -152,7 +146,7 @@ ptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8
 | 
|  	dest = loclstr;
 | 
|  	destlen = sizeof(loclstr)-1;
 | 
|  	nconv = (size_t)-1;
 | 
| -#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H)
 | 
| +#ifdef HAVE_ICONV
 | 
|  	if (params->cd_ucs2_to_locale != (iconv_t)-1)
 | 
|  		nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, &dest, &destlen);
 | 
|  #endif
 | 
| @@ -193,7 +187,7 @@ ptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t o
 | 
|  
 | 
|  	/* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */
 | 
|  	memset(ucs2strp, 0, sizeof(ucs2str));  /* XXX: necessary? */
 | 
| -#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H)
 | 
| +#ifdef HAVE_ICONV
 | 
|  	if (params->cd_locale_to_ucs2 != (iconv_t)-1) {
 | 
|  		size_t nconv;
 | 
|  		size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */
 | 
| @@ -206,8 +200,7 @@ ptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t o
 | 
|  	} else
 | 
|  #endif
 | 
|  	{
 | 
| -		unsigned int i;
 | 
| -
 | 
| +		int i;
 | 
|  		for (i=0;i<convlen;i++) {
 | 
|  			ucs2str[i] = string[i];
 | 
|  		}
 | 
| @@ -258,31 +251,16 @@ ptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size
 | 
|  }
 | 
|  
 | 
|  static inline uint32_t
 | 
| -ptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, unsigned int offset, unsigned int datalen, uint32_t **array)
 | 
| +ptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array)
 | 
|  {
 | 
|  	uint32_t n, i=0;
 | 
|  
 | 
| -	if (offset >= datalen)
 | 
| -		return 0;
 | 
| -
 | 
| -	if (offset + sizeof(uint32_t) > datalen)
 | 
| -		return 0;
 | 
| -
 | 
| -	*array = NULL;
 | 
|  	n=dtoh32a(&data[offset]);
 | 
| -	if (n >= UINT_MAX/sizeof(uint32_t))
 | 
| -		return 0;
 | 
| -	if (!n)
 | 
| -		return 0;
 | 
| -
 | 
| -	if (offset + sizeof(uint32_t)*(n+1) > datalen) {
 | 
| -		ptp_debug (params ,"array runs over datalen bufferend (%d vs %d)", offset + sizeof(uint32_t)*(n+1) , datalen);
 | 
| -		return 0;
 | 
| -	}
 | 
| -
 | 
|  	*array = malloc (n*sizeof(uint32_t));
 | 
| -	for (i=0;i<n;i++)
 | 
| +	while (n>i) {
 | 
|  		(*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]);
 | 
| +		i++;
 | 
| +	}
 | 
|  	return n;
 | 
|  }
 | 
|  
 | 
| @@ -299,25 +277,16 @@ ptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, u
 | 
|  }
 | 
|  
 | 
|  static inline uint32_t
 | 
| -ptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, unsigned int offset, unsigned int datalen, uint16_t **array)
 | 
| +ptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array)
 | 
|  {
 | 
|  	uint32_t n, i=0;
 | 
|  
 | 
| -	*array = NULL;
 | 
|  	n=dtoh32a(&data[offset]);
 | 
| -	if (n >= UINT_MAX/sizeof(uint16_t))
 | 
| -		return 0;
 | 
| -	if (!n)
 | 
| -		return 0;
 | 
| -	if (offset + sizeof(uint32_t) > datalen)
 | 
| -		return 0;
 | 
| -	if (offset + sizeof(uint32_t)+sizeof(uint16_t)*n > datalen) {
 | 
| -		ptp_debug (params ,"array runs over datalen bufferend (%d vs %d)", offset + sizeof(uint32_t)+n*sizeof(uint16_t) , datalen);
 | 
| -		return 0;
 | 
| -	}
 | 
|  	*array = malloc (n*sizeof(uint16_t));
 | 
| -	for (i=0;i<n;i++)
 | 
| +	while (n>i) {
 | 
|  		(*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]);
 | 
| +		i++;
 | 
| +	}
 | 
|  	return n;
 | 
|  }
 | 
|  
 | 
| @@ -351,28 +320,23 @@ ptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsign
 | 
|  		dtoh16a(&data[PTP_di_FunctionalMode+totallen]);
 | 
|  	di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data,
 | 
|  		PTP_di_OperationsSupported+totallen,
 | 
| -		datalen,
 | 
|  		&di->OperationsSupported);
 | 
|  	totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
 | 
|  	di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data,
 | 
|  		PTP_di_OperationsSupported+totallen,
 | 
| -		datalen,
 | 
|  		&di->EventsSupported);
 | 
|  	totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
 | 
|  	di->DevicePropertiesSupported_len =
 | 
|  		ptp_unpack_uint16_t_array(params, data,
 | 
|  		PTP_di_OperationsSupported+totallen,
 | 
| -		datalen,
 | 
|  		&di->DevicePropertiesSupported);
 | 
|  	totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
 | 
|  	di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data,
 | 
|  		PTP_di_OperationsSupported+totallen,
 | 
| -		datalen,
 | 
|  		&di->CaptureFormats);
 | 
|  	totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t);
 | 
|  	di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data,
 | 
|  		PTP_di_OperationsSupported+totallen,
 | 
| -		datalen,
 | 
|  		&di->ImageFormats);
 | 
|  	totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t);
 | 
|  	di->Manufacturer = ptp_unpack_string(params, data,
 | 
| @@ -392,44 +356,44 @@ ptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsign
 | 
|  		&len);
 | 
|  }
 | 
|  
 | 
| -inline static void
 | 
| +static void inline
 | 
|  ptp_free_DI (PTPDeviceInfo *di) {
 | 
| -	free (di->SerialNumber);
 | 
| -	free (di->DeviceVersion);
 | 
| -	free (di->Model);
 | 
| -	free (di->Manufacturer);
 | 
| -	free (di->ImageFormats);
 | 
| -	free (di->CaptureFormats);
 | 
| -	free (di->VendorExtensionDesc);
 | 
| -	free (di->OperationsSupported);
 | 
| -	free (di->EventsSupported);
 | 
| -	free (di->DevicePropertiesSupported);
 | 
| +	if (di->SerialNumber) free (di->SerialNumber);
 | 
| +	if (di->DeviceVersion) free (di->DeviceVersion);
 | 
| +	if (di->Model) free (di->Model);
 | 
| +	if (di->Manufacturer) free (di->Manufacturer);
 | 
| +	if (di->ImageFormats) free (di->ImageFormats);
 | 
| +	if (di->CaptureFormats) free (di->CaptureFormats);
 | 
| +	if (di->VendorExtensionDesc) free (di->VendorExtensionDesc);
 | 
| +	if (di->OperationsSupported) free (di->OperationsSupported);
 | 
| +	if (di->EventsSupported) free (di->EventsSupported);
 | 
| +	if (di->DevicePropertiesSupported) free (di->DevicePropertiesSupported);
 | 
|  }
 | 
|  
 | 
|  /* EOS Device Info unpack */
 | 
|  static inline void
 | 
|  ptp_unpack_EOS_DI (PTPParams *params, unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen)
 | 
|  {
 | 
| -	unsigned int totallen = 4;
 | 
| +	int totallen = 4;
 | 
|  
 | 
|  	memset (di,0, sizeof(*di));
 | 
|  	if (datalen < 8) return;
 | 
|  
 | 
|  	/* uint32_t struct len - ignore */
 | 
|  	di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data,
 | 
| -		totallen, datalen, &di->EventsSupported);
 | 
| +		totallen, &di->EventsSupported);
 | 
|  	if (!di->EventsSupported) return;
 | 
|  	totallen += di->EventsSupported_len*sizeof(uint32_t)+4;
 | 
|  	if (totallen >= datalen) return;
 | 
|  
 | 
|  	di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data,
 | 
| -		totallen, datalen, &di->DevicePropertiesSupported);
 | 
| +		totallen, &di->DevicePropertiesSupported);
 | 
|  	if (!di->DevicePropertiesSupported) return;
 | 
|  	totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4;
 | 
|  	if (totallen >= datalen) return;
 | 
|  
 | 
|  	di->unk_len = ptp_unpack_uint32_t_array(params, data,
 | 
| -		totallen, datalen, &di->unk);
 | 
| +		totallen, &di->unk);
 | 
|  	if (!di->unk) return;
 | 
|  	totallen += di->unk_len*sizeof(uint32_t)+4;
 | 
|  	return;
 | 
| @@ -451,7 +415,7 @@ static inline void
 | 
|  ptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len)
 | 
|  {
 | 
|  	if (len) {
 | 
| -		oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, len, &oh->Handler);
 | 
| +		oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler);
 | 
|  	} else {
 | 
|  		oh->n = 0;
 | 
|  		oh->Handler = NULL;
 | 
| @@ -465,12 +429,13 @@ ptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, uns
 | 
|  static inline void
 | 
|  ptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len)
 | 
|  {
 | 
| -	if (!data || !len) {
 | 
| +        if (!data && !len) {
 | 
|  		sids->n = 0;
 | 
|  		sids->Storage = NULL;
 | 
|  		return;
 | 
|          }
 | 
| -	sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, len, &sids->Storage);
 | 
| +	sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids,
 | 
| +	&sids->Storage);
 | 
|  }
 | 
|  
 | 
|  /* StorageInfo pack/unpack */
 | 
| @@ -488,15 +453,12 @@ ptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsig
 | 
|  {
 | 
|  	uint8_t storagedescriptionlen;
 | 
|  
 | 
| -	if (len < 26) return;
 | 
|  	si->StorageType=dtoh16a(&data[PTP_si_StorageType]);
 | 
|  	si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]);
 | 
|  	si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]);
 | 
|  	si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]);
 | 
|  	si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]);
 | 
|  	si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]);
 | 
| -
 | 
| -	/* FIXME: check more lengths here */
 | 
|  	si->StorageDescription=ptp_unpack_string(params, data,
 | 
|  		PTP_si_StorageDescription, &storagedescriptionlen);
 | 
|  	si->VolumeLabel=ptp_unpack_string(params, data,
 | 
| @@ -642,12 +604,6 @@ ptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsign
 | 
|  	uint8_t capturedatelen;
 | 
|  	char *capture_date;
 | 
|  
 | 
| -	if (len < PTP_oi_SequenceNumber)
 | 
| -		return;
 | 
| -
 | 
| -	oi->Filename = oi->Keywords = NULL;
 | 
| -
 | 
| -	/* FIXME: also handle length with all the strings at the end */
 | 
|  	oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]);
 | 
|  	oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]);
 | 
|  	oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]);
 | 
| @@ -697,14 +653,12 @@ ptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsign
 | 
|  }
 | 
|  
 | 
|  #define RARR(val,member,func)	{			\
 | 
| -	unsigned int n,j;				\
 | 
| +	int n,j;					\
 | 
|  	if (total - *offset < sizeof(uint32_t))		\
 | 
|  		return 0;				\
 | 
|  	n = dtoh32a (&data[*offset]);			\
 | 
|  	*offset += sizeof(uint32_t);			\
 | 
|  							\
 | 
| -	if (n >= UINT_MAX/sizeof(val->a.v[0]))		\
 | 
| -		return 0;				\
 | 
|  	val->a.count = n;				\
 | 
|  	val->a.v = malloc(sizeof(val->a.v[0])*n);	\
 | 
|  	if (!val->a.v) return 0;			\
 | 
| @@ -712,9 +666,9 @@ ptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsign
 | 
|  		CTVAL(val->a.v[j].member, func);	\
 | 
|  }
 | 
|  
 | 
| -static inline unsigned int
 | 
| +static inline int
 | 
|  ptp_unpack_DPV (
 | 
| -	PTPParams *params, unsigned char* data, unsigned int *offset, unsigned int total,
 | 
| +	PTPParams *params, unsigned char* data, int *offset, int total,
 | 
|  	PTPPropertyValue* value, uint16_t datatype
 | 
|  ) {
 | 
|  	switch (datatype) {
 | 
| @@ -796,6 +750,7 @@ ptp_unpack_DPV (
 | 
|  }
 | 
|  
 | 
|  /* Device Property pack/unpack */
 | 
| +
 | 
|  #define PTP_dpd_DevicePropertyCode	0
 | 
|  #define PTP_dpd_DataType		2
 | 
|  #define PTP_dpd_GetSet			4
 | 
| @@ -804,7 +759,7 @@ ptp_unpack_DPV (
 | 
|  static inline int
 | 
|  ptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen)
 | 
|  {
 | 
| -	unsigned int offset = 0, ret;
 | 
| +	int offset=0, ret;
 | 
|  
 | 
|  	memset (dpd, 0, sizeof(*dpd));
 | 
|  	dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]);
 | 
| @@ -874,163 +829,7 @@ outofmemory:
 | 
|  	return 0;
 | 
|  }
 | 
|  
 | 
| -/* Device Property pack/unpack */
 | 
| -#define PTP_dpd_Sony_DevicePropertyCode	0
 | 
| -#define PTP_dpd_Sony_DataType		2
 | 
| -#define PTP_dpd_Sony_GetSet		4
 | 
| -#define PTP_dpd_Sony_Unknown		5
 | 
| -#define PTP_dpd_Sony_FactoryDefaultValue	6
 | 
| -
 | 
| -static inline int
 | 
| -ptp_unpack_Sony_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen, unsigned int *poffset)
 | 
| -{
 | 
| -	unsigned int ret;
 | 
| -#if 0
 | 
| -	unsigned int unk1, unk2;
 | 
| -#endif
 | 
| -
 | 
| -	memset (dpd, 0, sizeof(*dpd));
 | 
| -	dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_Sony_DevicePropertyCode]);
 | 
| -	dpd->DataType=dtoh16a(&data[PTP_dpd_Sony_DataType]);
 | 
| -
 | 
| -#if 0
 | 
| -	/* get set ? */
 | 
| -	unk1 = dtoh8a(&data[PTP_dpd_Sony_GetSet]);
 | 
| -	unk2 = dtoh8a(&data[PTP_dpd_Sony_Unknown]);
 | 
| -	ptp_debug (params, "prop 0x%04x, datatype 0x%04x, unk1 %d unk2 %d", dpd->DevicePropertyCode, dpd->DataType, unk1, unk2);
 | 
| -#endif
 | 
| -	dpd->GetSet=1;
 | 
| -
 | 
| -	dpd->FormFlag=PTP_DPFF_None;
 | 
| -
 | 
| -	*poffset = PTP_dpd_Sony_FactoryDefaultValue;
 | 
| -	ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType);
 | 
| -	if (!ret) goto outofmemory;
 | 
| -	if ((dpd->DataType == PTP_DTC_STR) && (*poffset == dpdlen))
 | 
| -		return 1;
 | 
| -	ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->CurrentValue, dpd->DataType);
 | 
| -	if (!ret) goto outofmemory;
 | 
| -
 | 
| -	/* if offset==0 then Data Type format is not supported by this
 | 
| -	   code or the Data Type is a string (with two empty strings as
 | 
| -	   values). In both cases Form Flag should be set to 0x00 and FORM is
 | 
| -	   not present. */
 | 
| -
 | 
| -	if (*poffset==PTP_dpd_Sony_FactoryDefaultValue)
 | 
| -		return 1;
 | 
| -
 | 
| -	dpd->FormFlag=dtoh8a(&data[*poffset]);
 | 
| -	*poffset+=sizeof(uint8_t);
 | 
| -
 | 
| -	switch (dpd->FormFlag) {
 | 
| -	case PTP_DPFF_Range:
 | 
| -		ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType);
 | 
| -		if (!ret) goto outofmemory;
 | 
| -		ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType);
 | 
| -		if (!ret) goto outofmemory;
 | 
| -		ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType);
 | 
| -		if (!ret) goto outofmemory;
 | 
| -		break;
 | 
| -	case PTP_DPFF_Enumeration: {
 | 
| -		int i;
 | 
| -#define N	dpd->FORM.Enum.NumberOfValues
 | 
| -		N = dtoh16a(&data[*poffset]);
 | 
| -		*poffset+=sizeof(uint16_t);
 | 
| -		dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0]));
 | 
| -		if (!dpd->FORM.Enum.SupportedValue)
 | 
| -			goto outofmemory;
 | 
| -
 | 
| -		memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0]));
 | 
| -		for (i=0;i<N;i++) {
 | 
| -			ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType);
 | 
| -
 | 
| -			/* Slightly different handling here. The HP PhotoSmart 120
 | 
| -			 * specifies an enumeration with N in wrong endian
 | 
| -			 * 00 01 instead of 01 00, so we count the enum just until the
 | 
| -			 * the end of the packet.
 | 
| -			 */
 | 
| -			if (!ret) {
 | 
| -				if (!i)
 | 
| -					goto outofmemory;
 | 
| -				dpd->FORM.Enum.NumberOfValues = i;
 | 
| -				break;
 | 
| -			}
 | 
| -		}
 | 
| -		}
 | 
| -	}
 | 
| -#undef N
 | 
| -	return 1;
 | 
| -outofmemory:
 | 
| -	ptp_free_devicepropdesc(dpd);
 | 
| -	return 0;
 | 
| -}
 | 
| -
 | 
| -static inline void
 | 
| -duplicate_PropertyValue (const PTPPropertyValue *src, PTPPropertyValue *dst, uint16_t type) {
 | 
| -	if (type == PTP_DTC_STR) {
 | 
| -		if (src->str)
 | 
| -			dst->str = strdup(src->str);
 | 
| -		else
 | 
| -			dst->str = NULL;
 | 
| -		return;
 | 
| -	}
 | 
| -
 | 
| -	if (type & PTP_DTC_ARRAY_MASK) {
 | 
| -		unsigned int i;
 | 
| -
 | 
| -		dst->a.count = src->a.count;
 | 
| -		dst->a.v = malloc (sizeof(src->a.v[0])*src->a.count);
 | 
| -		for (i=0;i<src->a.count;i++)
 | 
| -			duplicate_PropertyValue (&src->a.v[i], &dst->a.v[i], type & ~PTP_DTC_ARRAY_MASK);
 | 
| -		return;
 | 
| -	}
 | 
| -	switch (type & ~PTP_DTC_ARRAY_MASK) {
 | 
| -	case PTP_DTC_INT8:	dst->i8 = src->i8; break;
 | 
| -	case PTP_DTC_UINT8:	dst->u8 = src->u8; break;
 | 
| -	case PTP_DTC_INT16:	dst->i16 = src->i16; break;
 | 
| -	case PTP_DTC_UINT16:	dst->u16 = src->u16; break;
 | 
| -	case PTP_DTC_INT32:	dst->i32 = src->i32; break;
 | 
| -	case PTP_DTC_UINT32:	dst->u32 = src->u32; break;
 | 
| -	case PTP_DTC_UINT64:	dst->u64 = src->u64; break;
 | 
| -	case PTP_DTC_INT64:	dst->i64 = src->i64; break;
 | 
| -#if 0
 | 
| -	case PTP_DTC_INT128:	dst->i128 = src->i128; break;
 | 
| -	case PTP_DTC_UINT128:	dst->u128 = src->u128; break;
 | 
| -#endif
 | 
| -	default:		break;
 | 
| -	}
 | 
| -	return;
 | 
| -}
 | 
| -
 | 
| -static inline void
 | 
| -duplicate_DevicePropDesc(const PTPDevicePropDesc *src, PTPDevicePropDesc *dst) {
 | 
| -	int i;
 | 
| -
 | 
| -	dst->DevicePropertyCode	= src->DevicePropertyCode;
 | 
| -	dst->DataType		= src->DataType;
 | 
| -	dst->GetSet		= src->GetSet;
 | 
| -	
 | 
| -	duplicate_PropertyValue (&src->FactoryDefaultValue, &dst->FactoryDefaultValue, src->DataType);
 | 
| -	duplicate_PropertyValue (&src->CurrentValue, &dst->CurrentValue, src->DataType);
 | 
| -
 | 
| -	dst->FormFlag		= src->FormFlag;
 | 
| -	switch (src->FormFlag) {
 | 
| -	case PTP_DPFF_Range:
 | 
| -		duplicate_PropertyValue (&src->FORM.Range.MinimumValue, &dst->FORM.Range.MinimumValue, src->DataType);
 | 
| -		duplicate_PropertyValue (&src->FORM.Range.MaximumValue, &dst->FORM.Range.MaximumValue, src->DataType);
 | 
| -		duplicate_PropertyValue (&src->FORM.Range.StepSize,     &dst->FORM.Range.StepSize,     src->DataType);
 | 
| -		break;
 | 
| -	case PTP_DPFF_Enumeration:
 | 
| -		dst->FORM.Enum.NumberOfValues = src->FORM.Enum.NumberOfValues;
 | 
| -		dst->FORM.Enum.SupportedValue = malloc (sizeof(dst->FORM.Enum.SupportedValue[0])*src->FORM.Enum.NumberOfValues);
 | 
| -		for (i = 0; i<src->FORM.Enum.NumberOfValues ; i++)
 | 
| -			duplicate_PropertyValue (&src->FORM.Enum.SupportedValue[i], &dst->FORM.Enum.SupportedValue[i], src->DataType);
 | 
| -		break;
 | 
| -	case PTP_DPFF_None:
 | 
| -		break;
 | 
| -	}
 | 
| -}
 | 
| -
 | 
| +/* (MTP) Object Property pack/unpack */
 | 
|  #define PTP_opd_ObjectPropertyCode	0
 | 
|  #define PTP_opd_DataType		2
 | 
|  #define PTP_opd_GetSet			4
 | 
| @@ -1039,7 +838,7 @@ duplicate_DevicePropDesc(const PTPDevicePropDesc *src, PTPDevicePropDesc *dst) {
 | 
|  static inline int
 | 
|  ptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen)
 | 
|  {
 | 
| -	unsigned int offset=0, ret;
 | 
| +	int offset=0, ret;
 | 
|  
 | 
|  	memset (opd, 0, sizeof(*opd));
 | 
|  	opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]);
 | 
| @@ -1066,7 +865,7 @@ ptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd,
 | 
|  		if (!ret) goto outofmemory;
 | 
|  		break;
 | 
|  	case PTP_OPFF_Enumeration: {
 | 
| -		unsigned int i;
 | 
| +		int i;
 | 
|  #define N	opd->FORM.Enum.NumberOfValues
 | 
|  		N = dtoh16a(&data[offset]);
 | 
|  		offset+=sizeof(uint16_t);
 | 
| @@ -1105,7 +904,7 @@ ptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr
 | 
|  {
 | 
|  	unsigned char* dpv=NULL;
 | 
|  	uint32_t size=0;
 | 
| -	unsigned int i;
 | 
| +	int	i;
 | 
|  
 | 
|  	switch (datatype) {
 | 
|  	case PTP_DTC_INT8:
 | 
| @@ -1286,7 +1085,7 @@ ptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops,
 | 
|  { 
 | 
|  	uint32_t prop_count = dtoh32a(data);
 | 
|  	MTPProperties *props = NULL;
 | 
| -	unsigned int offset = 0, i;
 | 
| +	int offset = 0, i;
 | 
|  
 | 
|  	if (prop_count == 0) {
 | 
|  		*pprops = NULL;
 | 
| @@ -1344,18 +1143,13 @@ ptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops,
 | 
|  static inline void
 | 
|  ptp_unpack_EC (PTPParams *params, unsigned char* data, PTPContainer *ec, unsigned int len)
 | 
|  {
 | 
| -	unsigned int	length;
 | 
| +	int	length;
 | 
|  	int	type;
 | 
|  
 | 
|  	if (data==NULL)
 | 
|  		return;
 | 
|  	memset(ec,0,sizeof(*ec));
 | 
| -
 | 
|  	length=dtoh32a(&data[PTP_ec_Length]);
 | 
| -	if (length > len) {
 | 
| -		ptp_debug (params, "length %d in container, but data only %d bytes?!", length, len);
 | 
| -		return;
 | 
| -	}
 | 
|  	type = dtoh16a(&data[PTP_ec_Type]);
 | 
|  
 | 
|  	ec->Code=dtoh16a(&data[PTP_ec_Code]);
 | 
| @@ -1446,8 +1240,7 @@ ObjectInfo for 'IMG_0199.JPG':
 | 
|  0014  72 0c 74 92  OID
 | 
|  0018  01 00 02 00  StorageID
 | 
|  001c  01 38 00 00  OFC
 | 
| -0020  00 00 00 00 ??
 | 
| -0024  21 00 00 00  flags (4 bytes? 1 byte?)
 | 
| +0020  00 00 00 00 00 00 00 00  ? 
 | 
|  0028  19 d5 21 00  Size
 | 
|  002c  00 00 74 92  ?
 | 
|  0030  70 0c 74 92  OID
 | 
| @@ -1460,7 +1253,7 @@ ObjectInfo for 'IMG_0199.JPG':
 | 
|  #define PTP_cefe_ObjectHandle		0
 | 
|  #define PTP_cefe_StorageID		4
 | 
|  #define PTP_cefe_ObjectFormatCode	8
 | 
| -#define PTP_cefe_Flags			16
 | 
| +#define PTP_cefe_Flags			12
 | 
|  #define PTP_cefe_ObjectSize		20
 | 
|  #define PTP_cefe_Filename		32
 | 
|  #define PTP_cefe_Time			48
 | 
| @@ -1579,98 +1372,12 @@ ptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value
 | 
|  	return s;
 | 
|  }
 | 
|  
 | 
| -/* 00: 32 bit size
 | 
| - * 04: 16 bit subsize
 | 
| - * 08: 16 bit version (?)
 | 
| - * 0c: 16 bit focus_points_in_struct
 | 
| - * 10: 16 bit focus_points_in_use
 | 
| - * 14: variable arrays:
 | 
| - * 	16 bit sizex, 16 bit sizey
 | 
| - * 	16 bit othersizex, 16 bit othersizey
 | 
| - * 	16 bit array height[focus_points_in_struct]
 | 
| - * 	16 bit array width[focus_points_in_struct]
 | 
| - * 	16 bit array offsetheight[focus_points_in_struct] middle is 0
 | 
| - * 	16 bit array offsetwidth[focus_points_in_struct] middle is ?
 | 
| - * bitfield of selected focus points, starting with 0 [size focus_points_in_struct in bits]
 | 
| - * unknown stuff , likely which are active
 | 
| - * 16 bit 0xffff
 | 
| - *
 | 
| - * size=NxN,size2=NxN,points={NxNxNxN,NxNxNxN,...},selected={0,1,2}
 | 
| - */
 | 
| -static inline char*
 | 
| -ptp_unpack_EOS_FocusInfoEx (PTPParams* params, unsigned char** data )
 | 
| -{
 | 
| -	uint32_t size 			= dtoh32a( *data );
 | 
| -	uint32_t halfsize		= dtoh16a( (*data) + 4);
 | 
| -	uint32_t version		= dtoh16a( (*data) + 6);
 | 
| -	uint32_t focus_points_in_struct	= dtoh16a( (*data) + 8);
 | 
| -	uint32_t focus_points_in_use	= dtoh16a( (*data) + 10);
 | 
| -	uint32_t sizeX			= dtoh16a( (*data) + 12);
 | 
| -	uint32_t sizeY			= dtoh16a( (*data) + 14);
 | 
| -	uint32_t size2X			= dtoh16a( (*data) + 16);
 | 
| -	uint32_t size2Y			= dtoh16a( (*data) + 18);
 | 
| -	uint32_t i;
 | 
| -	uint32_t maxlen;
 | 
| -	char	*str, *p;
 | 
| -
 | 
| -	/* every focuspoint gets 4 (16 bit number and a x) and a ,*/
 | 
| -	/* inital things around lets say 100 chars at most. 
 | 
| -	 * FIXME: check selected when we decode it */
 | 
| -	maxlen = focus_points_in_use*6*4 + focus_points_in_use + 100;
 | 
| -	if (halfsize != size-4) {
 | 
| -		ptp_error(params, "halfsize %d is not expected %d", halfsize, size-4);
 | 
| -		return "bad size";
 | 
| -	}
 | 
| -	if (20 + focus_points_in_struct*8 + (focus_points_in_struct+7)/8 > size) {
 | 
| -		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);
 | 
| -		return "bad size 2";
 | 
| -	}
 | 
| -#if 0
 | 
| -	ptp_debug(params,"d1d3 content:");
 | 
| -	for (i=0;i<size;i+=2)
 | 
| -		ptp_debug(params,"%d: %02x %02x", i, (*data)[i], (*data)[i+1]);
 | 
| -#endif
 | 
| -	ptp_debug(params,"d1d3 version", version);
 | 
| -	ptp_debug(params,"d1d3 focus points in struct %d, in use %d", focus_points_in_struct, focus_points_in_use);
 | 
| -
 | 
| -	str = (char*)malloc( maxlen );
 | 
| -	if (!str)
 | 
| -		return NULL;
 | 
| -	p = str;
 | 
| -
 | 
| -	p += sprintf(p,"eosversion=%d,size=%dx%d,size2=%dx%d,points={", version, sizeX, sizeY, size2X, size2Y);
 | 
| -	for (i=0;i<focus_points_in_use;i++) {
 | 
| -		int16_t x = dtoh16a((*data) + focus_points_in_struct*4 + 20 + 2*i);
 | 
| -		int16_t y = dtoh16a((*data) + focus_points_in_struct*6 + 20 + 2*i);
 | 
| -		int16_t w = dtoh16a((*data) + focus_points_in_struct*2 + 20 + 2*i);
 | 
| -		int16_t h = dtoh16a((*data) + focus_points_in_struct*0 + 20 + 2*i);
 | 
| -
 | 
| -		p += sprintf(p,"{%d,%d,%d,%d}",x,y,w,h);
 | 
| -
 | 
| -		if (i<focus_points_in_use-1)
 | 
| -			p += sprintf(p,",");
 | 
| -	}
 | 
| -	p += sprintf(p,"},select={");
 | 
| -	for (i=0;i<focus_points_in_use;i++) {
 | 
| -		if ((1<<(i%7)) & ((*data)[focus_points_in_struct*8+20+i/8]))
 | 
| -			p+=sprintf(p,"%d,", i);
 | 
| -	}
 | 
| -
 | 
| -	p += sprintf(p,"},unknown={");
 | 
| -	for (i=focus_points_in_struct*8+(focus_points_in_struct+7)/8+20;i<size;i++) {
 | 
| -		p+=sprintf(p,"%02x", (*data)[i]);
 | 
| -	}
 | 
| -	p += sprintf(p,"}");
 | 
| -	return str;
 | 
| -}
 | 
| -
 | 
| -
 | 
|  static inline char*
 | 
|  ptp_unpack_EOS_CustomFuncEx (PTPParams* params, unsigned char** data )
 | 
|  {
 | 
|  	uint32_t s = dtoh32a( *data );
 | 
|  	uint32_t n = s/4, i;
 | 
| -	char* str = (char*)malloc( s*2+s/4+1 ); /* n is size in uint32, maximum %x len is 8 chars and \0*/
 | 
| +	char* str = (char*)malloc( s ); // n is size in uint32, average len(itoa(i)) < 4 -> alloc n chars
 | 
|  	if (!str)
 | 
|  		return str;
 | 
|  	char* p = str;
 | 
| @@ -1693,7 +1400,7 @@ ptp_pack_EOS_CustomFuncEx (PTPParams* params, unsigned char* data, char* str)
 | 
|  	for (i=0; i<n; i++)
 | 
|  	{
 | 
|  		v = strtoul(str, &str, 16);
 | 
| -		str++; /* skip the ',' delimiter */
 | 
| +		str++; // skip the ',' delimiter
 | 
|  		htod32a(data + i*4, v);
 | 
|  	}
 | 
|  
 | 
| @@ -1726,38 +1433,11 @@ ptp_pack_EOS_CustomFuncEx (PTPParams* params, unsigned char* data, char* str)
 | 
|  #define PTP_ece_OA_Parent	0x20
 | 
|  #define PTP_ece_OA_Name		0x28
 | 
|  
 | 
| -static PTPDevicePropDesc*
 | 
| -_lookup_or_allocate_canon_prop(PTPParams *params, uint16_t proptype)
 | 
| -{
 | 
| -	unsigned int j;
 | 
| -
 | 
| -	for (j=0;j<params->nrofcanon_props;j++)
 | 
| -		if (params->canon_props[j].proptype == proptype)
 | 
| -			break;
 | 
| -	if (j<params->nrofcanon_props)
 | 
| -		return ¶ms->canon_props[j].dpd;
 | 
| -
 | 
| -	if (j)
 | 
| -		params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1));
 | 
| -	else
 | 
| -		params->canon_props = malloc(sizeof(params->canon_props[0]));
 | 
| -	params->canon_props[j].proptype = proptype;
 | 
| -	params->canon_props[j].size = 0;
 | 
| -	params->canon_props[j].data = NULL;
 | 
| -	memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd));
 | 
| -	params->canon_props[j].dpd.GetSet = 1;
 | 
| -	params->canon_props[j].dpd.FormFlag = PTP_DPFF_None;
 | 
| -	params->nrofcanon_props = j+1;
 | 
| -	return ¶ms->canon_props[j].dpd;
 | 
| -}
 | 
| -
 | 
| -
 | 
|  static inline int
 | 
| -ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **pce)
 | 
| +ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **ce)
 | 
|  {
 | 
|  	int	i = 0, entries = 0;
 | 
|  	unsigned char	*curdata = data;
 | 
| -	PTPCanon_changes_entry *ce;
 | 
|  
 | 
|  	if (data==NULL)
 | 
|  		return 0;
 | 
| @@ -1765,56 +1445,49 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  		uint32_t	size = dtoh32a(&curdata[PTP_ece_Size]);
 | 
|  		uint32_t	type = dtoh32a(&curdata[PTP_ece_Type]);
 | 
|  
 | 
| +		curdata += size;
 | 
|  		if ((size == 8) && (type == 0))
 | 
|  			break;
 | 
| -		if (type == PTP_EC_CANON_EOS_OLCInfoChanged) {
 | 
| -			unsigned int j;
 | 
| -
 | 
| -			for (j=0;j<31;j++)
 | 
| -				if (dtoh32a(curdata+12) & (1<<j))
 | 
| -					entries++;
 | 
| -		}
 | 
| -		curdata += size;
 | 
|  		entries++;
 | 
|  	}
 | 
| -	ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1));
 | 
| -	if (!ce) return 0;
 | 
| +	*ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1));
 | 
| +	if (!*ce) return 0;
 | 
|  
 | 
|  	curdata = data;
 | 
|  	while (curdata - data < datasize) {
 | 
|  		uint32_t	size = dtoh32a(&curdata[PTP_ece_Size]);
 | 
|  		uint32_t	type = dtoh32a(&curdata[PTP_ece_Type]);
 | 
|  
 | 
| -		ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -		ce[i].u.info = NULL;
 | 
| +		(*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| +		(*ce)[i].u.info = NULL;
 | 
|  		switch (type) {
 | 
|  		case  PTP_EC_CANON_EOS_ObjectAddedEx:
 | 
| -			ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO;
 | 
| -			ce[i].u.object.oid    		= dtoh32a(&curdata[PTP_ece_OA_ObjectID]);
 | 
| -			ce[i].u.object.oi.StorageID 		= dtoh32a(&curdata[PTP_ece_OA_StorageID]);
 | 
| -			ce[i].u.object.oi.ParentObject	= dtoh32a(&curdata[PTP_ece_OA_Parent]);
 | 
| -			ce[i].u.object.oi.ObjectFormat 	= dtoh16a(&curdata[PTP_ece_OA_OFC]);
 | 
| -			ce[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]);
 | 
| -			ce[i].u.object.oi.Filename 		= strdup(((char*)&curdata[PTP_ece_OA_Name]));
 | 
| -			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);
 | 
| +			(*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO;
 | 
| +			(*ce)[i].u.object.oid    		= dtoh32a(&curdata[PTP_ece_OA_ObjectID]);
 | 
| +			(*ce)[i].u.object.oi.StorageID 		= dtoh32a(&curdata[PTP_ece_OA_StorageID]);
 | 
| +			(*ce)[i].u.object.oi.ParentObject	= dtoh32a(&curdata[PTP_ece_OA_Parent]);
 | 
| +			(*ce)[i].u.object.oi.ObjectFormat 	= dtoh16a(&curdata[PTP_ece_OA_OFC]);
 | 
| +			(*ce)[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]);
 | 
| +			(*ce)[i].u.object.oi.Filename 		= strdup(((char*)&curdata[PTP_ece_OA_Name]));
 | 
| +			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);
 | 
|  			break;
 | 
|  		case  PTP_EC_CANON_EOS_RequestObjectTransfer:
 | 
| -			ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER;
 | 
| -			ce[i].u.object.oid    		= dtoh32a(&curdata[PTP_ece_OI_ObjectID]);
 | 
| -			ce[i].u.object.oi.StorageID 		= 0; /* use as marker */
 | 
| -			ce[i].u.object.oi.ObjectFormat 	= dtoh16a(&curdata[PTP_ece_OI_OFC]);
 | 
| -			ce[i].u.object.oi.ParentObject	= 0; /* check, but use as marker */
 | 
| -			ce[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]);
 | 
| -			ce[i].u.object.oi.Filename 		= strdup(((char*)&curdata[PTP_ece_OI_Name]));
 | 
| -
 | 
| -			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);
 | 
| +			(*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER;
 | 
| +			(*ce)[i].u.object.oid    		= dtoh32a(&curdata[PTP_ece_OI_ObjectID]);
 | 
| +			(*ce)[i].u.object.oi.StorageID 		= 0; /* use as marker */
 | 
| +			(*ce)[i].u.object.oi.ObjectFormat 	= dtoh16a(&curdata[PTP_ece_OI_OFC]);
 | 
| +			(*ce)[i].u.object.oi.ParentObject	= 0; /* check, but use as marker */
 | 
| +			(*ce)[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]);
 | 
| +			(*ce)[i].u.object.oi.Filename 		= strdup(((char*)&curdata[PTP_ece_OI_Name]));
 | 
| +
 | 
| +			ptp_debug (params, "event %d: request object transfer oid %08lx, ofc %04x, size %d, filename %s", i, (*ce)[i].u.object.oid, (*ce)[i].u.object.oi.ObjectFormat, (*ce)[i].u.object.oi.ObjectCompressedSize, (*ce)[i].u.object.oi.Filename);
 | 
|  			break;
 | 
|  		case  PTP_EC_CANON_EOS_AvailListChanged: {	/* property desc */
 | 
|  			uint32_t	proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]);
 | 
|  			uint32_t	propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]);
 | 
|  			uint32_t	propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]);
 | 
|  			unsigned char	*xdata = &curdata[PTP_ece_Prop_Desc_Data];
 | 
| -			unsigned int	j;
 | 
| +			int		j;
 | 
|  			PTPDevicePropDesc	*dpd;
 | 
|  
 | 
|  			ptp_debug (params, "event %d: EOS prop %04x desc record, datasize %d, propxtype %d", i, proptype, size-PTP_ece_Prop_Desc_Data, propxtype);
 | 
| @@ -1838,14 +1511,12 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  			}
 | 
|  			if (! propxcnt)
 | 
|  				break;
 | 
| -			if (propxcnt >= 2<<16) /* buggy or exploit */
 | 
| -				break;
 | 
|  
 | 
|  			ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.",
 | 
|  				   i, propxtype, proptype, dpd->DataType, propxcnt);
 | 
|  			dpd->FormFlag = PTP_DPFF_Enumeration;
 | 
|  			dpd->FORM.Enum.NumberOfValues = propxcnt;
 | 
| -			free (dpd->FORM.Enum.SupportedValue);
 | 
| +			if (dpd->FORM.Enum.SupportedValue) free (dpd->FORM.Enum.SupportedValue);
 | 
|  			dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt);
 | 
|  
 | 
|  			switch (proptype) {
 | 
| @@ -1856,7 +1527,7 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				/* special handling of ImageFormat properties */
 | 
|  				for (j=0;j<propxcnt;j++) {
 | 
|  					dpd->FORM.Enum.SupportedValue[j].u16 =
 | 
| -							ptp_unpack_EOS_ImageFormat( params, &xdata );
 | 
| +							dtoh16( ptp_unpack_EOS_ImageFormat( params, &xdata ) );
 | 
|  					ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16);
 | 
|  				}
 | 
|  				break;
 | 
| @@ -1887,7 +1558,7 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  		}
 | 
|  		case PTP_EC_CANON_EOS_PropValueChanged:
 | 
|  			if (size >= 0xc) {	/* property info */
 | 
| -				unsigned int j;
 | 
| +				int j;
 | 
|  				uint32_t	proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]);
 | 
|  				unsigned char	*xdata = &curdata[PTP_ece_Prop_Val_Data];
 | 
|  				PTPDevicePropDesc	*dpd;
 | 
| @@ -1907,6 +1578,7 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  						params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1));
 | 
|  					else
 | 
|  						params->canon_props = malloc(sizeof(params->canon_props[0]));
 | 
| +					params->canon_props[j].type = type;
 | 
|  					params->canon_props[j].proptype = proptype;
 | 
|  					params->canon_props[j].size = size;
 | 
|  					params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data);
 | 
| @@ -1918,8 +1590,8 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				}
 | 
|  				dpd = ¶ms->canon_props[j].dpd;
 | 
|  
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 | 
| -				ce[i].u.propid = proptype;
 | 
| +				(*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 | 
| +				(*ce)[i].u.propid = proptype;
 | 
|  
 | 
|  				/* fix GetSet value */
 | 
|  				switch (proptype) {
 | 
| @@ -1960,8 +1632,6 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				/* set DataType */
 | 
|  				switch (proptype) {
 | 
|  				case PTP_DPC_CANON_EOS_CameraTime:
 | 
| -				case PTP_DPC_CANON_EOS_UTCTime:
 | 
| -				case PTP_DPC_CANON_EOS_Summertime: /* basical the DST flag */
 | 
|  				case PTP_DPC_CANON_EOS_AvailableShots:
 | 
|  				case PTP_DPC_CANON_EOS_CaptureDestination:
 | 
|  				case PTP_DPC_CANON_EOS_WhiteBalanceXA:
 | 
| @@ -1972,8 +1642,6 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				case PTP_DPC_CANON_EOS_ModelID:
 | 
|  				case PTP_DPC_CANON_EOS_LensID:
 | 
|  				case PTP_DPC_CANON_EOS_StroboFiring:
 | 
| -				case PTP_DPC_CANON_EOS_AFSelectFocusArea:
 | 
| -				case PTP_DPC_CANON_EOS_ContinousAFMode:
 | 
|  					dpd->DataType = PTP_DTC_UINT32;
 | 
|  					break;
 | 
|  				/* enumeration for AEM is never provided, but is available to set */
 | 
| @@ -1996,14 +1664,12 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				case PTP_DPC_CANON_EOS_QuickReviewTime:
 | 
|  				case PTP_DPC_CANON_EOS_EVFMode:
 | 
|  				case PTP_DPC_CANON_EOS_EVFOutputDevice:
 | 
| -				case PTP_DPC_CANON_EOS_AutoPowerOff:
 | 
| -				case PTP_DPC_CANON_EOS_EVFRecordStatus:
 | 
|  					dpd->DataType = PTP_DTC_UINT16;
 | 
|  					break;
 | 
|  				case PTP_DPC_CANON_EOS_PictureStyle:
 | 
|  				case PTP_DPC_CANON_EOS_WhiteBalance:
 | 
|  				case PTP_DPC_CANON_EOS_MeteringMode:
 | 
| -				case PTP_DPC_CANON_EOS_ExpCompensation:
 | 
| +				case PTP_DPC_CANON_EOS_ExpCompensation: /* actually int8 if you calculate */
 | 
|  					dpd->DataType = PTP_DTC_UINT8;
 | 
|  					break;
 | 
|  				case PTP_DPC_CANON_EOS_Owner:
 | 
| @@ -2018,6 +1684,7 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  					dpd->DataType = PTP_DTC_INT16;
 | 
|  					break;
 | 
|  				/* unknown props, listed from dump.... all 16 bit, but vals might be smaller */
 | 
| +				case 0xd114:
 | 
|  				case PTP_DPC_CANON_EOS_DPOFVersion:
 | 
|  					dpd->DataType = PTP_DTC_UINT16;
 | 
|  					ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data);
 | 
| @@ -2054,19 +1721,18 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				case PTP_DPC_CANON_EOS_EVFWBMode:
 | 
|  				case PTP_DPC_CANON_EOS_EVFClickWBCoeffs:
 | 
|  				case PTP_DPC_CANON_EOS_EVFColorTemp:
 | 
| +				case PTP_DPC_CANON_EOS_EVFRecordStatus:
 | 
|  				case PTP_DPC_CANON_EOS_ExposureSimMode:
 | 
|  				case PTP_DPC_CANON_EOS_LvAfSystem:
 | 
|  				case PTP_DPC_CANON_EOS_MovSize:
 | 
|  				case PTP_DPC_CANON_EOS_DepthOfField:
 | 
|  				case PTP_DPC_CANON_EOS_LvViewTypeSelect:
 | 
| -				case PTP_DPC_CANON_EOS_AloMode:
 | 
| -				case PTP_DPC_CANON_EOS_Brightness:
 | 
|  					dpd->DataType = PTP_DTC_UINT32;
 | 
|  					ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data);
 | 
|  					if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0)
 | 
|  						ptp_debug (params, "event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) );
 | 
|  					for (j=0;j<(size-PTP_ece_Prop_Val_Data)/sizeof(uint32_t);j++)
 | 
| -						ptp_debug (params, "    %d: 0x%8x", j, dtoh32a(xdata+j*4));
 | 
| +						ptp_debug (params, "    %d: 0x%8x", j, ((uint32_t*)xdata)[j]);
 | 
|  					break;
 | 
|  				/* ImageFormat properties have to be ignored here, see special handling below */
 | 
|  				case PTP_DPC_CANON_EOS_ImageFormat:
 | 
| @@ -2074,7 +1740,6 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				case PTP_DPC_CANON_EOS_ImageFormatSD:
 | 
|  				case PTP_DPC_CANON_EOS_ImageFormatExtHD:
 | 
|  				case PTP_DPC_CANON_EOS_CustomFuncEx:
 | 
| -				case PTP_DPC_CANON_EOS_FocusInfoEx:
 | 
|  					break;
 | 
|  				default:
 | 
|  					ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data);
 | 
| @@ -2088,11 +1753,6 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  					dpd->CurrentValue.u32		= dtoh32a(xdata);
 | 
|  					ptp_debug (params ,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32);
 | 
|  					break;
 | 
| -				case PTP_DTC_INT16:
 | 
| -					dpd->FactoryDefaultValue.i16	= dtoh16a(xdata);
 | 
| -					dpd->CurrentValue.i16		= dtoh16a(xdata);
 | 
| -					ptp_debug (params,"event %d: currentvalue of %x is %d", i, proptype, dpd->CurrentValue.i16);
 | 
| -					break;
 | 
|  				case PTP_DTC_UINT16:
 | 
|  					dpd->FactoryDefaultValue.u16	= dtoh16a(xdata);
 | 
|  					dpd->CurrentValue.u16		= dtoh16a(xdata);
 | 
| @@ -2103,21 +1763,16 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  					dpd->CurrentValue.u8		= dtoh8a(xdata);
 | 
|  					ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8);
 | 
|  					break;
 | 
| -				case PTP_DTC_INT8:
 | 
| -					dpd->FactoryDefaultValue.i8	= dtoh8a(xdata);
 | 
| -					dpd->CurrentValue.i8		= dtoh8a(xdata);
 | 
| -					ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.i8);
 | 
| -					break;
 | 
|  				case PTP_DTC_STR: {
 | 
|  #if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */
 | 
|  					uint8_t len = 0;
 | 
|  					dpd->FactoryDefaultValue.str	= ptp_unpack_string(params, data, 0, &len);
 | 
|  					dpd->CurrentValue.str		= ptp_unpack_string(params, data, 0, &len);
 | 
|  #else
 | 
| -					free (dpd->FactoryDefaultValue.str);
 | 
| +					if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str);
 | 
|  					dpd->FactoryDefaultValue.str	= strdup( (char*)xdata );
 | 
|  
 | 
| -					free (dpd->CurrentValue.str);
 | 
| +					if (dpd->CurrentValue.str) free (dpd->CurrentValue.str);
 | 
|  					dpd->CurrentValue.str		= strdup( (char*)xdata );
 | 
|  #endif
 | 
|  					ptp_debug (params,"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str);
 | 
| @@ -2141,233 +1796,20 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  					break;
 | 
|  				case PTP_DPC_CANON_EOS_CustomFuncEx:
 | 
|  					dpd->DataType = PTP_DTC_STR;
 | 
| -					free (dpd->FactoryDefaultValue.str);
 | 
| -					free (dpd->CurrentValue.str);
 | 
| -					dpd->FactoryDefaultValue.str	= ptp_unpack_EOS_CustomFuncEx( params, &xdata );
 | 
| +					if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str);
 | 
| +					if (dpd->CurrentValue.str)	  free (dpd->CurrentValue.str);
 | 
| +					dpd->FactoryDefaultValue.str	= ptp_unpack_EOS_CustomFuncEx( params, &data );
 | 
|  					dpd->CurrentValue.str		= strdup( (char*)dpd->FactoryDefaultValue.str );
 | 
|  					ptp_debug (params,"event %d: decoded custom function, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str);
 | 
|  					break;
 | 
| -				case PTP_DPC_CANON_EOS_FocusInfoEx:
 | 
| -					dpd->DataType = PTP_DTC_STR;
 | 
| -					free (dpd->FactoryDefaultValue.str);
 | 
| -					free (dpd->CurrentValue.str);
 | 
| -					dpd->FactoryDefaultValue.str	= ptp_unpack_EOS_FocusInfoEx( params, &xdata );
 | 
| -					dpd->CurrentValue.str		= strdup( (char*)dpd->FactoryDefaultValue.str );
 | 
| -					ptp_debug (params,"event %d: decoded focus info, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str);
 | 
| -					break;
 | 
|  				}
 | 
|  
 | 
|  				break;
 | 
|  		}
 | 
| -		/* one more information record handed to us */
 | 
| -		case PTP_EC_CANON_EOS_OLCInfoChanged: {
 | 
| -			uint32_t		len, curoff;
 | 
| -			uint16_t		mask,proptype;
 | 
| -			PTPDevicePropDesc	*dpd;
 | 
| -
 | 
| -			/* unclear what OLC stands for */
 | 
| -			ptp_debug (params, "event %d: EOS event OLCInfoChanged (size %d)", i, size);
 | 
| -			if (size >= 0x8) {	/* event info */
 | 
| -				unsigned int k;
 | 
| -				for (k=8;k<size;k++)
 | 
| -					ptp_debug (params, "    %d: %02x", k-8, curdata[k]);
 | 
| -			}
 | 
| -			len = dtoh32a(curdata+8);
 | 
| -			if (len != size-8) {
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ptp_debug (params, "event %d: size %d, len %d", i, size, len);
 | 
| -				break;
 | 
| -			}
 | 
| -			mask = dtoh16a(curdata+8+4);
 | 
| -			curoff = 8+4+4;
 | 
| -			if (mask & CANON_EOS_OLC_BUTTON) {
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("Button 1234567"));
 | 
| -				sprintf(ce[i].u.info, "Button %d",  dtoh16a(curdata+curoff));
 | 
| -				i++;
 | 
| -				curoff += 2;
 | 
| -			}
 | 
| -			
 | 
| -			if (mask & CANON_EOS_OLC_SHUTTERSPEED) {
 | 
| -				/* 6 bytes: 01 01 98 10 00 60 */
 | 
| -				/* this seesm to be the shutter speed record */
 | 
| -				proptype = PTP_DPC_CANON_EOS_ShutterSpeed;
 | 
| -				dpd = _lookup_or_allocate_canon_prop(params, proptype);
 | 
| -				dpd->CurrentValue.u16 = curdata[curoff+5]; /* just use last byte */
 | 
| -
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 | 
| -				ce[i].u.propid = proptype;
 | 
| -				curoff += 6;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & CANON_EOS_OLC_APERTURE) {
 | 
| -				/* 5 bytes: 01 01 5b 30 30 */
 | 
| -				/* this seesm to be the aperture record */
 | 
| -				proptype = PTP_DPC_CANON_EOS_Aperture;
 | 
| -				dpd = _lookup_or_allocate_canon_prop(params, proptype);
 | 
| -				dpd->CurrentValue.u16 = curdata[curoff+4]; /* just use last byte */
 | 
| -
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 | 
| -				ce[i].u.propid = proptype;
 | 
| -				curoff += 5;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & CANON_EOS_OLC_ISO) {
 | 
| -				/* 5 bytes: 01 01 00 78 */
 | 
| -				/* this seesm to be the aperture record */
 | 
| -				proptype = PTP_DPC_CANON_EOS_ISOSpeed;
 | 
| -				dpd = _lookup_or_allocate_canon_prop(params, proptype);
 | 
| -				dpd->CurrentValue.u16 = curdata[curoff+3]; /* just use last byte */
 | 
| -
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY;
 | 
| -				ce[i].u.propid = proptype;
 | 
| -				curoff += 4;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0010) {
 | 
| -				/* mask 0x0010: 4 bytes, 04 00 00 00 observed */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("OLCInfo event 0x0010 content 01234567")+1); 
 | 
| -				sprintf(ce[i].u.info,"OLCInfo event 0x0010 content %02x%02x%02x%02x",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					curdata[curoff+2],
 | 
| -					curdata[curoff+3]
 | 
| -				);
 | 
| -				curoff += 4;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0020) {
 | 
| -				/* mask 0x0020: 6 bytes, 00 00 00 00 00 00 observed */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("OLCInfo event 0x0020 content 0123456789ab")+1); 
 | 
| -				sprintf(ce[i].u.info,"OLCInfo event 0x0020 content %02x%02x%02x%02x%02x%02x",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					curdata[curoff+2],
 | 
| -					curdata[curoff+3],
 | 
| -					curdata[curoff+4],
 | 
| -					curdata[curoff+5]
 | 
| -				);
 | 
| -				curoff += 6;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0040) {
 | 
| -				int	value = (signed char)curdata[curoff+2];
 | 
| -				/* mask 0x0040: 7 bytes, 01 01 00 00 00 00 00 observed */
 | 
| -				/* exposure indicator */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("OLCInfo exposure indicator 012345678901234567890123456789abcd")+1); 
 | 
| -				sprintf(ce[i].u.info,"OLCInfo exposure indicator %d,%d,%d.%d (%02x%02x%02x%02x)",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					value/10,abs(value)%10,
 | 
| -					curdata[curoff+3],
 | 
| -					curdata[curoff+4],
 | 
| -					curdata[curoff+5],
 | 
| -					curdata[curoff+6]
 | 
| -				);
 | 
| -				curoff += 7;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0080) {
 | 
| -				/* mask 0x0080: 4 bytes, 00 00 00 00 observed */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("OLCInfo event 0x0080 content 01234567")+1); 
 | 
| -				sprintf(ce[i].u.info,"OLCInfo event 0x0080 content %02x%02x%02x%02x",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					curdata[curoff+2],
 | 
| -					curdata[curoff+3]
 | 
| -				);
 | 
| -				curoff += 4;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0100) {
 | 
| -				/* mask 0x0100: 6 bytes, 00 00 00 00 00 00 (before focus) and 00 00 00 00 01 00 (on focus) observed */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO;
 | 
| -				ce[i].u.info = malloc(strlen("0123456789ab")+1); 
 | 
| -				sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					curdata[curoff+2],
 | 
| -					curdata[curoff+3],
 | 
| -					curdata[curoff+4],
 | 
| -					curdata[curoff+5]
 | 
| -				);
 | 
| -				curoff += 6;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0200) {
 | 
| -				/* mask 0x0200: 7 bytes, 00 00 00 00 00 00 00 observed */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSMASK;
 | 
| -				ce[i].u.info = malloc(strlen("0123456789abcd0123456789abcdef")+1); 
 | 
| -				sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x%02x",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					curdata[curoff+2],
 | 
| -					curdata[curoff+3],
 | 
| -					curdata[curoff+4],
 | 
| -					curdata[curoff+5],
 | 
| -					curdata[curoff+6]
 | 
| -				);
 | 
| -				curoff += 7;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0400) {
 | 
| -				/* mask 0x0400: 7 bytes, 00 00 00 00 00 00 00 observed */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("OLCInfo event 0x0400 content 0123456789abcd")+1); 
 | 
| -				sprintf(ce[i].u.info,"OLCInfo event 0x0400 content %02x%02x%02x%02x%02x%02x%02x",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					curdata[curoff+2],
 | 
| -					curdata[curoff+3],
 | 
| -					curdata[curoff+4],
 | 
| -					curdata[curoff+5],
 | 
| -					curdata[curoff+6]
 | 
| -				);
 | 
| -				curoff += 7;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x0800) {
 | 
| -				/* mask 0x0800: 8 bytes, 00 00 00 00 00 00 00 00 and 19 01 00 00 00 00 00 00 and others observed */
 | 
| -				/*   might be mask of focus points selected */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("OLCInfo event 0x0800 content 0123456789abcdef")+1); 
 | 
| -				sprintf(ce[i].u.info,"OLCInfo event 0x0800 content %02x%02x%02x%02x%02x%02x%02x%02x",
 | 
| -					curdata[curoff],
 | 
| -					curdata[curoff+1],
 | 
| -					curdata[curoff+2],
 | 
| -					curdata[curoff+3],
 | 
| -					curdata[curoff+4],
 | 
| -					curdata[curoff+5],
 | 
| -					curdata[curoff+6],
 | 
| -					curdata[curoff+7]
 | 
| -				);
 | 
| -				curoff += 8;
 | 
| -				i++;
 | 
| -			}
 | 
| -			if (mask & 0x1000) {
 | 
| -				/* mask 0x1000: 1 byte, 00 observed */
 | 
| -				ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -				ce[i].u.info = malloc(strlen("OLCInfo event 0x1000 content 01")+1); 
 | 
| -				sprintf(ce[i].u.info,"OLCInfo event 0x1000 content %02x",
 | 
| -					curdata[curoff]
 | 
| -				);
 | 
| -				curoff += 1;
 | 
| -				i++;
 | 
| -			}
 | 
| -			/* handle more masks */
 | 
| -			ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -			ce[i].u.info = malloc(strlen("OLCInfo event mask 0123456789")+1);
 | 
| -			sprintf(ce[i].u.info, "OLCInfo event mask=%x",  mask);
 | 
| -			break;
 | 
| -		}
 | 
|  		case PTP_EC_CANON_EOS_CameraStatusChanged:
 | 
| -			ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS;
 | 
| -			ce[i].u.status =  dtoh32a(curdata+8);
 | 
| -			ptp_debug (params, "event %d: EOS event CameraStatusChanged (size %d) = %d", i, size, dtoh32a(curdata+8));
 | 
| +			ptp_debug (params, "event %d: EOS event CameraStatusChanged (size %d)", i, size);
 | 
| +			(*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS;
 | 
| +			(*ce)[i].u.status =  dtoh32a(curdata+8);
 | 
|  			params->eos_camerastatus = dtoh32a(curdata+8);
 | 
|  			break;
 | 
|  		case 0: /* end marker */
 | 
| @@ -2376,22 +1818,19 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  			ptp_debug (params, "event %d: EOS event 0, but size %d", i, size);
 | 
|  			break;
 | 
|  		case PTP_EC_CANON_EOS_BulbExposureTime:
 | 
| -			ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| -			ce[i].u.info = malloc(strlen("BulbExposureTime 123456789"));
 | 
| -			sprintf (ce[i].u.info, "BulbExposureTime %d",  dtoh32a(curdata+8));
 | 
| -			break;
 | 
| -		case PTP_EC_CANON_EOS_ObjectRemoved:
 | 
| -			ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTREMOVED;
 | 
| -			ce[i].u.object.oid = dtoh32a(curdata+8);
 | 
| +			(*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| +			(*ce)[i].u.info = malloc(strlen("BulbExposureTime 123456789"));
 | 
| +			sprintf ((*ce)[i].u.info, "BulbExposureTime %d",  dtoh32a(curdata+8));
 | 
|  			break;
 | 
|  		default:
 | 
|  			switch (type) {
 | 
|  #define XX(x)		case PTP_EC_CANON_EOS_##x: 								\
 | 
|  				ptp_debug (params, "event %d: unhandled EOS event "#x" (size %d)", i, size); 	\
 | 
| -				ce[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 123456789)"));	\
 | 
| -				sprintf (ce[i].u.info, "unhandled EOS event "#x" (size %d)",  size);		\
 | 
| +				(*ce)[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 123456789)"));	\
 | 
| +				sprintf ((*ce)[i].u.info, "unhandled EOS event "#x" (size %d)",  size);		\
 | 
|  				break;
 | 
|  			XX(RequestGetEvent)
 | 
| +			XX(ObjectRemoved)
 | 
|  			XX(RequestGetObjectInfoEx)
 | 
|  			XX(StorageStatusChanged)
 | 
|  			XX(StorageInfoChanged)
 | 
| @@ -2414,24 +1853,23 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  				break;
 | 
|  			}
 | 
|  			if (size >= 0x8) {	/* event info */
 | 
| -				unsigned int j;
 | 
| +				int j;
 | 
|  				for (j=8;j<size;j++)
 | 
|  					ptp_debug (params, "    %d: %02x", j, curdata[j]);
 | 
|  			}
 | 
| -			ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
| +			(*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN;
 | 
|  			break;
 | 
|  		}
 | 
|  		curdata += size;
 | 
| +		i++;
 | 
|  		if ((size == 8) && (type == 0))
 | 
|  			break;
 | 
| -		i++;
 | 
|  	}
 | 
| -	if (!i) {
 | 
| -		free (ce);
 | 
| -		ce = NULL;
 | 
| +	if (!entries) {
 | 
| +		free (*ce);
 | 
| +		*ce = NULL;
 | 
|  	}
 | 
| -	*pce = ce;
 | 
| -	return i;
 | 
| +	return entries;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -2442,9 +1880,9 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
 | 
|  #define PTP_nikon_ec_Param1		4
 | 
|  #define PTP_nikon_ec_Size		6
 | 
|  static inline void
 | 
| -ptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, unsigned int *cnt)
 | 
| +ptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, int *cnt)
 | 
|  {
 | 
| -	unsigned int i;
 | 
| +	int i;
 | 
|  
 | 
|  	*ec = NULL;
 | 
|  	if (data == NULL)
 | 
| @@ -2548,11 +1986,11 @@ ptp_unpack_canon_directory (
 | 
|  	for (i=0;i<cnt;i++)
 | 
|  		if (ISOBJECT(dir+i*0x4c)) nrofobs++;
 | 
|  	handles->n = nrofobs;
 | 
| -	handles->Handler = calloc(nrofobs,sizeof(handles->Handler[0]));
 | 
| +	handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs);
 | 
|  	if (!handles->Handler) return PTP_RC_GeneralError;
 | 
| -	*oinfos = calloc(nrofobs,sizeof((*oinfos)[0]));
 | 
| +	*oinfos = calloc(sizeof((*oinfos)[0]),nrofobs);
 | 
|  	if (!*oinfos) return PTP_RC_GeneralError;
 | 
| -	*flags  = calloc(nrofobs,sizeof((*flags)[0]));
 | 
| +	*flags  = calloc(sizeof((*flags)[0]),nrofobs);
 | 
|  	if (!*flags) return PTP_RC_GeneralError;
 | 
|  
 | 
|  	/* Migrate data into objects ids, handles into
 | 
| @@ -2593,7 +2031,7 @@ ptp_unpack_canon_directory (
 | 
|  	}
 | 
|  	/* Walk over all objects and distribute the storage ids */
 | 
|  	while (1) {
 | 
| -		unsigned int changed = 0;
 | 
| +		int changed = 0;
 | 
|  		for (i=0;i<cnt;i++) {
 | 
|  			unsigned char	*cur = dir+i*0x4c;
 | 
|  			uint32_t	oid = dtoh32a(cur + ptp_canon_dir_objectid);
 | 
| 
 |