Setting up your WPD application to handle protected WMDRM content

The WPD API supports the transfer and licensing operations for Windows Media Digital Rights Management (WMDRM) content.

This MSDN article describes two additional properties that are required to enable your WPD application to transfer protected content.   


Property Vartype Description
WPD_CLIENT_WMDRM_APPLICATION_PRIVATE_KEY VT_VECTOR | VT_UI1 Specifies the application's private key.
WPD_CLIENT_WMDRM_APPLICATION_CERTIFICATE VT_VECTOR | VT_UI1 Specifies the application's certificate.

To initialize WPD for protected content, call IPortableDevice::Open() with the above parameters added to the pClientInfo IPortableDeviceValues.  If this succeeds, you can use the derived IPortableDeviceContent interface (from IPortableDevice::Content()) to transfer protected (and clear) content using IPortableDeviceContent::CreateObjectWithPropertiesAndData().

To obtain a private application key and certificate, visit this link.

Transferring Content

To transfer WMDRM protected content, use IPortableDeviceContent::CreateObjectWithPropertiesAndData().   The same CreateObjectWithPropetiesAndData API call can be used for both protected and clear content without additional options.   The WPD API will automatically select the protected or clear channel depending on whether the content is protected or clear.   It interfaces with the WMDRM Secure Content Provider to process the WMDRM licenses.

Transferring Known Clear Content

If you've enabled WPD to handle protected content, but you know that a specific file is not protected, you can tell WPD to skip the DRM processing by setting WPD_API_OPTION_USE_CLEAR_DATA_STREAM option to TRUE in the input IPortableDeviceValues when calling IPortableDeviceContent::CreateObjectWithPropertiesAndData() for clear content.

Accessing Metering Operations using IWMDRMDeviceApp

WPD provides a mechanism to access the IWMDRMDeviceApp APIs for license updates and metering data retrieval.  To access IWMDRMDeviceApp through WPD, call QueryInterface on IID_IWMDRMDeviceApp from the IStream returned from IPortableDeviceContent::CreateObjectWithPropertiesAndData().   This IWMDRMDeviceApp instance tied to the IPortableDevice connection to your WMDRM-compatible device, and not the specific content where the IStream was obtained.     WPD internally wraps the metering APIs and makes it accessible to your application.   Your application uses a constant for the IWMDMDevice* parameter:  WMDRMDEVICEAPP_USE_WPD_DEVICE_PTR.

IStream*               pDataStream = NULL;

IWMDRMDeviceApp*       pWMDRMApp   = NULL;


// ... Initialization


hr = pPortableDeviceContent->CreateObjectWithPropertiesAndData(pValues,





// ... Transfer the protected WMDRM content

pDataStream->Write(pData, cbData, &cbWritten);




hr = pDataStream->QueryInterface(IID_IWMDRMDeviceApp,



if (SUCCEEDED(hr))


   DWORD dwStatus = 0;


   // Call metering operations on the current device using the WPD device pointer






The same pre-requisitie with the application private key and certificate applies here as well.   If the key/certificate is invalid or if the WMDRM system fails to initialize, the QueryInferface call will fail.   


Update [March 13, 2007]:  The above method to acquire the IWMDRMDeviceApp interface from the IStream pointer is just a convenience if your application is already doing a prior protected content transfer, before proceeding on to do metering and license synchronization operations.    

Our recommendation for most applications that need to access IWMDRMDeviceApp is to initialize IWMDRMDeviceApp directly as this does not require your application to transfer protected content or hold on to the transfer interfaces in order to do device metering and license sync.   For details, refer to this MSDN article entitled "Handling Protected Content in the Application."  

Update [May 5, 2007]:  The whitepaper (and sample code) on initializing IWMDRMDeviceApp for WPD is now posted here


This posting is provided "AS IS" with no warranties, and confers no rights.