Working with WMDRM Protected Content using WPD

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,

                              &pDataStream,

                              &dwOptimalWriteBufferSize,

                              NULL);

// ... Transfer the protected WMDRM content

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

pDataStream->Commit(0);

hr = pDataStream->QueryInterface(IID_IWMDRMDeviceApp,

                                 (void**)&pWMDRMApp);

 

if (SUCCEEDED(hr))

{

   DWORD dwStatus = 0;

 

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

  hr = pWMDRMApp->QueryDeviceStatus((IWMDMDevice *)WMDRMDEVICEAPP_USE_WPD_DEVICE_PTR,

                                     &dwStatus);

}

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.

Comments

  • Anonymous
    February 25, 2007
    Could someone say exactly which license and certificates an app needs to use DRM with WPD for file transfers to devices? I have a query in with wmla, but it would be useful to know (for other users to i expect), to avoid wasting time trying to work it out from various inpenetrable license agreements. I'm a developer not a lawyer :)

  • Anonymous
    February 28, 2007
    To answer my own question, I've been told to apply for the "WM DRM Certificates Agreement for Format SDK 11" on the licesning form mentioned above. Of the options provided on the emailed application form, I need the "WMDM Transfer Certificate".

  • Anonymous
    March 13, 2007
    The licensing instructions are here:  http://www.microsoft.com/windows/windowsmedia/licensing/Licensing_DRM_Apps.aspx.  See the bottom of the page for applications that want to play, burn or transfer protected content. It's correct that you should just need the transfer certificate, assuming that your application does not need to playback the protected content.

  • Anonymous
    May 04, 2007
    Hi. I have two questions about WPD DRM capabilities compared with WMDM. First, can the WPD fetch properties on a DRM file corresponding to those in the WMDMRIGHTS structure (returned by a GetRights call on a WMDM storage object)? I couldn't find reference to comparable DRM object properties in the WPD documentation. And second, does one need to have an issued key/certificate pair, not to transfer a DRM file (at this stage), but just to check said DRM file properties (via WPD if that is indeed possible, or via WMDM's GetRights call) on a device?

  • Anonymous
    May 04, 2007
    Forgot the link to the WMDMRIGHTS struct I was talking about (though no doubt folks who'd know the answer to my question know what I'm referring to): http://msdn2.microsoft.com/en-us/library/bb232007.aspx Thanks.

  • Anonymous
    May 07, 2007
    The WMDRMRIGHTS structure is reserved for a legacy DRM scheme, and does not apply to WMDRM-PD.  Direct DRM property queries on content sitting on the device is not supported for WMDRM-PD in WMDM or WPD. However, you can still query the rights on a DRM protected file on the PC from your client application using WMDRMSDK: http://msdn2.microsoft.com/en-us/library/aa391568.aspx

  • Anonymous
    May 07, 2007
    Thanks much for the quick reply, that is very useful to know. For older WMDRM based devices that do support the WMDM rights querying api, then, is a key/certificate pair necessary for just a DRM query? When I try a call to GetRights on a DRM protected file, it is returning the error NS_E_DRM_UNABLE_TO_GET_DEVICE_CERT (0xC00D2772L), described as "a problem has occurred in obtaining the device's certificate"; I'm not sure if that is because a key/certificate pair must be supplied, or for some other reason. Note, the two Creative devices I'm testing with seem to be pre-Windows Media DRM 10 for Portable Devices (IWMDRMDeviceApp::QueryDeviceStatus yields a status of 0). Also, it is interesting to me that in WMP 11, when checking the "Media usage rights" properties of the DRM files on the device, it says "This file is not protected", though the same file in the library on the desktop does correctly show the DRM properties. Thanks again for any insight you can provide.

  • Anonymous
    May 07, 2007
    In general, WMDRM devices will not support the WMDM GetRights query.  This applies to PDDRM devices only (not WMDRM). NS_E_DRM_UNABLE_TO_GET_DEVICE_CERT is actually a side-effect of a known bug with the WPD Service Provider when retrieving the device certificate from an MTP device.   Even after this bug is fixed, GetRights would still not work for a WMDRM device.   Checking the DRM device properties from WMP11 is probably doing the same query. From the error, looks like your Creative devices are MTP, and therefore WMDRM.  To be sure, try QueryDeviceStatus2 with WMDRM_QUERY_DEVICE_ISWMDRM.

  • Anonymous
    May 07, 2008
    Hi I am using the code specified in this blog which is as follows   // Call metering operations on the current device using the WPD device pointer   hr = pWMDRMApp->QueryDeviceStatus((IWMDMDevice *)WMDRMDEVICEAPP_USE_WPD_DEVICE_PTR,                                     &dwStatus); But on compiling I am getting following compiler error Error 3 error LNK2001: unresolved external symbol _IID_IWMDRMDeviceApp WPD_OP.obj

  • Anonymous
    April 16, 2009
    Hi guys, Can someone help me after passing the following 2 properties to the WPD API Open,  what happens. I mean will they allow any DRM protected file to transfer to portable device.In this case any license is required on the device or not? Can i then transfer any DRM protected files CWM files also? Are CWM files requires license on device ? (WPD_CLIENT_WMDRM_APPLICATION_PRIVATE_KEY)  and (WPD_CLIENT_WMDRM_APPLICATION_CERTIFICATE). Thanks in advance. Harish

  • Anonymous
    April 16, 2009
    Hi, I am uing WPD API's to connect to MTP supported devices. My application can connect to more than 1 devices. I am creating a seperate thread for each device. I open the devices by passing below 2 pproperties so that DRM check is enabled in WPD. (WPD_CLIENT_WMDRM_APPLICATION_PRIVATE_KEY)  and (WPD_CLIENT_WMDRM_APPLICATION_CERTIFICATE). But when i connect 2 devices then my CWM content transfer on one device and did not transfer on other. But the correct behavior should be, these content should not get transferred in to any device because these are CWM protected content and my 2 devices are not CWM enabled. Thanks in advance Harish

  • Anonymous
    June 29, 2010
    Hi ! I am using WPD API to transfer files to the device ,but I don't know how to create a objectData  by C# "PortableDeviceApiLib.IStream pFileStream;" I want to know how to get Istream from a file PortableDeviceApiLib.IStream pFileStream; the "hr = SHCreateStreamOnFile(szFilePath, STGM_READ, &pFileStream);" in C++ how to use in C# . Thanks in advance      yu0zhuo

  • Anonymous
    June 29, 2010
    Hi ! I am using WPD API to transfer files to the device ,but I don't know how to create a objectData  by C# "PortableDeviceApiLib.IStream pFileStream;" I want to know how to get Istream from a file PortableDeviceApiLib.IStream pFileStream; the "hr = SHCreateStreamOnFile(szFilePath, STGM_READ, &pFileStream);" in C++ how to use in C# . Thanks in advance      yu0zhuo