<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Windows Portable Devices Team Blog</title><subtitle type="html" /><id>http://blogs.msdn.com/b/wpdblog/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/wpdblog/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2007-03-24T18:24:00Z</updated><entry><title>Sensors and Windows</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/12/17/sensors-and-windows.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/12/17/sensors-and-windows.aspx</id><published>2009-12-17T20:03:00Z</published><updated>2009-12-17T20:03:00Z</updated><content type="html">&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;Prior to the introduction of WPD, developers wrote a significant amount of code to integrate data from sensors into their Windows applications. But, with the release of WPD, it was possible to create a driver that handled communications between the operating system and the remote device. And, once the driver was written, a developer could write an application with a minimal code footprint—200 lines or less—to retrieve sensor data. For an example, refer to the downloadable whitepaper and code at: &lt;A href="http://wpdtempsensor.codeplex.com/" mce_href="http://wpdtempsensor.codeplex.com/"&gt;http://wpdtempsensor.codeplex.com/&lt;/A&gt;. (For an example WPD driver, refer to the WpdBasicHardwareDriver that ships in the Windows Driver Kit.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;For Windows 7, Microsoft introduced the Sensors and Location platform. This platform includes both a driver model for IHVs and an API for application developers. Microsoft recently released a sample driver, sample firmware, and a sample application on the MSDN Code Gallery to demonstrate the use of this new platform. See: &lt;A href="http://code.msdn.microsoft.com/motionsensor" mce_href="http://code.msdn.microsoft.com/motionsensor"&gt;http://code.msdn.microsoft.com/motionsensor&lt;/A&gt;. This sample, like the WPD sample above, interacts with the Parallax BS2 microcontroller; and, it’s intended as an enhancement (or replacement) of the WPD sample.&lt;SPAN style="COLOR: #1f497d"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;So, you may be wondering: “When should I use WPD to support my sensors and when should I use the Sensors and Location Platform?” Good question. The answer is straightforward. If you’re targeting Microsoft Windows XP or Microsoft Windows Vista: Use WPD. If you’re targeting Windows 7, use the new Sensors and Location Platform.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;One of the key enhancements of the Sensor Platform is its class extension. The sample sensor driver uses the extension to fire both state-change events and data-update events. So, if the sensor is powered-down or disconnected, the driver calls a single class extension method: PostStateChange. And, each time the sensor sends new data, the driver calls the class extension’s &amp;nbsp;PostEvent method. The class extension, and these methods, make it very easy to support a “push” model for applications where the app registers to receive event notifications. &lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;Another enhancement is the platform’s “organization” of the sensor universe. The platform identifies specific categories and subcategories of sensors. So, for example, an application can retrieve all of the connected Passive Infrared sensors by invoking GetSensorsByCategory and specifying “BioMetric” as the specific category of interest. (The application developer doesn’t need to look for an identifier supplied by a hardware vendor for a particular passive infrared sensor.) &lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;By the way, if you were to compare the source code for the WpdBasicHardwareDriver and the SensorParallaxSample driver, you’d notice a number of similarities. This is by-design&lt;SPAN style="COLOR: #1f497d"&gt; &lt;/SPAN&gt;because the WPD and Sensor platform drivers are built on top of the User Mode Driver Framework (WUDF).&lt;SPAN style="COLOR: #1f497d"&gt; &lt;/SPAN&gt;&amp;nbsp;The code which configures the serial port, the code that creates the I/O Target, and the code that parses the packets returned by the sensor originated in the WpdBasicHardwareDriver and was ported to the Sensors and Location Platform.&lt;SPAN style="COLOR: #1f497d"&gt; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;o:p&gt;&lt;EM&gt;This posting is provided "AS IS" with no warranties and confers no rights.&lt;/EM&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;/o:p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9938364" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /><category term="Windows Portable Devices" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+Portable+Devices/" /><category term="Sensors" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Sensors/" /><category term="Sensor Application" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Sensor+Application/" /></entry><entry><title>Windows 7 Device Implementation Guidelines for Picture and Video Import</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/11/13/windows-7-device-implementation-guidelines-for-picture-and-video-import.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/11/13/windows-7-device-implementation-guidelines-for-picture-and-video-import.aspx</id><published>2009-11-14T00:51:42Z</published><updated>2009-11-14T00:51:42Z</updated><content type="html">&lt;p&gt;&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://www.microsoft.com/whdc/device/wpd/PV-Import_Win7.mspx"&gt;Guidelines for Picture and Video Import in Windows 7 white paper&lt;/a&gt; provides information about the picture and video import feature in Windows 7. The white paper includes guidelines for &lt;strong&gt;OEMs &lt;/strong&gt;designing digital cameras and camera-equipped portable devices compatible with and optimized for Windows 7. The following screenshot shows a Device Stage experience for a cellular phone that supports photo and/or video import. The Windows 7 inbox photo import task appears as one of the many tasks that an end-user can interact with that phone.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/Windows7DeviceImplementationGuidelinesfo_ED18/DeviceStage_PVImport_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DeviceStage_PVImport" border="0" alt="DeviceStage_PVImport" src="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/Windows7DeviceImplementationGuidelinesfo_ED18/DeviceStage_PVImport_thumb.png" width="640" height="472" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This white paper describes the types of devices that are supported in Windows 7 for the picture and video import feature. In addition, this paper discusses device requirements and recommended features for optimal performance during the import of pictures and video from the device.&lt;/p&gt;  &lt;h3&gt;Topics Covered&lt;/h3&gt;  &lt;p&gt;Some of the topics covered in this white paper are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The supported device classes &lt;/li&gt;    &lt;li&gt;The supported picture and video formats&lt;/li&gt;    &lt;li&gt;Device requirements and recommendations:      &lt;ul&gt;       &lt;li&gt;Preventing re-import of videos synchronized with Windows Media Player by implementing Sync ID device property &lt;/li&gt;        &lt;li&gt;Improving import performance by implementing the Hints Device Service &lt;/li&gt;        &lt;li&gt;Enabling a determinate-style progress bar like the one shown below, instead of the default indeterminate progress bar &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/Windows7DeviceImplementationGuidelinesfo_ED18/ProgressBar_PVImport_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="ProgressBar_PVImport" border="0" alt="ProgressBar_PVImport" src="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/Windows7DeviceImplementationGuidelinesfo_ED18/ProgressBar_PVImport_thumb.png" width="329" height="189" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;More Resources&lt;/h3&gt;  &lt;p&gt;You can find this whitepaper and more related Windows Portable Devices information (for both application and device development) on the &lt;a href="http://www.microsoft.com/whdc/device/wpd/default.mspx"&gt;Windows Hardware Developer Central&lt;/a&gt; portal.&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922350" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="Device Stage" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Stage/" /><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /><category term="Photo Import" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Photo+Import/" /></entry><entry><title>WPD Platform Update for Windows Vista</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/10/27/wpd-platform-update-for-windows-vista.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/10/27/wpd-platform-update-for-windows-vista.aspx</id><published>2009-10-28T01:04:58Z</published><updated>2009-10-28T01:04:58Z</updated><content type="html">&lt;p&gt;Today we are announcing the final release of the &lt;b&gt;Platform Update for Windows Vista&lt;/b&gt;, which includes an update to WPD to support new features introduced in Windows 7.&lt;/p&gt;  &lt;p&gt;The Platform Update for Windows Vista features a set of runtime libraries which add support for new technologies making it easier for developers to develop for Windows 7 and Windows Vista without impacting their users.&lt;/p&gt;  &lt;h2&gt;&lt;b&gt;Features&lt;/b&gt;&lt;/h2&gt;  &lt;p&gt;The WPD update adds &lt;strong&gt;&lt;i&gt;WPD and&lt;/i&gt; &lt;i&gt;MTP&lt;/i&gt; &lt;i&gt;Device Services&lt;/i&gt;&lt;/strong&gt; and&lt;strong&gt; &lt;i&gt;MTP over Bluetooth&lt;/i&gt;&lt;/strong&gt; features to Windows Vista. The following table identifies the WPD features supported for Windows 7, for Windows Vista, and for Windows Vista with the Platform Update for Windows Vista installed.&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;b&gt;Feature&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;Windows 7&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;Windows Vista&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;Windows Vista + Platform Update for Windows Vista&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;MTP over USB&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;MTP over IP&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;MTP over Bluetooth&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;WPD and MTP Device Services&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;WPD Automation&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Multi-function/Multi-transport&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Device Stage&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Device Sync Platform&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;No&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;h2&gt;Availability and installation&lt;/h2&gt;  &lt;p&gt;The Platform Update for Windows Vista is available for free via Windows Update, Windows Server Update Services and the Microsoft Download Center. Customers running Windows Vista Service Pack 2 with “recommended settings” enabled for Windows Update will automatically receive the update without additional action. The update is also available as a &lt;a href="http://support.microsoft.com/kb/971514"&gt;free download&lt;/a&gt; on the Microsoft Download Center.&lt;/p&gt;  &lt;h2&gt;Additional notes about the Platform Update for Windows Vista&lt;/h2&gt;  &lt;p&gt;All the updated technologies in the Platform Update for Windows Vista are already included in Windows 7. The Platform Update for Windows Vista is &lt;strong&gt;not required for Windows 7&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;To apply the Platform Update for Windows Vista, you must have &lt;strong&gt;Windows Vista Service Pack 2&lt;/strong&gt; installed. &lt;/p&gt;  &lt;h2&gt;More information&lt;/h2&gt;  &lt;p&gt;For specific details about the Platform Update for Windows Vista, &lt;a href="http://support.microsoft.com/kb/971644"&gt;click here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;For more information about MTP Device Services, check out the &lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/08/15/introducing-device-services.aspx"&gt;Introducing Device Services&lt;/a&gt; entry.&lt;/p&gt;  &lt;p&gt;For more information about MTP transports such as USB, IP, and Bluetooth, check out the &lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/08/29/mtp-over-various-transports.aspx"&gt;MTP Over Various Transports&lt;/a&gt; entry.&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9913830" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="Device Services" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Services/" /><category term="Bluetooth" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Bluetooth/" /></entry><entry><title>The MTP Device Simulator</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/10/23/the-mtp-device-simulator.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/10/23/the-mtp-device-simulator.aspx</id><published>2009-10-24T00:52:25Z</published><updated>2009-10-24T00:52:25Z</updated><content type="html">&lt;p&gt;The Media Transfer Protocol Device Simulator (MTP Simulator) is a fully-featured, self-contained device simulator that emulates an MTP device. Its primary purpose is to enable developers to exercise expected behavior based on the MTP specification by returning appropriate MTP response packets and generating MTP events. The tool’s graphical user interface (GUI) enables easy configuration of MTP parameters and presents MTP traffic and data in a friendly, human-readable format. &lt;/p&gt;  &lt;p&gt;The MTP Simulator implements all MTP device capabilities, object properties, and operations that are based on the &lt;a href="#_Supplemental_Information:"&gt;MTP Specification&lt;/a&gt; along with the major features in Windows 7. Additionally, the MTP Simulator also &lt;b&gt;supports&lt;/b&gt; &lt;b&gt;&lt;a href="http://windowsteamblog.com/blogs/windowsexperience/archive/2009/01/08/device-stage-a-new-way-of-interacting-with-devices-in-windows-7.aspx"&gt;Device Stage&lt;/a&gt;&lt;/b&gt; and loading &lt;b&gt;customizable device profiles.&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;For transport support, the MTP Simulator runs on &lt;b&gt;multiple transport options&lt;/b&gt; such as USB, Software-Simulated USB (SoftSim), Bluetooth, and IP. Last, but not the least, the MTP Simulator runs on both &lt;a&gt;Windows Vista and Windows 7.&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Where to get the MTP Simulator&lt;/h2&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The MTP Simulator is publicly available as part of the &lt;a href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;Windows 7 Portable Device Enabling Kit for MTP (DEK&lt;/a&gt;). The kit also includes support documentation for the MTP Simulator and the MTP Specification Version 1.0 and MTP Device Services for Windows. Included in the DEK is the &lt;em&gt;MTP Device Simulator User Guide&lt;/em&gt; which provides a detailed description of the MTP Simulator.&lt;/p&gt;  &lt;h2&gt;Installing the MTP Simulator&lt;/h2&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The MTP Device Simulator is installed as part of the Windows 7 Portable Device Enabling Kit for MTP (DEK). Before running the simulator for the first time, you may need to install the Device Simulation Framework (DSF).&lt;/p&gt;  &lt;p&gt;To install DSF:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Browse to the folder where the DEK is installed (usually C:\Windows7DEK) &lt;/li&gt;    &lt;li&gt;Navigate to the Tools\MTP Device Simulator\Dsf subfolder &lt;/li&gt;    &lt;li&gt;Open an elevated command window (i.e. &amp;quot;Run as Administrator”) and launch install.cmd to start the DSF MSI package install. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Once DSF is installed, you can launch the MTP Simulator from C:\WindowsDEK\Tools\MTP Device Simulator\MTPSimUI.exe. Select your desired transport, and click “Connect” to launch an instance of the MTP Simulator. The next section gives an overview of the User Interface.&lt;/p&gt;  &lt;h2&gt;User Interface&lt;/h2&gt;  &lt;p&gt;The following screenshot shows the MTP Simulator UI with navigation buttons and configuration options.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/TheMTPDeviceSimulator_FB0F/MTPSim.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="MTPSim" border="0" alt="MTPSim" src="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/TheMTPDeviceSimulator_FB0F/MTPSim_thumb.png" width="644" height="455" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;   &lt;table border="1" cellspacing="0" cellpadding="1"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="90"&gt;&lt;strong&gt;MTP Simulator              &lt;br /&gt;Configuration&lt;/strong&gt; &lt;/b&gt;&lt;/td&gt;          &lt;td valign="top" width="108"&gt;&lt;b&gt;Location&lt;/b&gt; &lt;/td&gt;          &lt;td valign="top" width="339"&gt;&lt;b&gt;Purpose&lt;/b&gt; &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="90"&gt;           &lt;p&gt;Connection&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="108"&gt;           &lt;p&gt;Left control tabs and menu options.&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="339"&gt;           &lt;p&gt;Connect, disconnect, or restart MTP Simulator by using the currently selected configuration. You can change the transport type on the &lt;b&gt;Transport&lt;/b&gt; tab and change the test mode on the &lt;b&gt;Device Mode&lt;/b&gt; tab.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="90"&gt;           &lt;p&gt;Transport&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="108"&gt;           &lt;p&gt;Left control tabs and menu options.&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="339"&gt;           &lt;p&gt;Select the transport to be used. To simulate a software-only USB device, select the “SoftUSB” transport.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="90"&gt;           &lt;p&gt;Device mode&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="108"&gt;           &lt;p&gt;Left control tabs and menu options.&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="339"&gt;           &lt;p&gt;Normal Mode should be used. Test Mode is reserved for internal Microsoft testing.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="90"&gt;           &lt;p&gt;Output windows&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="108"&gt;           &lt;p&gt;Lower-right output window.&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="339"&gt;           &lt;p&gt;This window displays redirected output from stdout. Any output from a printf statement, such as trace—from either MTP Simulator or a plug-in—appears in this window. The output is also saved as mtpsimui.log automatically under the MTP Simulator root directory.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;h6&gt;Table 1. MTP Simulator User Controls&lt;/h6&gt;  &lt;h2&gt;Command-Line Options&lt;/h2&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;In addition to the GUI, you can control MTP Simulator at startup by using command-line parameters. This can be useful when you need to perform automated testing. For details, see &lt;strong&gt;Appendix C&lt;/strong&gt; from the &lt;em&gt;MTP Device Simulator User Guide&lt;/em&gt;. &lt;/p&gt;  &lt;h2&gt;Customizing the MTP Simulator&lt;/h2&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;You can control the capabilities that the MTP Simulator reports to Windows by using an XML file (see Appendix F in the &lt;em&gt;MTP Device Simulator User Guide&lt;/em&gt; for details). Device capabilities are controlled by DeviceSummary.xml, and service capabilities are controlled by Services.xml.&lt;/p&gt;  &lt;p&gt;The DeviceSummary.xml file enables you to customize the contents of the DeviceInfo, StorageInfo, DevicePropDesc, and ObjectPropDesc datasets.&lt;/p&gt;  &lt;p&gt;The Services.xml file enables you to specify configurations that are related to device services, including service-supported formats, methods, and events.&lt;/p&gt;  &lt;h2&gt;Device Profiles&lt;/h2&gt;  &lt;p&gt;The MTP Simulator also supports loading &lt;a&gt;different device profiles&lt;/a&gt;. A device profile contains a set of customized configuration files (i.e. DeviceSummary.xml and Services.xml) describing a sample device. The DEK comes bundled with sample profiles representing each device class (Camera, Cellular Phone, Media Player, etc). Details of how to load the device profiles are outlined in the &lt;em&gt;MTP Device Simulator User Guide&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;   &lt;table border="1" cellspacing="0" cellpadding="1"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="217"&gt;&lt;strong&gt;Device Profile&lt;/strong&gt;&lt;/td&gt;          &lt;td valign="top" width="402"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="217"&gt;           &lt;p&gt;Fabrikam_Camera&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="402"&gt;           &lt;p&gt;Simulates a sample camera.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="217"&gt;           &lt;p&gt;Fabrikam_Phone&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="402"&gt;           &lt;p&gt;Simulates a cellular phone.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="217"&gt;           &lt;p&gt;Fabrikam_PMP&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="402"&gt;           &lt;p&gt;Simulates a portable media player.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="217"&gt;           &lt;p&gt;MtpSim-FullEnumSync&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="402"&gt;           &lt;p&gt;Simulates a device that supports the Full Enumeration synchronization model, for example for contacts, calendar, tasks, and notes synchronization.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="217"&gt;           &lt;p&gt;MtpSim-FullEnumSyncSimpleParticipant&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="402"&gt;           &lt;p&gt;Simulates a device that supports the Full Enumeration synchronization model (like MtpSim-FullEnumSync), with additional support for the simple participant feature.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;h6&gt;Table 2: Sample MTP Simulator Device Profiles&lt;/h6&gt;  &lt;p&gt;Each of these profiles has a corresponding Device Stage package. Each of these packages supports the same set of standard Device Stage tasks, with the exception of the Ringtone task which is not supported by the Fabrikam_Camera and Fabrikam_PMP profiles. For more information on authoring Device Stage metadata, refer to the &lt;b&gt;Windows 7 Device Stage Development Guide&lt;/b&gt; in the &lt;a href="http://www.microsoft.com/whdc/device/DeviceExperience/Dev-Kit.mspx"&gt;Microsoft Device Experience Development Kit&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Testing Device Stage Packages&lt;/h2&gt;  &lt;p&gt;The MTP Simulator can also be used to test custom Device Stage packages. The MTP Device Inspector tool can be used to generate a device profile which can be loaded into the Simulator (see the &lt;i&gt;MTP Device Simulator User Guide &lt;/i&gt;for details&lt;i&gt;)&lt;/i&gt;. Once a custom Device Stage metadata package has been authored, the package contains all the files necessary to display a Device Stage experience in Windows 7. The package may be tested by copying it to the PC’s device metadata store and connecting the test device, in this case rapid development can be done using the MTP Simulator. In order to load (unsigned) custom Device Stage metadata the system will need to be boot into test mode. For more details, refer to page 40 of the &lt;b&gt;Windows 7 Device Stage Development Guide&lt;/b&gt; document that is included in the &lt;a href="http://www.microsoft.com/whdc/device/DeviceExperience/Dev-Kit.mspx"&gt;Microsoft Device Experience Development Kit&lt;/a&gt; for details on testing Device Stage metadata packages.&lt;/p&gt;  &lt;h2&gt;Want to Learn More?&lt;/h2&gt;  &lt;p&gt;The &lt;i&gt;MTP Device Simulator User Guide&lt;/i&gt; in the Documentation for the &lt;a href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;Device Enabling Kit&lt;/a&gt; contains more information on the features described above.&lt;/p&gt;  &lt;p&gt;If you have general questions about the MTP Simulator contact AskMTP at Microsoft dot com.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9912325" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="Tools" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Tools/" /><category term="Device Stage" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Stage/" /><category term="Device Services" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Services/" /></entry><entry><title>Windows 7 Portable Devices and the Windows Logo Program</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/10/09/windows-7-portable-devices-and-the-windows-logo-program.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/10/09/windows-7-portable-devices-and-the-windows-logo-program.aspx</id><published>2009-10-10T03:22:00Z</published><updated>2009-10-10T03:22:00Z</updated><content type="html">&lt;p&gt;With the release of Windows 7 we are seeing a great deal of maturity of the Windows Portable Device (WPD) Platform. The WPD Platform includes the WPD APIs with WPD Automation and native Device Services, the Media Transfer Protocol (MTP) class drivers with MTP over USB, MTP over IP, and MTP over Bluetooth. For more information on what was new for Windows 7, see our &lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/08/07/windows-7-new-features.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/08/07/windows-7-new-features.aspx"&gt;New Features for Windows 7 post&lt;/a&gt;. Due largely to the native support in Windows and our high level of engagement with industry partners we were able to put together a new comprehensive Logo program for Portable Devices that work well with Windows.&lt;/p&gt;  &lt;p&gt;This blog post covers the following topics:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;What is the Windows Logo Program for Hardware?&lt;/li&gt;    &lt;li&gt;Supported Portable Device Logo Programs&lt;/li&gt;    &lt;li&gt;Prepared Requirement Reports&lt;/li&gt;    &lt;li&gt;Windows Logo Kit&lt;/li&gt;    &lt;li&gt;Additional Information on the Windows Logo Program for Hardware&lt;/li&gt;    &lt;li&gt;Development Tools and Support&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;What is the Windows Logo Program for Hardware?&lt;/h2&gt;  &lt;p&gt;The Windows Logo Program is designed to address the current and future market needs of customers using the Windows platform. The Windows logo signifies the compatibility and reliability of systems and devices with the Windows operating system. It gives customers confidence that your product is thoroughly tested with Microsoft-provided tools and ensures a good user experience.&lt;/p&gt;  &lt;p&gt;The Windows Logo Program helps partners to innovate and bring a premium experience to market, thereby improving their ability to increase market share. The program strives to continuously improve its processes, responsiveness, and partner satisfaction.    &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Supported Portable Device Logo Programs&lt;/h2&gt;  &lt;p&gt;There are currently 3 logo categories that are accepting submissions for Portable Devices, they are:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Digital Still Camera- &lt;/b&gt;This program supports logo for Windows 7 and Windows Vista&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Portable Media Player&lt;/b&gt;- This program supports logo for Windows 7 and Windows Vista. The PlaysForSure program was retired at the end of August 2009.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Cellular Handset (Phone)&lt;/b&gt;- This program supports logo for Windows 7, Windows Vista, and Windows XP.The PlaysForSure program was retired at the end of August 2009.&lt;b&gt; &lt;/b&gt;&lt;/p&gt;  &lt;p&gt;With the release of the Windows Logo Kit (WLK) 1.5, which is due to release at the end of November 2009, we will see one additional category:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Other Portable Devices &lt;/b&gt;- This program supports logo for Windows 7.&lt;/p&gt;  &lt;p&gt;This new category is being made available as an option for hardware manufacturers that support the core set of MTP Revision 1.0 operations, device properties, and object formats. Passing this logo program provides validation that the device has implemented the MTP protocol correctly, so that the device will work as expected with the MTP class driver in Windows 7.&lt;/p&gt;  &lt;p&gt;The following table provides a breakdown of requirements for each of these 4 categories. The ‘R' in the table implies that the operation,property, or object format is required. If the field is blank the requirement is optional.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;RequiredOperations&lt;/b&gt;&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p align="center"&gt;&lt;b&gt;&amp;#160;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;&lt;b&gt;Property Code&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;&lt;b&gt;Cellular Handset&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&lt;b&gt;Portable Media Player&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&lt;b&gt;Digital Camera&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&lt;b&gt;Other Portable Devices             &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="479" colspan="6"&gt;         &lt;p&gt;&lt;b&gt;Operations&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetDeviceInfo&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1001&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;OpenSession&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1002&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;CloseSession&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1003&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetStorageIDs&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1004&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetStorageInfo&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1005&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetNumObjects&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1006&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetObjectHandles&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1007&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetObjectInfo&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1008&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetObject&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1009&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;SetDevicePropValue&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x100a&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;DeleteObject&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x100b&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;SendObjectInfo&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x100c&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;SendObject&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x100d&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetDevicePropDesc&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1014&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetDevicePropValue&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x1015&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetPartialObject&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x101b&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetObjectPropsSupported&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x9801&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetObjectPropDesc&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x9802&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetObjectPropValue&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x9803&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;SetObjectPropValue&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x9804&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;GetObjectReferences&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x9810&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;SetObjectReferences&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x9811&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;See &lt;b&gt;Appendix D - Operations&lt;/b&gt; in the MTP Specification, Revision 1.0 for complete list of defined MTP Operations. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Required Device Properties&lt;/b&gt;&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p align="center"&gt;&lt;b&gt;&amp;#160;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;&lt;b&gt;Property Code&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;&lt;b&gt;Cellular Handset&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&lt;b&gt;Portable Media Player&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&lt;b&gt;Digital Camera&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&lt;b&gt;Other Portable Devices             &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="479" colspan="6"&gt;         &lt;p&gt;&lt;b&gt;Device Properties&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;Battery Level&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0x5001&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(1)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;Synchronization Partner&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0xd401&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="129"&gt;         &lt;p&gt;Device Friendly Name&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="80"&gt;         &lt;p align="center"&gt;0xd402&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="61"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;See &lt;b&gt;Appendix C - Device Properties &lt;/b&gt;in the MTP Specification, Revision1.0 for complete list of defined Device Properties. &lt;/p&gt;  &lt;p&gt;(1)Digital Cameras are required to support Battery Level after June 2010.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Required Object Formats&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The following table represents the list of required object formats for a portable device. Each object format also has a list of object properties that must be supported per object type. See requirement &lt;b&gt;PORTABLE-0064&lt;/b&gt; for more details.&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p align="center"&gt;&lt;b&gt;&amp;#160;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;&lt;b&gt;Property Code&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;&lt;b&gt;Cellular Handset&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&lt;b&gt;Portable Media Player&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&lt;b&gt;Digital Camera&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&lt;b&gt;Other Portable Devices             &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="479" colspan="6"&gt;         &lt;p&gt;&lt;b&gt;Object Formats&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;Undefined&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x3000&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;Association&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x3001&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;Abstract Audio Album&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0xba03&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;Abstract Audio &amp;amp; Video Playlist&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0xba05&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;WAV&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x3008&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;MP3&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x3009&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;AVI&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x300a&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;MPEG&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x300b&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;ASF&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x300c&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;EXIF/JPEG&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x3801&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;R&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;TIFF/EP&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x3802&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;BMP&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0x3804&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;WMA&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0xb901&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;AAC&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0xb903&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;WMV&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0xb981&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;MP4 Container&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0xb982&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;         &lt;p&gt;3GP Container&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="79"&gt;         &lt;p align="center"&gt;0xb984&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="60"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;R&lt;sup&gt;(2)&lt;/sup&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="69"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="70"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;(2) Portable devices that are capable of playing audio and/or video must support at least one of these formats.&amp;#160; This table does not represent the complete list of supported formats; it represents the list of commonly used formats.&lt;/p&gt;  &lt;p&gt;See &lt;b&gt;Appendix A - Object Formats&lt;/b&gt; in the MTP Specification, Revision 1.0 for complete list of defined Device Properties.&amp;#160; &lt;/p&gt;  &lt;h2&gt;Prepared Requirement Reports&lt;/h2&gt;  &lt;p&gt;The Windows Logo Program for Hardware creates a list of requirements that the validation tests are based on. During the hardware design phase it is critical that manufacturers that are going to be involved with the logo process review the logo requirements that are applicable to a target OS,such as Windows 7. Although the majority of requirements that are outlined for Portable Devices are based on industry standards and specifications or white papers &lt;a href="http://www.microsoft.com/whdc/device/wpd/default.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/default.mspx"&gt;published by Microsoft&lt;/a&gt;, there are some requirements that may not be apparent until you attempt to run through the WLK and come across a failure that you do not expect. For example, we have portable device specific behavior requirements defined but there are also fundamental requirements that apply to all devices for Windows. There are also requirements that apply to all USB devices, one such requirement is support for USB serial numbers for all portable USB devices. Additional requirements can be reviewed by downloading the &lt;a href="https://winqual.microsoft.com/member/LogoPoint/Requirements/PreparedRequirementReport.aspx" mce_href="https://winqual.microsoft.com/member/LogoPoint/Requirements/PreparedRequirementReport.aspx"&gt;Prepared Requirements Reports&lt;/a&gt; which are organized by specific hardware technologies.     &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Windows Logo Kit&lt;/h2&gt;  &lt;p&gt;The Windows Logo Kit (WLK) is used to validate the requirements defined for the logo program. This kit can also be used for product development. We encourage its use during the product development cycle of hardware in order to ensure device compliance with both Windows and industry standards. The kit includes several tests designed to validate device implementation and behavior at multiple levels. There are tests for USB compliance, MTP compliance, and WPD platform compliance that also cover device services validation.&amp;#160; &lt;/p&gt;  &lt;p&gt;Thecore tests provided for portable devices are:&lt;/p&gt;  &lt;ul class="unIndentedList"&gt;   &lt;li&gt;MTP Compliance Tests &lt;/li&gt;    &lt;li&gt;WPD Compliance Tests&lt;/li&gt;    &lt;li&gt;WMDM Compliance Tests&lt;/li&gt;    &lt;li&gt;WMDM Sync Test&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For detailed description of these tests, please go to the &lt;a href="http://msdn.microsoft.com/en-us/library/dd327436.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd327436.aspx"&gt;WLK help documentation&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;There is a significant amount of information available about the WLK, including user guides and video tutorials. For more information about the WLK see: &lt;a href="http://www.microsoft.com/whdc/winlogo/WLK/default.mspx" mce_href="http://www.microsoft.com/whdc/winlogo/WLK/default.mspx"&gt;http://www.microsoft.com/whdc/winlogo/WLK/default.mspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The kit is free to download and use.    &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Additional Information on the Windows Logo Program for Hardware&lt;/h2&gt;  &lt;p&gt;There is a wealth of additional information that has been made available for this program. Here are some of the key helpful links that will help you navigate the logo program.&lt;/p&gt;  &lt;ul class="unIndentedList"&gt;   &lt;li&gt;&lt;a href="http://www.microsoft.com/whdc/winlogo/default.mspx" mce_href="http://www.microsoft.com/whdc/winlogo/default.mspx"&gt;http://www.microsoft.com/whdc/winlogo/default.mspx&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc300359.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc300359.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc300359.aspx&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx?dg=microsoft.public.development.device.drivers.dtm&amp;amp;cat=en_us_7CF920C0-483A-5AF9-37A8-BB5310F0ACF4&amp;amp;lang=en&amp;amp;cr=us" mce_href="http://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx?dg=microsoft.public.development.device.drivers.dtm&amp;amp;cat=en_us_7CF920C0-483A-5AF9-37A8-BB5310F0ACF4&amp;amp;lang=en&amp;amp;cr=us"&gt;http://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx?dg=microsoft.public.development.device.drivers.dtm&amp;amp;cat=en_us_7CF920C0-483A-5AF9-37A8-BB5310F0ACF4&amp;amp;lang=en&amp;amp;cr=us&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We strongly encourage anyone that is going to participate in the logo program to review the &lt;a href="http://www.microsoft.com/whdc/winlogo/logocast.mspx" mce_href="http://www.microsoft.com/whdc/winlogo/logocast.mspx"&gt;Windows Logo Program Webcasts&lt;/a&gt; as well. These are a series of videos that can be viewed on demand that covers logo planning, testing, development, and how to submit logo packages using the qualification page at &lt;a href="https://winqual.microsoft.com/" mce_href="https://winqual.microsoft.com/"&gt;https://winqual.microsoft.com&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Development Tools and Support&lt;/h2&gt;  &lt;p&gt;There are several development resources available for portable device manufacturers. Probably the best source for this information was put together and released as a WPD Team Blog back in September, refer to &lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/09/11/windows-7-portable-device-development-kits.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/09/11/windows-7-portable-device-development-kits.aspx"&gt;Windows7 Portable Device Development Kits&lt;/a&gt; for details. That blog post covered the following development resources:&lt;/p&gt;  &lt;ul class="unIndentedList"&gt;   &lt;li&gt;Windows 7 Portable Device Enabling Kit for MTP &lt;/li&gt;    &lt;li&gt;Windows Portable Devices SDK &lt;/li&gt;    &lt;li&gt;Windows Portable Devices Driver Kit &lt;/li&gt;    &lt;li&gt;Windows Media Device Manager SDK &lt;/li&gt;    &lt;li&gt;Microsoft Device Experience Development Kit &lt;/li&gt;    &lt;li&gt;Windows Logo Kit &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you have general questions about MTP or WPD development, contact AskMTP at microsoft dot com. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905689" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /><category term="Windows Logo" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+Logo/" /><category term="WLK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WLK/" /></entry><entry><title>Windows 7 Application Samples</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/09/25/windows-7-application-samples.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/09/25/windows-7-application-samples.aspx</id><published>2009-09-26T01:52:00Z</published><updated>2009-09-26T01:52:00Z</updated><content type="html">
&lt;p&gt;The Windows Portable Devices (WPD) SDK includes two sample command-line applications written in C++. The first application, WpdApiSample, lets the user accomplish tasks like: enumerating connected devices, exploring objects on these devices, and enumerating object properties. The second application, WpdServiceApiSample, is designed to explore a Contacts Device Service. The user can enumerate connected device services, retrieve properties and formats for a given service, and invoke methods on that service. The WPD SDK is included in the Windows SDK which can be downloaded from &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following sections describe each sample application, the modules found in that application, and the operating systems that it will run on. &lt;/p&gt;
&lt;h4&gt;WpdApiSample&lt;/h4&gt;
&lt;p&gt;Of the two sample applications, the WpdApiSample, is the most generalized. It demonstrates how a developer would use the WPD API to accomplish tasks common to most applications. For example, this application demonstrates how a developer would:&lt;/p&gt;

&lt;p&gt;· Enumerate the devices connected to a computer.&lt;/p&gt;

&lt;p&gt;· Establish a connection to a connected device.&lt;/p&gt;

&lt;p&gt;· Enumerate device content.&lt;/p&gt;

&lt;p&gt;· Retrieve the properties for a given object on a device.&lt;/p&gt;

&lt;p&gt;· Set the properties for a given object on a device.&lt;/p&gt;

&lt;p&gt;· Retrieve general device information (for example, a description of the operations that a device can perform).&lt;/p&gt;

&lt;p&gt;· Operate on device content (for example, move a file from one folder on the device to another).&lt;/p&gt;

&lt;p&gt;The WpdApiSample application includes the following files: 
&lt;/p&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;&lt;b&gt;File&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ContentEnumeration.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains functions that enumerate all the objects on a device.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ContentProperties.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains functions that read and write object properties and make bulk property set/get requests.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ContentTransfer.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains functions that transfer content to or from the device, read object type requirements, and create a folder on the device.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;DeviceCapabilities.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains functions to list the functional object types on the device, list the content types supported by each functional object type, and display rendering object profiles.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;DeviceEnumeration.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Lists the friendly names, manufacturers, and descriptions of all connected devices.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;DeviceEvents.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains functions that log device events and their parameters whenever events are fired.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;Stdafx.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Includes the standard files.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;WpdApiSample.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Displays a list of available devices and tasks available to the user.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;This application is supported on Windows XP, Windows Vista, and Windows 7. &lt;/p&gt;

&lt;p&gt;Even if you have no WPD devices connected to your computer, you can familiarize yourself with the WPD API and this application by installing the WpdHelloWorldDriver sample from the Windows Driver Kit (WDK), which emulates a simple WPD device. For information about downloading the WDK, see &lt;a href="http://www.microsoft.com/whdc/resources/downloads.mspx" mce_href="http://www.microsoft.com/whdc/resources/downloads.mspx"&gt;http://www.microsoft.com/whdc/resources/downloads.mspx&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;WpdServiceApiSample&lt;/h4&gt;
&lt;p&gt;The WpdServiceApiSample sample demonstrates how a developer would use the WPD API to explore a Contacts Device Service on a device that’s attached to a computer. For example, this application demonstrates how a developer would:&lt;/p&gt;

&lt;p&gt;· Enumerate the services on a devce.&lt;/p&gt;

&lt;p&gt;· Open a service.&lt;/p&gt;

&lt;p&gt;· Enumerate service content.&lt;/p&gt;

&lt;p&gt;· Retrieve the events and methods supported by a service.&lt;/p&gt;

&lt;p&gt;· Access the service object properties.&lt;/p&gt;

&lt;p&gt;· Invoke service methods (both synchronously and asynchronously).&lt;/p&gt;

&lt;p&gt;The WpdServiceApiSample application includes the following files: 
&lt;/p&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;&lt;b&gt;File&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ContentEnumeration.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains methods that enumerate the content on a given Contacts service.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ContentProperties.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains methods that read and write properties on a given Contacts service.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ServiceCapabilities.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains the methods that retrieve the supported formats, events, and abstract services that are supported by a given Contacts service.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ServiceEnumeration.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains the helper functions that retrieve device information such as the device-friendly name or the supported Contacts services.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;ServiceMethods.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Contains the methods that retrieve and invoke methods supported by a given Contacts service.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;Stdafx.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Includes the standard files.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="319"&gt;
&lt;p&gt;WpdServiceApiSample.cpp&lt;/p&gt;
&lt;/td&gt;

&lt;td valign="top" width="319"&gt;
&lt;p&gt;Displays a list of available device services and tasks available to the user&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Because Device Services is new for Windows 7, this application is only supported in the Windows 7 operating system. &lt;/p&gt;

&lt;p&gt;Even if you have no WPD devices connected to your computer, you can familiarize yourself with the WPD API and this application by installing the WpdServiceSampleDriver that’s included as a sample in the Windows Driver Kit (WDK). This sample driver emulates a simple WPD device service. &lt;/p&gt;
&lt;h4&gt;Other Samples&lt;/h4&gt;
&lt;p&gt;In addition to the two samples that ship in the SDK, the WPD team created three other samples that demonstrate using WPD to display the current office temperature in the Windows Sidebar. One of these samples is written using unmanaged-code and C++; another is written using the COM interop and Visual Basic .Net; and, the third is written using the COM interop and Visual C# .Net.&lt;/p&gt;

&lt;p&gt;All three of these samples rely on a simple temperature sensor device, device-firmware, and a sample WPD driver. You can download the circuit description, device-firmware, and sample driver from here: &lt;a href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx" mce_href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx"&gt;http://www.microsoft.com/whdc/device/media/WPD_drv.mspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you build the device, download the firmware, and install the driver, you can begin exploring the WPD API samples. You’ll find a description of the unmanaged application at: &lt;a href="http://blogs.msdn.com/wpdblog/archive/2007/12/19/creating-a-temperature-sensor-gadget-for-windows-sidebar-with-c.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/12/19/creating-a-temperature-sensor-gadget-for-windows-sidebar-with-c.aspx"&gt;http://blogs.msdn.com/wpdblog/archive/2007/12/19/creating-a-temperature-sensor-gadget-for-windows-sidebar-with-c.aspx&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You’ll find a description of the COM interop and Visual Basic .Net application at: &lt;a href="http://wpdtempsensor.codeplex.com/" mce_href="http://wpdtempsensor.codeplex.com/"&gt;http://wpdtempsensor.codeplex.com/&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;And, you’ll find a description of the COM interop and the C# application at: &lt;a href="http://blogs.msdn.com/wpdblog/archive/2007/11/26/creating-a-temperature-sensor-gadget-for-windows-sidebar.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/11/26/creating-a-temperature-sensor-gadget-for-windows-sidebar.aspx"&gt;http://blogs.msdn.com/wpdblog/archive/2007/11/26/creating-a-temperature-sensor-gadget-for-windows-sidebar.aspx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties and confers no rights.&lt;/i&gt;&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899742" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="SDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/SDK/" /><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /></entry><entry><title>Windows 7 Driver Samples</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/09/18/windows-7-driver-samples.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/09/18/windows-7-driver-samples.aspx</id><published>2009-09-19T00:24:00Z</published><updated>2009-09-19T00:24:00Z</updated><content type="html">&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;The Windows Portable Devices Driver Kit in the Windows Driver Kit (WDK) comes bundled with five WPD sample drivers. Two of these drivers, WpdHelloWorldDriver and WpdWudfSampleDriver, were available in previous versions of the WDK. The remaining three drivers, WpdBasicHardwareDriver, WpdServiceSampleDriver, and WpdMultiTransportDriver, are new additions in the Windows 7 WDK. Together, these samples illustrate how to build a WPD driver for the different scenarios that WPD enables, including interaction with basic hardware, media synchronization, device services, and multi-transport. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;We had mentioned these samples in a previous post on the &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/wpdblog/archive/2009/09/11/windows-7-portable-device-development-kits.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/09/11/windows-7-portable-device-development-kits.aspx"&gt;&lt;FONT size=2&gt;Windows 7 Portable Devices Development Kits&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=2&gt;. The purpose of this post is to spend some time covering each sample in greater detail. Hopefully, this will help driver developers navigate the various WPD samples, and figure out which sample(s) best fit their driver requirements. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;The following sections will describe each driver, the &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd434932.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd434932.aspx"&gt;&lt;FONT size=2&gt;WPD commands&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=2&gt; that each implements, and the operating systems that each supports. In addition, we will provide the links to instructions for building and installing.&lt;/FONT&gt;&lt;/P&gt;
&lt;H2&gt;WpdHelloWorldDriver&lt;/H2&gt;
&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;SPAN&gt;Of all the sample drivers, the WpdHelloWorldDriver is the most simple. This driver supports and emulates four objects in software: a device object, a storage object, a folder object, and a text file object. WpdHelloWorldDriver was designed to provide the most basic scaffolding or skeleton required for developing a WPD driver; similar to the canonical "Hello World" program used for introducing a framework or programming language. If you are new to WPD driver development and need a kick start, we recommend starting with this sample.&lt;/SPAN&gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;The WpdHelloWorldDriver sample supports 22 commands. These commands cover the basic functionality that enables a WPD device to be browsed in Windows Explorer as a read-only device. The commands fall into four categories: object enumeration, object properties, object resources, and device capabilities. Like all WPD drivers, when this driver is installed and a WPD application calls a method to enumerate objects, set a property, open a resource, and so on, the driver will invoke a corresponding command handler for one of these supported commands. &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;This driver is supported on Windows XP, Windows Vista (x86, amd64), and Windows 7 (x86, amd64). &lt;/P&gt;
&lt;P&gt;For instructions on how to build and install this driver, see: &lt;A href="http://msdn.microsoft.com/en-us/library/dd573842.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd573842.aspx"&gt;http://msdn.microsoft.com/en-us/library/dd573842.aspx&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;WpdBasicHardwareDriver&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;The WpdBasicHardwareDriver sample is new for Windows 7 and builds upon the WpdHelloWorldDriver. This sample stands apart from the other WPD samples in that it accesses real device hardware instead of emulating a software-only device. We provided this sample to demonstrate how a basic WPD driver can be built to interact with simple devices. &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;For our demonstration device, we targetted a “hobbyist” microcontroller that reads data from a variety of sensors. The sensors include: a 2-axis accelerometer, a 3-axis accelerometer, a temperature/humidity sensor, a pressure sensor, a distance sensor, a passive infrared sensor, a compass, a vibration sensor, and a light sensor. These sensor devices are controlled by a Parallax BS2 microcontroller attached to the PC via an RS232 port. In addition to the driver source code, we also provided some sample firmware code that retrieves the sensor data and sends them over the serial port to the PC.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;The WpdBasicHardwareDriver sample supports an even smaller set of commands than the WpdHelloWorldDriver. In the interests of only providing the code that is necessary to demontrate the concepts, we removed some commands for object resources because the WpdBasicHardwareDriver does not need to support reading of files from the device. The remaining commands fall under these three categories: object enumeration, object properties, and device capabilities. To see this driver in action, you can use WpdMon to view the events corresponding to each sensor reading.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This sample also showcases how WPP Software Tracing can be used for error checking macros. A while ago, we had a post &lt;FONT size=2&gt;that describes how you can &lt;A href="http://blogs.msdn.com/wpdblog/archive/2007/04/01/driver-dev-guide-using-wpp-tracing-in-your-wpd-driver.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/04/01/driver-dev-guide-using-wpp-tracing-in-your-wpd-driver.aspx"&gt;migrate your existing WPD driver from OutputDebugString to WPP Tracing&lt;/A&gt;. The WpdBasicHardwareDriver is now bundled with the macros.&lt;/FONT&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This driver is supported on Windows XP, Windows Vista (x86, amd64), and Windows 7 (x86, amd64). If you plan to develop drivers that integrate sensors with Windows 7, we recommend using the &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd318953%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd318953(VS.85).aspx"&gt;&lt;FONT size=2&gt;Sensor API&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=2&gt; and &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/cc974537.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc974537.aspx"&gt;&lt;FONT size=2&gt;Sensor Driver Model&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=2&gt;. If you need to develop drivers to integrate sensors with Windows Vista or Windows XP, WPD provides a viable solution.&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;For instructions on how to build and install this driver, see: &lt;A href="http://msdn.microsoft.com/en-us/library/dd573829.aspx"&gt;http://msdn.microsoft.com/en-us/library/dd573829.aspx&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;H2&gt;WpdWudfSampleDriver&lt;/H2&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;SPAN&gt;The WpdWudfSampleDriver is a comprehensive driver sample that demonstrates using the WPD DDI for media transfer scenarios.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;In addition to file browsing and transfer via Windows Explorer, this sample contains additional functionality that supports media synchronization with Windows Media Device Manager (WMDM) applications (e.g. Windows Media Player), and photo acquisition with Windows Image Acquisition (WIA) applications (e.g. Paint). All interactions with hardware are emulated in software (meaning that this driver talks to a "fake" device).&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;To enable the media transfer scenarios, the WpdWudfSampleDriver sample had to support a large set of commands, including the commands supported by the WpdHelloWorldDriver. These commands can be divided into eight categories: object enumeration, object management, object properties, bulk properties, object resources, capabilities, and storage.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;In this version, we fixed &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/wpdblog/archive/2007/05/08/getting-a-wpd-sample-driver-working-with-windows-media-player-11.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/05/08/getting-a-wpd-sample-driver-working-with-windows-media-player-11.aspx"&gt;&lt;FONT size=2&gt;a compatibility issue&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=2&gt; in the Vista WDK version of the sample driver code that prevents it from being properly enumerated in Windows Media Player.&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;This driver is supported on Windows XP, Windows Vista (x86, amd64), and Windows 7 (x86, amd64).&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;For instructions on how to build and install this driver, see: &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd573843.aspx"&gt;http://msdn.microsoft.com/en-us/library/dd573843.aspx&lt;/A&gt; &lt;/P&gt;
&lt;H2&gt;WpdMultiTransportDriver&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;The WpdMultiTransportDriver builds upon the WpdHelloWorldDriver and demonstrates how driver developers can take advantage of the Windows 7 support for Multiple Transports. For an overview on what multi transport is all about, check out our post two weeks ago about &lt;A href="http://blogs.msdn.com/wpdblog/archive/2009/09/04/multi-transport-devices-in-windows-7.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/09/04/multi-transport-devices-in-windows-7.aspx"&gt;Multi-Transport support in Windows 7&lt;/A&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;. &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: small" class=Apple-style-span&gt;This driver emulates a transport driver and illustrates how to set the relevant multi-transport settings and generate the Functional Unique Identifier (FUID) during device arrival, in order to perform handshaking with the WPD Composite Driver. In addition, this sample supports multiple Windows Driver Framework I/O queues, where all the other WPD samples only support a single I/O queue.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: small" class=Apple-style-span&gt;Other than the multi-transport support, the WpdMultiTransportDriver sample is virtually identical as the WpdHelloWorldDriver, and supports the same set of WPD commands. A quick way to zero-in on the code modifications needed to support Multi-Transport is to use your favorite diff program to compare the WpdHelloWorldDriver and WpdMultiTransportDriver source folders.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;Because multi-transport support is a new feature in Windows 7, this sample driver is only supported on Windows 7 (x86, amd64). &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;For instructions on how to build and install this driver, see: &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd573843.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd573843.aspx"&gt;&lt;FONT size=2&gt;http://msdn.microsoft.com/en-us/library/dd573843.aspx&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;SPAN&gt;
&lt;H2&gt;WpdServiceSampleDriver&lt;/H2&gt;&lt;/SPAN&gt;
&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;The WpdServiceSampleDriver demonstrates how a driver can support Windows 7 Device Services. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;We covered an &lt;A href="http://blogs.msdn.com/wpdblog/archive/2009/08/15/introducing-device-services.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/08/15/introducing-device-services.aspx"&gt;introduction to Device Services&lt;/A&gt; in another recent post&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;. This driver emulates a basic Contacts device service that uses the Full Enumeration Sync device service. To support Device Services, this driver implements device services-specific WPD command sets: WPD_CATEGORY_SERVICE_COMMON, WPD_CATEGORY_SERVICE_CAPABILITIES, and WPD_CATEGORY_SERVICE_METHODS. These commands would allow an application to determine the capabilities of a service and invoke methods supported by the service. This driver also uses the new functionality in the WPD Class Extension (IPortableDeviceClassExtension) to register and unregister the Contacts device service interface. Last but not the least, to support object and property management, this sample also supports commands for object enumeration, object properties, bulk properties, object resources, and device capabilities.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;The WpdServiceSampleDriver does not emulate a Media Transfer Protocol (MTP) device. Like most of the other WPD samples, it simulates a software-only device that is not tied to a specific protocol or transport. If you are looking to build firmware for an MTP device that supports device services, you should start with the &lt;/FONT&gt;&lt;/SPAN&gt;&lt;A href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;Device Enabling Kit&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;&lt;FONT size=2&gt;. &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: small" class=Apple-style-span&gt;Device Services is a new feature we introduced in Windows 7, therefore this sample is only supported on Windows 7 (x86, amd64).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;For instructions on how to build and install this driver, see: &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd573846.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd573846.aspx"&gt;&lt;FONT size=2&gt;http://msdn.microsoft.com/en-us/library/dd573846.aspx&lt;/FONT&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;I&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt"&gt;This posting is provided "AS IS" with no warranties and confers no rights.&lt;/SPAN&gt;&lt;/I&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9896984" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /><category term="WMDM" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WMDM/" /><category term="WIA" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WIA/" /><category term="Device Services" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Services/" /><category term="multi-transport" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/multi_2D00_transport/" /></entry><entry><title>Windows 7 Portable Device Development Kits</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/09/11/windows-7-portable-device-development-kits.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/09/11/windows-7-portable-device-development-kits.aspx</id><published>2009-09-12T09:58:00Z</published><updated>2009-09-12T09:58:00Z</updated><content type="html">&lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;There are several different resources made available to portable device manufacturers to assist in device firmware and driver development, and to application developers wishing to create applications that interact with these portable devices. These resources are provided and maintained by members of the Windows Portable Devices team. &lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;This post provides a description for the following development kits: &lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpFirst"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;span style="font-family: symbol; mso-bidi-font-family: symbol; mso-fareast-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Windows 7 Portable Device Enabling Kit for MTP &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Windows Portable Devices SDK &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Windows Portable Devices Driver Kit &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Windows Media Device Manager SDK &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Microsoft Device Experience Development Kit &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;/span&gt;Windows Logo Kit &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Windows 7 Portable Device Enabling Kit for MTP&lt;/h2&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;This development kit is designed to assist portable device manufacturers in the development of Media Transfer Protocol (MTP) device firmware that is compatible with the &lt;/font&gt;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/08/29/mtp-over-various-transports.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/08/29/mtp-over-various-transports.aspx"&gt;&lt;font size="2"&gt;various MTP device transports that Windows supports&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;, and with &lt;/font&gt;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/08/15/introducing-device-services.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/08/15/introducing-device-services.aspx"&gt;&lt;font size="2"&gt;Device Services&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;. There are two packages provided for download: &lt;/font&gt;&lt;/p&gt;  &lt;p style="margin-left: 0.5in"&gt;&lt;i&gt;&lt;font face="Verdana"&gt;Windows 7 Portable Device Enabling Kit for MTP - Tools&lt;/font&gt;&lt;/span&gt;&lt;/i&gt;&lt;font face="Verdana"&gt;      &lt;br /&gt;The tools kit includes design documentation and implementation guidelines, a Windows-based reference design, development tools, and the updated MTP Device Simulator. &lt;/font&gt;&lt;/p&gt;  &lt;p style="margin-left: 0.5in"&gt;&lt;i&gt;&lt;font face="Verdana"&gt;Windows 7 Portable Device Enabling Kit for MTP - Reference Code&lt;/font&gt;&lt;/i&gt;&lt;font face="Verdana"&gt;      &lt;br /&gt;The reference code kit includes the core responder reference source code that is being made available under a separate Berkeley Software Distribution (BSD)–style license. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;To download both packages of the Windows 7 Portable Device Enabling Kit for MTP, go to: &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&lt;a href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;You are not required to license the reference code in order to use the tools and resources provided in the tools kit.&lt;span class="MsoCommentReference"&gt;&lt;span style="line-height: 115%; mso-bidi-font-size: 11.0pt; mso-ansi-font-size: 11.0pt"&gt; &lt;/span&gt;&lt;/span&gt;This kit is free to download and use.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;Windows Portable Devices SDK&lt;/h2&gt; &lt;span style="color: black"&gt;   &lt;p&gt;&lt;font size="2"&gt;The WPD SDK includes the WPD Application Programming Interface (API) that is supported in Windows 7, Windows Vista, and Windows XP operating Systems. Developers will use this API to write Windows applications in C++. &lt;span style="mso-spacerun: yes"&gt;&amp;#160;&lt;/span&gt;Being a COM API, the WPD API is also accessible from Managed code, so C# .Net, and Visual Basic .Net applications can use COM Interoperability to invoke the same functionality that the C++ API provides. WPD applications can: explore a device, send and receive content, and even control the device, for example, take a picture or send a text message.&lt;/font&gt;&lt;/p&gt; &lt;/span&gt;  &lt;p style="vertical-align: top"&gt;&lt;span style="color: black"&gt;&lt;font size="2"&gt;The WPD SDK includes two sample applications for C++/COM developers. The first, WpdApiSample, is a command-line desktop application that demonstrates how you would: enumerate connected devices, explore those devices, query device-objects for properties and attributes, send and retrieve data, and so on. The second sample, WpdServicesApiSample, is a command-line desktop application that demonstrates how you would explore a Contacts service on a device that is attached to your computer. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="color: black"&gt;&lt;font size="2"&gt;The WPD SDK also includes an Automation Object Model that is supported in Windows 7. Developers can use the Automation model to write web applications that accomplish tasks similar to those accomplished with the API. We provided an introduction to WPD Automation in this recent &lt;/font&gt;&lt;/span&gt;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/08/21/introducing-wpd-automation.aspxhttp:/blogs.msdn.com/wpdblog/archive/2009/08/21/introducing-wpd-automation.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/08/21/introducing-wpd-automation.aspxhttp:/blogs.msdn.com/wpdblog/archive/2009/08/21/introducing-wpd-automation.aspx"&gt;&lt;font color="#0080ff" size="2"&gt;post&lt;/font&gt;&lt;/a&gt;&lt;font size="3"&gt;&lt;span style="color: black"&gt;&lt;font size="2"&gt;.&lt;/font&gt; &lt;/span&gt;&lt;span style="color: black; mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;span style="color: black"&gt;The WPD SDK is included in the Windows SDK which can be downloaded from &lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505&amp;amp;displaylang=en&lt;/a&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="color: black"&gt;&lt;/span&gt; &lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="color: black"&gt;&lt;font size="2"&gt;The documentation for the WPD SDK (both the API and Automation Object Model) is found on MSDN at: &lt;/font&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx"&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx"&gt;&lt;font size="2"&gt;http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx&lt;/font&gt;&lt;/a&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="line-height: 140%; font-family: &amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;; color: black; font-size: 12pt; mso-bidi-font-size: 11.0pt"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Windows Portable Devices Driver Kit&lt;/h2&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The WPD Driver Kit includes a Device Driver Interface (DDI) that is supported in Windows 7, Windows Vista, and Windows XP operating Systems. Developers will use this DDI to write drivers for devices that are not already supported by the MTP or Mass Storage class drivers that Microsoft distributes.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The WPD Driver Kit includes five sample device drivers which are described in the following table. In the next &lt;/font&gt;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/09/18/windows-7-driver-samples.aspx"&gt;&lt;font size="2"&gt;post&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;, we covered each sample in more detail.&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;/span&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;   &lt;table style="border-collapse: collapse; mso-yfti-tbllook: 1184; mso-padding-alt: 0in 0in 0in 0in" class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"&gt;         &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;b&gt;&lt;font size="2"&gt;Sample Driver&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;b&gt;Description&lt;/b&gt;&lt;b&gt;&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="mso-yfti-irow: 1"&gt;         &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;WpdHelloWorldDriver&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;This is the most basic WPD driver that emulates interaction with hardware. Supports four objects: device, storage, folder, and file. This provides the scaffolding or skeleton for developing a WPD driver.&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="mso-yfti-irow: 2"&gt;         &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;WpdBasicHardwareDriver&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;Builds upon the WpdHelloWorldDriver and demonstrates interaction with simple hardware devices. Supports nine sensor devices: 2-axis accelerometer, 3-axis accelerometer, temperature/humidity sensor, pressure sensor, distance sensor, passive infrared sensor, compass, vibration sensor, and light sensor. These sensor devices are simple devices that are controlled by a Parallax BS2 microcontroller attached to the PC. &lt;/font&gt;&lt;/p&gt;            &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;font size="2"&gt;If you plan to develop drivers that integrate sensors with Windows 7, we recommend using the &lt;/font&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd318953(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd318953(VS.85).aspx"&gt;&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;font size="2"&gt;Sensor API&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;font size="2"&gt; and &lt;/font&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc974537.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc974537.aspx"&gt;&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;font size="2"&gt;Sensor Driver Model&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt;&lt;font size="2"&gt;. If you need to develop drivers to integrate sensors with Windows Vista or Windows XP, WPD provides a viable solution. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="mso-yfti-irow: 3"&gt;         &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;WpdServiceSampleDriver&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;Demonstrates how a developer would extend the WpdHelloWorldDriver to support a simulated device with a Contacts device service.(Using this service, WPD applications can discover events, methods, and properties associated with the Contacts stored on the device. This sample emulates interaction with hardware.&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="mso-yfti-irow: 4"&gt;         &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;WpdMultiTransportDriver&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;Demonstrates how developers can take advantage of the Windows 7 support for multiple transports. The sample emulates interaction with hardware and demonstrates support for the following transports: IP, Bluetooth, and USB. We covered an overview of Multi-transport support in Windows 7 &lt;/font&gt;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/09/04/multi-transport-devices-in-windows-7.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2009/09/04/multi-transport-devices-in-windows-7.aspx"&gt;&lt;font size="2"&gt;here&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;.&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr style="mso-yfti-irow: 5; mso-yfti-lastrow: yes"&gt;         &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;WpdWudfSampleDriver&lt;span style="mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-bidi-font-family: calibri"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 239.4pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in" valign="top" width="319"&gt;           &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;A comprehensive sample driver that demonstrates what to enable in the WPD DDI for media transfer scenarios (such as music and photos). This sample supports media synchronization with Windows Media Player, and also emulates interaction with hardware.&lt;/font&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="color: black"&gt;&lt;font size="2"&gt;The WPD Driver Kit is included in the Windows Driver Kit (WDK). For information about downloading the WDK, see: &lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff" size="2"&gt;&lt;a href="http://www.microsoft.com/whdc/devtools/wdk/WDKpkg.mspx"&gt;http://www.microsoft.com/whdc/devtools/wdk/WDKpkg.mspx&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="color: black"&gt;&lt;font size="2"&gt;The documentation for the WPD Driver Kit is found on MSDN at: &lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff" size="2"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd419925.aspx"&gt;http://msdn.microsoft.com/en-us/library/dd419925.aspx&lt;/a&gt;&lt;/font&gt;&lt;span style="color: #1f497d"&gt;&lt;/span&gt; &lt;/p&gt;  &lt;h2&gt;Windows Media Device Manager SDK &lt;/h2&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The Windows Media Device Manager (WMDM) SDK &lt;span style="color: black"&gt;enables you to build desktop applications and components that can communicate with connected portable devices. WMDM enables your application or component to enumerate, explore, and exchange files with a device, query for metadata, and request play count information. Applications or components built on WMDM have a consistent API for communicating with a wide range of devices including Media Transfer Protocol (MTP), Mass Storage Class (MSC), RAPI, and other devices built on both the latest and previous versions of Windows Media technology. &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;font size="2"&gt;The Windows Media Device Manager SDK is available at: &lt;/font&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/windows/bb190309.aspx" mce_href="http://msdn.microsoft.com/en-us/windows/bb190309.aspx"&gt;&lt;font size="2"&gt;http://msdn.microsoft.com/en-us/windows/bb190309.aspx&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;. &lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Microsoft Device Experience Development Kit&lt;/h2&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The Microsoft Device Experience Development Kit provides detailed information and material that you would need to know in order to develop Device Stage™ experiences for Portable Devices. The development kit includes device development guides, planning worksheets, tutorials, and development samples that you can use when developing a Device Stage experience on Windows 7. For portable devices, Device Stage supports the industry-standard Media Transfer Protocol (MTP) 1.0 with device services that enable a new rich set of features in Windows 7. &lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The development kit along with other pertinent information to build a complete Windows Device Experience is available at: &lt;/font&gt;&lt;a href="http://www.microsoft.com/whdc/device/DeviceExperience/default.mspx" mce_href="http://www.microsoft.com/whdc/device/DeviceExperience/default.mspx"&gt;&lt;font size="2"&gt;http://www.microsoft.com/whdc/device/DeviceExperience/default.mspx&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The kit is free to download and use. &lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Windows Logo Kit&lt;/h2&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The primary use of the Windows Logo Kit (WLK) is for Windows Logo Program device certification. This kit can also be used for product development. We encourage its use during the product development cycle of hardware in order to ensure device compliance with both Windows and industry standards. The kit includes several tests designed to validate device implementation and behavior at multiple levels. There are tests for USB compliance, Media Transfer Protocol (MTP) compliance, and Windows Portable Devices (WPD) platform compliance that also cover device services validation.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;There is a significant amount of information available about the WLK, including user guides and video tutorials. For more information about the WLK see: &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&lt;a href="http://www.microsoft.com/whdc/winlogo/WLK/default.mspx"&gt;http://www.microsoft.com/whdc/winlogo/WLK/default.mspx&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The kit is free to download and use.&lt;/font&gt; &lt;/p&gt;  &lt;h2&gt;Other Resources&lt;/h2&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;Windows Portable Devices node on Windows Hardware Developer Central &lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;a href="http://www.microsoft.com/whdc/device/wpd/default.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/default.mspx"&gt;&lt;font size="2"&gt;http://www.microsoft.com/whdc/device/wpd/default.mspx&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font size="2"&gt;Windows Portable Devices on Microsoft Developer Network &lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;font color="#0000ff" size="2"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx&lt;/a&gt;&lt;/font&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&lt;/span&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;span style="font-family: &amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;; font-size: 10pt"&gt;&lt;em&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9894442" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="SDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/SDK/" /><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="Tools" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Tools/" /><category term="WMDM" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WMDM/" /><category term="Device Stage" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Stage/" /><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /></entry><entry><title>Multi-Transport Devices in Windows 7</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/09/04/multi-transport-devices-in-windows-7.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/09/04/multi-transport-devices-in-windows-7.aspx</id><published>2009-09-05T05:46:00Z</published><updated>2009-09-05T05:46:00Z</updated><content type="html">&lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;In Windows Vista, the WPD team shipped an MTP driver with support for two transports: USB and TCP/IP (typically WiFi). This expanded support also introduced an interesting problem: to Windows, the same device connected twice looks like two different devices. This is because device identity in Windows is based on information derived from the underlying transport (or bus). Why is this a problem? Consider the case of an MTP camera. Windows has a photo import application that remembers which photos have already been imported. If the user leaves photos on the camera storage after import, the next import will skip those and only pick up the new ones. However, the photo import application stores this information about imported photos based on the device identity. If the device identity changes when it connects to the same PC using a different transport, those old photos will be imported again because the OS presents this as a different device to the application. Similar problems can occur with music players or mobile phones, where two different synchronization partnerships would be created for the same device.&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;One way to address this would be to have the device provide its own identity that could be retrieved and examined by each application. This approach can work, but it requires that applications that rely on device identity be modified to use this new identity instead. It also wouldn’t account for future scenarios where multiple transports might be active at the same time.&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;There have been proprietary solutions, where a custom WPD driver was written to communicate with the device over any of its transports via a multi-transport-aware service. But to make this work, the hardware vendor was required to install and run a Windows service and a kernel mode bus enumerator that communicate with each other to load and unload drivers based on device presence.&lt;/font&gt;&lt;/p&gt;  &lt;h2 style="margin: 10pt 0in 0pt"&gt;&lt;font color="#4f81bd" size="4" face="Cambria"&gt;The Composite Driver Solution&lt;/font&gt;&lt;/h2&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;With Windows 7, there is now built-in support for devices with multiple transports. This support is currently limited to WPD devices, but the groundwork has been laid for other device classes in future OS releases. Now, when a multi-transport device is connected with a Windows 7 PC, it has a single identity. This is even true when multiple transports are simultaneously active, which with the added support for MTP over Bluetooth, will be a common occurrence, such as when a device already connected over Bluetooth is plugged into a USB port for charging.&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The Windows 7 solution is a combination of the approaches mentioned above. The following diagram shows the general relationship between the components involved:&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal" mce_keep="true"&gt;&amp;#160;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;img style="width: 733px; height: 768px" title="Multi-Transport Diagram" alt="Multi-Transport Diagram" src="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/Foo_E0C8/WpdMultiTransport_thumb.jpg" width="733" height="768" mce_src="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/Foo_E0C8/WpdMultiTransport_thumb.jpg" /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&amp;#160;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;Each transport will continue to have a driver loaded that knows how to talk to the device over that transport. But this “transport” driver won’t be seen by applications. Instead, the transport driver will inform a system service (the Composite Bus Enumerator) that a transport is available. The Composite Bus Enumerator will keep track of the transports announced for any one device, and will cause a single Composite Driver to be loaded for that device. Only the Composite Driver will be seen by applications, and it will be the single point of contact with the device. This will be true whether the device has one transport active, or many, either sequentially, or simultaneously. When the last active transport is disconnected, the Composite Bus Enumerator will remove the Composite Driver.&lt;/font&gt;&lt;/p&gt;  &lt;h2 style="margin: 10pt 0in 0pt"&gt;&lt;font color="#4f81bd" size="4" face="Cambria"&gt;Composite Driver&lt;/font&gt;&lt;/h2&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The Composite Driver has three primary functions. One, it chooses the best underlying transport when an application opens a handle to the device (typically via IPortableDevice::Open). Two, it acts as a pass-through for WPD requests and responses between the application and the transport drivers. And three, it acts as a proxy for registering and unregistering PnP interfaces on behalf of the underlying transport drivers. This latter functionality is how the transport drivers remain hidden from applications: since no PnP interfaces are registered by the transport driver, there is no (easy) way for an application to obtain a symbolic link directly to the transport. This latter functionality was also the most complex aspect of the implementation, where multiple transport drivers interacting with the Composite Driver to dynamically register and unregister interfaces must be made to look like a single underlying device.&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;How does the Composite Driver determine the “best” transport when multiple transports are simultaneously active? In Windows 7, it’s a simple comparison of reported theoretical maximum bandwidths reported by the transport driver to the Composite Driver: USB is faster than IP is faster than Bluetooth. While this is generally true, it is also theoretically possible for USB and IP to actually be slower than Bluetooth depending on conditions at the time. All are asynchronous protocols that rely on some form of bandwidth sharing.&lt;/font&gt;&lt;/p&gt;  &lt;h2 style="margin: 10pt 0in 0pt"&gt;&lt;font color="#4f81bd" size="4" face="Cambria"&gt;Transport Drivers&lt;/font&gt;&lt;/h2&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;What’s the difference between a transport driver and a regular driver? Not much. A transport driver has the added responsibility of communicating transport status with the Composite Bus Enumerator and the Composite Driver, but it is otherwise just a normal WPD driver. For instance, the Windows 7 MTP driver fulfills either duty depending on the capability of the underlying device. Much of the complexity is encapsulated in the WPD Class Extension (a helper object that manages the communication with the Composite Bus Enumerator and the Composite Driver).&lt;/font&gt;&lt;/p&gt;  &lt;h2 style="margin: 10pt 0in 0pt"&gt;&lt;font color="#4f81bd" size="4" face="Cambria"&gt;Multi-Transport Capable Devices&lt;/font&gt;&lt;/h2&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;What makes a device a multi-transport device? Simple: it just supplies a device property known as the Functional Unique ID (FUID). This is a 128-bit GUID (Globally Unique ID). For MTP devices, this property is defined by the new MTP Device Services Extension (see the &lt;/font&gt;&lt;a href="http://www.microsoft.com/whdc/device/wpd/MTPDevServExt_Spec.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/MTPDevServExt_Spec.mspx"&gt;&lt;font size="2"&gt;MTP Device Services Extension Specification&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;). This does not mean that the device must support services. It is perfectly okay for a device to indicate support for this extension, but only implement the parts that it needs (in this case, the “Functional ID” 0xD301 device property code).&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The FUID must be unique across all devices of the same manufacturer, model and version. If two devices of the same model also had the same FUID, they would be treated as different transports of the same device. To avoid this, and to further simplify things for the device manufacturer, if the MTP driver finds an empty value for the FUID property on the device, it will automatically provision the device with a FUID generated at runtime. The only responsibility of the device manufacturer is to ensure that the FUID value is persisted across connections and available over all transports.&lt;/font&gt;&lt;/p&gt;  &lt;h2 style="margin: 10pt 0in 0pt"&gt;&lt;font color="#4f81bd" size="4" face="Cambria"&gt;Writing your own Transport Driver&lt;/font&gt;&lt;/h2&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;To help simplify the explanation so far, I’ve been describing how this works for an MTP device, where the system-provided MTP Class driver does most of the bookkeeping. However, this is supported for 3rd-party WPD drivers as well. Because most of the complexity is hidden from the driver by the WPD Class Extension, the driver just has to make a few simple adjustments to become multi-transport capable. This is covered in more detail in the documentation for the WPD Multi-Transport Sample driver, but the key changes are as follows:&lt;/font&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;In single-transport WPD drivers, the default I/O queue is sequential (a UMDF term for a queue that delivers one request at a time). The default I/O queue for a multi-transport driver must be parallel (a UMDF term for asynchronous delivery of I/O requests). WPD requests received in this queue shall be forwarded to the sequential WPD queue. All other requests are to be forwarded to a queue obtained from the WPD Class Extension.&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;On driver initialization (in the OnPrepareHardware callback), the driver must provision the device with a FUID (if necessary), and it must use the WPD Class Extension to inform the Composite Bus Enumerator of the Manufacturer, Model, Version and FUID values for the device.&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;h2 style="margin: 10pt 0in 0pt"&gt;&lt;font color="#4f81bd" size="4" face="Cambria"&gt;Application Development Considerations&lt;/font&gt;&lt;/h2&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;While applications are now largely isolated from the complexities of multi-transport devices, there are some things to be aware of, and things an application can do, to provide a better experience. When one transport goes away and another arrives for the same device, the Composite Driver may remain loaded during the transition, but it will not automatically “fail over” to the new transport. There are several reasons why this was not feasible, with limitations of the current MTP protocol being chief among them. The handle associated with the departed transport will no longer function (attempts to use it will result in an ERROR_DEVICE_REMOVED response). If other transports for the device are active, the Composite Driver will re-advertise the PnP interfaces available for the new best transport. But this does not lend itself to a seamless transition if the application treats it as a device departure followed by a device arrival.&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The application can mitigate transport departures in a couple ways:&lt;/font&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The application can close and reopen its handle at some scenario-specific interval (e.g., between object transfers when synchronizing with the device, or between user interactions with the device). This happens to be the way both Windows Media Player and the Windows Shell already behaved. This approach has the added benefit of guaranteeing that the fastest underlying transport will be used when multiple transports are simultaneously active.&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;font size="2"&gt;The application can recognize that an ERROR_DEVICE_REMOVED failure might be transient and that it should try reopening the handle once before giving up on the device. Because the device has the same identity regardless of transport, the same symbolic link is used (and reused) across all transports.&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNormal"&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;&amp;#160;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: &amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;; font-size: 10pt"&gt;&lt;em&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9891569" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /><category term="multi-transport" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/multi_2D00_transport/" /></entry><entry><title>MTP Over Various Transports</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/08/29/mtp-over-various-transports.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/08/29/mtp-over-various-transports.aspx</id><published>2009-08-29T08:52:00Z</published><updated>2009-08-29T08:52:00Z</updated><content type="html">&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;font size="3"&gt;     &lt;h3&gt;Introduction&lt;/h3&gt;      &lt;p&gt;&lt;/p&gt;   &lt;/font&gt;&lt;/b&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;span style="mso-bidi-font-style: italic"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;span style="mso-bidi-font-style: italic"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;span style="mso-bidi-font-style: italic"&gt;The Media Transfer Protocol (MTP) was originally created as an extension to the Picture Transfer Protocol but today it also supports media transfer, Device Services, command &amp;amp; control, and many other scenarios. MTP supports three transports: USB, IP, and Bluetooth.&lt;/span&gt; &lt;/font&gt;&lt;/p&gt; &lt;font size="2"&gt;&lt;/font&gt;  &lt;p&gt;&lt;font size="2"&gt;One of most common drivers that WPD applications will interact with is the Media Transfer Protocol (MTP) driver.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;MTP was introduced in Windows XP with an inbox user mode driver allowing for effortless device installation and connectivity.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;MTP is standardized through the USB Implementer’s Forum (&lt;font color="#0000ff"&gt;&lt;a href="http://www.usb.org"&gt;www.usb.org&lt;/a&gt;&lt;/font&gt;) and also features Windows-specific extensions. &lt;/font&gt;&lt;/p&gt; &lt;font size="2"&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;  &lt;p&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;We introduced a MTP driver for USB in Windows XP.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;In Windows Vista, we added support for MTP over TCP/IP for devices that use WiFi and LAN connections.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;In Windows 7, we continue the parade of MTP support with the introduction of Bluetooth.&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;/p&gt; &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;font size="3"&gt;     &lt;h3&gt;3 transports, one protocol&lt;/h3&gt;      &lt;p&gt;&lt;/p&gt;   &lt;/font&gt;&lt;/b&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;MTP includes a protocol definition and several transport definitions.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;As devices and PCs pick and choose which connectivity transports they support, device &amp;amp; application developers can be assured that the MTP protocol and WPD API will be consistent.&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160; &lt;/span&gt;Three-transport support gives device manufacturers flexibility to choose wired or wireless, high or low power, faster or slower transfer speed, etc.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The MTP driver is also the first multi-transport driver in Windows, which means that a device manufacturer can feel free to implement all three and Windows will choose the best.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;We’ll talk about that more in our next entry &lt;/font&gt;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/09/04/multi-transport-devices-in-windows-7.aspx"&gt;&lt;font size="2"&gt;Multi-transport Devices in Windows 7&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;.&lt;/font&gt; &lt;/font&gt;&lt;/p&gt; &lt;i style="mso-bidi-font-style: normal"&gt;&lt;font size="3"&gt;     &lt;h4&gt;USB&lt;/h4&gt;      &lt;p&gt;&lt;/p&gt;   &lt;/font&gt;&lt;/i&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Our first MTP transport driver is also the fastest and most powerful way to connect an MTP-enabled device.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Windows XP through Windows 7 support USB 1.1 or higher.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;The binding of MTP to USB is described in the MTP specification itself (&lt;font color="#0000ff"&gt;&lt;a href="http://www.usb.org/developers/devclass_docs/MTP_1.0.zip"&gt;http://www.usb.org/developers/devclass_docs/MTP_1.0.zip&lt;/a&gt;&lt;/font&gt;)&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;and in the Still Imaging Capture Device Definition specification (&lt;font color="#0000ff"&gt;&lt;a href="http://www.usb.org/developers/devclass_docs/usb_still_img10.zip"&gt;http://www.usb.org/developers/devclass_docs/usb_still_img10.zip&lt;/a&gt;&lt;/font&gt;).&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Windows XP uses the Microsoft OS Descriptor to identify MTP devices; Windows Vista and Windows 7 can identify MTP devices by either the OS Descriptor or the USB Still Image Class Code (Class 6, Subclass 1, Protocol 1).&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;Much of this is detailed in the Windows Portable Device Enabling Kit. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In Windows 7, we also enabled the USB Selective Suspend for the MTP driver, although this option is not enabled by default to preserve maximum ecosystem compatibility. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;USB is great for fast file transfer, media synchronization, and charging the device while you’re using it.&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;/p&gt; &lt;i style="mso-bidi-font-style: normal"&gt;&lt;font size="3"&gt;     &lt;h4&gt;IP &lt;/h4&gt;      &lt;p&gt;&lt;/p&gt;   &lt;/font&gt;&lt;/i&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;In Windows Vista, we implemented MTP over TCP/IP to enable WiFi and networked devices to interact with WPD applications.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;We used the PTP/IP binding (&lt;/font&gt;&lt;a href="http://www.cipa.jp/ptp-ip/index_e.html" mce_href="http://www.cipa.jp/ptp-ip/index_e.html"&gt;&lt;font size="2"&gt;http://www.cipa.jp/ptp-ip/index_e.html&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;), then used UPnP for pairing and discovery.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;When devices report their presence on a network via UPnP after the initial pairing, Windows will automatically connect and make the device available to the user. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;MTP/IP is ideal for devices with WiFi that can be connected and synchronized anywhere in the home.&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;/p&gt; &lt;i style="mso-bidi-font-style: normal"&gt;&lt;font size="3"&gt;     &lt;h4&gt;Bluetooth&lt;/h4&gt;      &lt;p&gt;&lt;/p&gt;   &lt;/font&gt;&lt;/i&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In Windows 7, we introduced Bluetooth as the third transport for MTP. We implemented MTP over the L2CAP protocol for fast, efficient, and secure connections. The specification is available in the Windows Portable Device Enabling Kit. PC users can switch the connection on and off through the Devices &amp;amp; Printers folder, or devices themselves can initiate and terminate connections to the PC. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;We also implemented an &amp;quot;auto connect&amp;quot; feature in which Windows attempts to connect to your device every few minutes to maintain a low power connection for automatic synchronization and status updates.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;When you are holding the device near your PC, you’re connected; when you walk away, the connection breaks and waits silently to reconnect when you return and your device gets back into Bluetooth range. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Applications can use the IPortableDeviceConnect&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&lt;/span&gt;interface to issue connect/disconnect requests to an MTP/Bluetooth device.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;When a connection request is made, the MTP/Bluetooth link is established, the WPD MTP driver stack will load, and the device becomes visible to WPD applications to connect to using the WPD API. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Windows requires Bluetooth 1.2 or higher with the Microsoft Bluetooth stack installed.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;For maximum security, Windows also requires that the device is paired securely with a pin code. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;MTP/BT is great for low power, low speed scenarios like synchronizing PIM data or a quick file transfer.&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;font size="3"&gt;     &lt;h3&gt;Operating System Support&lt;/h3&gt;      &lt;p&gt;&lt;/p&gt;   &lt;/font&gt;&lt;/b&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;The MTP driver is present in Windows XP with Windows Media Player 10 or higher installed, Windows Vista, and Windows 7.&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;/p&gt; &lt;i style="mso-bidi-font-style: normal"&gt;&lt;font size="3"&gt;     &lt;h4&gt;MTP Driver Support by Operating System&lt;/h4&gt;      &lt;p&gt;&lt;/p&gt;   &lt;/font&gt;&lt;/i&gt;  &lt;p&gt;&lt;/p&gt;  &lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-yfti-tbllook: 1184; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"&gt;       &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;strong&gt;&lt;font size="2"&gt;Windows Version &lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;strong&gt;&lt;font size="2"&gt;USB 1.1 or higher &lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;strong&gt;&lt;font size="2"&gt;IP &lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;strong&gt;&lt;font size="2"&gt;Bluetooth 1.2 or higher &lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr style="mso-yfti-irow: 1"&gt;       &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Windows XP &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes, with Windows Media Player 10 or higher &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;No &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;No &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr style="mso-yfti-irow: 2"&gt;       &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Windows Vista &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;No &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr style="mso-yfti-irow: 3; mso-yfti-lastrow: yes"&gt;       &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Windows Vista + &lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/10/27/wpd-platform-update-for-windows-vista.aspx"&gt;Platform Update for Window Vista&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr style="mso-yfti-irow: 3; mso-yfti-lastrow: yes"&gt;       &lt;td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Windows 7 &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;Yes &lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td style="border-bottom: black 1pt solid; padding-bottom: 0in; background-color: transparent; border-top-color: #f0f0f0; padding-left: 5.4pt; width: 119.7pt; padding-right: 5.4pt; border-left-color: #f0f0f0; border-right: black 1pt solid; padding-top: 0in; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign="top" width="200"&gt;         &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;Yes &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;&amp;#160;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;i&gt;&lt;span style="font-family: &amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;; font-size: 10pt"&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9888867" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="Device Services" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Services/" /><category term="Bluetooth" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Bluetooth/" /></entry><entry><title>Introducing WPD Automation</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/08/21/introducing-wpd-automation.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/08/21/introducing-wpd-automation.aspx</id><published>2009-08-21T23:15:00Z</published><updated>2009-08-21T23:15:00Z</updated><content type="html">&lt;P class=MsoNormal&gt;In Windows 7, we introduced WPD Automation, which is a layer above the WPD API that exposes access to common WPD functionality through IDispatch. &lt;/P&gt;
&lt;P class=MsoNormal&gt;This post introduces this new component, and describes what you can and cannot do with WPD Automation, and how you, the developer, can access it from ActiveX and Device Stage™.&lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 8pt"&gt;&lt;FONT size=3&gt;What WPD Automation Is&lt;/FONT&gt;&lt;/H2&gt;
&lt;H3 style="MARGIN: 12pt 0in 8pt"&gt;&lt;B&gt;&lt;FONT size=2&gt;A simple way to access WPD from IDispatch/JScript&lt;/FONT&gt;&lt;/B&gt;&lt;/H3&gt;
&lt;P class=MsoNormal&gt;WPD provides a C++/COM API that allows you to access a portable device in a protocol-independent manner. Each interface represents a logical grouping of related functionality (e.g. IPortableDeviceProperties contains methods for retrieving and setting object properties). A WPD application would typically acquire and use multiple WPD interfaces to accomplish most tasks. For example, the application would use an IPortableDeviceProperties to get properties of any object on the device, and IPortableDeviceResources to read data from that same object, and so on. &lt;/P&gt;
&lt;P class=MsoNormal&gt;WPD Automation seeks to simplify the programming model of WPD by wrapping the device and its contents as IDispatch objects which are then accessible from JScript. The complexity of WPD is hidden by employing an object-based model: each object is encapsulated by an IDispatch object; properties of that object are mapped to IDispatch properties; tasks on each object are available as IDispatch methods. More details on the WPD Automation Object Model are available on &lt;A href="http://msdn.microsoft.com/en-us/library/dd389295(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd389295(VS.85).aspx"&gt;MSDN&lt;/A&gt;.&lt;/P&gt;
&lt;P class=MsoNormal&gt;Let’s contrast the two APIs is with an example. The first code snippet demonstrates how to read some properties for an object on the device using the WPD API in C++:&lt;/P&gt;
&lt;DIV style="BACKGROUND: #dddddd; FONT-SIZE: 8pt"&gt;&lt;PRE&gt;// Sample code for illustration purposes only, may contain typos.
HRESULT ReadPropertiesFromObject(
         PCWSTR   pszObjectID,
         IPortableDeviceProperties* pProperties)     
{
    // 1. Create an IPortableDeviceKeyCollection to hold the keys we wish to read
    IPortableDeviceKeyCollection* pPropertiesToRead;
    HRESULT hr =  CoCreateInstance(CLSID_PortableDeviceKeyCollection, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&amp;amp;pPropertiesToRead));

    if (SUCCEEDED(hr))
    {
        // 2. Populate the IPortableDeviceKeyCollection.
        pPropertiesToRead -&amp;gt;Add(WPD_OBJECT_NAME);
        pPropertiesToRead -&amp;gt;Add(WPD_OBJECT_PERSISTENT_UNIQUE_ID);
        pPropertiesToRead -&amp;gt;Add(WPD_OBJECT_FORMAT);

        // 3. Request the properties from the device.
        hr =  pProperties -&amp;gt;GetValues(pszObjectID,  // The object whose properties we are reading
                                         pPropertiesToRead,   // The properties we want to read
                                         &amp;amp;pObjectProperties); // Result property values for the specified object
         
        // 4. Read the properties we just retrieved.
        if (SUCCEEDED(hr))
        {
            // Read the object name
            LPWSTR pszObjectName = NULL;
            hr = pObjectProperties-&amp;gt;GetStringValue(WPD_OBJECT_NAME, &amp;amp;pszObjectName);
            CoTaskMemFree(pszObjectName);
 
            // Read the object format, e.g. WPD_OBEJCT_FORMAT_MP3
            GUID Format;
            hr = pObjectProperties-&amp;gt;GetGuidValue(WPD_OBJECT_FORMAT, &amp;amp;Format); 
                 
            // and it goes on . . .
         }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal mce_keep="true"&gt;Now, to accomplish the same task in WPD Automation, we call a few lines of JScript on an IDispatch object (&lt;A href="http://msdn.microsoft.com/en-us/library/dd389275(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd389275(VS.85).aspx"&gt;wpdObject&lt;/A&gt;):&lt;/P&gt;
&lt;DIV style="BACKGROUND: #dddddd; FONT-SIZE: 8pt"&gt;&lt;PRE&gt;function ReadPropertiesFromObject(wpdObject)
{
    var name = wpdObject.ObjectName;                 
    var puid = wpdObject.ObjectPersistentUniqueID;  
    var format = wpdObject.ObjectFormat; // “MP3”
    alert(“The format of “ + name + “ is “ + format);
}&lt;/PRE&gt;&lt;/DIV&gt;&lt;FONT size=2&gt;
&lt;P class=MsoNormal mce_keep="true"&gt;As you can see, WPD Automation makes it very quick and easy to programmatically access the device.&lt;/P&gt;
&lt;P class=MsoNormal mce_keep="true"&gt;&lt;B&gt;&lt;FONT size=2&gt;A simple way to write custom code to access a device from Device Stage™&lt;/FONT&gt;&lt;/B&gt;&lt;FONT size=3&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P class=MsoNormal mce_keep="true"&gt;One requirement for bringing the power of the WPD API to Device Stage is to provide a way for device vendors (IHVs) to create custom WPD applications without writing, packaging, and delivering a complete Windows application to users. Device Stage integrates with an Internet Explorer™ web browser control that allows IHV-created web content to be viewed from the Device Stage UI. Using WPD Automation, IHVs can embed JScript into their web pages that can then access connected devices on the user’s Windows 7 PCs. These WPD Automation-enabled web pages are referenced by a special category of web tasks known as the &lt;STRONG&gt;HostedSiteWithDevice&lt;/STRONG&gt; task. &lt;/P&gt;
&lt;P&gt;For example, the following "Register your phone" sample task is a web page (hosted on an IHV’s server) that contains JScript client-side code to query the device properties (name, model, serial number, ...)&amp;nbsp;of the user's cellular phone and populate the results in the "Product Information" section.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 520px; HEIGHT: 574px" title="Sample HostedSiteWithDevice Task" alt="Sample HostedSiteWithDevice Task" align=middle src="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/a2ac99f536ce_DE29/RingtoneTask_thumb.png" width=520 height=574 mce_src="http://blogs.msdn.com/blogfiles/wpdblog/WindowsLiveWriter/a2ac99f536ce_DE29/RingtoneTask_thumb.png"&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;You can find more details about the above example in the "Windows 7 Device Stage Portable Device Class Development Guide"&amp;nbsp;from the &lt;A href="http://www.microsoft.com/whdc/device/DeviceExperience/Dev-Kit.mspx"&gt;Device Experience Development Kit&lt;/A&gt;. &lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 8pt"&gt;&lt;FONT size=3&gt;What WPD Automation Isn't&lt;/FONT&gt;&lt;/H2&gt;
&lt;P mce_keep="true"&gt;Now that we've described what WPD Automation can do, let’s spend&amp;nbsp;some time&amp;nbsp;describing what it can't do.&lt;/P&gt;
&lt;H3 style="MARGIN: 12pt 0in 8pt"&gt;&lt;B&gt;&lt;FONT size=2&gt;Not a way to access WPD from Managed Code&lt;/FONT&gt;&lt;/B&gt;&lt;/H3&gt;
&lt;P class=MsoNormal&gt;In spite of the use of "Automation" in its name, WPD Automation is not a way to access WPD from managed code.&amp;nbsp; WPD Automation is designed for allowing a web application to programmatically interact with device functionality through script.&lt;/P&gt;
&lt;P class=MsoNormal&gt;This does not mean that all is lost.&amp;nbsp; An application can still call the WPD API from managed code, using &lt;A href="http://msdn.microsoft.com/en-us/library/kew41ycz(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/kew41ycz(VS.71).aspx"&gt;COM Interop&lt;/A&gt;.&amp;nbsp; Details are covered in earlier blog posts (&lt;A href="http://blogs.msdn.com/wpdblog/archive/2007/11/26/creating-a-temperature-sensor-gadget-for-windows-sidebar.aspx"&gt;C#&lt;/A&gt; and &lt;A href="http://blogs.msdn.com/wpdblog/archive/2008/01/16/visual-basic-net-sample-for-wpd.aspx"&gt;VB.NET&lt;/A&gt;). &lt;/P&gt;
&lt;H3 style="MARGIN: 12pt 0in 8pt"&gt;&lt;B&gt;&lt;FONT size=2&gt;Not a way to access WPD from non-JScript scripting languages&lt;/FONT&gt;&lt;/B&gt;&lt;/H3&gt;
&lt;P class=MsoNormal mce_keep="true"&gt;WPD Automation can be called from either JScript or Javascript. Other scripting languages (such as VBScript) are not supported.&lt;/P&gt;
&lt;H3 style="MARGIN: 12pt 0in 8pt"&gt;&lt;B&gt;&lt;FONT size=2&gt;Not a way to write a generic WPD application&lt;/FONT&gt;&lt;/B&gt;&lt;/H3&gt;
&lt;P class=MsoNormal&gt;One big difference between the WPD API and WPD Automation is the absence of support in WPD Automation to programmatically discover device capabilities (i.e. the supported properties, supported formats, supported commands, etc.). This was intentional for two reasons: 1) to optimize and simplify the programming model of WPD Automation; and 2) the target developer audience - IHVs writing custom applications only for their devices – know their device capabilities best, and can customize their scripts accordingly. &lt;/P&gt;
&lt;H3 style="MARGIN: 12pt 0in 8pt"&gt;&lt;B&gt;&lt;FONT size=2&gt;Not a way to access all functionality of the WPD API&lt;/FONT&gt;&lt;/B&gt;&lt;/H3&gt;
&lt;P class=MsoNormal&gt;WPD Automation supports accessing the storage and device service functionality on a portable device, including property management, object enumeration, object transfer, and invoking device service methods. WPD Automation does not support querying of capabilities (see above), bulk properties, updating secondary resources, and accessing functional objects &lt;I&gt;other&lt;/I&gt; &lt;I&gt;than&lt;/I&gt; services or storages (such as the rendering information or image capture functional objects).&lt;/P&gt;
&lt;H2 style="MARGIN: 12pt 0in 8pt"&gt;&lt;FONT size=3&gt;Accessing WPD Automation&lt;/FONT&gt;&lt;/H2&gt;
&lt;P class=MsoNormal&gt;There are two ways to access WPD Automation: 1) from Device Stage and 2) from an ActiveX control. Both methods retrieve the Device Object, the entry point object for WPD Automation.&lt;/P&gt;
&lt;H3 style="MARGIN: 12pt 0in 8pt"&gt;&lt;B&gt;&lt;FONT size=2&gt;Using WPD Automation from Device Stage™&lt;/FONT&gt;&lt;/B&gt;&lt;/H3&gt;
&lt;P class=MsoNormal&gt;Device Stage integrates with WPD Automation by providing access to the Device Object through the &lt;B&gt;window.external&lt;/B&gt; property. &lt;/P&gt;
&lt;DIV style="BACKGROUND: #dddddd; FONT-SIZE: 8pt"&gt;&lt;PRE&gt;var deviceObject = window.external;

// Once the deviceObject is retrieved, we can proceed with using WPD Automation
var manufacturer = deviceObject.DeviceManufacturer;
var storages = deviceObject.Storages;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal&gt;It is very important to note that the Device Stage secure scripting host imposes additional requirements on the definition of a &lt;STRONG&gt;HostedSiteWithDeviceTask&lt;/STRONG&gt;. In particular, the webpage must be authenticated with an SSL certificate trusted by the client machine for the allowedDomain attribute specified in the task; otherwise accessing any WPD Automation properties and&amp;nbsp;methods&amp;nbsp;from script will result in "access denied" errors.&lt;/P&gt;
&lt;P class=MsoNormal&gt;These requirements are covered in the "Windows 7 Device Stage Reference Guide" of the &lt;A href="http://www.microsoft.com/whdc/device/DeviceExperience/Dev-Kit.mspx"&gt;Device Experience Development Kit&lt;/A&gt;.&lt;/P&gt;
&lt;H3 style="MARGIN: 12pt 0in 8pt"&gt;&lt;B&gt;&lt;FONT size=2&gt;Using WPD Automation from an ActiveX™ Control&lt;/FONT&gt;&lt;/B&gt;&lt;/H3&gt;
&lt;P class=MsoNormal&gt;WPD Automation can also be instantiated outside of Device Stage by writing and registering an ActiveX object that contains a utility method that can be invoked in script return the Device Object. For more details on writing ActiveX objects, click &lt;A href="http://msdn.microsoft.com/en-us/library/ms221326.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P class=MsoNormal&gt;In the utility method: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Call the WPD APIs to retrieve the device's Plug-and-play (PnP) identifier.&lt;/LI&gt;
&lt;LI&gt;CoCreate CLSID_PortableDeviceDispatchFactory and call the GetDeviceDispatch method, providing the PnP identifier, and retrieving an IDispatch object representing the Device Object.&lt;/LI&gt;
&lt;LI&gt;Return the Device Object in the method results.&lt;/LI&gt;&lt;/OL&gt;
&lt;DIV style="BACKGROUND: #dddddd; FONT-SIZE: 8pt"&gt;&lt;PRE&gt;// Sample code for illustration purposes only, may contain typos.
// Returns the IDispatch object so that the device can be accessed from WPD Automation
IFACEMETHODIMP CMyDeviceFactory::GetMyDeviceObject(IDispatch** ppDevice)
{
    IPortableDeviceManager *pDeviceManager = NULL;

    HRESULT hr = CoCreateInstance(CLSID_PortableDeviceManager, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&amp;amp;pDeviceManager);
    if (SUCCEEDED(hr))
    {
       // To simplify this example, we are only looking for the first device encountered
       // (A real-life example may, for example, search all connected devices to find a match using device properties.)
       PWSTR pszPnPID = NULL;
       DWORD cPnPIDs = 1;
       hr = pDeviceManager-&amp;gt;GetDevices(&amp;amp;pszPnPID, &amp;amp;cPnPIDs);

       if (SUCCEEDED(hr) &amp;amp;&amp;amp;  cPnPIDs == 1)
       {
           // CoCreate CLSID_PortableDeviceDispatchFactory
           IPortableDeviceDispatchFactory *pDispatchFactory = NULL;

           hr = CoCreateInstance(CLSID_PortableDeviceDispatchFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&amp;amp;pDispatchFactory);
           if(SUCCEEDED(hr))
           {
             // Pass the PnP identifier as a parameter to IPortableDeviceDispatchFactory::GetDeviceDispatch
             // to retrieve the Device Object’s as an IDispatch object.
             hr = pDispatchFactory-&amp;gt;GetDeviceDispatch(pszPnPID, ppDevice); 
           }
       . . .&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal&gt;After installing and registering the ActiveX Control, you can now create a new ActiveX object in JScript and call the utility method to get to the Device Object.&lt;/P&gt;
&lt;DIV style="BACKGROUND: #dddddd; FONT-SIZE: 8pt"&gt;&lt;PRE&gt;// Initialize our custom ActiveX control
var deviceFactory = new ActiveXObject("MyTestControl.MyDeviceFactory");
// Get the WPD Automation Device Object from our custom ActiveX control by calling GetMyDeviceObject.
var deviceObject = deviceFactory.GetMyDeviceObject();

// Once the deviceObject is retrieved, we can proceed with using WPD Automation
var manufacturer = deviceObject.DeviceManufacturer;
var storages = deviceObject.Storages;
&lt;/PRE&gt;&lt;/DIV&gt;
&lt;H2 style="MARGIN: 12pt 0in 8pt"&gt;&lt;FONT size=3&gt;References&lt;/FONT&gt;&lt;/H2&gt;
&lt;P&gt;The Device Experience Development Kit: &lt;A href="http://www.microsoft.com/whdc/device/DeviceExperience/Dev-Kit.mspx"&gt;http://www.microsoft.com/whdc/device/DeviceExperience/Dev-Kit.mspx&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The WPD Automation Object Model: &lt;A href="http://msdn.microsoft.com/en-us/library/dd389295(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/dd389295(VS.85).aspx&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Using IPortableDeviceDispatchFactory to instantiate WPD Automation: &lt;A href="http://msdn.microsoft.com/en-us/library/dd389215(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/dd389215(VS.85).aspx&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;I&gt;&lt;SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt"&gt;This posting is provided "AS IS" with no warranties and confers no rights.&lt;/SPAN&gt;&lt;/I&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9879244" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="Device Stage" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Stage/" /><category term="WPD Automation" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WPD+Automation/" /></entry><entry><title>Introducing Device Services</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/08/15/introducing-device-services.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/08/15/introducing-device-services.aspx</id><published>2009-08-15T07:10:00Z</published><updated>2009-08-15T07:10:00Z</updated><content type="html">&lt;h2 style="margin: 12pt 0in 8pt"&gt;What are Device Services?&lt;/h2&gt;  &lt;p&gt;&amp;quot;Device Services&amp;quot; is a brand new concept introduced in Windows 7 that provides a framework for device manufacturers to extend device functionality, and new APIs for applications to discover and access that extended functionality using WPD. We decided to call these extensions to device functionality &amp;quot;Device Services&amp;quot; because they foster rich interaction between the PC and devices by providing a model for devices to formalize extension capabilities and make these capabilities accessible to applications. &lt;/p&gt;  &lt;p&gt;Device Services are available in Windows 7 and Windows Vista with the &lt;a href="http://blogs.msdn.com/wpdblog/archive/2009/10/27/wpd-platform-update-for-windows-vista.aspx"&gt;Platform Update for Windows Vista&lt;/a&gt;.&lt;/p&gt;  &lt;h2 style="margin: 12pt 0in 8pt"&gt;Why do we need Device Services?&lt;/h2&gt;  &lt;p&gt;First, a quick historical perspective. Media Transfer Protocol (MTP - one of the protocols supported within WPD) was introduced beginning with Windows Media Player 10 as an extension of the Picture Transfer Protocol (PTP). MTP became a USB standard, and was widely adopted by a myriad of device classes: media players, mobile phones, cameras, Xbox 360s, etc.&amp;#160; True to its PTP origins, MTP 1.0 was very media-centric; the scenarios it excelled in revolved around browsing device content and exchanging media files (images, music, and video, etc) between device and the PC.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;font size="2"&gt;Enabling PIM Scenarios&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;With Windows 7, we shifted our focus to enabling more device-to-PC scenarios centered around managing and accessing Personal Information Management (PIM) data (contacts, tasks, calendar, etc.) on the device. These involved more complex operations such as SMS, email and advanced synchronization with Outlook™. Non-media files present additional challenges in accessing and enumerating them efficiently on the device. Unlike an MP3 or a JPEG file, a contact or task may not be represented by a physical file on the device storage.&amp;#160; Depending on device implementation, these objects could be stashed anywhere: in databases, in SIM cards, etc. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;font size="2"&gt;Honey, where did you put my contacts (and music, and photos, and ...)?&lt;/font&gt;&lt;/b&gt; &lt;/p&gt;  &lt;p&gt;Another common problem is that there was no standardized method for a device to figure out where to put its content.&amp;#160; Most applications would have to guess at a location, choose or specify an application-specific location, or crawl the entire device, often just to locate a subset of content. [Aside: In Vista, WPD does support the concept of &amp;quot;Device Hints&amp;quot;, where devices/drivers provision a list of known folders that would accept particular content types. Unfortunately, this was not uniformly adopted by devices/drivers, and was limited to known WPD content types]. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;font size="2"&gt;Crowded MTP 1.0 Extension Space&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Last but not the least, MTP 1.0 had inherent limitations for growth and new functionality. The operation codes and property codes were constrained by a DWORD (4 byte) numerical space, with only a small subset allocated for extension codes. Without a notion of vendor-specific namespaces, new extensions must be careful not to collide with existing extensions. This would usually add the overhead of having to publish the codes or risk incompatibilities with applications that rely on existing extensions.&amp;#160; And, if the device/application needs to support new types of content, adding a new object format involves updating the MTP Specification, which is not easily revised.&lt;/p&gt;  &lt;h2 style="margin: 12pt 0in 8pt"&gt;How do Device Services help?&lt;/h2&gt;  &lt;p&gt;To solve the problems and overcome the limitations described above, we introduced the concept of Device Services to MTP. In a nutshell, &amp;quot;MTP Device Services&amp;quot; is an MTP Extension that defines a set of MTP operations revolving around a new type of object known as a &amp;quot;service.&amp;quot; &lt;/p&gt;  &lt;p&gt;A service is composed of 3 parts:    &lt;br /&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The core definition of that service and what it does, including its globally unique identifier (GUID). &lt;/li&gt;    &lt;li&gt;The properties of the service itself, and &lt;/li&gt;    &lt;li&gt;The properties and capabilities of objects and methods of that service.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Properties are represented by PROPERTYKEYS, and formats are represented by GUIDs, which eliminate the operation and format number space restrictions. Together, these provide the structure that applications would rely on to programmatically discover and use services in a consistent way.&amp;#160; &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;The following describes the most common ways in which Device Services are used today:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;span style="font-weight: bold; text-decoration: underline"&gt;Provide a set of properties and events associated with a common scenario&lt;/span&gt;. One example is the Status Service, which defines properties for the battery level, the number of missed calls, the number of new voicemail messages, and the number of new pictures acquired by a device. These may be custom properties, and any application that discovers this service can programmatically discover these properties.       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;span style="font-weight: bold; text-decoration: underline"&gt;Provide a known source and/or sink for content&lt;/span&gt;. The Contacts, Calendar, Task, and Notes services are all services that allow applications to access and store PIM data. These are analogous to &amp;quot;virtual storages.&amp;quot;&amp;#160; The device represents the content in a standard location (as child objects of these services) so that applications do not have to grovel through the device hierarchy to find them. At the same time, this abstraction allows a device implementation greater control over how objects are actually stored on the device. Services are not limited to the known MTP or WPD formats, and may support any arbitrary type of data. For example, devices that wish to provide a Device Stage™ experience upon install can implement a Device Metadata Service that stores *.devicemetadata-ms files.      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;span style="font-weight: bold; text-decoration: underline"&gt;Provide a set of functionality associated with a common scenario&lt;/span&gt;.&amp;#160; The Full Enumeration and Anchor Synchronization services support &amp;quot;methods.&amp;quot;&amp;#160; Methods are like extensions to WPD commands, with the added benefits of being easily discoverable and supporting both synchronous and asynchronous invocation. The Anchor Synchronization Service features a method that allows a synchronization application to retrieve the set of changes to content on the device from a given anchor value (which can be a timestamp or a tick count). Methods also provide a flexible way to access content residing on multiple services. For instance, the Ringtones Service contains a method that allows an application to associate a ringtone (an object within the Ringtones Service) with a contact (an object within the Contacts Service).&lt;/li&gt; &lt;/ol&gt;  &lt;h2 style="margin: 12pt 0in 8pt"&gt;How are Device Services used in Windows 7?&lt;/h2&gt;  &lt;p&gt;After creating Device Services, we put it through its paces in real-life scenarios that are part of Windows 7.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-weight: bold"&gt;Device Stage™&lt;/span&gt;- Uses the Status service to display status on the Branding bar, and on the Taskbar and preview pane.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-weight: bold"&gt;Windows 7 Synchronization &lt;/span&gt;– The Portable Devices Sync Provider uses the Contact Service, Calendar Service, Task Service, and Notes Service to access PIM data on the device. In addition, the Enumeration Synchronization Service and Anchor Synchronization Service are used to determine the level of synchronization capabilities that a device supports.&lt;/p&gt;  &lt;p&gt;&lt;span style="font-weight: bold"&gt;Windows Media Player and Windows Explorer&lt;/span&gt; – Both these applications use WPD Device Hints to determine content locations more efficiently.&amp;#160; For MTP devices, WPD Device Hints is now implemented at the MTP layer as a Hints Service. Devices that implement the Hints Service get WPD Device Hints for free.&lt;/p&gt;  &lt;p&gt;&lt;span style="font-weight: bold"&gt;Ringtone Editor&lt;/span&gt; – Uses the Ringtones Service to transfer user-created ringtones to the device, and to associate a ringtone with a contact that is located using the Contacts service.&lt;/p&gt;  &lt;p&gt;&lt;span style="font-weight: bold"&gt;WPD Class Installer &lt;/span&gt;– Uses the Device Metadata Service to retrieve and transfer metadata stored on the device, so that the richer, device-manufacturer-customized, Device Stage experience gets presented to the user after the first time the device is connected and installed.    &lt;br /&gt;&lt;/p&gt;  &lt;h2 style="margin: 12pt 0in 8pt"&gt;More Information&lt;/h2&gt;  &lt;p&gt;We hope this post has given you a taste of what Device Services can do. Here are some additional links for further information.   &lt;br /&gt;&lt;/p&gt;  &lt;h4&gt;&lt;b&gt;&lt;font size="2"&gt;Device Services:&lt;/font&gt;&lt;/b&gt; &lt;/h4&gt;  &lt;p&gt;Media Transfer Protocol: &lt;a href="http://www.usb.org/developers/devclass_docs/MTP_1.0.zip" mce_href="http://www.usb.org/developers/devclass_docs/MTP_1.0.zip"&gt;http://www.usb.org/developers/devclass_docs/MTP_1.0.zip&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;MTP Device Services Extension Specification: &lt;a href="http://www.microsoft.com/whdc/device/wpd/MTPDevServExt_Spec.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/MTPDevServExt_Spec.mspx"&gt;http://www.microsoft.com/whdc/device/wpd/MTPDevServExt_Spec.mspx&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Windows Portable Device Enabling Kit for MTP: &lt;a href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Application Development:&lt;/h4&gt;  &lt;p&gt;Using the WPD API for Device Services: &lt;a href="http://msdn.microsoft.com/en-us/library/dd319325(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd319325(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/dd319325(VS.85).aspx&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;The WPD Services API Sample: (available from the &lt;a href="http://msdn.microsoft.com/en-us/windows/bb980924.aspx" mce_href="http://msdn.microsoft.com/en-us/windows/bb980924.aspx"&gt;Windows 7 SDK&lt;/a&gt;): &lt;a href="http://msdn.microsoft.com/en-us/library/dd389002(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd389002(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/dd389002(VS.85).aspx&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;The WPD Automation Object Model: &lt;a href="http://msdn.microsoft.com/en-us/library/dd389295(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd389295(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/dd389295(VS.85).aspx&lt;/a&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-weight: bold"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h4&gt;Driver Development:&lt;/h4&gt;  &lt;p&gt;The WPD Services Sample Driver (available from the &lt;a href="http://www.microsoft.com/whdc/devtools/WDK/default.mspx" mce_href="http://www.microsoft.com/whdc/devtools/WDK/default.mspx"&gt;Windows Driver Kit&lt;/a&gt;): &lt;a href="http://msdn.microsoft.com/en-us/library/dd573849.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd573849.aspx"&gt;http://msdn.microsoft.com/en-us/library/dd573849.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;span style="font-family: &amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;; font-size: 10pt"&gt;&lt;font face="Verdana"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin: 0in 0in 10pt" class="MsoNormal"&gt;&lt;i&gt;&lt;span style="font-family: &amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;; font-size: 10pt"&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties and confers no rights.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9870650" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /><category term="Device Services" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Services/" /></entry><entry><title>New Features for Windows 7</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2009/08/07/windows-7-new-features.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2009/08/07/windows-7-new-features.aspx</id><published>2009-08-08T01:03:00Z</published><updated>2009-08-08T01:03:00Z</updated><content type="html">&lt;P&gt;In Windows 7 we introduced several new features that improve how users discover and use devices connected to their PC. These new features simplify how device manufacturers present their devices, applications, and services in Windows. This behavior is exposed in the new Device Stage™ experience (see Better Device Management &lt;A href="http://www.microsoft.com/whdc/device/DeviceExperience/default.mspx" mce_href="http://www.microsoft.com/whdc/device/DeviceExperience/default.mspx"&gt;here&lt;/A&gt;).&lt;/P&gt;
&lt;P&gt;In the Windows Portable Device (WPD) space the Windows team made significant investments to address concerns raised by device manufacturers. One of the key improvements was the addition of the Device Service. A Device Service is an extension of the functional object that was supported in prior versions of WPD. Applications can use Device Services to discover device capabilities and to interact more efficiently with content. &lt;/P&gt;
&lt;P&gt;In addition to the Device Service, WPD was further improved by investing in additional transports: support for MTP over Bluetooth has been added. With multiple transports (USB, IP, and Bluetooth) now available, the next step was to enable a seamless data transfer scenario when the device supports more than one transport.&lt;/P&gt;
&lt;P&gt;Now that we have introduced some of the key Windows 7 features for WPD, we’ll take a closer look.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;MTP Device Services for Windows 7&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;MTP has proven to be an excellent protocol for exchanging files and performing device command and control. However, it is not well-suited for newer, more advanced scenarios.&amp;nbsp; These scenarios are now supported with the introduction of the Device Services architecture. This architecture allows applications to locate and use various services and content types on a device.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The new Device Services architecture allows applications to locate, consume, and interact with both content and functionality on the device.&amp;nbsp; Our flagship use of Device Services in Windows 7 is to support Personal Information Management (PIM) data, settings, and restricted-capabilities content types on a device. The resulting architecture is also the means for future extensibility by 3rd parties: An IHV can implement an application (or web script) and a custom service that interoperate (without having to wait for new functionality in the next OS release). &lt;/P&gt;
&lt;P&gt;Device Services are identified by Globally Unique Identifiers (GUIDS). These GUIDS allow hardware vendors to specify new device services independently of each other without the risk of conflicts. &lt;/P&gt;
&lt;P&gt;The native Windows 7 supported services defined for portable devices are:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Calendar Service&lt;/STRONG&gt; - The calendar service contains the data for a calendar, and uses a synchronization service to facilitate synchronization with the PC.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Contact Service&lt;/STRONG&gt; - The contact service contains the data for contacts, and can optionally use a synchronization service to facilitate synchronization with the PC.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Notes Service&lt;/STRONG&gt; - The notes service uses a synchronization service to sync notes to and from the device.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Task Service&lt;/STRONG&gt; - The task service uses a synchronization service to synchronize tasks to and from the device.&amp;nbsp; &lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;STRONG&gt;Status Service&lt;/STRONG&gt; - The status service reports various status properties about the device to the PC. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Hints Service&lt;/STRONG&gt; - The hints service enables the device to select preferred storage locations for various content types in legacy storages.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Device Metadata Service&lt;/STRONG&gt; - The device metadata service permits the delivery of Device Stage™ metadata by the device during device installation. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Ringtone Service&lt;/STRONG&gt; - The ringtone service provides a method to copy ringtones from the PC to the target ringtone storage on the device.&amp;nbsp; &amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Enumeration Synchronization Service&lt;/STRONG&gt; - The enumeration synchronization service describes basic synchronization capabilities for a storage-based device. This is an “abstract” Device Service, which, analogous to an interface in C++, describes the capabilities of a “data” service that supports basic synchronization. &amp;nbsp;For example, a device that supports basic synchronization of contacts will contain a Contacts Service that implements the Enumeration Synchronization Service.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Anchor Synchronization Service&lt;/STRONG&gt; - The anchor sync service is another abstract MTP Device Service defined to enable other services to opt in to a sync relationship using anchor-based synchronization semantics.&amp;nbsp; Anchor-based synchronization uses a simple tick-count based mechanism for change detection (e.g. timestamp, tick counts).&lt;/P&gt;
&lt;P&gt;Sample implementations of some of these services along with device simulation software is provided in the 7R2 version of the Windows 7 Portable Device Enabling Kit and is now available &lt;A href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;here&lt;/A&gt;. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;MTP Device Services Extension&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In addition to the pre-defined device services mentioned above, Windows is also capable of supported custom device services that use the newly defined &lt;A href="http://www.microsoft.com/whdc/device/wpd/MTPDevServExt_Spec.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/MTPDevServExt_Spec.mspx"&gt;MTP Device Services Extension&lt;/A&gt; to MTP. The MTP Device Services Extension enables Windows to locate and use various services and content types located on a device.&lt;/P&gt;
&lt;P&gt;In the recent applications of MTP without device services, content is distributed throughout a device, which makes it difficult for the operating system to determine where the useful assets are and how to deploy them. With the creation of the Device Services extension to the MTP protocol, Windows now has the ability to locate, consume, and interact with this content in practical ways based on Microsoft and manufacturer defined services. This feature is particularly useful in accessing device content that is not based on file system data, accessing settings, or that has restricted capabilities. For example, a device manufacturer could define a custom SMS service. &lt;/P&gt;
&lt;P&gt;While MTP already supports enumeration by format, it is cumbersome when applying rich semantics to simple hierarchical storage. With Device Services, content and functionality can be combined under a single functional object, resulting in well-scoped access to only the content and functions specific to that service.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Windows Portable Devices (WPD) Platform Enhancements&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;For Windows 7, in addition to the legacy behavior, Windows Portable Devices (WPD) supports a new Device Services model. A Device Service is an extension of the functional object supported in prior versions of WPD. Applications will use service objects to discover device capabilities and to interact more efficiently with content.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;Device Services are available to applications as part of the WPD API. Some Device Services include built-in support by Windows 7. Two examples of operating-system components that use Device Services are the Windows Portable Devices Sync Provider and the Windows Portable Device Status Provider.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The Windows Portable Devices Sync Provider determines whether a cellular phone supports basic contacts synchronization by querying for its implementation of the Enumeration Sync device service on the device. The provider then uses this service to locate all contacts stored on the device without having to search the entire storage hierarchy. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;The Windows Portable Device Status Provider retrieves real-time status information from a cellular phone&amp;nbsp;that supports the Status device service, and relays information including battery life, signal strength, unread text messages, and number of missed calls to Device Stage™.&lt;/P&gt;
&lt;P&gt;Note that although cellular phones are featured in both sceanrios above, Device Services are not limited to a specific WPD device class.&amp;nbsp;Further examples of Device Services will be covered in a later post.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Device Stage™&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Device Stage provides additional customization of the user’s device experience by providing a new way for users to interact with their cell phones, cameras, printers, and portable media players. Device Stage provides a visual interface that makes it easy for users to find and use applications and services for a given device. &lt;/P&gt;
&lt;P&gt;Through a new set of XML schemas supported in Windows 7, device makers can:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Provide rich branding and customization for their device&lt;/LI&gt;
&lt;LI&gt;Define applications and services that are specific to each device&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Device Stage can be accessed by double clicking a supported device from within the Devices and Printers folder, or for portable devices, by clicking the device icon which appears on the taskbar when the device is connected. &lt;/P&gt;
&lt;P&gt;The Device Stage user interface follows the model of any shell view in Windows, and Device Stage devices appear on the Windows taskbar whenever the Device Stage is open. &lt;/P&gt;
&lt;P&gt;Device makers may enable additional features by supporting standard and vendor-unique Device Services, and authoring Device Stage tasks that make use of the service. When a device is connected which supports the any of the authored tasks, the tasks will appear within the Device Stage experience. Optionally, additional Partner applications and hosted web tasks may be specified within the Device Stage XML without modifications to device firmware. &amp;nbsp;These custom device experiences (via Hosted Site with Device option) within Device Stage are made possible by enhancements to the WPD API (mentioned above) and driver model which may now be extended via scripting and custom MTP Device Service extensions on the device. To assist device makers in all of this work, Microsoft has released a Portable Device Enabling Kit with documentation and device code samples. The 7R2 version of the kit is now available &lt;A href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx" mce_href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;here&lt;/A&gt;. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;In the Windows 7 Control Panel, there is a new experience known as the Devices and Printers folder through which users can see all the devices that are connected to their PC. The devices in this folder are physically connected via USB or paired via Wi-Fi or Bluetooth interfaces.&amp;nbsp; (As a general rule, internal PC devices or device functions will not be exposed in this folder.) &lt;/P&gt;
&lt;P&gt;Using a new set of XML schemas, device makers can customize how their device is described and presented within the Devices and Printers folder. For more information on developing metadata packages for both the Devices and Printers folder and Device Stage in Windows 7, see the Windows Device Experience topic on WHDC.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Extended Transport Support&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In Windows 7 we have expanded support with WPD over other transports. A new class driverhas been introduced to enable MTP over Bluetooth. &amp;nbsp;With the support in Windows 7 for multiple transports the next step was to make Windows multi-transport aware, and the addition of the WPD composite driver provides the bridge between a logical device and the transports it simultaneously supports. The new features and functionality mentioned above are supported across all three of the MTP transports (Bluetooth, IP, and USB). &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Resources&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;Information on MTP can be found at &lt;A href="http://www.usb.org/developers/devclass_docs/MTP_1.0.zip"&gt;http://www.usb.org/developers/devclass_docs/MTP_1.0.zip&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Details on MTP over Bluetooth and MTP over IP are provided in the documentation that ship in the Windows 7 Portable Device Enabling Kit for MTP and on MSDN. The kit can be downloaded from &lt;A href="http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx"&gt;http://www.microsoft.com/whdc/device/wpd/MTP-DEK_Win7.mspx&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Information on the WPD APIs can also be found on &lt;A href="http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd388998(VS.85).aspx"&gt;MSDN&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;That’s it for now. Stay tuned for more posts diving into the details of the new Windows 7 WPD features.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;/EM&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;&lt;/P&gt;&lt;/EM&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9860720" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="Device Stage" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Stage/" /><category term="Devices and Printers" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Devices+and+Printers/" /><category term="Windows 7" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+7/" /><category term="Device Services" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Device+Services/" /><category term="Windows Portable Devices" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Windows+Portable+Devices/" /><category term="WPD" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WPD/" /></entry><entry><title>Visual Basic .Net Sample for WPD</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2008/01/16/visual-basic-net-sample-for-wpd.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2008/01/16/visual-basic-net-sample-for-wpd.aspx</id><published>2008-01-16T20:49:00Z</published><updated>2008-01-16T20:49:00Z</updated><content type="html">&lt;P&gt;We've created a Visual Basic .Net sample for WPD and posted it to CodePlex: Microsoft's open source project-hosting web site. Take a look at &lt;A href="http://www.codeplex.com/wpdtempsensor" mce_href="http://www.codeplex.com/wpdtempsensor"&gt;http://www.codeplex.com/wpdtempsensor&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;In addition to the Visual Basic project and source files, we've posted a document that describes the sample. This document also describes how you can address and resolve the COM Interop issues associated with .Net and WPD.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;/EM&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/EM&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7133124" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="SDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/SDK/" /></entry><entry><title>Creating a Temperature Sensor Gadget for Windows Sidebar with C++</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/12/19/creating-a-temperature-sensor-gadget-for-windows-sidebar-with-c.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/12/19/creating-a-temperature-sensor-gadget-for-windows-sidebar-with-c.aspx</id><published>2007-12-20T01:13:00Z</published><updated>2007-12-20T01:13:00Z</updated><content type="html">&lt;p&gt;&lt;span class="Bold"&gt;&lt;span style="font-family: Verdana; font-weight: normal;"&gt;The following post describes a gadget for Windows Sidebar that displays the temperature reading from a temperature sensor device. Similar applications could be written to display: battery-level or available memory for a portable media device, contact lists from a mobile phone or PDA, route lists from a GPS device, and so on.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;span class="Bold"&gt;&lt;span style="font-family: Verdana; font-weight: normal;"&gt;&lt;/span&gt;&lt;/span&gt;
&lt;h2 style="margin: 12pt 0in 8pt;"&gt;Introduction&lt;/h2&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Microcontrollers are used in a variety of applications from industrial to automotive to the home. One use that stretches across these boundaries is the microcontroller-based sensor which monitors parameters such as temperature, humidity, acceleration, distance, and light.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;While the microcontroller device-universe has grown exponentially, there hasn’t been a common interface for integrating these devices with the PC. As a result, device and application developers were forced to write custom software to handle operations like data retrieval and display.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Microsoft recently introduced Microsoft® Windows® Portable Devices (WPD), a technology that addresses the challenges of integrating microcontroller-based devices with your PC. A microcontroller-based device can be as simple as a remote sensor or as complex as a mobile phone, a portable media player, or a digital camera. WPD consists of a driver model that runs in the user-mode driver framework (UMDF) and an API that simplifies the creation of applications for these devices.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;This paper describes the use of the WPD API to create a Windows Console application that retrieves temperature data from a temperature sensor device. In addition, it describes a corresponding gadget for Windows Sidebar that consumes the data collected by the application.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The temperature sensor used by this application is based on the BASIC Stamp Activity Kit for Windows Portable Devices. This kit is offered by the Parallax Corporation in Rocklin, California. You can order the kit from the company’s &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98659" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98659"&gt;&lt;font color="#0000ff" face="Verdana"&gt;Web site&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The console application obtains real-time temperature data from a Parallax temperature sensor device. It writes this data to a file on disk. A script in the gadget’s HTML file retrieves the data and renders it in Windows Sidebar.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The console application was written in Microsoft Visual Studio® 8 using the C++ programming language. The WPD gadget was written in HTML and Jscript®. &lt;/font&gt;&lt;/p&gt;

&lt;h2 style="margin: 12pt 0in 8pt;"&gt;Downloading the Sample Application and Sidebar Gadget&lt;/h2&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;To download the sample application, see this &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98948" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98948"&gt;&lt;font color="#0000ff" face="Verdana"&gt;page&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt; on the Microsoft Downloads site.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;To download the gadget, see this &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98949" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98949"&gt;&lt;font color="#0000ff" face="Verdana"&gt;page&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt; on the Microsoft Downloads site.&lt;/font&gt;&lt;/p&gt;

&lt;h2 style="margin: 12pt 0in 8pt;"&gt;Running the Sample Application&lt;/h2&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The sample application requires that the WPD temperature sensor driver (WpdTempSensorDriver.dll) is installed and that a temperature sensor device is connected over a standard RS232 port.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The WPD temperature sensor driver exposes a Temperature Sensor object. This object, in turn, exposes three programmatic elements: two properties and an event. These elements are described in the following table.&lt;/font&gt;&lt;/p&gt;

&lt;table style="border-collapse: collapse;" class="MsoNormalTable" border="0" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;Programmatic Element&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;Description&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Interval property&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;This read/write property specifies the frequency at which the device should return the current temperature. (This property is specified in milliseconds.)&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Temperature property&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;This read-only property specifies the current temperature in degrees Kelvin.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Temperature-reading event&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;This event is fired each time the device retrieves the current temperature. (The Interval property specifies the frequency at which the device will fire this event.)&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 3pt 0pt 0pt;" class="TableSpacingAfter"&gt;&lt;o:p&gt;&lt;font size="1" color="#ffff00" face="Verdana"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The sample console application, described in this white paper, registers to receive the Temperature-reading event notification each time it’s fired. Upon receiving the notification, the application writes the temperature data as HTML and saves it in an ASCII text file. The gadget, in turn, reads the HTML from this file and renders it in Sidebar.&lt;/font&gt;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Building and Installing the Temperature Sensor Device&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The temperature sensor device referenced in this paper is based on a Parallax BS2 microcontroller and an AD592 Temperature Sensor transducer.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Parallax supplies a complete hardware kit that includes all of the required components. To order the kit, see this &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98659" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98659"&gt;&lt;font color="#0000ff" face="Verdana"&gt;page&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt; on the Parallax site.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;You can download the Basic Stamp source code for the temperature sensor device from the &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98661" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98661"&gt;&lt;font color="#0000ff" face="Verdana"&gt;WHDC site&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Building and Installing the WPD Temperature Sensor Driver&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;In order to install the driver, download the source code and build it. For information about downloading the driver, see the following topic on the &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98661" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98661"&gt;&lt;font color="#0000ff" face="Verdana"&gt;WHDC Web site&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Installing the Gadget&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The download package referenced above in this article contains a file named WpdTemperatureSensor.gadget. Copy this file to your local machine, open Windows Explorer, and double-click this file. You will be asked whether you want to install the gadget. Click Install. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The gadget will be installed in the Desktop\&lt;user name=""&gt;\AppData\Local\Microsoft\Windows Sidebar\Gadgets folder.&lt;/user&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Now you’re ready to build and run the sample application.&lt;/font&gt;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Building and Running the Sample Application&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The download package included with this white paper contains the project, source, and header files for the sample console application that retrieves temperature data from the sensor. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;After you’ve installed the temperature sensor device, driver, and gadget files, you’ll need to extract the contents of the download package to your development machine. This includes the following files.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;stdafx.h&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;stdafx.cpp&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;deviceevents.cpp&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;sidebar_console.cpp&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;sidebar_console.vcproj&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;For a description of these files, see the Temperature Sensor Console Application section that follows. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;If you haven’t installed the Windows SDK for Windows Vista, you’ll need to do so before building the project. For information about installing the Windows SDK, visit the &lt;a href="http://msdn.microsoft.com/en-us/windows/bb980924.aspx" title="Windows SDK web page" mce_href="http://msdn.microsoft.com/en-us/windows/bb980924.aspx"&gt;Windows SDK web page&lt;/a&gt;&lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98663" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98663"&gt;&lt;font color="#0000ff" face="Verdana"&gt;&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Once the Windows SDK is installed, open the project file (sidebar_console.vcproj) in Visual Studio 8. Select the Build_Sidebar console option from the Build menu. Visual Studio 8 will build an executable file and place it in the \Debug subdirectory. You can test the gadget and verify that it works by selecting Start Debugging from the Debug menu.&lt;/font&gt;&lt;/p&gt;

&lt;h2 style="margin: 12pt 0in 8pt;"&gt;WPD Application and Gadget Overview&lt;/h2&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The WPD application and gadget consists of two separate processes: a server and a client. The server is a console application which monitors the temperature sensor device for event notifications. Each time this application receives a notification, it writes corresponding temperature data formatted as HTML to a file on disk. The client is a script running in the gadget’s HTML file. This script retrieves the data from the file created by the console application and renders it in Sidebar. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The WPD Console Application registers to receive temperature events from the device. These events are fired at an interval specified by the device’s Interval property. (The default value for this property is 2,000 milliseconds.)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The event handler in the console application writes the temperature as a string of HTML to an ASCII text file on the local disk. This string has the following appearance.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;P&amp;gt;Office Temperature&amp;lt;P&amp;gt;304&amp;amp;deg; Kelvin&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The gadget’s script executes every 3,000 milliseconds. The script reads the string of HTML created by the console application and inserts that string into the body of the gadget’s HTML.&lt;/font&gt;&lt;/p&gt;

&lt;h2 style="margin: 12pt 0in 8pt;"&gt;The Temperature Sensor Console Application&lt;/h2&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The temperature sensor console application is a simple application that accomplishes the following tasks.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Searches for the temperature sensor device and opens a connection if the device is found.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Registers to receive event notifications from the device.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Enters a loop and responds to any one of three inputs from the user.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;While listening for user input, and for as long as the event registration is intact, writes temperature data to the local disk.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The temperature sensor application project consists of the following files:&lt;/font&gt;&lt;/p&gt;

&lt;table style="border-collapse: collapse;" class="MsoNormalTable" border="0" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;File&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Description&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;stdafx.h&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Contains #defines for the target platform as well as #includes for the standard system include file.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;deviceevents.cpp&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Implements &lt;b style=""&gt;IPortableDeviceEventCallback&lt;/b&gt; which is required by any WPD application that registers to receive device events.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;sidebar_console.cpp&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Implements the entry point for the console application and the helper functions which perform tasks like searching for the device and establishing a connection. &lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;stdafx.cpp&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Contains #include for stdafx.h&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;sidebar_console.vcproj&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The Visual Studio 8 project file.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 3pt 0pt 0pt;" class="TableSpacingAfter"&gt;&lt;o:p&gt;&lt;font size="1" color="#ffff00" face="Verdana"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Most of work accomplished by the application is found in the module named sidebar_console.cpp; the exception is the event handling code which is found in the module deviceevents.cpp.&lt;/font&gt;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Opening a Connection to the Temperature Sensor Device&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The WPD API provides a set of interfaces that a Windows programmer can use to accomplish tasks like enumerating connected devices, opening a device, closing a device, enumerating objects on a device, reading and writing properties on a device, sending a command to a device, and registering to receive events from a device.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;One of the primary interfaces is the &lt;span class="Bold"&gt;&lt;b&gt;IPortableDevice&lt;/b&gt;&lt;/span&gt; interface which supports the methods a programmer calls to open a device, receive events, send a command, and so on. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The first task the sample application accomplishes is to open (establish a connection to) the temperature sensor device. It does this by calling the &lt;span class="Bold"&gt;&lt;b&gt;IPortableDevice::Open&lt;/b&gt;&lt;/span&gt; method. This method takes two parameters: a pointer to a string that specifies a special identifier for the device and a pointer to an array of key/value pairs that specify information about the calling application.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;hr = CoCreateInstance(CLSID_PortableDevice,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CLSCTX_INPROC_SERVER,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IID_IPortableDevice,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(VOID**) &amp;amp;pIPortableDevice);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (SUCCEEDED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (pIPortableDevice != NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = (pIPortableDevice)-&amp;gt;Open(DeviceID, pClientInformation);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (FAILED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Release the IPortableDevice interface&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;// because we cannot proceed with an&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// unopen device.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pIPortableDevice = NULL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("Device successfully opened.\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;br&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;In order to retrieve the device identifier &lt;span class="Italic"&gt;&lt;i&gt;DeviceID&lt;/i&gt;&lt;/span&gt;, which is passed as the first parameter to &lt;span class="Bold"&gt;&lt;b&gt;IPortableDevice::Open&lt;/b&gt;&lt;/span&gt;, the application first needs to determine whether the temperature sensor device is connected to the PC and, if it is, retrieve the identifier. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The &lt;span class="Bold"&gt;&lt;b&gt;FindDevice&lt;/b&gt;&lt;/span&gt; helper function in the Sidebar_Console.cpp module accomplishes this work. The &lt;span class="Bold"&gt;&lt;b&gt;FindDevice&lt;/b&gt;&lt;/span&gt; function has two arguments: the first is a “friendly” name for the target device; the second is the special Plug and Play identifier that the WPD API returns as a match for this friendly name.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The &lt;span class="Bold"&gt;&lt;b&gt;FindDevice&lt;/b&gt;&lt;/span&gt; helper function accomplishes the following tasks.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;1.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;Retrieves a count of devices connected to the PC.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;2.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Retrieves an array of friendly names for each device.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;3.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Compares the friendly name passed in its first argument to the friendly names for each of the connected devices.If a match is found, it retrieves the Plug and Play identifier for the target device.&lt;/font&gt;&lt;/p&gt;

&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;u&gt;&lt;font size="2"&gt;Retrieving a Count of Connected Devices&lt;/font&gt;&lt;/u&gt;&lt;/h4&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The first task of the &lt;span class="Bold"&gt;&lt;b&gt;FindDevice&lt;/b&gt;&lt;/span&gt; function is the retrieval of a count of connected devices. This is done in two stages: first, by creating an &lt;span class="Bold"&gt;&lt;b&gt;IPortableDeviceManager&lt;/b&gt;&lt;/span&gt; object, and second, by calling the &lt;span class="Bold"&gt;&lt;b&gt;IPortableDeviceManager::GetDevices&lt;/b&gt;&lt;/span&gt; method. (In order to retrieve a count of connected devices, the first argument to &lt;span class="Bold"&gt;&lt;b&gt;GetDevices&lt;/b&gt;&lt;/span&gt; is set to NULL.)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;// CoCreate the IPortableDeviceManager interface to enumerate&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;// portable devices and to get information about them.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;hr = CoCreateInstance(CLSID_PortableDeviceManager,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CLSCTX_INPROC_SERVER,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IID_IPortableDeviceManager,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(VOID**) &amp;amp;pPortableDeviceManager);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;if (FAILED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to CoCreateInstance CLSID_PortableDeviceManager\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return hr;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;// First, pass NULL as the LPWSTR array pointer to get the total&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;// number of devices found on the system.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;if (SUCCEEDED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pPortableDeviceManager-&amp;gt;GetDevices(NULL, &amp;amp;cPnPDeviceIDs);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (FAILED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to get number of devices on the system\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return hr;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;u&gt;&lt;font size="2"&gt;Retrieving a Plug and Play name for the Temperature Sensor&lt;/font&gt;&lt;/u&gt;&lt;/h4&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;WPD supports two types of device names: friendly names and Plug and Play names. The friendly names are the names applications display to the user. The friendly name for the temperature sensor device is: "Parallax BS2 Temperature Sensor". The Plug and Play names are used internally by WPD to identify devices.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;The Plug and Play name for the temperature sensor device is: &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;a href="file:///%5C%5C%3f%5Croot#wpd#0000#%7B6ac27878-a6fa-4155-ba85-f98f491d4f33%7D" mce_href="file:///\\%3f\root#wpd#0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}"&gt;&lt;span style="color: black; text-decoration: none;"&gt;&lt;font face="Courier New"&gt;\\?\root#wpd#0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;This string uniquely identifies the device instance and the device interface, and it is defined as part of the Windows Driver Model (WDM). For more information, refer to this &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=98665" target="_blank" mce_href="http://go.microsoft.com/fwlink/?LinkId=98665"&gt;&lt;font color="#0000ff" face="Verdana"&gt;MSDN topic&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;After retrieving a count of connected devices and storing it in the cPnPDeviceIDs variable, &lt;span class="Bold"&gt;&lt;b&gt;FindDevice&lt;/b&gt;&lt;/span&gt; iterates through the available devices until it finds a device whose friendly name matches the string “Parallax BS2 Temperature Sensor”. If this match is made, &lt;span class="Bold"&gt;&lt;b&gt;FindDevice&lt;/b&gt;&lt;/span&gt; returns the corresponding Plug and Play name in the DeviceID argument. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (cPnPDeviceIDs &amp;gt; 0)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pPnpDeviceIDs = new LPWSTR[cPnPDeviceIDs];&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (pPnpDeviceIDs != NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DWORD dwIndex = 0;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pPortableDeviceManager-&amp;gt;GetDevices(pPnpDeviceIDs, &amp;amp;cPnPDeviceIDs);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (SUCCEEDED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// For each device found, retrieve the friendly&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// name and compare it to the submitted name.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;for (dwIndex = 0; dwIndex &amp;lt; cPnPDeviceIDs; dwIndex++)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CAtlStringW FriendlyName;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = RetrieveFriendlyName(pPortableDeviceManager, pPnpDeviceIDs[dwIndex], FriendlyName);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;if ((hr == S_OK) &amp;amp;&amp;amp; (DeviceName.CompareNoCase(FriendlyName) == 0))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DeviceID = pPnpDeviceIDs[dwIndex];&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;bFoundDevice = TRUE;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;break;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to get the device list from the system\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (SUCCEEDED(hr) &amp;amp;&amp;amp; (!bFoundDevice))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to find a matching device\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = E_FAIL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Free all returned PnPDeviceID strings by using&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// CoTaskMemFree.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;// NOTE: CoTaskMemFree can handle NULL pointers, so&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;no NULL check is needed.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;for (dwIndex = 0; dwIndex &amp;lt; cPnPDeviceIDs; dwIndex++)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoTaskMemFree(pPnpDeviceIDs[dwIndex]);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pPnpDeviceIDs[dwIndex] = NULL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Delete the array of LPWSTR pointers.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;delete [] pPnpDeviceIDs;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pPnpDeviceIDs = NULL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to allocate memory for LPWSTR array\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = E_OUTOFMEMORY;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return hr;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The application passes the returned Plug and Play name as the first argument to &lt;b style=""&gt;IPortableDevice::Open&lt;/b&gt; when it opens the device.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Note that the FindDevice function calls the RetrieveFriendlyName helper function to retrieve a friendly name for each Plug and Play name returned by IPortableDeviceManager::GetDevices. The RetrieveFriendlyName function calls the IPortableDeviceManager::GetFriendlyName method twice to retrieve the friendly name string. The first time, it calls this method to retrieve a count of characters in the friendly name string; the second time, it calls this method to retrieve the actual string.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// First, pass NULL as the LPWSTR return string parameter to get&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// the total number of characters to allocate for the string&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// value.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pPortableDeviceManager-&amp;gt;GetDeviceFriendlyName(pPnPDeviceID, NULL, &amp;amp;cchFriendlyName);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (FAILED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to get number of characters for device friendly name.\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return hr;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Second, allocate the number of characters needed and retrieve&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// the string value.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if ((hr == S_OK) &amp;amp;&amp;amp; (cchFriendlyName &amp;gt; 0))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;wszFriendlyName = new WCHAR[cchFriendlyName];&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (wszFriendlyName != NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pPortableDeviceManager-&amp;gt;GetDeviceFriendlyName(pPnPDeviceID, wszFriendlyName, &amp;amp;cchFriendlyName);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (SUCCEEDED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;FriendlyName = wszFriendlyName;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to get device friendly name\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Delete the allocated friendly name string.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;delete [] wszFriendlyName;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;wszFriendlyName = NULL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&amp;nbsp;&lt;br&gt;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Receiving Device Events&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The WPD API and driver model were designed so devices can issue events and applications can register to receive notifications when these events occur. Applications that receive events must implement the &lt;span class="Bold"&gt;&lt;b&gt;IPortableDeviceEventCallback&lt;/b&gt;&lt;/span&gt; interface. This interface supports a single &lt;span class="Bold"&gt;&lt;b&gt;OnEvent&lt;/b&gt;&lt;/span&gt; method. The driver calls this method each time an event is fired. However, in order for a driver to call this method, an application first needs to register with the driver. An application registers with the driver by calling the &lt;span class="Bold"&gt;&lt;b&gt;IPortableDevice::Advise&lt;/b&gt;&lt;/span&gt; method. The third argument for this method, &lt;span class="Italic"&gt;&lt;i&gt;pCallback&lt;/i&gt;&lt;/span&gt;, is a pointer to the &lt;span class="Bold"&gt;&lt;b&gt;IPortableDeviceEventCallback&lt;/b&gt;&lt;/span&gt; interface that the application implemented.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The temperature sensor device issues a single temperature-reading event that the sample application registers to receive. Each time the driver calls the &lt;span class="Bold"&gt;&lt;b&gt;OnEvent&lt;/b&gt;&lt;/span&gt; method, the sample application writes the received temperature to a local file on disk. The gadget’s script then reads from this file to update the gadget with the most recent office temperature.&lt;/font&gt;&lt;/p&gt;

&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;u&gt;&lt;font size="2"&gt;Implementing IPortableDeviceEventCallback&lt;/font&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The sample application implements the &lt;span class="Bold"&gt;&lt;b&gt;IPortableDeviceEventCallback&lt;/b&gt;&lt;/span&gt; interface in the DeviceEvents.cpp module. Most of the code in this module was taken from the WpdApiSample application that ships with the Windows SDK. The following changes were made to the original file.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;The TEMPERATURE_SENSOR_READING property key was defined and declared.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;The &lt;span class="Bold"&gt;&lt;b&gt;OnEvent&lt;/b&gt;&lt;/span&gt; method was modified to process the TEMPERATURE_SENSOR_READING property and write the new temperature value to disk.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The &lt;span class="Bold"&gt;&lt;b&gt;IPortableDeviceEventCallback&lt;/b&gt;&lt;/span&gt; interface is implemented in the &lt;span class="Bold"&gt;&lt;b&gt;CPortableDeviceEventsCallback&lt;/b&gt;&lt;/span&gt; class in DeviceEvents.cpp. This class supports the following methods.&lt;/font&gt;&lt;/p&gt;

&lt;table style="border-collapse: collapse;" class="MsoNormalTable" border="0" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Method&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Description&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;CPortableDeviceEventsCallback&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Object constructor&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;~CPortableDeviceEventsCallback&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Object destructor&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;QueryInterface&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Returns a pointer to the &lt;b style=""&gt;IPortableDeviceEventCallback&lt;/b&gt; interface.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;AddRef&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Increments the object’s reference count.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;Release&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Decrements the object’s reference count.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;OnEvent&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Event handler. WPD will call this method if the application is registered to receive event notifications.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 3pt 0pt 0pt;" class="TableSpacingAfter"&gt;&lt;o:p&gt;&lt;font size="1" color="#ffff00" face="Verdana"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;In addition to implementing &lt;b style=""&gt;IPortableDeviceEventCallback&lt;/b&gt;, the DeviceEvents.cpp module also contains two functions that the application calls in order to register and unregister for event notifications. These functions are described in the following table.&lt;/font&gt;&lt;/p&gt;

&lt;table style="border-collapse: collapse;" class="MsoNormalTable" border="0" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Function&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Description&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;RegisterForEventNotifications&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Registers the application to receive event notifications. (This method is called when the application first starts.It’s also called if the user requests registration by entering the number &lt;b&gt;2&lt;/b&gt; at the command prompt.)&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;b style=""&gt;&lt;font face="Verdana"&gt;UnregisterForEventNotifications&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Unregisters the application from receiving event notifications. (This method is called if the user requests cancellation of registration by entering the number &lt;b&gt;1&lt;/b&gt; at the command prompt.)&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 3pt 0pt 0pt;" class="TableSpacingAfter"&gt;&lt;o:p&gt;&lt;font size="1" color="#ffff00" face="Verdana"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;u&gt;&lt;font size="2"&gt;Implementing the IPortableDeviceEventCallback::OnEvent Method&lt;/font&gt;&lt;/u&gt;&lt;/h4&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Once an application registers to receive event notifications, the WPD device driver will call the &lt;b style=""&gt;IPortableDeviceEventCallback::OnEvent&lt;/b&gt; method whenever the device fires an event. Each time the driver calls this method, it passes data associated with the given event in an &lt;b style=""&gt;IPortableDeviceValues&lt;/b&gt; interface. The &lt;i style=""&gt;pEventParameters&lt;/i&gt; argument is a pointer to this interface.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The temperature sensor device fires one event per temperature reading update, and the accompanying data is a single, signed integer value which specifies the current temperature in degrees Kelvin. The sample application retrieves this value by calling the IPortableDeviceValues::GetSignedIntegerValue method and passing the property key for the TEMPERATURE_SENSOR_READING property as the first argument. (This property key was declared and defined at the top of DeviceEvents.cpp.)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;HRESULT __stdcall OnEvent(&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IPortableDeviceValues* pEventParameters)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT hr = S_OK;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;LONG i=0;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HANDLE hFile;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DWORD dwBytesWritten;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;char strHtmlPrefix[]="&amp;lt;P&amp;gt;Office Temperature&amp;lt;P&amp;gt;";&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;char strHtmlSuffix[]="&amp;amp;deg; Kelvin";&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;char strHtml[40];&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (pEventParameters != NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pEventParameters-&amp;gt;GetSignedIntegerValue(TEMPERATURE_SENSOR_READING, &amp;amp;i);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;sprintf_s(strHtml, "%s%d%s\0", strHtmlPrefix, i, strHtmlSuffix);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hFile = CreateFileW(_T("c:\\temp\\tempdata.txt"),&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;GENERIC_WRITE,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CREATE_ALWAYS,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;FILE_ATTRIBUTE_NORMAL,&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (WriteFile(hFile, strHtml, sizeof(strHtml), &amp;amp;dwBytesWritten, NULL))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("Current temperature: %d Kelvin\n\r", i);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("Temperature written to target file.\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("Temperature not written to target file.\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("WriteFile failed with error %d.\n\r\n\r", GetLastError());&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CloseHandle(hFile); // We need to close the handle.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return hr;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Upon retrieving the current temperature, the &lt;b style=""&gt;OnEvent&lt;/b&gt; method writes a string of HTML to a temporary file on disk (c:\temp\tempdata.txt). The gadget reads this string of HTML from the temporary file and incorporates it into the gadget’s own HTML. In addition, the &lt;b style=""&gt;OnEvent&lt;/b&gt; method writes the current temperature to the console window.&lt;/font&gt;&lt;/p&gt;

&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;u&gt;&lt;font size="2"&gt;Implementing the RegisterForEventNotifications Function&lt;/font&gt;&lt;/u&gt;&lt;/h4&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The sample application supports a single function, &lt;b style=""&gt;RegisterForEventNotfications&lt;/b&gt;, which it calls at startup and if the user explicitly requests registration. This function performs the following tasks.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;4.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Examines the event registration cookie (g_strEventRegistrationCookie) to determine whether the application is already registered.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;5.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;If not, creates an instance of the CPortableDeviceEventsCallback object.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;6.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Calls the IPortableDevice::Advise method to complete the registration.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;7.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;If registration is successful, assigns the event cookie returned by the Advise method to the &lt;i style=""&gt;g_strEventRegistrationCookie&lt;/i&gt; variable.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;void RegisterForEventNotifications(IPortableDevice* pDevice)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = S_OK;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;LPWSTR&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;wszEventCookie = NULL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CPortableDeviceEventsCallback* pCallback = NULL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (pDevice == NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Check to see if we already have an event registration cookie.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// If so, then avoid registering again.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// NOTE: An application can register for events as many times as.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;wanted. This sample only keeps a single registration&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;cookie around for simplicity.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (g_strEventRegistrationCookie.GetLength() &amp;gt; 0)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("This application has already registered to receive device events.\n\r\n\r");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Create an instance of the callback object. This will be&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// called when events are received.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (hr == S_OK)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pCallback = new CPortableDeviceEventsCallback();&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (pCallback == NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = E_OUTOFMEMORY;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("Failed to allocate memory for IPortableDeviceEventsCallback object, hr = 0x%lx\n\r\n\r",hr);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Call Advise to register the callback and receive events.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (hr == S_OK)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pDevice-&amp;gt;Advise(0, pCallback, NULL, &amp;amp;wszEventCookie);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (FAILED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to register for device events, hr = 0x%lx\n\r\n\r",hr);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Save the event registration cookie if event registration was&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// successful.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (hr == S_OK)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;g_strEventRegistrationCookie = wszEventCookie;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Free the event registration cookie if one was returned.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (wszEventCookie != NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoTaskMemFree(wszEventCookie);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;wszEventCookie = NULL;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (hr == S_OK)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("This application has registered for device event notifications.\r\n\r\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// If a failure occurs, remember to delete the allocated callback&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// object if one exists.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (pCallback != NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pCallback-&amp;gt;Release();&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;u&gt;&lt;font size="2"&gt;Implementing the UnregisterForEventNotifications Function&lt;/font&gt;&lt;/u&gt;&lt;/h4&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The sample application supports a single function, UnregisterForEventNotfications, which it calls if the user explicitly cancels registration. This function performs the following tasks.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;8.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Calls the IPortableDevice::Unadvise method and passes the registration cookie (which is also the event cookie returned by the IPortableDevice::Advise method).&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Verdana"&gt;9.&lt;/font&gt;&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;Sets the internal event registration-cookie variable g_strEventRegistrationCookie to an empty string.&lt;/font&gt;&lt;/p&gt;

&lt;br&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;void UnregisterForEventNotifications(IPortableDevice* pDevice)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT hr = S_OK;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (pDevice == NULL)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pDevice-&amp;gt;Unadvise(g_strEventRegistrationCookie);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (FAILED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to unregister for device events using registration cookie '%ws', hr = 0x%lx\n\r\n\r",g_strEventRegistrationCookie.GetString(), hr);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (hr == S_OK)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("This application used the registration cookie '%ws' to unregister from receiving device event notifications\n\r\n\r", g_strEventRegistrationCookie.GetString());&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;g_strEventRegistrationCookie = L"";&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Handling User Input&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The sample application displays a simple menu in the console window when it begins execution. This menu has three options corresponding to three integer values.&lt;/font&gt;&lt;/p&gt;

&lt;table style="border-collapse: collapse;" class="MsoNormalTable" border="0" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Option/Value&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Description&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;1&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Unregister for device notifications. (The application calls the &lt;b&gt;UnregisterForEventNotifications&lt;/b&gt; function.)&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;2&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Register for device notifications. (The application calls the &lt;span class="Bold"&gt;&lt;b&gt;RegisterForEventNotifications&lt;/b&gt;&lt;/span&gt; function.)&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;99&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;Exit. (The application exits.)&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 3pt 0pt 0pt;" class="TableSpacingAfter"&gt;&lt;o:p&gt;&lt;font size="1" color="#ffff00" face="Verdana"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The code that supports the menu and its options is found in the &lt;b style=""&gt;ProcessInput&lt;/b&gt; function in the Sidebar_Console.cpp module.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;void ProcessInput(CComPtr&amp;lt;IPortableDevice&amp;gt; pIPortableDevice)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT hr&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;= S_OK;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;UINT&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;uiSelection&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;= 0;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CHAR&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;szSelection[81] = {0};&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("\n\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("===============================================\r\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("1.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Unregister for device notifications.\r\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("2.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Register for device notifications.\r\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("99. Exit.\r\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("===============================================\r\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("\n\n");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;while (uiSelection != 99)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ZeroMemory(szSelection, sizeof(szSelection));&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = StringCbGetsA(szSelection,sizeof(szSelection));&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (SUCCEEDED(hr))&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;uiSelection = (UINT) atoi(szSelection);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;switch (uiSelection)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;case 1:&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Unregister to receive device events&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;UnregisterForEventNotifications(pIPortableDevice);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;break;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;case 2:&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Register to receive device events&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;RegisterForEventNotifications(pIPortableDevice);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;default:&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;break;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;printf("! Failed to read menu selection string input, hr = 0x%lx\n\r\n\r",hr);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2 style="margin: 12pt 0in 8pt;"&gt;The Temperature Sensor Gadget&lt;/h2&gt;

&lt;p style="margin: 3pt 0pt 9pt;" class="Figure"&gt;&lt;font face="Verdana"&gt;The temperature sensor gadget displays the current office temperature in degrees Kelvin in Windows Sidebar. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;If you’ve never created a gadget for Windows Sidebar before, refer to the &lt;/font&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa965850.aspx" target="_blank" mce_href="http://msdn2.microsoft.com/en-us/library/aa965850.aspx"&gt;&lt;font face="Verdana"&gt;Gadget Development Overview&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;The Temperature Sensor Gadget Files&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The temperature sensor gadget consists of three files: an HTML file, an XML file, and a JPEG file. These files are described in the following table.&lt;/font&gt;&lt;/p&gt;

&lt;table style="border-collapse: collapse;" class="MsoNormalTable" border="0" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;File Name&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none none solid; border-color: rgb(212, 208, 200) rgb(212, 208, 200) windowtext; border-width: medium medium 1pt; padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Label"&gt;&lt;b&gt;&lt;font face="Verdana"&gt;Description&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;UpdateTemperatureReading.htm&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;An HTML file that contains the script which retrieves the updated temperature data from the local disk every 3,000 milliseconds. &lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;gadget.xml&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The gadget manifest. This file specifies properties such as the name of the gadget, the name of its HTML file, a string of descriptive text, and so on.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;background.jpg&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border: medium none rgb(212, 208, 200); padding: 0pt 4pt; background-color: transparent; width: 223pt;" valign="top" width="297"&gt;
&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;A 163 x 58 pixel image that produces the gadget’s two-tone blue background color.&lt;/font&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 3pt 0pt 0pt;" class="TableSpacingAfter"&gt;&lt;o:p&gt;&lt;font size="1" color="#ffff00" face="Verdana"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;font size="3"&gt;Retrieving the Current Temperature&lt;/font&gt;&lt;/b&gt;&lt;/h3&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The gadget’s HTML file, UpdateTemperatureReading.htm, contains a script which opens the file created by the console application (c:\temp\tempdata.txt) and copies the contents of this file into a span element identified as “temperature_data” within the body of the gadget’s HTML.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;This script creates a FileSystemObject which it uses to open and read the text file. It uses the OpenTextFile method to open the file and the ReadAll method to retrieve its contents. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The script uses the setTimeout method on the window object to recursively execute the update function every 3,000 milliseconds. (This function contains the code that retrieves the contents of c:\temp\tempdata.txt.)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;html&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;head&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;script&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;var fileSystemObject = null;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;function loaded()&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;fileSystemObject = new ActiveXObject("Scripting.FileSystemObject");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;update();&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;function update()&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;var textStream = fileSystemObject.OpenTextFile("c:\\temp\\tempdata.txt");&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;try&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;temperature_data.innerHTML = textStream.ReadAll();&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;finally&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;textStream.Close();&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;window.setTimeout(update, 3000);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;/script&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;style&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;body &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{ &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;margin: 0;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;width: 125px;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;height: 62px;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;font: 'normal 8pt Arial';&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;line-height: 12pt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;text-align:center;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;/style&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;/head&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;body onload="loaded()"&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;g:background src="background.png"&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;span id="temperature_data"&amp;gt;&amp;lt;/span&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;/g:background&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;/body&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&lt;font face="Courier New"&gt;&amp;lt;/html&amp;gt;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0pt 0pt 3pt;" class="Code"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The HTML file also contains a description of the gadget’s window between the &amp;lt;style&amp;gt; and &amp;lt;/style&amp;gt; tags that follow the script. Note that the width and height attributes match the width and height of the background image (background.png). In addition to specifying the size of the gadget’s window, the attributes found here specify the font used to render text, the line height (which creates padding between the two lines of text), and the text alignment. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The g:background element specifies the source file (background.png) for the gadget’s background image. &lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&lt;font face="Verdana"&gt;The span element “temperature_data” identifies the location of the HTML which is copied from c:\temp\tempdata.txt by the Update function.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt;" class="Text"&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2 style="margin: 12pt 0in 8pt;"&gt;More Information&lt;/h2&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;For general information about developing gadgets for Windows Sidebar, see the &lt;/font&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa965850.aspx" target="_blank" mce_href="http://msdn2.microsoft.com/en-us/library/aa965850.aspx"&gt;&lt;font face="Verdana"&gt;Gadget Development Overview&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&lt;span style="font-family: Symbol; color: windowtext;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Verdana"&gt;To learn more about &lt;span style="color: windowtext;"&gt;the BASIC Stamp Activity Kit for Windows Portable Devices, refer to the &lt;a href="http://go.microsoft.com/fwlink?linkid=98659" target="_blank " mce_href="http://go.microsoft.com/fwlink?linkid=98659"&gt;&lt;font color="#0000ff"&gt;Parallax site&lt;/font&gt;&lt;/a&gt;.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p style="margin: 3pt 0pt 3pt 18pt;" class="BulletedList1"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties, and confers no 
rights.&lt;/i&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6810306" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="SDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/SDK/" /></entry><entry><title>Creating a Temperature-Sensor Gadget for Windows Sidebar with C#</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/11/26/creating-a-temperature-sensor-gadget-for-windows-sidebar.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/11/26/creating-a-temperature-sensor-gadget-for-windows-sidebar.aspx</id><published>2007-11-27T00:51:00Z</published><updated>2007-11-27T00:51:00Z</updated><content type="html">&lt;p style="margin: 3pt 0in;" class="Text"&gt;This article was written for application developers who are interested in displaying portable device data in the Windows Sidebar. It describes a Microsoft .Net application written in C# as well as a gadget for Windows Sidebar. The application was written&amp;nbsp;using Microsoft Visual Studio 8. The WPD gadget was written in HTML and JScript.&lt;/p&gt;

&lt;p style="margin: 3pt 0in;" class="Text"&gt;The .Net application retrieves temperature data from a Parallax temperature-sensor device and writes this data to a file on the local disk. A&amp;nbsp;script&amp;nbsp;in the gadget's HTML file reads the contents of this&amp;nbsp;local file and displays the temperature in the Sidebar.&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 3pt 0in;" class="Text"&gt;The temperature sensor used by this application is based on the BASIC Stamp Activity Kit for Windows Portable Devices. This kit is offered by the Parallax Corporation in Rocklin, California. You can order the kit from the company’s &lt;a href="http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/WPD/List/1/ProductID/430/Default.aspx?SortField=ProductName%2cProductName" title="website" mce_href="http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/WPD/List/1/ProductID/430/Default.aspx?SortField=ProductName%2cProductName"&gt;website&lt;/a&gt;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;h2 style="margin: 12pt 0in 8pt;"&gt;Running the Application and Viewing the Gadget&lt;o:p&gt;&lt;/o:p&gt;&lt;/h2&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The application and gadget described in this article require that you install the WPD temperature sensor driver (WpdTempSensorDriver.dll) and that you connect the temperature sensor device over a standard RS232 port.&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The WPD temperature-sensor driver exposes a Temperature Sensor object. This object, in turn, exposes three programmatic elements: two properties and an event. These elements are described in the following table.&lt;/p&gt;

&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid windowtext; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;b style=""&gt;&lt;span style="font-family: 'Verdana';"&gt;Programmatic Element&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext rgb(212, 208, 200); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;b style=""&gt;&lt;span style="font-family: 'Verdana';"&gt;Description&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;span style="font-family: 'Verdana';"&gt;Interval property&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;span style="font-family: 'Verdana';"&gt;This read/write property specifies the frequency at which the device should return the current temperature. (This property is specified in milliseconds.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;span style="font-family: 'Verdana';"&gt;Temperature property&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;span style="font-family: 'Verdana';"&gt;This read-only property specifies the current temperature in degrees Kelvin.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;span style="font-family: 'Verdana';"&gt;Temperature-reading event&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;

&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 3.2in;" valign="top" width="307"&gt;
&lt;p style="margin: 3pt 0in;" class="Text"&gt;&lt;span style="font-family: 'Verdana';"&gt;This event is fired each time the device retrieves the current temperature. (The Interval property specifies the frequency at which the device will fire this event.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;span style=""&gt;&lt;font size="3"&gt;Building and Installing the Temperature Sensor Device&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The temperature sensor device, referenced in this article, is based on a Parallax BS2 microcontroller and an AD592 Temperature Sensor transducer.&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;Parallax supplies a complete hardware kit that includes all of the required components. To order the kit, see &lt;a href="http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/WPD/List/1/ProductID/430/Default.aspx?SortField=ProductName%2cProductName" title="this page" mce_href="http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/WPD/List/1/ProductID/430/Default.aspx?SortField=ProductName%2cProductName"&gt;this page&lt;/a&gt; on the Parallax site. &lt;/p&gt;&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;You can download the Basic Stamp source code for the temperature sensor device from the &lt;a href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx" title="WHDC site" mce_href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx"&gt;WHDC site&lt;/a&gt;.&lt;span class="MsoHyperlink"&gt;&lt;span style="font-size: 9pt;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;span style=""&gt;&lt;font size="3"&gt;Building and Installing the WPD Temperature Sensor Driver&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;In order to install the driver, you’ll first need to download the source code and build it. For information about downloading the driver, see the following topic on the &lt;a href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx" title="WHDC site" mce_href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx"&gt;WHDC site&lt;/a&gt;.&lt;span class="MsoHyperlink"&gt;&lt;span style="font-size: 9pt;"&gt;&lt;u&gt;&lt;font color="#333399"&gt;&lt;/font&gt;&lt;/u&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;font size="3"&gt;&lt;b&gt;&lt;span style=""&gt;Installing the Gadget&lt;/span&gt;&lt;/b&gt;&lt;span class="MsoHyperlink"&gt;&lt;b&gt;&lt;span style="font-size: 9pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The sidebar gadget is found &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4deae5b8-fb78-421e-9fa0-1ee1336fa441&amp;amp;DisplayLang=en" title="here" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4deae5b8-fb78-421e-9fa0-1ee1336fa441&amp;amp;DisplayLang=en"&gt;here&lt;/a&gt; at the Microsoft Download Center. &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4deae5b8-fb78-421e-9fa0-1ee1336fa441&amp;amp;DisplayLang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4deae5b8-fb78-421e-9fa0-1ee1336fa441&amp;amp;DisplayLang=en"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;Download this file to your local machine, open Windows Explorer, and double-click on the icon. Vista will ask you whether or not you want to install the gadget. Choose the Install button. &lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The gadget will be installed under the Desktop\&amp;lt;user name&amp;gt;\AppData\Local\Microsoft\Windows Sidebar\Gadgets folder.&lt;/p&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;b&gt;&lt;span style=""&gt;&lt;font size="3"&gt;Installing the Windows SDK&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;Because there’s no native .Net support for the WPD API, you’ll need to use the WPD COM interfaces if you are writing a .Net application. Your application will access these interfaces through the COM Interoperability (interop) feature of .Net. &lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;When working with the type libraries for COM objects, it’s sometimes necessary to make minor revisions to the type library metadata. Microsoft provides tools you can use to make these changes in the Windows SDK; so, you’ll want to download this SDK onto your development machine.&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;You can download the Windows SDK &lt;a href="http://msdn.microsoft.com/en-us/windowsserver/bb980924.aspx" title="here" mce_href="http://msdn.microsoft.com/en-us/windowsserver/bb980924.aspx"&gt;here&lt;/a&gt;.&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;amp;displaylang=en"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 style="margin: 12pt 0in 3pt;"&gt;&lt;span style=""&gt;&lt;font size="5"&gt;A Client/Server Model&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The .Net application described in this article is a server while the gadget acts as its client. The server monitors the temperature sensor device for event notifications. Each time it receives a notification, this application writes corresponding temperature data to a file on disk. The data is formatted as HTML. The client (or gadget) retrieves the data from the file created by the application and renders it in the sidebar. &lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;a class="" title="_Toc149027234" name="_Toc149027234"&gt;&lt;/a&gt;The .Net application sets a timer event to fire every three seconds. Each time the event fires, the application retrieves the current temperature from the WPD temperature-sensor device. The application then writes the temperature as a string of HTML to an ASCII text file on the local disk. This string has the following appearance:&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;P&amp;gt;Office Temperature&amp;lt;P&amp;gt;70&amp;amp;deg; Farenheit&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The gadget’s script executes every 3,000 milliseconds; this script reads the string of HTML created by the application and inserts the string into the body of the gadget’s HTML&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;The Temperature-Sensor Application&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The temperature-sensor application described in this article is a simple application that accomplishes the following tasks:&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.5in;" class="BulletedList2"&gt;&lt;span style=""&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;It searches for the temperature-sensor device and opens a connection if it’s found.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.5in;" class="BulletedList2"&gt;&lt;span style=""&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;It sets a timer event which is fired ever 3 seconds.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.5in;" class="BulletedList2"&gt;&lt;span style=""&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;·&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Each time the event fires, it retrieves the current temperature from the connected device and writes it to local disk.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;A Windows temperature-sensor application project, written in C# and .Net, might consist of the following files:&lt;/span&gt;&lt;/p&gt;

&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid windowtext; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;File&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext rgb(212, 208, 200); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;Description&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Form1.cs&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Searches for the temperature-sensor device and opens a connection if it’s found. Sets the timer event and retrieves the current temperature from the device, and, writes the temperature value to a file on local disk.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Form1.Designer.cs&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Defines the &lt;b style=""&gt;InitializeComponent&lt;/b&gt; method (a method describing the application’s form and its contents). &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Form1.resx&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Defines the resources found on the form (a single timer resource).&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Interop.PortableDeviceApiLib.dll&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Revised interop assembly that correctly handles the call to the &lt;b style=""&gt;IPortableDeviceManager::GetDevices&lt;/b&gt; method. (See &lt;/span&gt;&lt;a href="http://blogs.msdn.com/dimeby8" mce_href="http://blogs.msdn.com/dimeby8"&gt;&lt;font color="#333399"&gt;&lt;span style=""&gt;&lt;span style=""&gt;http://blogs.msdn.com/dimeby8&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;&lt;span style=""&gt; and the Enumerating WPD devices in C# topic.)&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Portabledeviceconstants.cs&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;A file containing definitions for the property-keys used by the WPD API as well as the property key for the &lt;b style=""&gt;TEMP_SENSOR_READING&lt;/b&gt; property.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Program.cs&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Defines the application’s main entry point.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;WpdSidebarGadget.csproj&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The Visual Studio 8 project file.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;b&gt;&lt;span style=""&gt;&lt;font size="3"&gt;Accessing the WPD API through .Net&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Because there’s no native .Net support for the WPD API, you’ll need to use the WPD COM interfaces through the COM Interoperability (interop) feature of .Net. This feature lets your .Net application “think” that it’s accessing a .Net version of WPD, when, in fact, it’s accessing the unmanaged objects instead. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;COM objects (like the WPD API) are described by type libraries. These libraries give the Visual Studio 8 compiler a definition of the types, interfaces, and methods that WPD supports. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;When working with the type libraries for COM objects, it’s sometimes necessary to make minor revisions to the metadata associated with these libraries. Microsoft provides the tools necessary to make these changes in the Windows SDK, so, you’ll want to download this SDK onto your development machine.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Your application will use the COM interfaces found in the WPD API to accomplish tasks like: enumerating connected devices, opening a device, closing a device, enumerating objects on a device, reading and writing properties on a device, sending a command to a device, and registering to receive events from a device.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;In order to access these interfaces and their methods from your C# .Net application, you’ll need to add references to the PortableDeviceApiLib and the PortableDeviceTypes Type Libraries in your Visual Studio 8 .Net project.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;You’ll add these references through the Project/Add Reference menu and the COM tab found on the associated dialog. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Once you add the references to these two type libraries, you’ll need to resolve several marshalling restrictions in the Interop assembly that Visual Studio generates for the PortableDeviceApiLib. (You’ll use a couple of tools found in the Windows SDK to resolve these restrictions.)&lt;/span&gt;&lt;/p&gt;
&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font size="2"&gt;Resolving the Marshalling Restrictions&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Create a Visual Studio 8 project for a C# Windows application and add the references to the two type libraries listed above (PortableDeviceApiLib and PortableDeviceTypes). Next, build your application.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;When you built your application, Visual Studio invoked the type library importer and created what’s called an Interop Assembly for each of the type libraries that you’d added. You’ll find these assemblies in the \bin\debug folder of your project (if you built a debug version of your application); otherwise, you’ll find these assemblies in the \bin\release folder.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;An Interop Assembly lists the COM types that your application can access via COM interoperability. These assemblies contain metadata that the .Net compiler uses to resolve method calls.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Unfortunately, some of the metadata generated by the type library importer is incorrect for C# applications. For example, if you examine the metadata for the &lt;b style=""&gt;IPortableDeviceManager::GetDevices&lt;/b&gt; method, you’ll see that the first argument (an array of string pointers) is specified to be:&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;i&gt;&lt;span style="font-family: 'Arial','sans-serif';"&gt;[in][out] string&amp;amp;&amp;nbsp; marshal( lpwstr) pPnPDeviceIDs&lt;/span&gt;&lt;/i&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;You’ll need to replace unary &amp;amp; operator with the square brackets which are used to specify an array type in C#. And, you’ll need to replace the &lt;/span&gt;&lt;span style=""&gt;&lt;span class="Italic"&gt;&lt;i&gt;&lt;font face="Times New Roman"&gt;lpwstr&lt;/font&gt;&lt;/i&gt;&lt;/span&gt; type after the marshal keyword with the &lt;i style=""&gt;[]&lt;/i&gt; operator. So, the new description of this argument would appear as below:&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;i&gt;&lt;span style="font-family: 'Arial','sans-serif';"&gt;[in][out] string[]&amp;nbsp; marshal([]) pPnPDeviceIDs&lt;/span&gt;&lt;/i&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;In general, for WPD methods that take an array or buffer as an argument, you’ll want to replace any occurrence of the unary &amp;amp; operator found in the type-libraries metadata with the square brackets. (And, you may also need to add the marshal keyword and arguments.)&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;To edit the metadata in the interop assembly, you’ll need to use the IL Disassembler (ILDASM.EXE) and the IL Assembler (ILASM.EXE). The disassembler creates an editable text file from an interop assembly file. After you’ve edited this text file (and revised the metadata), you’ll rebuild the interop assembly using the assembler.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The following steps describe how you would create an editable text file from the PortableDeviceApi interop assembly, how you would revise the metadata for the &lt;b style=""&gt;GetDevices&lt;/b&gt; and &lt;b style=""&gt;GetDeviceFriendlyName&lt;/b&gt; methods, and how you would create a new, revised assembly.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;span style=""&gt;1.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Open an instance of the Windows SDK command shell.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;span style=""&gt;2.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Use the “cd” command to change directory to your project’s \debug folder that contains the file Interop.PortableDeviceApiLib.dll&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;span style=""&gt;3.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Use the following command to disassemble the PortableDeviceAPI interop assembly into an editable text file: &lt;br&gt;ildasm Interop.PortableDeviceApiLib.dll /out:pdapi.il&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;i&gt;&lt;span style="font-family: 'Arial','sans-serif';"&gt;&lt;span style=""&gt;4.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;Open the text file pdapil.il in notepad and replace all occurrences of the &lt;i style=""&gt;pPnPDeviceIDs&lt;/i&gt; argument for the &lt;b style=""&gt;GetDevices&lt;/b&gt; method with the correct metadata. Replase the following string:&lt;br&gt;&lt;i&gt;&lt;span style="font-family: 'Arial','sans-serif';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;instance void&amp;nbsp; GetDevices([in][out] string&amp;amp;&amp;nbsp; marshal( lpwstr) pPnPDeviceIDs,&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;br&gt;&lt;/i&gt;with the revised string:&lt;i&gt;&lt;br&gt;&lt;i&gt;&lt;span style="font-family: 'Arial','sans-serif';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;instance void&amp;nbsp; GetDevices([in][out] string[]&amp;nbsp; marshal([]) pPnPDeviceIDs,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style="color: windowtext;"&gt;&lt;span style=""&gt;5.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;For the sample described in this article, you’ll also want to&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;make the following changes to the description of the &lt;i style=""&gt;pDeviceFriendlyName&lt;/i&gt; argument for the &lt;b style=""&gt;GetDeviceFriendlyName&lt;/b&gt; method. Replace the following string:&lt;br&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;i&gt;&lt;span style="color: windowtext;"&gt;[in][out] uint16&amp;amp; pDeviceFriendlyName&lt;/span&gt;&lt;/i&gt;&lt;br&gt;with the revised string:&lt;br&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;i&gt;&lt;span style="color: windowtext;"&gt;[in][out] uint16[] marshal( []) pDeviceFriendlyName&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="color: windowtext;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;span style=""&gt;6.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Assemble the revised metadata text file into a new interop assembly using the following command:&lt;br&gt;ilasm pdapi.il /dll /output=Interop.PortableDeviceApiLib.dll&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;span style=""&gt;7.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Move the newly created assembly to the root folder of your project. (If you leave in the \debug folder, Visual Studio will overwrite it the next time you build.)&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 4pt 0.25in;" class="NumberedList1"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;span style=""&gt;8.&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Remove the reference in our Visual Studio project to the original interop assembly and create a new reference to the newly modified assembly that resides in the root folder of your project.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;If your application invokes other WPD methods that use arrays or buffers as arguments, you would repeat the revisions described in steps 4. and 5. above before you created the new interop assembly.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font size="2"&gt;Accessing the WPD Properties and Commands&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;WPD properties and commands are identified by a PROPERTYKEY structure. This structure has two parts: a GUID and a DWORD. (For more information, see the discussion of WPD PROPERTYKEYS on &lt;a href="http://msdn2.microsoft.com/en-us/library/ms740204.aspx" title="MSDN" mce_href="http://msdn2.microsoft.com/en-us/library/ms740204.aspx"&gt;MSDN&lt;/a&gt;&lt;/span&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms740204.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms740204.aspx"&gt;&lt;font color="#333399"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;&lt;span style=""&gt;).&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;In order to use the common WPD PROPERTYKEYs, you’ll need to add a file containing their definition to your C# project. For a complete description of how this is done, refer to the following &lt;a href="%20http://blogs.msdn.com/dimeby8/archive/2006/12/06/where-are-the-wpd-property-keys-in-c.aspx" title="link" mce_href=" http://blogs.msdn.com/dimeby8/archive/2006/12/06/where-are-the-wpd-property-keys-in-c.aspx"&gt;link&lt;/a&gt; on the dimeby8 blog&lt;/span&gt;&lt;span style=""&gt;.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;In the sample code found in this article, we refer to a file portabledeviceconstants.cs which we created using the guidelines in the dimeby8 blog (above).&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;b&gt;&lt;span style=""&gt;&lt;font size="3"&gt;Creating the WPD Objects&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;One of the first tasks a .Net will accomplish is the creation of the WPD objects that are used throughout the application to invoke methods, retrieve property values, and so on. The following snippet demonstrates how an application might create instances of the device-manager object, a device-values collection, and a portable device object.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;namespace WpdSidebarGadget&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public partial class Form1 : Form&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Get an instance of the device manager&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.PortableDeviceManagerClass devMgr&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;= new PortableDeviceApiLib.PortableDeviceManagerClass();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Create our client information collection&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.IPortableDeviceValues pValues =&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;(PortableDeviceApiLib.IPortableDeviceValues)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;new PortableDeviceTypesLib.PortableDeviceValuesClass();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Create a new IPortableDevice instance&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.PortableDeviceClass pPortableDevice =&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;new PortableDeviceApiLib.PortableDeviceClass();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;br&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The following table lists the variable corresponding to each object and describes its use later in the application.&lt;/span&gt;&lt;/p&gt;

&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid windowtext; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;Variable&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext rgb(212, 208, 200); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;Description&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;i style=""&gt;devMgr&lt;o:p&gt;&lt;/o:p&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Used to retrieve a count of connected devices, to retrieve Plug and Play identifiers for those devices, and to retrieve friendly names for those devices, &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;i style=""&gt;pValues&lt;o:p&gt;&lt;/o:p&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Used to specify client information when opening a connection to the device.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;i style=""&gt;pPortableDevice&lt;o:p&gt;&lt;/o:p&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Used to open a connection to the temperature-sensor device. Also used to retrieve the value of the TEMP_SENSOR_READING property.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;b&gt;&lt;span style=""&gt;&lt;font size="3"&gt;Opening a Connection to the Temperature-Sensor Device&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The process of opening a connection to a device is done in two phases: in the first phase we check to see if the device is connected to the PC; if it’s found, we open the connection in the second phase.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font size="2"&gt;Searching for a Specific Device&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The &lt;b style=""&gt;IPortableDeviceManager::GetDevices&lt;/b&gt; method serves two purposes. If the first parameter is set to &lt;b style=""&gt;null&lt;/b&gt;, it returns a count of connected devices. Otherwise, it returns a list of Plug and Play identifiers for each connected device. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The Plug and Play names are used internally by WPD to identify devices.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;The Plug and Play name for the temperature sensor device is: “\\?\root#wpd#0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}”. This string uniquely identifies the device instance and the device interface and is defined as part of the Windows Driver Model (WDM). For more information, refer to &lt;a href="http://msdn2.microsoft.com/en-us/library/ms791083.aspx" title="this topic" mce_href="http://msdn2.microsoft.com/en-us/library/ms791083.aspx"&gt;this topic&lt;/a&gt; on MSDN&lt;/span&gt;&lt;span style=""&gt;. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The &lt;b style=""&gt;IPortableDeviceManager::GetFriendlyName&lt;/b&gt; method maps a given Plug and Play identifier back to the given device’s friendly name. This is the name commonly associated with a device by the user. For example: “Parallax BS2 Temperature Sensor”. For more details about the use of the &lt;b style=""&gt;GetFriendlyName&lt;/b&gt; method, see the following section titled: “&lt;b style=""&gt;Retrieving the Friendly Name for a Given Device&lt;/b&gt;”.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The following code demonstrates how an application used the &lt;b style=""&gt;GetDevices&lt;/b&gt; method to retrieve a count of connected devices and then, subsequently, retrieve the Plug and Play identifier for each device. This code then retrieves the friendly name for each connected device (by calling the &lt;b style=""&gt;RetrieveFriendlyName&lt;/b&gt; helper function), and checks to see if any of the connected devices have a friendly name that matches the string: “Parallax BS2 Temperature Sensor”. If such a device exists, its Plug and Play identifier is passed to the &lt;b style=""&gt;StartProcessing&lt;/b&gt; helper function which opens a connection to the device and begins retrieving temperature data.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;private void Form1_Load(object sender, EventArgs e)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;uint i = 0;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;uint cDevices = 0;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string strDeviceID = String.Empty;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string strFriendlyName = String.Empty;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Retrieve a count of connected WPD devices.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;devMgr.GetDevices(null, ref cDevices);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Iterate through the connected WPD devices--searching for &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// a TemperatureSensor device. If it's found, open the device&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// and begin retrieving the temperature property.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (cDevices &amp;gt; 0)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Retrieve the PnP identifiers for each &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// connected device.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string[] strPnPDeviceIDs = new string[cDevices];&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;devMgr.GetDevices(strPnPDeviceIDs, ref cDevices);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// For each connected device, retrieve the friendly&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// name and compare it to the TempSensor's name.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;for (i = 0; i &amp;lt; cDevices; i++)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strFriendlyName = RetrieveFriendlyName(devMgr, strPnPDeviceIDs[i]);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (strFriendlyName == "Parallax BS2 Temperature Sensor")&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Open the device and begin retrieving the temperature&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;StartProcessing(pPortableDevice, pValues, strPnPDeviceIDs[i]);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font size="2"&gt;Retrieving the Friendly Name for a Given Device&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;As noted in the previous section, the &lt;b style=""&gt;IPortableDeviceManager::GetFriendlyName&lt;/b&gt; method maps a given Plug and Play identifier back to the given device’s friendly name. In addition to retrieving a device’s friendly name, this method also returns a count of characters in the friendly-name string--if the second parameter is set to null. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The following helper function, &lt;b style=""&gt;RetrieveFriendlyName&lt;/b&gt;, demonstrates how your application could use the &lt;b style=""&gt;GetFriendlyName&lt;/b&gt; method to retrieve the count of characters in the friendly-name string, allocate memory for the string, and then retrieve it.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;string RetrieveFriendlyName(&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.PortableDeviceManagerClass PortableDeviceManager,&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string PnPDeviceID)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;uint&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;cFriendlyName = 0;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ushort[] usFriendlyName;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string strFriendlyName = String.Empty;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// First, pass NULL as the LPWSTR return string parameter to get the total number&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// of characters to allocate for the string value.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceManager.GetDeviceFriendlyName(PnPDeviceID, null, ref cFriendlyName);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Second allocate the number of characters needed and retrieve the string value.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;usFriendlyName = new ushort[cFriendlyName];&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (usFriendlyName.Length &amp;gt; 0)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceManager.GetDeviceFriendlyName(PnPDeviceID, usFriendlyName, ref cFriendlyName);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// We need to convert the array of ushorts to a string, one&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// character at a time.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;foreach (ushort letter in usFriendlyName)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (letter != 0)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strFriendlyName += (char)letter;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;// Return the friendly name&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return strFriendlyName;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return null;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font size="2"&gt;Opening a Connection to the Device&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The &lt;b style=""&gt;IPortableDevice::Open&lt;/b&gt; method opens a connection to a device that’s attached to a PC. This method takes two arguments: the first is the Plug and Play identifier for the target device; the second is an &lt;b style=""&gt;IPortableDeviceValues&lt;/b&gt; object that specifies client information for the device. At a minimum, the client information must include the following:&lt;/span&gt;&lt;/p&gt;

&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid windowtext; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;Client Information&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext rgb(212, 208, 200); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;Description&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Name&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;A friendly-name for the device.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Major Version Number&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The device’s major version number.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Minor Version Number&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The device’s minor version number.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Revision Number&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The device’s most recent revision number.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The following &lt;b style=""&gt;StartProcessing&lt;/b&gt; helper function configures the client information in an &lt;b style=""&gt;IPortableDeviceValues&lt;/b&gt; object and then calls the &lt;b style=""&gt;Open&lt;/b&gt; method. Once the connection is opened, the &lt;b style=""&gt;StartProcessing&lt;/b&gt; method calls a &lt;b style=""&gt;RetrieveTemp&lt;/b&gt; method to retrieve the current temperature from the connected temperature-sensor device. After calling the &lt;b style=""&gt;RetrieveTemp&lt;/b&gt; method, a timer is enabled so that it fires an event every 3 seconds.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;void StartProcessing(&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.PortableDeviceClass pPortableDevice,&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.IPortableDeviceValues pValues,&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string PnPDeviceID)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// We have to provide at the least our name, version, revision&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pValues.SetStringValue(&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ref PortableDevicePKeys.WPD_CLIENT_NAME, "Temp-Sensor Client");&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pValues.SetUnsignedIntegerValue(&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ref PortableDevicePKeys.WPD_CLIENT_MAJOR_VERSION, 1);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pValues.SetUnsignedIntegerValue(&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ref PortableDevicePKeys.WPD_CLIENT_MINOR_VERSION, 0);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pValues.SetUnsignedIntegerValue(&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ref PortableDevicePKeys.WPD_CLIENT_REVISION, 2);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// We are now ready to open a connection to the device&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// We'll assume deviceID contains a valid WPD device path and connect to it&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pPortableDevice.Open(PnPDeviceID, pValues);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Retrieve and display the initial temperature&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strVal = RetrieveTemp(pPortableDevice, "Temperature");&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;iVal = Convert.ToInt32(strVal);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Enable the timer for UI&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;timer1.Interval = 3000;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;// 3 second intervals&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;timer1.Enabled = true;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;Retrieving the Temperature Property&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;You can retrieve a collection of readable properties for a WPD device by calling the &lt;b style=""&gt;IPortableDeviceProperties::GetValues&lt;/b&gt; method. This method takes a collection of property keys as input and returns a collection of property values as output. Once the WPD driver returns the collection of values, you can retrieve an individual property’s value by calling one of the &lt;b style=""&gt;Get&lt;/b&gt;xxx methods on the &lt;b style=""&gt;IPortableDeviceValues&lt;/b&gt; interface. In the case of the temperature property, we’ll call the &lt;b style=""&gt;IPortableDeviceValues::GetSignedIntegerValue&lt;/b&gt; method. And, when we call this method, we’ll pass the corresponding property key (TEMP_SENSOR_CURRENT_VALUE) which we’ve added to the file portabledeviceconstants.cs.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The new entry in portabledeviceconstants.cs has the following form:&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;namespace PortableDeviceConstants&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;class PortableDevicePKeys&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;static PortableDevicePKeys()&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;TEMP_SENSOR_READING.fmtid = new Guid(0xA7EF4367, 0x6550,&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0x4055, 0xB6, 0x6F, 0xBE, 0x6F, 0xDA, 0xCF, 0x4E, 0x9F);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;TEMP_SENSOR_READING.pid = 2;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The following helper function, &lt;b style=""&gt;RetrieveTemp&lt;/b&gt;, retrieves the temperature property from the temperature sensor device and returns that value in string form.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;string RetrieveTemp(&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;PortableDeviceApiLib.PortableDeviceClass pPortableDevice,&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string objectID)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string strTemp = String.Empty;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;// Receives current temp&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Retrieve IPortableDeviceContent interface required to&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// obtain the IPortableDeviceProperties interface&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.IPortableDeviceContent pContent;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pPortableDevice.Content(out pContent);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Retrieve IPortableDeviceProperties interface required&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// to get all the properties&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;PortableDeviceApiLib.IPortableDeviceProperties pProperties;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pContent.Properties(out pProperties);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Create a key collection&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.IPortableDeviceKeyCollection pKeyCollection =&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(PortableDeviceApiLib.IPortableDeviceKeyCollection)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;new PortableDeviceTypesLib.PortableDeviceKeyCollectionClass();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Add the TEMP_SENSOR_READING property to the key collection&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// This value is defined in PortableDeviceConstans.cs&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pKeyCollection.Add(ref PortableDevicePKeys.TEMP_SENSOR_READING);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Call the GetValues to retrieve the prop values for the given&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// key. Then, retrieve the TEMP_SENSOR_CURRENT_VALUE property&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// by calling the GetStringValue method.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PortableDeviceApiLib.IPortableDeviceValues pPropValues;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pProperties.GetValues(objectID, pKeyCollection, out pPropValues);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;int iTemp = 0;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pPropValues.GetSignedIntegerValue(ref PortableDevicePKeys.TEMP_SENSOR_READING, out iTemp);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (iTemp &amp;gt; 0)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return iTemp.ToString();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;else&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return "Invalid temperature!";&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;There are two approaches to retrieving the current temperature for the temperature-sensor device: an application can register to receive a temperature-update event from the device, or, it can retrieve the temperature value directly. This article focuses on the latter. In this article we’ve used an application-defined timer event to retrieve the temperature property.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The first step in enabling an application-defined timer event requires that you add a timer object to your application’s form. (You’ll find the timer in the Components section of the Visual Studio Toolbox when viewing your application’s form in Design mode.) &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Once you add the timer to your form, you can specify the interval at which the corresponding event will be fired, and you can enable the timer object. Both of these tasks were accomplished in the final lines of the &lt;b style=""&gt;StartProcessing&lt;/b&gt; method which was described previously in the Open a Connection to the Device section.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Enable the timer for UI&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;timer1.Interval = 3000;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;// 3 second intervals&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;timer1.Enabled = true;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;Each time the timer event fires, it calls the application’s &lt;b style=""&gt;Tick &lt;/b&gt;callback function. In our sample, the code for the &lt;b style=""&gt;timer1_Tick&lt;/b&gt; method retrieves the temperature from the device, converts it from degrees Kelvin to degrees Farenheit and then writes a string of HTML to disk. (The gadget script will read the contents of this file and use it to render the current temperature in the Sidebar.)&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;private void timer1_Tick(object sender, EventArgs e)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Use DateTime structure to retrieve timestamp&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DateTime dtNow = DateTime.Now;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Retrieve the temp prop&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strVal = RetrieveTemp(pPortableDevice, "Temperature");&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;iVal = KelvinToFarenheit(strVal);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Use the StreamWriter object for file I/O&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;StreamWriter sw = new StreamWriter("c:\\temp\\tempdata.txt");&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Write the data to the file&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;sw.WriteLine("&amp;lt;P&amp;gt;Office Temperature&amp;lt;P&amp;gt;" + Convert.ToString(iVal) + "&amp;amp;deg; Farenheit");&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Close the streamwriter object&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;sw.Close();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Update the Window text&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;this.Text = dtNow.Hour + ":" + dtNow.Minute + ":" + dtNow.Second + "&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;" + Convert.ToString(iVal) + "°";&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The following snippet contains the code for the &lt;b style=""&gt;KelvinToFarenheit&lt;/b&gt; method which converts the temperature value.&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;private int KelvinToFarenheit(string strTemp)&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;double dTemp = 0.0;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;int iVal = 0;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;dTemp = Convert.ToDouble(strTemp);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;iVal = (int)(((dTemp - 273.15) * 1.8) + 32);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return iVal;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;The Temperature-Sensor Gadget&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The temperature-sensor gadget displays the current office temperature in degrees Farenheit in the Windows Sidebar. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;If you’ve never created a gadget for Windows Sidebar before, you should refer to the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms723694.aspx" title="Gadget Development Overview" mce_href="http://msdn2.microsoft.com/en-us/library/ms723694.aspx"&gt;Gadget Development Overview&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;b&gt;&lt;span style=""&gt;&lt;font size="3"&gt;The Temperature-Sensor Gadget Files&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The temperature-sensor gadget consists of three files: an HTML file, an XML file, and a .jpg file. These files are described in the following table.&lt;/span&gt;&lt;/p&gt;

&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid windowtext; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;File Name&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext rgb(212, 208, 200); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;Description&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;UpdateTemperatureReading.htm&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;An HTML file that contains the script which retrieves the updated temperature data from the local disk every 3,000 milliseconds. &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;gadget.xml&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The gadget manifest. This file specifies properties such as the name of the gadget, the name of its HTML file, a string of descriptive text, and so on.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;

&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;background.jpg&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; background-color: transparent; width: 201.4pt;" valign="top" width="269"&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;A 163 x 58 pixel image that produces the gadget’s two-tone blue background color.&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;span style=""&gt;&lt;/span&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style="margin: 12pt 0in 8pt;"&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;font size="2"&gt;Retrieving the Current Temperature&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The gadget’s HTML file, UpdateTemperatureReading.htm, contains a script which opens the file created by the application (c:\temp\tempdata.txt) and copies the contents of this file into a span element identified as “temperature_data” within the body of the gadget’s HTML. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;This script creates a &lt;b style=""&gt;FileSystemObject&lt;/b&gt; which it uses to open and read the text file. It uses the &lt;b style=""&gt;OpenTextFile&lt;/b&gt; method to open the file and the &lt;b style=""&gt;ReadAll&lt;/b&gt; method to retrieve its contents. &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The script uses the &lt;b style=""&gt;setTimeout&lt;/b&gt; method on the &lt;b style=""&gt;window&lt;/b&gt; object to recursively execute the &lt;b style=""&gt;update&lt;/b&gt; function every 3,000 milliseconds. (This function contains the code that retrieves the contents of c:\temp\tempdata.txt.)&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;html&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;head&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;script&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;var fileSystemObject = null;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;function loaded()&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;fileSystemObject = new ActiveXObject("Scripting.FileSystemObject");&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;update();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;function update()&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;var textStream = fileSystemObject.OpenTextFile("c:\\temp\\tempdata.txt");&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;try&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;temperature_data.innerHTML = textStream.ReadAll();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;finally&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;textStream.Close();&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;window.setTimeout(update, 3000);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;/script&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;style&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;body &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{ &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;margin: 0;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;width: 125px;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;height: 62px;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;font: 'normal 8pt Arial';&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;line-height: 12pt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;text-align:center;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;/style&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;/head&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;body onload="loaded()"&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;g:background src="background.png"&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;span id="temperature_data"&amp;gt;&amp;lt;/span&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;/g:background&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;/body&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 0pt 0.25in;" class="Code"&gt;&lt;span style=""&gt;&lt;font face="Courier New"&gt;&amp;lt;/html&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;span style=""&gt;The HTML file &lt;/span&gt;also contains a description of the gadget’s window in the &amp;lt;style&amp;gt;&amp;lt;/style&amp;gt; tags that follow the script. Note that the width and height attributes match the width and height of the background image (background.png). In addition to specifying the size of the gadget’s window, the attributes found here specify the font used to render text, the line-height (which creates padding between the two lines of text), and the text alignment. &lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The &lt;b style=""&gt;g:background&lt;/b&gt; element specifies the source file (background.png) for the gadget’s background image. &lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;The &lt;b style=""&gt;span&lt;/b&gt; element “temperature_data” identifies the location of the HTML which is copied from c:\temp\tempdata.txt by the &lt;b style=""&gt;Update&lt;/b&gt; function.&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;o:p&gt;
&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/i&gt;&lt;/p&gt;

&lt;p style="margin: 0in 0in 8pt;" class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/o:p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6535616" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Driver Dev Guide: Client Context Management</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/06/06/driver-dev-guide-client-context-management.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/06/06/driver-dev-guide-client-context-management.aspx</id><published>2007-06-06T02:41:00Z</published><updated>2007-06-06T02:41:00Z</updated><content type="html">&lt;b&gt;Client Context Management in WPD Drivers&lt;/b&gt;
&lt;p&gt;A WPD driver provides the communication channel between applications and the physical device.&amp;nbsp;&amp;nbsp;&amp;nbsp;There&amp;nbsp;can be multiple WPD applications running&amp;nbsp;at any time, and the driver&amp;nbsp;needs to handle requests from different clients and identify the clients based on the queued requests.&amp;nbsp;&amp;nbsp; In other words, the driver needs an efficient and easy way to&amp;nbsp;store client data&amp;nbsp;on a per-connection basis, and retrieve the data per request.&amp;nbsp;&amp;nbsp;&amp;nbsp; Fortunately, UMDF supports &lt;b&gt;context areas&lt;/b&gt;, a generic&amp;nbsp;mechanism to save data with a framework object.&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/b&gt;A WPD driver can allocate a data structure or object to hold the data, assign it to the framework object's context area, and retrieve the context at a later time.&amp;nbsp; The appropriate per-connection WDF framework object to use is the WDF file object.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Step 1: Assigning the Context&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The driver assigns the context when the client opens a connection to it.&amp;nbsp;&amp;nbsp; When a WPD&amp;nbsp;application calls &lt;a href="http://msdn.microsoft.com/en-us/library/dd375690%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd375690(VS.85).aspx"&gt;IPortableDevice::Open&lt;/a&gt;, the WPD API creates a handle to the driver using Win32 &lt;b&gt;CreateFile&lt;/b&gt;.&amp;nbsp;&amp;nbsp; Under the hood, UMDF initializes an &lt;a href="http://msdn2.microsoft.com/en-us/library/aa511202.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511202.aspx"&gt;IWDFFile&lt;/a&gt; object and&amp;nbsp;forwards it, along with the Creation request, to the driver's&amp;nbsp;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa511424.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511424.aspx"&gt;IQueueCallbackCreate::OnCreateFile&lt;/a&gt;&amp;nbsp;method.&amp;nbsp;&amp;nbsp; The IWDFFile in this case represents&amp;nbsp;a Win32&amp;nbsp;HANDLE&amp;nbsp;that is used for subsequent communication from this client to the driver.&amp;nbsp;&amp;nbsp; &lt;/p&gt;

&lt;p&gt;A example of a CreateFile callback&amp;nbsp;implementation is WpdWudfSampleDriver's &lt;b&gt;CQueue::OnCreateFile&lt;/b&gt;.&amp;nbsp; A driver-specific&amp;nbsp;&lt;b&gt;ContextMap&lt;/b&gt; COM object is used to store client data (application name, version, in-progress enumeration and resource contexts, etc).&amp;nbsp;&amp;nbsp; Note that the use of COM objects as context data is&amp;nbsp;NOT required by UMDF -&amp;nbsp;UMDF&amp;nbsp;sees the&amp;nbsp;context data&amp;nbsp;as an opaque&amp;nbsp;PVOID.&amp;nbsp;&amp;nbsp; If you are&amp;nbsp;using a COM object for storing context data, your driver needs to maintain the reference count for that COM object, and ensure that its resources are freed in the appropriate cleanup methods.&lt;/p&gt;
&lt;p&gt;To save context data, the driver initializes a new ContextMap object, and calls&amp;nbsp;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa511074.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511074.aspx"&gt;IWDFObject::AssignContext&lt;/a&gt;&amp;nbsp;for&amp;nbsp;the IWDFFile object handed in by UMDF.&amp;nbsp; &amp;nbsp; The parameters&amp;nbsp;for AssignContext are the pointers to an &lt;a href="http://msdn2.microsoft.com/en-us/library/aa511214.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511214.aspx"&gt;IObjectCleanup&lt;/a&gt;&amp;nbsp;object [containing the context cleanup code], and the newly-created ContextMap [containing the data to store].&amp;nbsp;&amp;nbsp; &lt;a href="http://msdn2.microsoft.com/en-us/library/aa511068.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511068.aspx"&gt;IObjectCleanup::OnCleanup&lt;/a&gt; will be called when the file object is destroyed during CloseHandle.&amp;nbsp;&amp;nbsp; See "Step 3" for further details on how to implement OnCleanup.&amp;nbsp;&amp;nbsp; &lt;/p&gt;

&lt;p&gt;In addition, only one context can be assigned to the file object (or any&amp;nbsp;UMDF&amp;nbsp;framework object).&amp;nbsp;&amp;nbsp;Subsequent calls to AssignContext will fail if a context has already been assigned.&amp;nbsp;&amp;nbsp; To add/remove&amp;nbsp;client-specific data dynamically,&amp;nbsp;one way is to implement a mapping object for managing the data (e.g.&amp;nbsp;WpdWudfSampleDriver's ContextMap object), and assign a pointer to that mapping object as file object's context.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Step 2: Retrieving and Saving Context Information&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;To access the client data during requests, the WPD driver gets the context from the&amp;nbsp;IWDFFile object. &amp;nbsp;&lt;/p&gt;

&lt;p&gt;The sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call &lt;a href="http://msdn2.microsoft.com/en-us/library/aa511217.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511217.aspx"&gt;IWDFIoRequest::GetFileObject&lt;/a&gt; to get the IWDFFile object. 
&lt;/li&gt;
&lt;li&gt;Call &lt;a href="http://msdn2.microsoft.com/en-us/library/aa511428.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511428.aspx"&gt;IWDFObject::RetrieveContext&lt;/a&gt;&amp;nbsp;on the IWDFFile object to access the context area.&amp;nbsp;&amp;nbsp; In the sample driver, this&amp;nbsp;will be&amp;nbsp;the pointer to the&amp;nbsp;ContextMap object that was created in CQueue::OnCreateFile during IPortableDevice::Open. 
&lt;/li&gt;
&lt;li&gt;Add/remove data to the ContextMap object directly when processing the WPD commands.&amp;nbsp; Each client connection (i.e. IPortableDevice::Open) will have its own IWDFFile object and ContextMap object.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
Example code from WpdWudfSampleDriver:&amp;nbsp; 
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CQueue::OnDeviceIoControl &lt;/b&gt;- Retrieving the context map from the&amp;nbsp;WDF request's file object 
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;WpdBaseDriver::OnSaveClientInfo&lt;/b&gt; - Adding client information to the context&amp;nbsp;map when processing the&amp;nbsp;WPD_COMMAND_COMMON_SAVE_CLIENT_INFORMATION command&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Step 3: Cleaning up the Context&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;When the client application calls &lt;a href="http://msdn.microsoft.com/en-us/library/dd375687%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd375687(VS.85).aspx"&gt;IPortableDevice::Close&lt;/a&gt;, the WPD API will in turn call CloseHandle on the Win32 handle associated with that open connection.&amp;nbsp;&amp;nbsp; Before destroying the&amp;nbsp;IWDFFile object in response to the CloseHandle,&amp;nbsp;UMDF calls the file object's &lt;b&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa511068.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa511068.aspx"&gt;IObjectCleanup::OnCleanup&lt;/a&gt;&lt;/b&gt; method that the driver passed into AssignContext during OnCreateFile.&lt;/p&gt;

&lt;p&gt;An example implementation of the IQueueCleanup callback is WpdWudfSampleDriver's &lt;b&gt;CQueue::OnCleanup&lt;/b&gt;.&amp;nbsp;&amp;nbsp; This method retrieves the&amp;nbsp;ContextMap stored in the IWDFObject object&amp;nbsp;(in this case,&amp;nbsp;the instance of&amp;nbsp;IWDFFile from OnCreateFile) and frees the allocated memory, including the objects that the ContextMap holds.&amp;nbsp;&amp;nbsp; To avoid memory leaks, ensure that the objects are properly cleaned up, and (if applicable) decrement the reference count.&lt;br&gt;&lt;/p&gt;

&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;A great WDF book is &lt;a href="http://www.microsoft.com/whdc/driver/wdf/wdfbook.mspx" mce_href="http://www.microsoft.com/whdc/driver/wdf/wdfbook.mspx"&gt;Developing Drivers with WDF&lt;/a&gt;&amp;nbsp;by Orwick/Smith.&amp;nbsp;Chapter 5 (pages 124-125) covers techniques for object-specific context data storage using UMDF.&amp;nbsp;&amp;nbsp;&amp;nbsp; The WpdWudfSampleDriver sample code is available in the Windows Driver Kit.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;&lt;/i&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3105948" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /></entry><entry><title>Which version of the WDK do I download?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/05/16/which-version-of-the-wdk-do-i-download.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/05/16/which-version-of-the-wdk-do-i-download.aspx</id><published>2007-05-16T22:24:00Z</published><updated>2007-05-16T22:24:00Z</updated><content type="html">&lt;P&gt;&lt;STRONG&gt;To develop&amp;nbsp;WPD&amp;nbsp;drivers for Vista SP1:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;-&amp;nbsp;Build them using the Vista WDK (version 6000) or from the Longhorn Server Beta 3 WDK build environments.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;-&amp;nbsp;WPD drivers built using Longhorn Server WDK Beta 3 will &lt;STRONG&gt;not run&lt;/STRONG&gt; on Vista RTM or Windows XP, this is because the version 1.7&amp;nbsp;WDF Co-installer shipped in the Beta 3 release does not support downlevel operating systems (Vista RTM, XP, Server 2003).&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;To develop WPD drivers for Vista RTM:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;-&amp;nbsp;Build&amp;nbsp;them from the Vista WDK (version 6000)&amp;nbsp;&lt;/P&gt;
&lt;P&gt;- The drivers can run on Windows XP with &lt;A class="" title="Installing the Sample Drivers on XP and Vista" href="http://blogs.msdn.com/wpdblog/archive/2007/04/03/installing-the-sample-drivers-on-xp-and-vista.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/04/03/installing-the-sample-drivers-on-xp-and-vista.aspx"&gt;INF changes&lt;/A&gt;&amp;nbsp;and Windows Media Player 11 or Format SDK&amp;nbsp;Redistributable 11&amp;nbsp;installed&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/EM&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2678855" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /></entry><entry><title>Getting a WPD Sample Driver working with Windows Media Player 11</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/05/08/getting-a-wpd-sample-driver-working-with-windows-media-player-11.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/05/08/getting-a-wpd-sample-driver-working-with-windows-media-player-11.aspx</id><published>2007-05-08T22:25:00Z</published><updated>2007-05-08T22:25:00Z</updated><content type="html">&lt;p&gt;We mentioned in a &lt;a href="http://blogs.msdn.com/wpdblog/archive/2007/01/31/building-driver-samples-from-the-wdk.aspx" class="" title="Building WPD Driver Samples from the WDK" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/01/31/building-driver-samples-from-the-wdk.aspx"&gt;previous post&lt;/a&gt;&amp;nbsp;that the WPD sample drivers are not designed to enumerate in Windows Media Player 11 (WMP11) due to compatibility issues.&amp;nbsp;&amp;nbsp; This post covers the changes needed to enable the WPD Comprehensive Sample Driver (WpdWudfSampleDriver) to&amp;nbsp;appear&amp;nbsp;as a&amp;nbsp;portable device in WMP11 and simulate a sync.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The WpdWudfSampleDriver is featured in this post because it contains a lot more functionality than the WpdHelloWorldDriver,&amp;nbsp;and is closer to meeting the requirements of WMP11 than the WpdHelloWorldDriver.&amp;nbsp;&amp;nbsp;&amp;nbsp; More specifically, the WpdWudfSampleDriver &lt;b&gt;simulates&lt;/b&gt; the following additional functionality:&lt;/p&gt;
&lt;p&gt;1. Creating and transferring data objects on the device.&lt;/p&gt;
&lt;p&gt;2. &lt;a href="http://msdn.microsoft.com/en-us/library/dd435167.aspx" title="Rendering Information" mce_href="http://msdn.microsoft.com/en-us/library/dd435167.aspx"&gt;Rendering information&lt;/a&gt; profiles for creating content to the device.&lt;/p&gt;
&lt;p&gt;3. Setting properties on objects.&lt;/p&gt;
&lt;p&gt;4. &lt;a href="http://blogs.msdn.com/wpdblog/archive/2007/03/16/how-to-post-events-from-your-wpd-driver.aspx" class="" title="Posting Events from a WPD Driver" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/03/16/how-to-post-events-from-your-wpd-driver.aspx"&gt;Posting device events&lt;/a&gt;.&lt;/p&gt;
&lt;p mce_keep="true"&gt;5. &lt;a href="http://msdn.microsoft.com/en-us/library/dd419971.aspx" title="An example of a Bulk Property Operation" mce_href="http://msdn.microsoft.com/en-us/library/dd419971.aspx"&gt;Bulk property operations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the list above, items 1-3&amp;nbsp;provide basic&amp;nbsp;compatibility with WMP11.&amp;nbsp; Device events&amp;nbsp;are a "good to have" feature,&amp;nbsp;for application responsiveness to changes in the device content and device state.&amp;nbsp; Bulk property operations are optional, but also provide improved application responsiveness -&amp;nbsp;multiple properties for objects can be sent in batches, instead of&amp;nbsp;multiple per-object "GetProperty" requests.&lt;/p&gt;
&lt;p&gt;During sync, the WpdWudfSampleDriver simulates&amp;nbsp;file and folder creation&amp;nbsp;by allowing content to be created and transferred to the device.&amp;nbsp;&amp;nbsp; The data&amp;nbsp;is not persisted by the driver, and will exist as long as the sample driver is still loaded.&amp;nbsp;&amp;nbsp;&amp;nbsp;Once the driver is disconnected (e.g. disable in Device Manager), the data goes away.&amp;nbsp;&amp;nbsp; Typically, your WPD driver&amp;nbsp;would be sending this data to your physical device and persisting it there, so this should not be an issue for real devices.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;Modifications to the WpdWudfSampleDriver to Enumerate and Sync in WMP11&lt;/b&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;Some of the changes below involve updating the fake contents on the device for illustration.&amp;nbsp;&amp;nbsp;&amp;nbsp;The same property requirements will apply for&amp;nbsp;your&amp;nbsp;own&amp;nbsp;driver or device objects.&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p mce_keep="true"&gt;1.&amp;nbsp; Add WPD_DEVICE_SYNC_PARTNER as a writable property for the "Device" object.&amp;nbsp;&amp;nbsp; This is needed by WMP11 for setting up a sync partnership&amp;nbsp;with the device.&amp;nbsp;&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;In deviceobjectfakecontent.h:&lt;br&gt;&lt;br&gt;class DeviceObjectFakeContent : public FakeContent&lt;br&gt;{&lt;br&gt;  ...&lt;br&gt;&lt;br&gt;    virtual HRESULT GetAllValues(&lt;br&gt;        IPortableDeviceValues*  pValues)&lt;br&gt;    {&lt;br&gt;	...&lt;br&gt;        // Add WPD_DEVICE_SYNC_PARTNER&lt;br&gt;        hrSetValue = pValues-&amp;gt;SetStringValue(WPD_DEVICE_SYNC_PARTNER, SyncPartner);&lt;br&gt;        if (hrSetValue != S_OK)&lt;br&gt;        {&lt;br&gt;            CHECK_HR(hrSetValue, "Failed to set WPD_DEVICE_SYNC_PARTNER");&lt;br&gt;            return hrSetValue;&lt;br&gt;        }&lt;br&gt;        ...&lt;br&gt;    }	&lt;br&gt;&lt;br&gt;    virtual HRESULT WriteValue(&lt;br&gt;        const PROPERTYKEY&amp;amp; key,&lt;br&gt;        const PROPVARIANT&amp;amp; Value)&lt;br&gt;    {&lt;br&gt;        ...&lt;br&gt;        else if(IsEqualPropertyKey(key, WPD_DEVICE_SYNC_PARTNER))&lt;br&gt;        {&lt;br&gt;            if (Value.vt == VT_LPWSTR)&lt;br&gt;            {&lt;br&gt;               SyncPartner = Value.pwszVal;&lt;br&gt;            }&lt;br&gt;            else&lt;br&gt;            {&lt;br&gt;                hr = E_INVALIDARG;&lt;br&gt;                CHECK_HR(hr, "Failed to set WPD_DEVICE_SYNC_PARTNER because type was not VT_LPWSTR");&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;	...&lt;br&gt;    }&lt;br&gt;   ...&lt;br&gt;&lt;br&gt;private:&lt;br&gt;    ...&lt;br&gt;    CAtlStringW SyncPartner;&lt;br&gt;};&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;2. Add WPD_OBJECT_NON_CONSUMABLE as a writable property for all objects.&amp;nbsp;&amp;nbsp; This allows simulating the saving of sync settings into a&amp;nbsp;file on the device called&amp;nbsp;WMPInfo.xml.&amp;nbsp;&amp;nbsp; This file is created by WMP11 on the device and&amp;nbsp;marked as "Non Consumable," with Format = WPD_OBJECT_FORMAT_UNSPECIFIED and Content Type =&amp;nbsp;WPD_CONTENT_TYPE_UNSPECIFIED.&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;In fakecontent.h:&lt;br&gt;&lt;br&gt;class FakeContent&lt;br&gt;{&lt;br&gt;&lt;br&gt;    virtual HRESULT WriteValue(&lt;br&gt;        const PROPERTYKEY&amp;amp; key,&lt;br&gt;        const PROPVARIANT&amp;amp; Value)&lt;br&gt;    {&lt;br&gt;        ...&lt;br&gt;        else if (IsEqualPropertyKey(key, WPD_OBJECT_NON_CONSUMABLE))&lt;br&gt;        {&lt;br&gt;            if(Value.vt == VT_BOOL)&lt;br&gt;            {&lt;br&gt;                NonConsumable = Value.boolVal;&lt;br&gt;            }&lt;br&gt;            else&lt;br&gt;            {&lt;br&gt;                hr = E_INVALIDARG;&lt;br&gt;                CHECK_HR(hr, "Failed to set WPD_OBJECT_NON_CONSUMABLE because type was not VT_BOOL");&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;        ...&lt;br&gt;    }&lt;br&gt;   ...&lt;br&gt;};&lt;br&gt;&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;3. Add&amp;nbsp;support for WPD_OBJECT_ORIGINAL_FILE_NAME in for all objects.&amp;nbsp; This involves updating the support properties and fixed attributes tables, and overriding FakeGenericFileContent::GetAllValues() to return this property in addition to the standard properties.&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;In helpers.cpp:&lt;br&gt;&lt;br&gt;const PROPERTYKEY* g_SupportedPropertiesForFakeContentFormat[] =&lt;br&gt;{&lt;br&gt;    ...&lt;br&gt;    &amp;amp;WPD_OBJECT_ORIGINAL_FILE_NAME,&lt;br&gt;    ...&lt;br&gt;};&lt;br&gt;&lt;br&gt;KeyAndAttributesEntry g_FixedAttributesTable [] =&lt;br&gt;{     &lt;br&gt;    ...&lt;br&gt;    {&amp;amp;FakeContent_Format, &amp;amp;WPD_OBJECT_ORIGINAL_FILE_NAME, &lt;br&gt;         UnspecifiedForm_CanRead_CannotWrite_CannotDelete_Fast},&lt;br&gt;    // Properties for the device object&lt;br&gt;    ...&lt;br&gt;}&lt;br&gt;&lt;br&gt;In fakecontent.h:&lt;br&gt;&lt;br&gt;class FakeGenericFileContent : public FakeContent&lt;br&gt;{&lt;br&gt;public:&lt;br&gt;&lt;br&gt;    virtual HRESULT GetAllValues(&lt;br&gt;        IPortableDeviceValues*  pStore)&lt;br&gt;    {&lt;br&gt;        HRESULT             hr          = S_OK;&lt;br&gt;        PropVariantWrapper  pvValue;&lt;br&gt;&lt;br&gt;        // Call the base class to fill in the standard properties&lt;br&gt;        hr = FakeContent::GetAllValues(pStore);&lt;br&gt;        if (FAILED(hr))&lt;br&gt;        {&lt;br&gt;            CHECK_HR(hr, "Failed to get basic property set");&lt;br&gt;            return hr;&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        // Add WPD_OBJECT_ORIGINAL_FILE_NAME&lt;br&gt;        pvValue = FileName;&lt;br&gt;        hr = pStore-&amp;gt;SetValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &amp;amp;pvValue);&lt;br&gt;        if (hr != S_OK)&lt;br&gt;        {&lt;br&gt;            CHECK_HR(hr, ("Failed to set WPD_OBJECT_ORIGINAL_FILE_NAME"));&lt;br&gt;            return hr;&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        return hr;&lt;br&gt;    }&lt;br&gt;    ...&lt;br&gt;};&lt;br&gt;&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;4. Add support for creation of folders.&amp;nbsp;&amp;nbsp; These folders need to support WPD_OBJECT_ORIGINAL_FILE_NAME.&amp;nbsp;&amp;nbsp;&amp;nbsp; This allows WMP11 to create the "Album", "Artist" folders on the device during the sync operation.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;One way to do this is to&amp;nbsp;define a new &lt;b&gt;FakeFolderContent &lt;/b&gt;class that inherits from &lt;b&gt;FakeContent&lt;/b&gt;, and return WPD_OBJECT_ORIGINAL_FILE_NAME in &lt;b&gt;FakeFolderContent::GetAllValues()&lt;/b&gt;.&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;Added new header file: fakefoldercontent.h&lt;br&gt;&lt;br&gt;class FakeFolderContent : public FakeContent&lt;br&gt;{&lt;br&gt;public:&lt;br&gt;    ...&lt;br&gt;&lt;br&gt;    virtual HRESULT GetAllValues(&lt;br&gt;        IPortableDeviceValues*  pStore)&lt;br&gt;    {&lt;br&gt;        HRESULT             hr          = S_OK;&lt;br&gt;        PropVariantWrapper  pvValue;&lt;br&gt;&lt;br&gt;        // Call the base class to fill in the standard properties&lt;br&gt;        hr = FakeContent::GetAllValues(pStore);&lt;br&gt;        if (FAILED(hr))&lt;br&gt;        {&lt;br&gt;            CHECK_HR(hr, "Failed to get basic property set");&lt;br&gt;            return hr;&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        // Add WPD_OBJECT_ORIGINAL_FILE_NAME&lt;br&gt;        pvValue = FileName;&lt;br&gt;        hr = pStore-&amp;gt;SetValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &amp;amp;pvValue);&lt;br&gt;        if (hr != S_OK)&lt;br&gt;        {&lt;br&gt;            CHECK_HR(hr, ("Failed to set WPD_OBJECT_ORIGINAL_FILE_NAME"));&lt;br&gt;            return hr;&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        return hr;&lt;br&gt;    }&lt;br&gt;};&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;All top level folders (e.g. Video Folder, Music Folder) in the sample driver can then initialize a &lt;b&gt;FakeFolderContent &lt;/b&gt;instead of a &lt;b&gt;FakeContent&lt;/b&gt;.&amp;nbsp;&amp;nbsp;&amp;nbsp; The value of WPD_OBJECT_ORIGINAL_FILE_NAME is usually the same as WPD_OBJECT_NAME.&amp;nbsp; Assign&amp;nbsp;the value of FileName in &lt;b&gt;FakeDevice::CreateContentObject() &lt;/b&gt;whenever an object is created, so that it will be returned during subsequent "Get Property" queries.&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;In fakedevice.h:&lt;br&gt;&lt;br&gt;class FakeDevice&lt;br&gt;{&lt;br&gt;    ...   &lt;br&gt;    HRESULT InitializeContent(&lt;br&gt;        IPortableDeviceClassExtension *pPortableDeviceClassExtension)&lt;br&gt;    {&lt;br&gt;        ...&lt;br&gt;        &lt;br&gt;        // Add Media folder: Music folder&lt;br&gt;        pContent = new FakeFolderContent();&lt;br&gt;        if (pContent)&lt;br&gt;        {&lt;br&gt;            ...&lt;br&gt;            pContent-&amp;gt;FileName  = pContent-&amp;gt;Name;  // Set Original File Name property&lt;br&gt;            ...&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        // Repeat for other types of folders declared here&lt;br&gt;        ...&lt;br&gt;&lt;br&gt;        // Add generic file content objects to storage 1&lt;br&gt;        for(DWORD dwIndex = 0; dwIndex &amp;lt; NUM_VERTICAL_OBJECTS; dwIndex++)&lt;br&gt;        {&lt;br&gt;            m_dwLastObjectID++;&lt;br&gt;&lt;br&gt;            pContent = new FakeGenericFileContent();&lt;br&gt;            if (pContent)&lt;br&gt;            {&lt;br&gt;                ...&lt;br&gt;                pContent-&amp;gt;FileName = pContent-&amp;gt;Name;&lt;br&gt;                ...&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;        ...&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    HRESULT CreateContentObject(&lt;br&gt;        LPCWSTR                 pszObjectName,&lt;br&gt;        LPCWSTR                 pszParentID,&lt;br&gt;        REFGUID                 guidContentType,&lt;br&gt;        IPortableDeviceValues*  pObjectProperties,&lt;br&gt;        FakeContent**           ppContent)&lt;br&gt;    {&lt;br&gt;        ...&lt;br&gt;        if(guidContentType == WPD_CONTENT_TYPE_FOLDER)&lt;br&gt;        {&lt;br&gt;            FakeContent* pContent = NULL;&lt;br&gt;&lt;br&gt;            pContent = new FakeContent();&lt;br&gt;            if (pContent)&lt;br&gt;            {&lt;br&gt;                ...&lt;br&gt;                pContent-&amp;gt;FileName = pszObjectName;&lt;br&gt;                ...&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;   }&lt;br&gt;   ...&lt;br&gt;}; &lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;5.&amp;nbsp; Modify WpdWudfSampleDriver.INF to set &lt;b&gt;EnableLegacySupport &lt;/b&gt;to&lt;b&gt; 3 &lt;/b&gt;so that the WMDM compatibility&amp;nbsp;component is registered and enabled&amp;nbsp;for this device when it installs.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;; Enable support for legacy WIA and WMDM applications&lt;br&gt;HKR,,"EnableLegacySupport",0x10001,3&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;6. When returning the list of rendering information profiles in &lt;b&gt;SetRenderingProfiles()&lt;/b&gt;, return an additional profile for WPD_OBJECT_FORMAT_WMV.&amp;nbsp; This profile contains a single WPD_PROPERTY_ATTRIBUTE_FORM_ENUMERATION entry with an IPortableDevicePropVariantCollection containing the list of valid FourCC Codec VT_UI4 values.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p mce_keep="true"&gt;This step is needed&amp;nbsp;because the sample driver reports support for WMV.&amp;nbsp;&amp;nbsp; &amp;nbsp;In your real driver implementation, you don't need this step unless your device needs to support WPD_OBJECT_FORMAT_WMV.&amp;nbsp;&amp;nbsp; WMP11 has additional requirements on the attributes of FourCC Codec property, and would not enumerate any content on the device otherwise [Symptom: you will see the device in the Sync Pane, but no content under the device].&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;In helpers.cpp:&lt;br&gt;&lt;br&gt;HRESULT GetVideoProfile(&lt;br&gt;    IPortableDeviceValues** ppProfile)&lt;br&gt;{&lt;br&gt;    HRESULT hr = S_OK;&lt;br&gt;    CComPtr&amp;lt;IPortableDeviceValues&amp;gt; pProfile;&lt;br&gt;    CComPtr&amp;lt;IPortableDeviceValues&amp;gt; pFourCCCode;&lt;br&gt;&lt;br&gt;    hr = CoCreateInstance(CLSID_PortableDeviceValues,&lt;br&gt;                          NULL,&lt;br&gt;                          CLSCTX_INPROC_SERVER,&lt;br&gt;                          IID_IPortableDeviceValues,&lt;br&gt;                          (VOID**) &amp;amp;pProfile);&lt;br&gt;    CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValues");&lt;br&gt;&lt;br&gt;    if (hr == S_OK)&lt;br&gt;    {&lt;br&gt;        hr = CoCreateInstance(CLSID_PortableDeviceValues,&lt;br&gt;                              NULL,&lt;br&gt;                              CLSCTX_INPROC_SERVER,&lt;br&gt;                              IID_IPortableDeviceValues,&lt;br&gt;                              (VOID**) &amp;amp;pFourCCCode);&lt;br&gt;        CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValues");&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    // Set the value for WPD_OBJECT_FORMAT to indicate this profile applies to WMV objects&lt;br&gt;    if (hr == S_OK)&lt;br&gt;    {&lt;br&gt;        hr = pProfile-&amp;gt;SetGuidValue(WPD_OBJECT_FORMAT, WPD_OBJECT_FORMAT_WMV);&lt;br&gt;        CHECK_HR(hr, "Failed to set WPD_OBJECT_FORMAT");&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    // Set the value for WPD_VIDEO_FOURCC_CODE&lt;br&gt;    if (hr == S_OK)&lt;br&gt;    {&lt;br&gt;        CComPtr&amp;lt;IPortableDevicePropVariantCollection&amp;gt; pFourCCCodeEnumElements;&lt;br&gt;&lt;br&gt;        if (hr == S_OK)&lt;br&gt;        {&lt;br&gt;            hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,&lt;br&gt;                                  NULL,&lt;br&gt;                                  CLSCTX_INPROC_SERVER,&lt;br&gt;                                  IID_IPortableDevicePropVariantCollection,&lt;br&gt;                                  (VOID**) &amp;amp;pFourCCCodeEnumElements);&lt;br&gt;            CHECK_HR(hr, "Failed to CoCreateInstance &lt;br&gt;                     CLSID_PortableDevicePropVariantCollection");&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        if (hr == S_OK)&lt;br&gt;        {&lt;br&gt;            hr = pFourCCCode-&amp;gt;SetUnsignedIntegerValue(&lt;br&gt;                                 WPD_PROPERTY_ATTRIBUTE_FORM, &lt;br&gt;                                 WPD_PROPERTY_ATTRIBUTE_FORM_ENUMERATION);&lt;br&gt;            CHECK_HR(hr, "Failed to set WPD_PROPERTY_ATTRIBUTE_FORM &lt;br&gt;                          for WPD_VIDEO_FOURCC_CODE");&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        if (hr == S_OK)&lt;br&gt;        {&lt;br&gt;            // Only 1 sample value is set here, add more as appropriate for your device&lt;br&gt;            PROPVARIANT pvValue;&lt;br&gt;            PropVariantInit(&amp;amp;pvValue);&lt;br&gt;            pvValue.vt = VT_UI4;&lt;br&gt;            pvValue.ulVal = MAKEFOURCC('W', 'M', 'V', '3');&lt;br&gt;            hr = pFourCCCodeEnumElements-&amp;gt;Add(&amp;amp;pvValue);&lt;br&gt;            CHECK_HR(hr, "Failed to populate the FourCC Code Enumeration Elements");&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        if (hr == S_OK)&lt;br&gt;        {&lt;br&gt;            hr = pFourCCCode-&amp;gt;SetIPortableDevicePropVariantCollectionValue(&lt;br&gt;                                 WPD_PROPERTY_ATTRIBUTE_ENUMERATION_ELEMENTS, &lt;br&gt;                                 pFourCCCodeEnumElements);&lt;br&gt;            CHECK_HR(hr, "Failed to set WPD_PROPERTY_ATTRIBUTE_ENUMERATION_ELEMENTS &lt;br&gt;                          for WPD_VIDEO_FOURCC_CODE");&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        // Now set the Video FourCC Code property to be pFourCCCode&lt;br&gt;        if (hr == S_OK)&lt;br&gt;        {&lt;br&gt;            hr = pProfile-&amp;gt;SetIPortableDeviceValuesValue(&lt;br&gt;                              WPD_VIDEO_FOURCC_CODE, &lt;br&gt;                              pFourCCCode);&lt;br&gt;            CHECK_HR(hr, "Failed to add the WPD_VIDEO_FOURCC_CODE attributes &lt;br&gt;                          to the WPD_OBJECT_FORMAT_WMV rendering profile");&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    // Set the output result&lt;br&gt;    if (hr == S_OK)&lt;br&gt;    {&lt;br&gt;        hr = pProfile-&amp;gt;QueryInterface(IID_PPV_ARGS(ppProfile));&lt;br&gt;        CHECK_HR(hr, "Failed to QI for IPortableDeviceValues");&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    return hr;&lt;br&gt;}&lt;br&gt;&lt;br&gt;HRESULT SetRenderingProfiles(&lt;br&gt;    IPortableDeviceValues*          pValues)&lt;br&gt;{&lt;br&gt;    ...&lt;br&gt;    CComPtr&amp;lt;IPortableDeviceValues&amp;gt;  pVideoProfile;&lt;br&gt;    ...&lt;br&gt;&lt;br&gt;    // Get the video profile&lt;br&gt;    if (hr == S_OK)&lt;br&gt;    {&lt;br&gt;        hr = GetVideoProfile(&amp;amp;pVideoProfile);&lt;br&gt;        CHECK_HR(hr, "Failed to get video profile properties");&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    // Add the profile to the collection&lt;br&gt;    if (hr == S_OK)&lt;br&gt;    {&lt;br&gt;        hr = pProfiles-&amp;gt;Add(pVideoProfile);&lt;br&gt;        CHECK_HR(hr, "Failed to add video profile to profile collection");&lt;br&gt;    }&lt;br&gt;    ...&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;

&lt;p&gt;&lt;b&gt;Known Issue with Multiple Storages&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;When a device that contains multiple storages&amp;nbsp;is disconnected, one of the storages will still remain in the treeview.&amp;nbsp;&amp;nbsp; This is a known bug in WMP11.&amp;nbsp;&amp;nbsp; Since the WpdWudfSampleDriver emulates multiple storages, you'll see this bug when you disable the driver from Device Manager while WMP11 is running.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;&lt;p mce_keep="true"&gt;&lt;b&gt;Update [August 7, 2009]:&amp;nbsp;&lt;/b&gt; The WDK 7.0.0 now contains 
an updated &lt;b&gt;WpdWudfSampleDriver&lt;/b&gt; sample that supports enumeration in 
Windows Media Player. You can get the latest WDK &lt;a href="http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx" mce_href="http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx"&gt;here&lt;/a&gt;. See &lt;a href="http://www.microsoft.com/whdc/devtools/wdk/RelNotesW7.mspx#EHJAE" mce_href="http://www.microsoft.com/whdc/devtools/wdk/RelNotesW7.mspx#EHJAE"&gt;this 
WDK 7.0.0 RTM release note&lt;/a&gt; for the complete list of build environments and 
target operating systems applicable to the WPD driver samples. &lt;br&gt;&lt;/p&gt;

&lt;p mce_keep="true"&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2485116" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /><category term="WMDM" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WMDM/" /></entry><entry><title>New Driver and Application Whitepapers Are Here</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/05/07/wpd-whitepapers.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/05/07/wpd-whitepapers.aspx</id><published>2007-05-07T21:51:00Z</published><updated>2007-05-07T21:51:00Z</updated><content type="html">&lt;P&gt;We've published two new WPD developer-centric&amp;nbsp;whitepapers at the Microsoft WHDC website for WinHEC.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The first&amp;nbsp;covers how to do WMDRM metering and license synchronization from a WPD application; the second&amp;nbsp;describes how to port the existing WPD "Hello World" sample driver to communicate with a Parallax Basic Stamp II microcontroller to&amp;nbsp;read temperature sensor data.&amp;nbsp;&amp;nbsp; Both contain sample code.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;I. Accessing WMDRM APIs from a WPD Application:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.microsoft.com/whdc/device/media/WMDRM_API.mspx" mce_href="http://www.microsoft.com/whdc/device/media/WMDRM_API.mspx"&gt;http://www.microsoft.com/whdc/device/media/WMDRM_API.mspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;This whitepaper describes how to associate a WPD device instance with a WMDM device instance for MTP devices; the WMDM device instance is then&amp;nbsp;used&amp;nbsp;for calling Windows Media Digital Rights Management (WMDRM) application interfaces. To&amp;nbsp;build the sample WPD application, you need the Windows Media Format SDK v11 and the Windows SDK (v6000).&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;II. Creating a WPD Driver for a Microcontroller-Based Sensor:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx" mce_href="http://www.microsoft.com/whdc/device/media/WPD_drv.mspx"&gt;http://www.microsoft.com/whdc/device/media/WPD_drv.mspx&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;This sample is based on the Parallax Basic Stamp II microcontroller to provide an example of a simple hardware device that&amp;nbsp;can have a WPD driver for it.&amp;nbsp;&amp;nbsp; Parallax provides an &lt;A class="" title="Basic Stamp Activity Kit for Windows Portable Devices" href="http://www.parallax.com/detail.asp?product_id=910-90005" mce_href="http://www.parallax.com/detail.asp?product_id=910-90005"&gt;activity kit&lt;/A&gt; that contains the hardware components for this sample&amp;nbsp;driver.&amp;nbsp; To&amp;nbsp;build the driver,&amp;nbsp;you need the&amp;nbsp;Windows Driver Kit&amp;nbsp;(v6000).&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;References&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;All WPD-related whitepapers are posted &lt;A class="" title="Windows Portable Devices Whitepapers" href="http://www.microsoft.com/whdc/device/netAttach/default.mspx" mce_href="http://www.microsoft.com/whdc/device/netAttach/default.mspx"&gt;here&lt;/A&gt;.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A class="" title="Downloading WPD for Development" href="http://blogs.msdn.com/controlpanel/blogs/To%20download%20the%20pre-requisities,%20see%20http://blogs.msdn.com/wpdblog/pages/downloading-wpd-for-development.aspx" mce_href="To download the pre-requisities, see http://blogs.msdn.com/wpdblog/pages/downloading-wpd-for-development.aspx"&gt;More information&lt;/A&gt; on downloading the various SDKs.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;EM&gt;&lt;/EM&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/EM&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2466855" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="SDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/SDK/" /><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /><category term="WMDM" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WMDM/" /><category term="DRM" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/DRM/" /></entry><entry><title>Driver Dev Guide:  Supporting WPD_CLIENT_EVENT_COOKIE</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/05/04/driver-dev-guide-sending-wpd-client-event-cookie-with-events.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/05/04/driver-dev-guide-sending-wpd-client-event-cookie-with-events.aspx</id><published>2007-05-04T03:13:00Z</published><updated>2007-05-04T03:13:00Z</updated><content type="html">&lt;p mce_keep="true"&gt;WPD Applications&amp;nbsp;can specify&amp;nbsp;a unique&amp;nbsp;string "cookie"&amp;nbsp;in the client information when calling &lt;a href="http://msdn.microsoft.com/en-us/library/dd375690%28VS.85%29.aspx" title="IPortableDevice::Open" mce_href="http://msdn.microsoft.com/en-us/library/dd375690(VS.85).aspx"&gt;IPortableDevice::Open&lt;/a&gt;:&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;table rules="rows" border="0" cols="3" frame="below"&gt;
&lt;tbody&gt;
&lt;tr valign="top"&gt;
&lt;td width="28%"&gt;&lt;b&gt;WPD_CLIENT_EVENT_COOKIE&lt;/b&gt;&lt;/td&gt;
&lt;td width="29%"&gt;VT_LPWSTR&lt;/td&gt;
&lt;td width="43%"&gt;Client supplied cookie returned by the driver in events posted as a direct result of operations issued by this client.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&amp;nbsp; 
&lt;p mce_keep="true"&gt;This is in addition&lt;b&gt; &lt;/b&gt;to the&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/dd419935.aspx" title="WPD Client Information Properties" mce_href="http://msdn.microsoft.com/en-us/library/dd419935.aspx"&gt;client information&amp;nbsp;properties&lt;/a&gt; described&amp;nbsp;on MSDN, and declared in &lt;b&gt;PortableDevice.h&lt;/b&gt;.&lt;/p&gt;
&lt;p mce_keep="true"&gt;Depending on the application, this&amp;nbsp;value&amp;nbsp;will typically contain&amp;nbsp;the application's&amp;nbsp;DLL name or CLSID, or a&amp;nbsp;unique application-generated identifier&amp;nbsp;if the application supports multiple instances of itself running simultaneously.&amp;nbsp;&amp;nbsp;&amp;nbsp; The actual string&amp;nbsp;contents does not matter to the driver, it is passed back to the application when events are sent.&lt;/p&gt;
&lt;p mce_keep="true"&gt;When your driver sends an event and sets the cookie in the event parameters, the application can retrieve the cookie to determine if the event is a result of actions that originated from itself or another program.&amp;nbsp;&amp;nbsp;&amp;nbsp;For example,&amp;nbsp;Application&amp;nbsp;A creates an object on the device,&amp;nbsp;and receives an ObjectAdded event&amp;nbsp;containing&amp;nbsp;its client event cookie, it can&amp;nbsp;choose not to refresh its view of the device contents&amp;nbsp;because&amp;nbsp;the view has been updated at the time the object was created.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If Application B&amp;nbsp;creates another object on the device,&amp;nbsp;Application A will receive an ObjectAdded event with a&amp;nbsp;different cookie (or no cookie), and knows that&amp;nbsp;it needs to refresh the&amp;nbsp;device&amp;nbsp;contents view, because the object was added by some other client application.&lt;/p&gt;
&lt;p mce_keep="true"&gt;In an environment where there can be two or more client applications&amp;nbsp;communicating with your driver (Explorer&amp;nbsp;is virtually guaranteed to be one client through the WPD Shell Namespace Extension), supporting the event cookie mechanism is a good WPD programming practice that may help reduce the client traffic to your device in response to events, and to&amp;nbsp;streamline application-side event handling.&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;How to support WPD_CLIENT_EVENT_COOKIE in your WPD driver:&lt;/b&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;1. Add a handler for the WPD_COMMAND_COMMON_SAVE_CLIENT_INFORMATION command.&amp;nbsp; The &lt;b&gt;WpdWudfSampleDriver&lt;/b&gt; from the WDK contains an example of this in &lt;b&gt;WpdBaseDriver::OnSaveClientInfo()&lt;/b&gt;.&lt;/p&gt;
&lt;p mce_keep="true"&gt;2. In &lt;b&gt;OnSaveClientInfo()&lt;/b&gt;, if the application sets WPD_CLIENT_EVENT_COOKIE in the client information parameters, save the cookie with your context info. Some applications may choose not to send this cookie, in which case your driver does not have to do anything here.&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;LPWSTR pszEventCookie&amp;nbsp;= NULL;&amp;nbsp;&lt;br&gt;&lt;br&gt;hr = pClientInfo-&amp;gt;GetStringValue(WPD_CLIENT_EVENT_COOKIE, &amp;amp;pszEventCookie);&lt;br&gt;&lt;br&gt;if (hr == S_OK &amp;amp;&amp;amp; pszEventCookie != NULL)&lt;br&gt;{&lt;br&gt;    // Store the cookie value with the client context&lt;br&gt;    pContext-&amp;gt;EventCookie = pszEventCookie;&lt;br&gt;}&lt;br&gt;&lt;br&gt;CoTaskMemFree(pszEventCookie);&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;3. When posting events, if the client event cookie is available, send it along with the event parameters.&amp;nbsp;&amp;nbsp; In the sample driver, this code will be added to the &lt;b&gt;PostWpdEvent()&lt;/b&gt; function.&lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;HRESULT hrEventCookie = GetClientEventCookie(pCommandParams, &amp;amp;pszEventCookie);&lt;br&gt;&lt;br&gt;if (hrEventCookie == S_OK &amp;amp;&amp;amp; pszEventCookie != NULL)&lt;br&gt;{&lt;br&gt;    // Add it to the event parameters&lt;br&gt;    // The application's OnEvent callback will match this with its cookie&lt;br&gt;    hrEventCookie = pEventParams-&amp;gt;SetStringValue(WPD_CLIENT_EVENT_COOKIE, pszEventCookie);&lt;br&gt;}&lt;br&gt;&lt;br&gt;CoTaskMemFree(pszEventCookie);&lt;br&gt;&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;And here's an outline of the &lt;b&gt;GetClientEventCookie()&lt;/b&gt; helper function.&amp;nbsp;&amp;nbsp; It uses the client information context&amp;nbsp;supplied in the command parameters&amp;nbsp;to look up the saved client cookie in the context map. &lt;/p&gt;&lt;span style="font-size: 9pt; font-family: 'courier-new';"&gt;&lt;pre&gt;ClientContext* pClientContext = NULL;&amp;nbsp;&amp;nbsp; // This is a context helper object defined by the sample driver&lt;br&gt;&lt;br&gt;hr = pCommandParams-&amp;gt;GetStringValue(WPD_PROPERTY_COMMON_CLIENT_INFORMATION_CONTEXT, &amp;amp;pszClientContext);&lt;br&gt;&lt;br&gt;if (hr == S_OK)&lt;br&gt;{&lt;br&gt;    hr = GetClientContext(pCommandParams, pszClientContext, (IUnknown**)&amp;amp;pClientContext);&lt;br&gt;&lt;br&gt;    if (hr == S_OK &amp;amp;&amp;amp; pClientContext != NULL &amp;amp;&amp;amp; pClientContext-&amp;gt;EventCookie.GetLength() &amp;gt; 0)&lt;br&gt;    {&lt;br&gt;       // Allocate the cookie string to return &lt;br&gt;       *ppszEventCookie = AtlAllocTaskWideString(pClientContext-&amp;gt;EventCookie);&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    if (pClientContext != NULL)&amp;nbsp;&lt;br&gt;     &amp;nbsp;&amp;nbsp;&amp;nbsp; pClientContext-&amp;gt;Release();&lt;br&gt;&lt;br&gt;    CoTaskMemFree(pszClientContext);&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;&lt;i&gt;&lt;/i&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;For an overview on posting events,&amp;nbsp;refer to this&amp;nbsp;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2007/03/16/how-to-post-events-from-your-wpd-driver.aspx" class="" title="How to Post Events From Your WPD Driver" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/03/16/how-to-post-events-from-your-wpd-driver.aspx"&gt;post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;/i&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2402905" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /></entry><entry><title>Cancellation Behavior of MTP USB Devices</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/04/15/cancellation-behavior-of-mtp-usb-devices.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/04/15/cancellation-behavior-of-mtp-usb-devices.aspx</id><published>2007-04-15T19:01:00Z</published><updated>2007-04-15T19:01:00Z</updated><content type="html">&lt;p&gt;The &lt;a href="http://www.usb.org/developers/devclass_docs/MTP_1.0.zip" title="MTP Specification" mce_href="http://www.usb.org/developers/devclass_docs/MTP_1.0.zip"&gt;MTP Specification&lt;/a&gt; contains&amp;nbsp;this definition of the &lt;b&gt;CancelTransaction &lt;/b&gt;Event:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;&lt;b&gt;G.2.2 CancelTransaction&lt;/b&gt;&lt;br&gt;&lt;/i&gt;Event Code: &lt;b&gt;0x4001&lt;/b&gt;&lt;br&gt;Parameter 1: None&lt;br&gt;Parameter 2: None&lt;br&gt;Parameter 3: None&lt;/p&gt;
&lt;p&gt;This event is used to initiate the cancellation of a transaction over transports which do not have their own mechanism for canceling transactions. The details of how a transaction is cancelled may be transport-specific. When an initiator or responder receives this event, it should cancel the transaction identified by the TransactionID in the event dataset. If the transaction has already completed, this event should be ignored.&lt;/p&gt;
&lt;p&gt;After receiving a CancelTransaction event from the initiator during an object transfer, the responder should send an Transaction_Cancelled response for the transfer which was in progress.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;br&gt;&lt;b&gt;MTP USB Transport Cancellation Behavior&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Why then does an MTP/USB device send a&amp;nbsp;&lt;b&gt;Status_OK &lt;/b&gt;(0x2001) instead of &lt;b&gt;Transaction_Cancelled&lt;/b&gt; (0x201F)&amp;nbsp;response when&amp;nbsp;it receives a &lt;b&gt;CancelTransaction&lt;/b&gt; (0x4001) from the application?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The reason is that the MTP USB transport&amp;nbsp;has defined how cancellation&amp;nbsp;is to be implemented.&amp;nbsp;&amp;nbsp;&amp;nbsp;As pointed out in the MTP Specification above, &lt;b&gt;CancelTransaction&lt;/b&gt;&amp;nbsp;is intended for "&lt;i&gt;transports which do not have their own mechanism for canceling transactions&lt;/i&gt;", and will not apply to MTP/USB devices.&lt;/p&gt;
&lt;p&gt;Here are&amp;nbsp;the MTP/USB specifications for each cancellation scenario.&amp;nbsp;&amp;nbsp; In the cases below, "Host"&amp;nbsp;can be a PC running Windows Media Player 11, and "Device"&amp;nbsp;can be a MTP&amp;nbsp;music player or a PTP camera that connects to the PC through USB.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Case A. When the Host Cancels&lt;br&gt;&lt;/u&gt;&lt;/b&gt;When&amp;nbsp;the device receives a cancellation request from the host,&amp;nbsp;it should return Device_Busy (0x2019) for&amp;nbsp;a &lt;b&gt;GetDeviceStatus&amp;nbsp;&lt;/b&gt;query.&amp;nbsp;&amp;nbsp;&amp;nbsp; The device should then perform cancellation and clean up, and return &lt;b&gt;Status_OK&lt;/b&gt; (0x2001)&amp;nbsp;for subsequent &lt;b&gt;GetDeviceStatus&lt;/b&gt; requests. The device should&amp;nbsp;NOT send a response for the cancelled transaction through the BULK-IN pipe.&lt;/p&gt;
&lt;p&gt;After the host receives a Status_OK response from&amp;nbsp;a &lt;b&gt;GetDeviceStatus &lt;/b&gt;query&amp;nbsp;on the device, it may issue the next transaction through the BULK-OUT pipe.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Case B. When the Device Cancels&lt;br&gt;&lt;/u&gt;&lt;/b&gt;If the device wants to cancel, it should STALL both BULK-IN and BULK-OUT endpoints.&amp;nbsp; When the device receives a &lt;b&gt;GetDeviceStatus &lt;/b&gt;request from host, the device should return &lt;b&gt;Transaction_Cancelled &lt;/b&gt;(0x201F) as the reason for the STALL, and the STALL-ed endpoint numbers.&lt;/p&gt;
&lt;p&gt;The host may then issue the &lt;b&gt;ClearFeature &lt;/b&gt;request to clear the STALL-ed endpoints. The device should clear, get ready for next command, and return Status_OK for next &lt;b&gt;GetDeviceStatus&lt;/b&gt; query.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Case C. When the Host and Device Both Cancel&lt;br&gt;&lt;/u&gt;&lt;/b&gt;When the device receives a cancel request from the host while it is trying to cancel,&amp;nbsp;it&amp;nbsp;should clear&amp;nbsp;any pending device-initiated cancellations, respond to the host with Device_Busy (0x2019) for subsequent &lt;b&gt;GetDeviceStatus&lt;/b&gt; requests, and proceed with normal host-initiated cancellation.&lt;/p&gt;
&lt;p&gt;When the device wants to cancel (this could be initiated by the user), it first checks if there&amp;nbsp;are any pending host-initiated cancellation.&amp;nbsp; If yes, the device can simply return.&amp;nbsp; If not, the device should STALL the BULK endpoints.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Cancellation Examples&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For cancellation examples, refer to the Picture Transfer Protocol (PTP)&amp;nbsp;Specification -&amp;nbsp;ISO 15740 Annex D: Sections D.7.2.1.2 (for device behavior) and D.9, available on the &lt;a href="http://www.i3a.org/technologies/image-formats/ptp/" title="I3A PTP Homepage" mce_href="http://www.i3a.org/technologies/image-formats/ptp/"&gt;I3A PTP website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In addition,&amp;nbsp;the &lt;a href="http://www.usb.org/developers/devclass_docs/usb_still_img10.pdf" class="" title="PTP/USB Definition" mce_href="http://www.usb.org/developers/devclass_docs/usb_still_img10.pdf"&gt;PTP USB Transport&lt;/a&gt;&amp;nbsp;specification also contains&amp;nbsp;a definition&amp;nbsp;for the GetDeviceStatus and&amp;nbsp;further descriptions of the BULK cancellation behavior.&lt;br&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2145678" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="MTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/MTP/" /><category term="PTP" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/PTP/" /></entry><entry><title>Installing the Sample Drivers on XP and Vista</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/04/03/installing-the-sample-drivers-on-xp-and-vista.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/04/03/installing-the-sample-drivers-on-xp-and-vista.aspx</id><published>2007-04-03T03:16:00Z</published><updated>2007-04-03T03:16:00Z</updated><content type="html">&lt;p&gt;A question was raised today on how to run the WPD sample drivers on Windows XP.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WPD drivers and applications&amp;nbsp;can run downlevel on Windows XP as long as the WPD and UMDF runtimes are both installed.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;Compiling a WPD Driver&amp;nbsp;for&amp;nbsp;your&amp;nbsp;OS&lt;/b&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;For the driver to run on Windows XP, it has to be built using a Windows XP x86 build environment provided by the Windows Driver Kit (v6000 or later).&amp;nbsp;&amp;nbsp; Similarly, for running on&amp;nbsp;Windows Vista,&amp;nbsp;use&amp;nbsp;one of the&amp;nbsp;Windows Vista build environments.&lt;/p&gt;
&lt;p mce_keep="true"&gt;If the runtime OS does not match the build environment, you may get a "Code 10 -&amp;nbsp;This Device Cannot Start" in error message in Device Manager after installing the driver.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;Installing WPD on the XP machine&lt;/b&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;Either one of these supply the WPD runtime components&amp;nbsp;for Windows XP:&lt;/p&gt;
&lt;p mce_keep="true"&gt;1. Install Windows Media Player 11, or&lt;/p&gt;
&lt;p mce_keep="true"&gt;2. Install the Windows Media Format SDK 11 redistributable: WMFDist11-WindowsXP-X86-ENU.exe package, typically under c:\WMSDK\WMFSDK11\Redist folder&amp;nbsp;from a Windows Media Format 11 SDK install.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;Obtaining the WUDF Co-Installer&lt;/b&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;The UMDF runtime is distributed and installed by referencing its co-installer in the driver INF.&amp;nbsp;&amp;nbsp; For Windows Vista and XP, the recommended co-installer to use is the version that is distributed&amp;nbsp;in&amp;nbsp;the&lt;b&gt; Windows Driver Kits&lt;/b&gt;: under the &lt;b&gt;\WinDDK\6001.xxxxx\redist\wdf\&lt;/b&gt; folder.&amp;nbsp;&amp;nbsp; Copy this to the same location as your updated driver INF&amp;nbsp;before installing your driver.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;Modifying the Sample Driver INF&lt;/b&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;The following example shows the&amp;nbsp;INF changes to enable the WpdHelloWorldDriver to install in Windows XP using the v1.7 UMDF co-installer.&amp;nbsp;&amp;nbsp; The actual version number would depend on what was provided in the WDK.&amp;nbsp; The modified/added entries are highlighted in &lt;font color="red"&gt;red&lt;/font&gt;, and the same updates would apply to both WPD driver samples. &lt;br&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;The changes involve&amp;nbsp;adding a CopyFiles directive that references WUDFUpdate_01007.dll, and updating the AddReg entries to use UMDF&amp;nbsp;v1.7.&lt;/p&gt;
&lt;p&gt;[SourceDisksFiles]&lt;br&gt;WpdHelloWorldDriver.dll=1&lt;br&gt;&lt;font color="red"&gt;WUDFUpdate_01007.dll=1&lt;/font&gt;&lt;br&gt;...&lt;br&gt;&lt;br&gt;[Basic_Install.CoInstallers]&lt;br&gt;AddReg=Basic_Install.CoInstallers_AddReg&lt;br&gt;&lt;font color="red"&gt;CopyFiles=CoInstallers_CopyFiles&lt;/font&gt;&lt;br&gt;...&lt;br&gt;&lt;/p&gt;
&lt;p&gt;; Add the co-installer&amp;nbsp;DLL to the CopyFiles list&lt;br&gt;&lt;font color="red"&gt;[CoInstallers_CopyFiles]&lt;br&gt;WUDFUpdate_01007.dll&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;&lt;br&gt;; Update the registration to use the&amp;nbsp;correct binary&lt;br&gt;[Basic_Install.CoInstallers_AddReg] &lt;br&gt;HKR,,CoInstallers32,0x00010000,&lt;font color="red"&gt;"WUDFUpdate_01007.dll"&lt;/font&gt;&lt;br&gt;&lt;br&gt;...&lt;/p&gt;
&lt;p&gt;&lt;br&gt;; Update the UMDF version to 1.7.0&lt;br&gt;[WpdHelloWorldDriver_Install]&lt;br&gt;UmdfLibraryVersion=&lt;font color="red"&gt;1.7.0&lt;/font&gt;&lt;br&gt;&lt;br&gt;...&lt;/p&gt;
&lt;p&gt;&lt;br&gt;; Set the Co-Installer CopyFiles destination to system32&lt;br&gt;[DestinationDirs]&lt;br&gt;System32Copy=12,UMDF ; copy to system32\drivers\umdf&lt;br&gt;&lt;font color="red"&gt;Basic_Install.CoInstallers_CopyFiles=11&lt;/font&gt;&lt;br&gt;...&lt;br&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The same updated INF&amp;nbsp;will also work&amp;nbsp;on Windows Vista, as long as the UMDF co-installer DLL is&amp;nbsp;provided&amp;nbsp;with&amp;nbsp;your driver files during install AND you've compiled the driver DLL with the correct WDK build environment (see the first section of this post).&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;On Windows Vista, installing the WPD runtime components is not required&amp;nbsp;because WPD is available inbox for most SKUs.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2015189" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /><category term="Issues" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Issues/" /><category term="WUDF Coinstaller" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WUDF+Coinstaller/" /><category term="Driver INF" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Driver+INF/" /></entry><entry><title>Driver Dev Guide: WPP Tracing in your WPD Driver</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/04/01/driver-dev-guide-using-wpp-tracing-in-your-wpd-driver.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/04/01/driver-dev-guide-using-wpp-tracing-in-your-wpd-driver.aspx</id><published>2007-04-01T21:14:00Z</published><updated>2007-04-01T21:14:00Z</updated><content type="html">&lt;P&gt;&lt;A class="" title="WPP Software Tracing" href="http://msdn2.microsoft.com/en-us/library/ms793164.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms793164.aspx"&gt;WPP Software Tracing&lt;/A&gt; is the recommended way to log trace and error&amp;nbsp;messages in your WPD driver.&amp;nbsp; WPP, short for &lt;B&gt;W&lt;/B&gt;indows Software Trace &lt;B&gt;P&lt;/B&gt;re&lt;B&gt;P&lt;/B&gt;rocessor, provides&amp;nbsp;an efficient real-time event logging mechanism.&amp;nbsp;&amp;nbsp;&amp;nbsp; In addition, WPP traces include the system timestamp and can be used as a way to measure performance,&amp;nbsp;for example&amp;nbsp;by calculating the elapsed time between function calls.&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;From OutputDebugString to WPP&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;The WPD&amp;nbsp;sample drivers in the Windows Driver Kit (WDK)&amp;nbsp;log&amp;nbsp;error&amp;nbsp;messages using a&amp;nbsp;CHECK_HR function that wraps around OutputDebugString.&amp;nbsp;&amp;nbsp; While OutputDebugString is simple to use during development,&amp;nbsp;it necessitates&amp;nbsp;an active debugger connection in order to view the traces, and should be used minimally in shipping code.&amp;nbsp;&amp;nbsp; WPP tracing&amp;nbsp;is much more lightweight, flexible,&amp;nbsp;and&amp;nbsp;preferable for a range of tracing applications: logging errors for diagnosing failures, tracing code execution during development, to name a few.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;How to switch your WPD driver's tracing from OutputDebugString to WPP transparently:&lt;/P&gt;
&lt;P&gt;Step 1. &lt;B&gt;Remove&lt;/B&gt; the original CHECK_HR() function&amp;nbsp;definition (it can be found in WpdHelloWorldDriver.cpp&amp;nbsp;or WpdWudfSampleDriver.cpp for the WPD samples) and&amp;nbsp;its declaration in stdafx.h.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Step 2. &lt;B&gt;Add&lt;/B&gt; the following code (&lt;B&gt;include&lt;/B&gt; the WPP config comment blocks)&amp;nbsp;to stdafx.h:&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'courier-new'"&gt;&lt;PRE&gt;// TODO: Choose a different trace ID for your WPD driver&lt;BR&gt;#define MYDRIVER_TRACING_ID      L"Microsoft\\WPD\\MyWpdDriver"&lt;BR&gt;&lt;BR&gt;// TODO: Choose a different trace control GUID for your WPD driver&lt;BR&gt;// TODO: Define trace flag bits for your WPD driver&lt;BR&gt;&lt;BR&gt;#define WPP_CONTROL_GUIDS                                                   \&lt;BR&gt;    WPP_DEFINE_CONTROL_GUID(                                                \&lt;BR&gt;        MyWpdDriverCtrlGuid, (da5fbdfd,1eae,4ecf,b426,a3818f325ddb),        \&lt;BR&gt;                                                                            \&lt;BR&gt;        WPP_DEFINE_BIT(TRACE_FLAG_ALL)                                      \&lt;BR&gt;        WPP_DEFINE_BIT(TRACE_FLAG_DRIVER)                                   \&lt;BR&gt;        WPP_DEFINE_BIT(TRACE_FLAG_DEVICE)                                   \&lt;BR&gt;        )                             &lt;BR&gt;&lt;BR&gt;//&lt;BR&gt;// Prefer trace statement that is based on&lt;BR&gt;//     - the standard trace LEVEL (evntrace.h), and&lt;BR&gt;//     - specific flag bit.&lt;BR&gt;//&lt;BR&gt;#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \&lt;BR&gt;           WPP_LEVEL_LOGGER(flags)&lt;BR&gt;               &lt;BR&gt;#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \&lt;BR&gt;           (WPP_LEVEL_ENABLED(flags) &amp;amp;&amp;amp; WPP_CONTROL(WPP_BIT_ ## flags).Level &amp;gt;= lvl)&lt;BR&gt;&lt;BR&gt;//&lt;BR&gt;// This comment block is scanned by the trace preprocessor to define our&lt;BR&gt;// Trace and TraceEvents function.&lt;BR&gt;//&lt;BR&gt;// begin_wpp config&lt;BR&gt;// FUNC Trace{FLAG=TRACE_FLAG_ALL}(LEVEL, MSG, ...);&lt;BR&gt;// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);&lt;BR&gt;// end_wpp&lt;BR&gt;//&lt;BR&gt;&lt;BR&gt;// MACRO: CHECK_HR&lt;BR&gt;// Configuration block that defines trace macro. It uses the PRE/POST macros to include&lt;BR&gt;// code as part of the trace macro expansion. CHECK_HR is equivalent to the code below:&lt;BR&gt;//&lt;BR&gt;// {if (hrCheck != S_OK){  // This is the code in the PRE macro&lt;BR&gt;//     DoTraceMessage(TRACE_FLAG_ALL,  "%!STDPREFIX!" MSG " hr= %!HRESULT!", ..., hrCheck)&lt;BR&gt;// ;}}                              // This is the code in the POST macro&lt;BR&gt;//                                 &lt;BR&gt;&lt;BR&gt;// begin_wpp config&lt;BR&gt;// USEPREFIX (CHECK_HR,"%!STDPREFIX!");&lt;BR&gt;// FUNC CHECK_HR{FLAG=TRACE_FLAG_ALL}(hrCheck, MSG, ...);&lt;BR&gt;// USESUFFIX (CHECK_HR, " hr= %!HRESULT!", hrCheck);&lt;BR&gt;// end_wpp&lt;BR&gt;&lt;BR&gt;#define WPP_FLAG_hrCheck_PRE(FLAGS, hrCheck) {if(hrCheck != S_OK) {&lt;BR&gt;#define WPP_FLAG_hrCheck_POST(FLAGS, hrCheck) ; } }&lt;BR&gt;#define WPP_FLAG_hrCheck_ENABLED(FLAGS, hrCheck) WPP_FLAG_ENABLED(FLAGS)&lt;BR&gt;#define WPP_FLAG_hrCheck_LOGGER(FLAGS, hrCheck) WPP_FLAG_LOGGER(FLAGS)&lt;BR&gt;&lt;/PRE&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Step 3. &lt;B&gt;Add&lt;/B&gt;&amp;nbsp;a RUN_WPP directive to your sources file:&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'courier-new'"&gt;&lt;PRE&gt;RUN_WPP= $(SOURCES) -scan:stdafx.h&lt;BR&gt;&lt;/PRE&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Step 4. &lt;B&gt;Add&lt;/B&gt;&amp;nbsp;the WPP initialization and cleanup routines to DllMain:&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'courier-new'"&gt;&lt;PRE&gt;// DLL Entry Point&lt;BR&gt;extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)&lt;BR&gt;{&lt;BR&gt;    if(DLL_PROCESS_ATTACH == dwReason)&lt;BR&gt;    {&lt;BR&gt;        g_hInstance = hInstance;&lt;BR&gt;      &lt;BR&gt;&lt;B&gt;        //&lt;BR&gt;        // Initialize tracing.&lt;BR&gt;        //&lt;BR&gt;        WPP_INIT_TRACING(MYDRIVER_TRACING_ID);&lt;/B&gt;&lt;BR&gt;    }&lt;BR&gt;    else if (DLL_PROCESS_DETACH == dwReason)&lt;BR&gt;    {&lt;BR&gt;&lt;B&gt;        //&lt;BR&gt;        // Cleanup tracing.&lt;BR&gt;        //&lt;BR&gt;        WPP_CLEANUP();&lt;/B&gt;&lt;BR&gt;    }&lt;BR&gt;&lt;BR&gt;    return _AtlModule.DllMain(dwReason, lpReserved);&lt;BR&gt;}&lt;BR&gt;&lt;/PRE&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Step 5. For&amp;nbsp;each .cpp file, &lt;B&gt;add &lt;/B&gt;a&amp;nbsp;#include &lt;I&gt;&amp;lt;filename&amp;gt;.tmh&lt;/I&gt; &lt;B&gt;after&lt;/B&gt;&amp;nbsp;the regular includes:&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'courier-new'"&gt;&lt;PRE&gt;//&lt;BR&gt;// WpdBaseDriver.cpp&lt;BR&gt;//&lt;BR&gt;&lt;BR&gt;#include "stdafx.h"&lt;BR&gt;#include "WpdBaseDriver.h"&lt;BR&gt;&lt;BR&gt;&lt;B&gt;// Include the WPP generated Trace Message Header (tmh) file for this .cpp&lt;BR&gt;#include "WpdBaseDriver.tmh"&lt;/B&gt;&lt;BR&gt;&lt;BR&gt;...&lt;BR&gt;&lt;BR&gt;&lt;/PRE&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;Repeat Step 5&lt;/B&gt; for all other .CPP files.&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Step 6. &lt;B&gt;Rebuild&lt;/B&gt; your driver.&amp;nbsp;&amp;nbsp;Since we&amp;nbsp;replaced the CHECK_HR&amp;nbsp;function with an equivalent WPP&amp;nbsp;macro that has the same&amp;nbsp;signature (our WPP changes&amp;nbsp;were "under the hood"),&amp;nbsp;&lt;B&gt;no&amp;nbsp;changes &lt;/B&gt;are needed for&amp;nbsp;any code&amp;nbsp;that uses&amp;nbsp;CHECK_HR. &amp;nbsp; You can continue to use CHECK_HR the same way as before :).&lt;/P&gt;
&lt;P mce_keep="true"&gt;The WPP preprocessor&amp;nbsp;will process stdafx.h for tracing macros,&amp;nbsp;and generate a &lt;A class="" title="Trace Message Header File" href="http://msdn2.microsoft.com/en-us/library/ms797965.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms797965.aspx"&gt;Trace Message Header &lt;/A&gt;(tmh) file for each cpp file in the obj folders.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;Inspecting the preprocessor output for&amp;nbsp;each&amp;nbsp;.CPP file&amp;nbsp;that calls CHECK_HR&amp;nbsp;(generated using&amp;nbsp;&lt;I&gt;make WpdBaseDriver.pp&lt;/I&gt;), you will notice that all CHECK_HR trace statements&amp;nbsp;have been&amp;nbsp;wrapped by WPP function calls, while the tracing&amp;nbsp;text and&amp;nbsp;WPP functions are defined in &lt;I&gt;WpdBaseDriver.tmh&lt;/I&gt;. &lt;/P&gt;
&lt;P mce_keep="true"&gt;The most common WPP-related&amp;nbsp;compilation errors you&amp;nbsp;may encounter&amp;nbsp;are due to mismatched format identifiers and&amp;nbsp;parameters &amp;nbsp;(e.g. if your format string contains an extra %d that does not match an argument) or&amp;nbsp;missing entries in the &lt;A class="" title=WPP_CONTROL_GUIDS href="http://msdn2.microsoft.com/en-us/library/ms793151.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms793151.aspx"&gt;WPP_CONTROL_GUIDS&lt;/A&gt;&amp;nbsp;macro.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;&lt;/B&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;More WPP Tracing Macros&lt;/B&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;We've also defined TraceEvents and Trace functions in&amp;nbsp;stdafx.h&amp;nbsp;that are general purpose WPP trace&amp;nbsp;macros wrapping &lt;A class="" title=DoTraceMessage href="http://msdn2.microsoft.com/en-us/library/ms793193.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms793193.aspx"&gt;DoTraceMessage&lt;/A&gt;.&amp;nbsp;&amp;nbsp; These can be used for both error and non-error trace logging using a combination of levels and flags.&amp;nbsp;&amp;nbsp;&amp;nbsp;For examples on how to use them in your driver, refer to the UMDF sample drivers in the WDK.&lt;/P&gt;
&lt;P mce_keep="true"&gt;To understand the WPP declarations used in stdafx.h,&amp;nbsp;customize the CHECK_HR macro, or to define&amp;nbsp;your own&amp;nbsp;tracing macros, visit the&amp;nbsp;&lt;A class="" title="WPP Macros in the tracedrv sample" href="http://msdn2.microsoft.com/en-us/library/ms793169.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms793169.aspx"&gt;WPP macros guide&lt;/A&gt;&amp;nbsp;which describes the WDK tracedrv sample in detail.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;Generating and Viewing Traces&lt;/B&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;To generate traces, you can use &lt;A class="" title=TraceView href="http://msdn2.microsoft.com/en-us/library/ms797981.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms797981.aspx"&gt;Traceview&lt;/A&gt;&amp;nbsp; (UI) or Tracelog (command line).&amp;nbsp;&amp;nbsp; TraceView also allows you to view traces in real-time as they are logged.&amp;nbsp;These are available in the WDK.&amp;nbsp;&amp;nbsp; A quick way to get started is to create a new log session from Traceview &lt;A class="" title="Creating a WPP Trace Session" href="http://msdn2.microsoft.com/en-us/library/ms797996.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms797996.aspx"&gt;using the PDB file&lt;/A&gt; that contains the private symbols for your driver.&amp;nbsp;&amp;nbsp; Alternatively, you use a .CTL file that specifies your driver as a trace provider (replace own values below):&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'courier-new'"&gt;&lt;PRE&gt;da5fbdfd-1eae-4ecf-b426-a3818f325ddb    MyWpdDriverCtlGuid&lt;BR&gt;&lt;/PRE&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;&lt;/B&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;Converting Binary Traces to A Human-Readable Form&lt;/B&gt;&lt;/P&gt;WPP traces log to a binary ETL format.&amp;nbsp; To convert them to text, supply Trace Format (TMF and TMC) files that can be generated from&amp;nbsp;the .PDB file using TracePDB.&amp;nbsp; For more details, refer to the &lt;A class="" title="WPP Tracing Tools" href="http://msdn2.microsoft.com/en-us/library/ms797960.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms797960.aspx"&gt;tracing tools&lt;/A&gt; section in the MSDN docs. 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;I&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/I&gt;&lt;/SPAN&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2007130" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="WDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WDK/" /><category term="Tools" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/Tools/" /></entry><entry><title>WPD and WMDM Side-by-side: An Application Development Perspective</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/wpdblog/archive/2007/03/24/wpd-and-wmdm-side-by-side-application-development.aspx" /><id>http://blogs.msdn.com/b/wpdblog/archive/2007/03/24/wpd-and-wmdm-side-by-side-application-development.aspx</id><published>2007-03-24T20:24:00Z</published><updated>2007-03-24T20:24:00Z</updated><content type="html">&lt;p&gt;This post will compare&amp;nbsp;WPD and the latest version of &lt;a href="http://msdn2.microsoft.com/en-us/library/bb231982.aspx" class="" title="Windows Media Device Manager 11" mce_href="http://msdn2.microsoft.com/en-us/library/bb231982.aspx"&gt;Windows Media Device Manager (WMDM)&lt;/a&gt;,&amp;nbsp;from an application developer's point of view.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Availability (aka SDK and Runtime Requirements)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/windows/bb980924.aspx" title="Windows SDK" mce_href="http://msdn.microsoft.com/en-us/windows/bb980924.aspx"&gt;Windows SDK&lt;/a&gt; contains the complete build environment&amp;nbsp;(headers, libs, sample code ...)&amp;nbsp;for&amp;nbsp;developing&amp;nbsp;a WPD application&amp;nbsp;for both 32 and 64-bit.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://msdn2.microsoft.com/en-us/windowsmedia/bb190309.aspx" class="" title="Windows Media Downloads" mce_href="http://msdn2.microsoft.com/en-us/windowsmedia/bb190309.aspx"&gt;Windows Media Format 11 SDK&lt;/a&gt;&amp;nbsp;(WMFSDK11) provides&amp;nbsp;headers and libs for WMDM 11.&amp;nbsp;&amp;nbsp;Since&amp;nbsp;WMFSDK11&amp;nbsp;is released in 32-bit, only 32-bit WMDM applications can be built.&amp;nbsp; On 64-bit Windows,&amp;nbsp;a 32-bit&amp;nbsp;WMDM application will run in SysWOW mode.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid black; padding: 0in 5.4pt; width: 125.6pt; background-color: transparent;" valign="top" width="167"&gt;&lt;br&gt;&lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 229.5pt; background-color: transparent;" valign="top" width="306"&gt;&lt;b&gt;WMDM 11&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 247.5pt; background-color: transparent;" valign="top" width="330"&gt;&lt;b&gt;WPD&lt;/b&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 125.6pt; background-color: transparent;" valign="top" width="167"&gt;Operating Systems &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 229.5pt; background-color: transparent;" valign="top" width="330"&gt;Windows XP + Windows Media Format 11 Redistributable, Windows Vista &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 247.5pt; background-color: transparent;" valign="top" width="330"&gt;Windows XP + Windows Media Format 11 Redistributable, Windows Vista &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 125.6pt; background-color: transparent;" valign="top" width="167"&gt;Processors &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 229.5pt; background-color: transparent;" valign="top" width="306"&gt;X86, AMD64 (SysWOW mode only) &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 247.5pt; background-color: transparent;" valign="top" width="330"&gt;X86, AMD64 &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 125.6pt; background-color: transparent;" valign="top" width="167"&gt;SDKs&lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 229.5pt; background-color: transparent;" valign="top" width="306"&gt;Windows Media Format SDK 11 &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 247.5pt; background-color: transparent;" valign="top" width="330"&gt;Windows SDK &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Common Device-level Operations&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Both WPD and WMDM support basic device-level operations: enumeration of connected devices,&amp;nbsp;managing device-level properties, and querying of static device capabilities.&lt;/p&gt;
&lt;p&gt;WMDM's &lt;a href="http://msdn.microsoft.com/en-us/library/bb231801%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb231801(VS.85).aspx"&gt;IWMDMDeviceControl&lt;/a&gt; operations&amp;nbsp;internally delegate to the service provider (through &lt;a href="http://msdn.microsoft.com/en-us/library/bb231655%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb231655(VS.85).aspx"&gt;IMDSPDeviceControl&lt;/a&gt;), and would require the service provider to support these operations. While device playback control is not natively supported by the WPD API, WPD's extensibility mechanism makes it easy to add this as a custom command to your driver. For example, your WPD driver can support a custom Playback command that&amp;nbsp;your&amp;nbsp;application can invoke using &lt;a href="http://msdn.microsoft.com/en-us/library/dd375691%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd375691(VS.85).aspx"&gt;IPortableDevice::SendCommand&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid black; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;&lt;b&gt;Operation&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;&lt;b&gt;Example WMDM API&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="401"&gt;&lt;b&gt;Suggested WPD API&lt;/b&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Enumerate attached devices &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDeviceManager2::EnumDevices2 &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceManager::GetDevices &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Enumerating device content &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMDevice::EnumStorage &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceContent::EnumObjects &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Examine device capabilities &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMDevice::GetFormatSupport, IWMDMDevice2::GetFormatCapability &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceCapabilities:: GetSupportedContentTypes, GetSupportFormats &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;
&lt;p&gt;Retrieve device properties&lt;/p&gt;&lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMDevice::GetManufacturer &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceManager:: GetDeviceManufacturer&amp;nbsp;&lt;span style="font-size: 10pt; font-family: 'Arial','sans-serif';"&gt;OR &lt;br&gt;&lt;/span&gt;IPortableDeviceProperties::GetValues(WPD_DEVICE_OBJECT_ID) &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Write device&amp;nbsp;properties &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMDevice3::SetProperty &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceProperties::SetValues(WPD_DEVICE_OBJECT_ID) &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Controlling device playback &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMDeviceControl::Play &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="401"&gt;- &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Common Object-level Operations&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A WPD object is analogous to a WMDM storage, and most WMDM storage operations have their equivalent WPD API.&amp;nbsp;&amp;nbsp; WPD is ObjectID-based, so each interface method that supports object-level operations receives&amp;nbsp;an Object Identifier&amp;nbsp;as a parameter.&amp;nbsp;&amp;nbsp; WMDM is interface-based, &lt;a href="http://msdn.microsoft.com/en-us/library/bb231928%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb231928(VS.85).aspx"&gt;IWMDMStorage&lt;/a&gt; represents a storage or a file, and&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/bb231909%28VS.85%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb231909(VS.85).aspx"&gt;IWMDMStorageControl&lt;/a&gt; implements the operations on a storage or a file.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For data object creation, both WPD and WMDM support transfer of protected Windows Media Digital Rights Management (WMDRM) content.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid black; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;&lt;b&gt;Operation&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;&lt;b&gt;Example WMDM API&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;&lt;b&gt;Suggested WPD API&lt;/b&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Enumerating&amp;nbsp;objects &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMDevice::EnumStorage, IWMDMEnumStorage::Next &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceContent::EnumObjects, IEnumPortableDeviceObjectIDs::Next &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Create a folder object &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMStorageControl::Insert3 &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceContent::&amp;nbsp; CreateObjectWithPropertiesOnly &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Create a data object &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMStorageControl::Insert3 &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceContent:: CreateObjectWithPropertiesAndData &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Transfer object data from device &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMStorageControl::Read &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceResources::GetStream &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Move objects &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMStorageControl::Move &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceContent::Move &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Copy objects &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;- &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceContent::Copy &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Delete objects &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMStorageControl::Delete &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceContent::Delete &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Retrieve object properties &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMStorage4::GetSpecifiedMetadata &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceProperties::GetValues &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Write object properties &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;IWMDMStorage3::SetMetadata &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceProperties::SetValues &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Delete object properties &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="273"&gt;- &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceProperties::Delete &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Device Events&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;There are only 4&amp;nbsp;events that WMDM applications can receive: media arrival/removal, and device arrival/removal. WPD supports device-level and the more granular object-level events, plus built-in extensibility for &lt;a href="http://blogs.msdn.com/wpdblog/archive/2007/03/16/how-to-post-events-from-your-wpd-driver.aspx" title="Custom WPD Events" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/03/16/how-to-post-events-from-your-wpd-driver.aspx"&gt;custom events&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid black; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;&lt;b&gt;Operation&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;&lt;b&gt;Example WMDM API&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;&lt;b&gt;Suggested WPD API&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Monitor object-level property changes 
&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;- &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceEventCallback::OnEvent (WPD_EVENT_OBJECT_UPDATED) &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Monitor object-level arrival and removal &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;- &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceEventCallback::OnEvent (WPD_EVENT_OBJECT_ADDED, WPD_EVENT_OBJECT_REMOVED) &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Monitor media arrival and removal &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMNotification::WMDMMessage (WMDM_MSG_MEDIA_ARRIVAL, WMDM_MSG_MEDIA_REMOVAL) &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceEventCallback::OnEvent (WPD_EVENT_OBJECT_ADDED, WPD_EVENT_OBJECT_REMOVED) &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Monitor device removal &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMNotification::WMDMMessage (WMDM_MSG_DEVICE_REMOVAL) &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;IPortableDeviceEventCallback::OnEvent (WPD_EVENT_DEVICE_REMOVED) &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;
&lt;p&gt;Monitor device arrival&lt;/p&gt;&lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.7pt; background-color: transparent;" valign="top" width="274"&gt;IWMDMNotification::WMDMMessage (WMDM_MSG_DEVICE_ARRIVAL) &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="401"&gt;&lt;a href="http://blogs.msdn.com/wpdblog/archive/2007/03/17/how-to-receive-wpd-device-arrival-events.aspx" mce_href="http://blogs.msdn.com/wpdblog/archive/2007/03/17/how-to-receive-wpd-device-arrival-events.aspx"&gt;Subscribe&lt;/a&gt; to WPD interface arrival PnP event &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Advanced Operations&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Both WPD and WMDM provide some extensibility mechanism for sending device-specific commands.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://msdn2.microsoft.com/en-us/library/bb231793.aspx" class="" title="IWMDMDevice3::DeviceIoControl" mce_href="http://msdn2.microsoft.com/en-us/library/bb231793.aspx"&gt;IWMDMDevice3::DeviceIoControl&lt;/a&gt; is used for&amp;nbsp;packaging and sending&amp;nbsp;commands only to Media Transfer Protocol&amp;nbsp;(MTP) portable media players.&lt;/p&gt;
&lt;p&gt;WPD API methods&amp;nbsp;that map to&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/aa528314.aspx" title="WPD Commands" mce_href="http://msdn.microsoft.com/en-us/library/aa528314.aspx"&gt;Command GUIDs&lt;/a&gt; internally delegate to &lt;a href="http://msdn.microsoft.com/en-us/library/dd375691%28VS.85%29.aspx" title="IPortableDevice::SendCommand" mce_href="http://msdn.microsoft.com/en-us/library/dd375691(VS.85).aspx"&gt;IPortableDevice::SendCommand&lt;/a&gt;.&amp;nbsp;&amp;nbsp;Applications&amp;nbsp;can&amp;nbsp;invoke these commands with additional options or parameters, such as the use of Read or Write&amp;nbsp;IOCTLs for access control.&lt;/p&gt;
&lt;p&gt;In addition, for better performance, WPD supports batching of property writes and retrievals across multiple objects, either per format or using a list of Object Identifiers.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table style="border: medium none ; border-collapse: collapse;" class="MsoNormalTable" border="1" cellpadding="0" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td style="border: 1pt solid black; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;&lt;b&gt;Operation&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 200.55pt; background-color: transparent;" valign="top" width="267"&gt;&lt;b&gt;Example WMDM API&lt;/b&gt; &lt;/td&gt;
&lt;td style="border-style: solid solid solid none; border-color: black black black rgb(240, 240, 240); border-width: 1pt 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="407"&gt;&lt;b&gt;Suggested WPD API&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Retrieve properties of multiple objects &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 200.55pt; background-color: transparent;" valign="top" width="267"&gt;- &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="407"&gt;IPortableDevicePropertiesBulk::&amp;nbsp; QueueGetValuesByObjectList, OR QueueGetValuesByObjectFormat &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="407"&gt;Set properties of multiple objects &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 200.55pt; background-color: transparent;" valign="top" width="267"&gt;- &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="407"&gt;IPortableDevicePropertiesBulk:: QueueSetValuesByObjectList &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Send device-specific commands &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 200.55pt; background-color: transparent;" valign="top" width="267"&gt;IWMDMDevice::SendOpaqueCommand OR IWMDMDevice3::DeviceIoControl &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="407"&gt;IPortableDevice::SendCommand &lt;/td&gt;&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td style="border-style: none solid solid; border-color: rgb(240, 240, 240) black black; border-width: medium 1pt 1pt; padding: 0in 5.4pt; width: 95.4pt; background-color: transparent;" valign="top" width="127"&gt;Cancel an operation &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 200.55pt; background-color: transparent;" valign="top" width="267"&gt;- &lt;/td&gt;
&lt;td style="border-style: none solid solid none; border-color: rgb(240, 240, 240) black black rgb(240, 240, 240); border-width: medium 1pt 1pt medium; padding: 0in 5.4pt; width: 205.05pt; background-color: transparent;" valign="top" width="407"&gt;IPortableDevice*::Cancel, e.g. IPortableDeviceProperties::Cancel &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Stability&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;WMDM loads registered service providers (SPs) within the same process as the application. Any crash or instability in the device driver or SP could cause undue crashes in the application process, or worse, trigger bluescreens if kernel mode drivers are involved.&lt;/p&gt;
&lt;p&gt;WPD drivers are sandboxed in the User Mode Driver Framework (UMDF) host process, and gain the &lt;a href="http://msdn2.microsoft.com/en-us/library/aa511005.aspx" title="UMDF Stability and Security" mce_href="http://msdn2.microsoft.com/en-us/library/aa511005.aspx"&gt;stability and security benefits&lt;/a&gt; of a UMDF driver. If a WPD driver crashes, only the sandbox process will be affected; the WPD application process is isolated from the driver instability. In a similar way, a WPD driver's process&amp;nbsp;is not affected when a WPD client application crashes.&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;b&gt;&lt;u&gt;The Verdict&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;WPD and WMDM have a lot of overlap in&amp;nbsp;terms of the&amp;nbsp;device operations that each enables.&amp;nbsp;&amp;nbsp; WMDM is geared&amp;nbsp;specifically towards portable media player applications and scenarios,&amp;nbsp;with media-centric metadata schema, support for device playback control, and direct access to Windows Media Digital Rights Management (WMDRM)&amp;nbsp;application interfaces.&amp;nbsp;&amp;nbsp;&amp;nbsp;WPD supports much of what WMDM does (including WMDRM transfers), &lt;i&gt;plus &lt;/i&gt;many key advantages over WMDM, including&amp;nbsp;stability, UMDF integration,&amp;nbsp;comprehensive property and content type&amp;nbsp;schema (beyond portable media devices),&amp;nbsp;extensibility for custom device solutions, broader device support,&amp;nbsp;and&amp;nbsp;not to mention, great &lt;a href="http://msdn2.microsoft.com/en-us/library/aa973613.aspx" class="" title="WpdInfo" mce_href="http://msdn2.microsoft.com/en-us/library/aa973613.aspx"&gt;development tools&lt;/a&gt;.&lt;/p&gt;
&lt;p mce_keep="true"&gt;For applications that&amp;nbsp;would&amp;nbsp;like to&amp;nbsp;connect to, control,&amp;nbsp;and manage content&amp;nbsp;across a &lt;i&gt;wide range of devices&lt;/i&gt; (digital still cameras, portable media players, cellular phones, third-party device classes,&amp;nbsp;and more), WPD is the clear choice.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0in 0in 10pt; line-height: normal;"&gt;&lt;i&gt;&lt;span style="font-size: 10pt; font-family: 'Arial','sans-serif';"&gt;&lt;/span&gt;&lt;/i&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0in 0in 10pt; line-height: normal;"&gt;&lt;i&gt;&lt;span style="font-size: 10pt; font-family: 'Arial','sans-serif';"&gt;This posting is provided "AS IS" with no warranties and confers no rights.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1943316" width="1" height="1"&gt;</content><author><name>WPD Blogger [MSFT]</name><uri>http://blogs.msdn.com/wpdblog_4000_live.com/ProfileUrlRedirect.ashx</uri></author><category term="SDK" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/SDK/" /><category term="WMDM" scheme="http://blogs.msdn.com/b/wpdblog/archive/tags/WMDM/" /></entry></feed>