Accessing MTP vendor extended properties through WPD

Apart from the standard device and object properties defined in the MTP specification, device vendors are free to add their own properties. The codes for these properties must lie in the vendor-extension range as defined by the MTP spec in section 3.3.1. Specifically, the range for vendor-extended device properties is 0xD000-0xD3FF and the range for vendor-extended object properties is 0xD800-0xDBFF.

Since these are vendor-extended properties, the WPD API and the MTP driver have no pre-existing mapping of these properties i.e. there isn't a handy pre-defined PROPERTYKEY to reference them with. Instead we have to manipulate the PROPERTYKEY structure to instruct the MTP driver on what properties to retrieve/set.

A PROPERTYKEY is a structure composed of a GUID and a DWORD.

 typedef struct {
    GUID fmtid;
    DWORD pid;
} PROPERTYKEY;

We set the fmtid member to a specific GUID and the pid member to the MTP property code that we are interested in. The GUIDs differ for device and object properties and are discussed further below.

MTP device properties

Vendor-extended MTP device properties are identified with the fmtid member set to WPD_PROPERTIES_MTP_VENDOR_EXTENDED_DEVICE_PROPS. The pid member then specifies the actual MTP device property code.

e.g. Consider the Janus DRM device certificate property on the device. It is defined by the device property code - 0xD101.

At the WPD level, this property would appear as the property-key "{4D545058-8900-40b3-8F1D-DC246E1E8370}.53505". The first part is the string representation of the actual WPD_PROPERTIES_MTP_VENDOR_EXTENDED_DEVICE_PROPS GUID. The second part (following the period) is the device property code in decimal (0xD101=53505).

To reference this property in code, we'd use something like:

 PROPERTYKEY pkeyJanusDevCert;
pkeyJanusDevCert.fmtid = WPD_PROPERTIES_MTP_VENDOR_EXTENDED_DEVICE_PROPS;
pkeyJanusDevCert.pid = 0xD101; 

MTP object properties

Vendor-extended MTP object properties are identified with the fmtid member set to WPD_PROPERTIES_MTP_VENDOR_EXTENDED_OBJECT_PROPS. The pid member then specifies the actual MTP object property code.

e.g. Consider the Janus DRM BuyNow object property. It is defined by the object property code - 0xD901.

At the WPD level, this property would appear as the property-key {4D545058-4FCE-4578-95C8-8698A9BC0F49}.55553". The first part is the string representation of the actual WPD_PROPERTIES_MTP_VENDOR_EXTENDED_OBJECT_PROPS GUID. The second part (following the period) is the object property code in decimal (0xD901=55553).

To reference this property in code, we'd use something like:

 PROPERTYKEY pkeyBuyNow;
pkeyBuyNow.fmtid = WPD_PROPERTIES_MTP_VENDOR_EXTENDED_OBJECT_PROPS;
pkeyBuyNow.pid = 0xD901; 

 

Once we have the the PROPERTYKEY representations of the MTP properties that we need, we can simply use these PROPERTYKEYs just like other regular WPD PROPERTYKEYs. They can be placed in IPortableDevicePropertyKeyCollection or IPortableDeviceValues interfaces and then can be used with the GetValues/SetValues APIs.