<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>dimeby8</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/dimeby8/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/dimeby8/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 05:49:00 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Sample XML document for ProvisioningAgent.provisionFromXmlDocumentAsync()</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/sample-xml-document-for-provisioningagent-provisionfromxmldocumentasync</link>
      <pubDate>Tue, 01 Nov 2011 09:50:00 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2011/11/01/sample-xml-document-for-provisioningagent-provisionfromxmldocumentasync/</guid>
      <description><![CDATA[Below is an example of a provisioning XML document that may be passed to the...]]></description>
      <content:encoded><![CDATA[<p>Below is an example of a provisioning XML document that may be passed to the <a href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.networkoperators.provisioningagent.provisionfromxmldocumentasync(v=VS.85).aspx" target="_blank">ProvisioningAgent.provisionFromXmlDocumentAsync</a> method. The following fields need to be customized at the least - Issuer and Subscriber. The value for the Subscriber node must be set to the subscriber ID for a mobile-broadband interface (can be retrieved by running 'netsh mbn show ready interface=*' at a command prompt).</p>
<p><br />&nbsp;</p>
<pre lang="xml">&lt;?xml version="1.0"?&gt;
&lt;CarrierProvisioning xmlns="https://www.microsoft.com/networking/CarrierControl/v1"&gt;
    &lt;Issuer&gt;{11111111-1111-1111-1111-111111111111}&lt;/Issuer&gt;
    &lt;Subscriber&gt;1234567890&lt;/Subscriber&gt;
    &lt;Provisioning&gt;
        &lt;RefreshParameters&gt;
            &lt;DelayInDays&gt;30&lt;/DelayInDays&gt;
            &lt;RefreshURL&gt;https://www.contoso.com/provisionme.aspx?subscriber=1234567890&lt;/RefreshURL&gt;
            &lt;Username&gt;012345678901234&lt;/Username&gt;
            &lt;Password&gt;SomePassword&lt;/Password&gt;
        &lt;/RefreshParameters&gt;
    &lt;/Provisioning&gt; 
    &lt;MBNProfiles&gt;
        &lt;DefaultProfile xmlns="https://www.microsoft.com/networking/CarrierControl/WWAN/v1"&gt;
            &lt;Name&gt;Contoso&lt;/Name&gt;
            &lt;Description&gt;Contoso&lt;/Description&gt;
            &lt;Cost xmlns="https://www.microsoft.com/networking/CarrierControl/DUSM/v1" PlanType="Fixed" OverDataLimit="true" Congested="true"&gt;
                &lt;UsageInMegabytes Timestamp="2002-05-30T09:30:10+06:00"&gt;25&lt;/UsageInMegabytes&gt;
                &lt;DataLimitInMegabytes&gt;10&lt;/DataLimitInMegabytes&gt;
                &lt;BillingCycle StartDate="2011-09-30T09:30:10+06:00" Duration="P1Y4M20DT2H34M78S" Resets="false"&gt;&lt;/BillingCycle&gt;
                &lt;BandwidthInKbps&gt;5&lt;/BandwidthInKbps&gt;
                &lt;MaxDownloadFileSizeInMegabytes&gt;25&lt;/MaxDownloadFileSizeInMegabytes&gt;
                &lt;CarrierPolicy&gt;
                    &lt;SecurityUpdatesExempt&gt;true&lt;/SecurityUpdatesExempt&gt;
                &lt;/CarrierPolicy&gt;
            &lt;/Cost&gt;
            &lt;HomeProviderName&gt;Contoso&lt;/HomeProviderName&gt;
            &lt;AutoConnectOnInternet&gt;true&lt;/AutoConnectOnInternet&gt;
            &lt;Context&gt;
                &lt;AccessString&gt;Contoso.Contoso&lt;/AccessString&gt;
                &lt;UserLogonCred&gt;
                    &lt;UserName&gt;user&lt;/UserName&gt;
                    &lt;Password&gt;password&lt;/Password&gt;
                &lt;/UserLogonCred&gt;
            &lt;/Context&gt;
        &lt;/DefaultProfile&gt;
    &lt;/MBNProfiles&gt;
    &lt;WLANProfiles&gt;
        &lt;WLANProfile xmlns="https://www.microsoft.com/networking/CarrierControl/WLAN/v1"&gt;
            &lt;name&gt;Contoso Wi-Fi&lt;/name&gt;
            &lt;SSIDConfig&gt;
                &lt;SSID&gt;
                    &lt;name&gt;contosowifi&lt;/name&gt;
                &lt;/SSID&gt;
            &lt;/SSIDConfig&gt;
            &lt;MSM&gt;
                &lt;security&gt;
                    &lt;authEncryption&gt;
                        &lt;authentication&gt;open&lt;/authentication&gt;
                        &lt;encryption&gt;none&lt;/encryption&gt;
                        &lt;useOneX&gt;false&lt;/useOneX&gt;
                    &lt;/authEncryption&gt;
                    &lt;HotspotProfile xmlns="https://www.microsoft.com/networking/WLAN/HotspotProfile/v1"&gt;
                        &lt;TrustedDomains&gt;
                            &lt;TrustedDomain&gt;.contoso.net&lt;/TrustedDomain&gt;
                        &lt;/TrustedDomains&gt;
                        &lt;UserName&gt;user@contoso.net&lt;/UserName&gt;
                        &lt;Password&gt;somepassword&lt;/Password&gt;
                    &lt;/HotspotProfile&gt;
                &lt;/security&gt;
            &lt;/MSM&gt;
        &lt;/WLANProfile&gt;
    &lt;/WLANProfiles&gt;
&lt;/CarrierProvisioning&gt;
</pre>]]></content:encoded>
    </item>
    <item>
      <title>Change ‘Unidentified network’ from Public to Work in Windows 7</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/change-unidentified-network-from-public-to-work-in-windows-7</link>
      <pubDate>Wed, 10 Jun 2009 18:13:00 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2009/06/10/change-unidentified-network-from-public-to-work-in-windows-7/</guid>
      <description><![CDATA[There isn&rsquo;t an easy way to set the category of an Unidentified network in Windows 7 RC+...]]></description>
      <content:encoded><![CDATA[<p>There isn&rsquo;t an easy way to set the category of an Unidentified network in Windows 7 RC+ builds. By default, an Unidentified network will be set to Public for security. Often, the Unidentified network is setup intentionally (e.g. two machines connected via a hub; a network TV tuner, etc.). In these cases, Home/Work is a better category to allow common network tasks to succeed.</p>
<p>Below is a Powershell script to change the category from Public to Work (identical to Home, except Homegroup won&rsquo;t be started up). You need to be already connected to the &lsquo;Unidentified network&rsquo; prior to running this script. </p>
<p><textarea style="font-size: 8pt; height: 329px; width: 100%;"># 
# Name: ChangeCategory.ps1 
# Copyright: Microsoft 2009 
# Revision: 1.0 
# 
# This script can be used to change the network category of 
# an 'Unidentified' network to Private to allow common network 
# activity. This script should only be run when connected to 
# a network that is trusted since it will also affect the 
# firewall profile used. 
# This script is provided as-is and Microsoft does not assume any 
# liability. This script may be redistributed as long as the file 
# contains these terms of use unmodified. 
# 
# Usage: 
# Start an elevated Powershell command window and execute 
# ChangeCategory.ps1 
#  
$NLMType = [Type]::GetTypeFromCLSID('DCB00C01-570F-4A9B-8D69-199FDBA5723B')
$INetworkListManager = [Activator]::CreateInstance($NLMType)

$NLM_ENUM_NETWORK_CONNECTED  = 1
$NLM_NETWORK_CATEGORY_PUBLIC = 0x00
$NLM_NETWORK_CATEGORY_PRIVATE = 0x01
$UNIDENTIFIED = "Unidentified network"

$INetworks = $INetworkListManager.GetNetworks($NLM_ENUM_NETWORK_CONNECTED)

foreach ($INetwork in $INetworks)
{
    $Name = $INetwork.GetName()
    $Category = $INetwork.GetCategory()

    if ($INetwork.IsConnected -and ($Category -eq $NLM_NETWORK_CATEGORY_PUBLIC) -and ($Name -eq $UNIDENTIFIED))
    {
        $INetwork.SetCategory($NLM_NETWORK_CATEGORY_PRIVATE)
    }
}
</textarea></p>
<p>&nbsp;</p>
<ol>
<li>Save the script locally as ChangeCategory.ps1 (say under c:\) </li>
<li>Launch an elevated Powershell command window </li>
<li>Change your execution policy to allow the script to run (if not already changed) <br /><b>PS&gt; set-executionpolicy remotesigned</b> </li>
<li>Run the script <br /><b>PS&gt; c:\ChangeCategory.ps1</b> </li>
</ol>
<p>At the end of this, the category for the Unidentified network will show as Work in Network and Sharing Center. This setting is not persisted across re-connects and you will require to run the script again to change the category. Be sure to run the script only for networks that you trust since this affects the firewall profile that will be used.</p>]]></content:encoded>
    </item>
    <item>
      <title>Where is wpdmtpextensions.h?</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/where-is-wpdmtpextensions-h</link>
      <pubDate>Tue, 15 May 2007 19:29:09 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2007/05/15/where-is-wpdmtpextensions-h/</guid>
      <description><![CDATA[The header file - Wpdmtpextensions.h - has been referenced in several of my posts and is needed to...]]></description>
      <content:encoded><![CDATA[<p>The header file - Wpdmtpextensions.h - has been referenced in several of my posts and is needed to talk MTP to the device through WPD. The header file is not available in the Vista SDK/WDK or the WMP 11 SDK, but is planned for inclusion in the Windows Server code name "Longhorn" SDK.</p> <p>I've just received a heads-up from the <a href="https://blogs.msdn.com/wpdblog/" target="_blank">WPD team</a> that the Server SDK has been published as a Beta (<a href="https://www.microsoft.com/downloads/details.aspx?FamilyId=58726ACA-8D84-4683-8959-BE0038DA7084&amp;displaylang=en" target="_blank">link</a>). Once you install the Server SDK, you can copy over wpdmtpextensions.h file to your desired SDK (e.g. Vista SDK/Visual Studio SDK) include folder if needed.&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Creating a WPD playlist object in C#</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/creating-a-wpd-playlist-object-in-c</link>
      <pubDate>Mon, 08 Jan 2007 18:44:04 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2007/01/08/creating-a-wpd-playlist-object-in-c/</guid>
      <description><![CDATA[This is a C# follow-up post on the earlier C++ playlist creation post. Be sure to read the earlier...]]></description>
      <content:encoded><![CDATA[<p>This is a C# follow-up post on the <a href="https://blogs.msdn.com/dimeby8/archive/2006/11/08/transferring-playlists-through-wpd.aspx">earlier C++ playlist creation post</a>. Be sure to read the earlier post for background information on playlists and how it stores references. We will also re-use the <em>StringToPropVariant</em> helper function that we defined in our <a href="https://blogs.msdn.com/dimeby8/archive/2007/01/08/creating-wpd-propvariants-in-c-without-using-interop.aspx">previous post</a>.</p> <p>To create a playlist object, the objects to be referenced should already have been transferred previously to the device. We'll write a function that will create a brand new playlist and set the references at creation-time. Setting the references is as easy as setting a property value, specifically the WPD_OBJECT_REFERENCES property.</p><pre>static void CreatePlaylistObject(
        PortableDeviceApiLib.PortableDeviceClass pPortableDevice,
        string parentID,
        string filename,
        ref string[] refObjectIDs,
        ref string newObjectID)
{
    // Get content interface required to create object
    PortableDeviceApiLib.IPortableDeviceContent pContent;
    pPortableDevice.Content(out pContent);

    // Create properties collection to send while creating object
    PortableDeviceApiLib.IPortableDeviceValues pValues =
        (PortableDeviceApiLib.IPortableDeviceValues)
            new PortableDeviceTypesLib.PortableDeviceValuesClass();

    pValues.SetStringValue(ref PortableDevicePKeys.WPD_OBJECT_PARENT_ID,
                            parentID);
    pValues.SetStringValue(ref PortableDevicePKeys.WPD_OBJECT_ORIGINAL_FILE_NAME,
                            filename);
    pValues.SetStringValue(ref PortableDevicePKeys.WPD_OBJECT_NAME,
                            filename);
    pValues.SetGuidValue(ref PortableDevicePKeys.WPD_OBJECT_FORMAT,
                            ref PortableDeviceGuids.WPD_OBJECT_FORMAT_WPLPLAYLIST);

    // References are stored in a PropVariantCollection object
    PortableDeviceApiLib.IPortableDevicePropVariantCollection pRefIDs =
        (PortableDeviceApiLib.IPortableDevicePropVariantCollection)
            new PortableDeviceTypesLib.PortableDevicePropVariantCollection();

    // Add the string object IDs to the references property
    for (int i = 0; i &lt; refObjectIDs.Length; i++)
    {
        PortableDeviceApiLib.tag_inner_PROPVARIANT propvarValue;
        StringToPropVariant(refObjectIDs[i], out propvarValue);

        pRefIDs.Add(ref propvarValue);
    }

    // Add the references property to the property collection
    pValues.SetIPortableDevicePropVariantCollectionValue(
        ref PortableDevicePKeys.WPD_OBJECT_REFERENCES, pRefIDs);

    // Create the playlist object using the CreateObjectWithPropertiesOnly API
    // The properties to be set have already been defined in pValues
    pContent.CreateObjectWithPropertiesOnly(pValues, ref newObjectID);
}
</pre>
<p>Since the playlist object does not require any data to be transferred, we will be using the <em>CreateObjectWithPropertiesOnly</em> API to create it. The function takes in the parent object i.e. the location at which the playlist object should be created and&nbsp;the name to use for the object. The object IDs that the playlist object will reference are passed in as a string array. The function will return the object ID of the new playlist object on success.</p>
<p>We create an <em>IPortableDeviceValues</em> instance - pValues -&nbsp;that will hold the properties of the playlist object to be applied. We set the required parent object ID, name and format properties. To add the references, we convert each string into a PROPVARIANT using our <em>StringToPropVariant</em> converter. We then add the PROPVARIANT into an <em>IPortableDevicePropVariantCollection </em>object. </p>
<p>Once we are done converting the input string array of object IDs into a PropVariant collection, we add the WPD_OBJECT_REFERENCES property to the <em>pValues </em>values collection with the PropVariant collection as the value (which is the list of object IDs to add as a reference).</p>
<p>Once the properties have been prepared, we call the <em>CreateObjectWithPropertiesOnly</em> API and create the object. Once the API completes successfully, a new object ID is returned which is the object ID of the newly created playlist object. </p>
<p>Invoking this function would look something like this:</p><pre>string newObjectID = "";

// Set the playlist to reference objects o1 and o2
string[] refObjectIDs = new string[2];
refObjectIDs[0] = "o1";
refObjectIDs[1] = "o2";

CreatePlaylistObject(pPortableDevice, "s10001", "hits2006.pls",
                            ref refObjectIDs, ref newObjectID);
</pre>
<p>Creating properties-only objects of other formats follows the same style. An example of another properties-only object is a <em>Contact </em>object - name, email, phone, etc. are just properties of the object itself. The object doesn't have any data. You can modify the function we have just presented to use the appropriate WPD_OBJECT_FORMAT code and create a contact object.</p>]]></content:encoded>
    </item>
    <item>
      <title>Creating WPD PROPVARIANTs in C# without using interop</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/creating-wpd-propvariants-in-c-without-using-interop</link>
      <pubDate>Mon, 08 Jan 2007 18:23:38 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2007/01/08/creating-wpd-propvariants-in-c-without-using-interop/</guid>
      <description><![CDATA[Previous posts have covered how to create, manage and marshal PROPVARIANTs using interop. Here's a...]]></description>
      <content:encoded><![CDATA[<p>Previous posts have covered how to create, manage and marshal PROPVARIANTs using interop. Here's a way on how to create a PROPVARIANT without interop. </p> <p>The <em>IPortableDeviceValues</em> interface exposes a <em>SetStringValue</em> method that allows a regular C# string to be added into the collection. IPortableDeviceValues also exposes a <em>GetValue</em> method which lets us retrieve any added property value as a PROPVARIANT. Armed with these two facts, it's pretty obvious how we can manufacture a string PROPVARIANT.</p><pre>static void StringToPropVariant(string value,
        out PortableDeviceApiLib.tag_inner_PROPVARIANT propvarValue)
{
    // We'll use an IPortableDeviceValues object to transform the
    // string into a PROPVARIANT
    PortableDeviceApiLib.IPortableDeviceValues pValues =
        (PortableDeviceApiLib.IPortableDeviceValues)
            new PortableDeviceTypesLib.PortableDeviceValuesClass();

    // We insert the string value into the IPortableDeviceValues object
    // using the SetStringValue method
    pValues.SetStringValue(ref PortableDevicePKeys.WPD_OBJECT_ID, value);

    // We then extract the string into a PROPVARIANT by using the 
    // GetValue method
    pValues.GetValue(ref PortableDevicePKeys.WPD_OBJECT_ID, 
                                out propvarValue);
}
</pre>
<p>We create an instance of an IPortableDeviceValues object named <em>pValues</em>. We then call SetStringValue with a dummy property key and the string to be converted. pValues now contains exactly one item - a string value which is internally held as a PROPVARIANT. To extract the internally held PROPVARIANT, we call <em>GetValue</em> which returns us a PROPVARIANT value.</p>
<p>This example function can be extended for other PROPVARIANT types. Use <em>Object Browser</em> and take a look at the Set* methods exposed by IPortableDeviceValues. Follow the same paradigm - use Set*Value for your source target type and then use GetValue to extract it as a PROPVARIANT.</p>]]></content:encoded>
    </item>
    <item>
      <title>Connecting to a WPD device in C#</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/connecting-to-a-wpd-device-in-c</link>
      <pubDate>Thu, 21 Dec 2006 18:51:27 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2006/12/21/connecting-to-a-wpd-device-in-c/</guid>
      <description><![CDATA[This is the C# equivalent of an earlier C++ post on connecting to a WPD device. We'll concentrate on...]]></description>
      <content:encoded><![CDATA[<p>This is the C# equivalent of an <a href="https://blogs.msdn.com/dimeby8/archive/2006/09/27/774259.aspx">earlier C++ post</a> on connecting to a WPD device. We'll concentrate on the implementation here - you may refer back to that earlier&nbsp;post for further explanation.</p><pre>// Create our client information collection
PortableDeviceApiLib.IPortableDeviceValues pValues = 
        (PortableDeviceApiLib.IPortableDeviceValues)
            new PortableDeviceTypesLib.PortableDeviceValuesClass();

// We have to provide at the least our name, version, revision
pValues.SetStringValue(
        ref PortableDevicePKeys.WPD_CLIENT_NAME, "Sample Client");
pValues.SetUnsignedIntegerValue(
        ref PortableDevicePKeys.WPD_CLIENT_MAJOR_VERSION, 1);
pValues.SetUnsignedIntegerValue(
        ref PortableDevicePKeys.WPD_CLIENT_MINOR_VERSION, 0);
pValues.SetUnsignedIntegerValue(
        ref PortableDevicePKeys.WPD_CLIENT_REVISION, 2);

// Create a new IPortableDevice instance
PortableDeviceApiLib.PortableDeviceClass pPortableDevice = 
        new PortableDeviceApiLib.PortableDeviceClass();

// We are now ready to open a connection to the device
// We'll assume deviceID contains a valid WPD device path and connect to it
pPortableDevice.Open(deviceID, pValues);
</pre>
<p>As you can see, it's pretty straight-forward to open a connection to a WPD device. We will set up our client information in a PortableDeviceValues collection and then send in the collection to the <em>Open</em> API call. If the device ID was valid, then a device connection will be opened and we can begin to use <em>pPortableDevice</em> to communicate with the device.</p>]]></content:encoded>
    </item>
    <item>
      <title>Marshalling variant properties in C#</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/marshalling-variant-properties-in-c</link>
      <pubDate>Tue, 12 Dec 2006 18:43:10 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2006/12/12/marshalling-variant-properties-in-c/</guid>
      <description><![CDATA[This post is a continuation of the one&nbsp;covering WPD property retrieval in C#. That post...]]></description>
      <content:encoded><![CDATA[<p>This post is a continuation of the one&nbsp;covering <a href="https://blogs.msdn.com/dimeby8/archive/2006/12/11/wpd-property-retrieval-in-c.aspx">WPD property retrieval in C#</a>. That post explained how to marshal strings and the basic int properties. Handling other types such as VT_DATE and VT_BOOL is trickier so I'll try to cover them here.</p> <p><strong>VT_DATE</strong></p> <p>VT_DATE variants hold the date time value in a field of type <em>double</em>. So we'll need to update our C# PropVariant definition to include a double field. </p><pre>[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct PropVariant
{
    [FieldOffset(0)]
    public short variantType;
    [FieldOffset(8)]
    public IntPtr pointerValue;
    [FieldOffset(8)]
    public byte byteValue;
    [FieldOffset(8)]
    public long longValue;
    <strong><em>[FieldOffset(8)]
    public double dateValue;</em></strong>
} 
</pre>
<p>Once we have a field that can hold the value, we need to convert it to something C# can understand. PROPVARIANTs are really OLE automation structures, so we can use the <em>DateTime.FromOADate</em> method to coerce our double into a <em>DateTime</em> object.</p><pre>DateTime date = DateTime.FromOADate(pvValue.dateValue);
</pre>
<p>To convert from <em>DateTime</em> to the double value in the PropVariant, use <em>DateTime.ToOADate</em>.</p>
<p><strong>VT_BOOL</strong></p>
<p>VT_BOOL variants hold the bool value in a field of type <em>short</em>. So we'll need to update the C# PropVariant definition to include the short field.</p>
<p></p><pre>[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct PropVariant
{
    [FieldOffset(0)]
    public short variantType;
    [FieldOffset(8)]
    public IntPtr pointerValue;
    [FieldOffset(8)]
    public byte byteValue;
    [FieldOffset(8)]
    public long longValue;
    [FieldOffset(8)]
    public double dateValue;
    <strong><em>[FieldOffset(8)]
    public short boolValue;</em></strong>
} 
</pre>
<p>Once we have the short field, we can convert it to a bool using <em>Convert.ToBoolean</em>.</p><pre>bool b = Convert.ToBoolean(pvValue.boolValue);
</pre>
<p><strong>VT_CLSID</strong></p>
<p>VT_CLSID variants hold the GUID value in a field of type <em>CLSID*</em>. The value itself is a pointer to a blob of memory allocated using CoTaskMemAlloc. Since we are dealing with a pointer, we can use the <em>pointerValue</em> field to access this.</p>
<p>We then use <em>PtrToStructure</em> (similar to how we handled LPWSTR) to marshal this pointer into a Guid we can use ourselves.</p><pre>Guid guid = (Guid)Marshal.PtrToStructure(pvValue.pointerValue, typeof(Guid));</pre>
<p><em>StructureToPtr</em> can be used to marshal a Guid back into the PropVariant.</p>
<p>&nbsp;</p>
<p>I'll update this post if I encounter other types that require special handling. Feel free to leave a comment on any that you come across as well.</p>]]></content:encoded>
    </item>
    <item>
      <title>WPD Content Enumeration in C#</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/wpd-content-enumeration-in-c</link>
      <pubDate>Tue, 12 Dec 2006 14:10:13 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2006/12/12/wpd-content-enumeration-in-c/</guid>
      <description><![CDATA[WPD content enumeration in C# is pretty close to the C++ style. Here's a basic example that...]]></description>
      <content:encoded><![CDATA[<p>WPD content enumeration in C# is pretty close to the C++ style. Here's a basic example that enumerates the object IDs of the objects present on the device.</p><pre>static void Enumerate(
    ref PortableDeviceApiLib.IPortableDeviceContent pContent,
    string parentID,
    string indent)
{
    //
    // Output object ID
    //
    Console.WriteLine(indent + parentID);

    indent += "    ";

    //
    // Enumerate children (if any)
    //
    PortableDeviceApiLib.IEnumPortableDeviceObjectIDs pEnum;
    pContent.EnumObjects(0, parentID, null, out pEnum);

    uint cFetched = 0;
    do
    {
        string objectID;
        pEnum.Next(1, out objectID, ref cFetched);

        if (cFetched &gt; 0)
        {
            //
            // Recurse into children
            //
            Enumerate(ref pContent, objectID, indent);
        }
    } while (cFetched &gt; 0);
}

static void StartEnumerate(
    ref PortableDeviceApiLib.PortableDeviceClass pPortableDevice)
{
    //
    // Get content interface required to enumerate
    //
    PortableDeviceApiLib.IPortableDeviceContent pContent;
    pPortableDevice.Content(out pContent);

    Enumerate(ref pContent, "DEVICE", "");
}
</pre>
<p><em>StartEnumerate</em>&nbsp;is the entry point into the enumeration. This needs to be called with a valid opened device connection. StartEnumerate then defers to the recursive <em>Enumerate</em> function which requires the parent object ID to enumerate. Using the <em>EnumObjects</em> API, we get back the <em>IEnumPortableDeviceObjectIDs</em> enumerator. For each object in the enumeration, we call <em>Enumerate</em> again.</p>
<p>Caveats:</p>
<ul>
<li><em>IEnumPortableDeviceObjectIDs::Next</em> allows more than one object IDs to be returned. We don't take advantage of this optimization since the default interop doesn't handle the array very well. If you need to use this, you will have to edit the interop by hand and fix up the assembly to handle the array correctly.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Setting WPD properties in C#</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/setting-wpd-properties-in-c</link>
      <pubDate>Mon, 11 Dec 2006 15:43:18 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2006/12/11/setting-wpd-properties-in-c/</guid>
      <description><![CDATA[Since setting a WPD property requires manipulating a PROPVARIANT structure through interop, we must...]]></description>
      <content:encoded><![CDATA[<p>Since setting a WPD property requires manipulating a PROPVARIANT structure through interop, we must make use of the marshalling rules we set in our <a href="https://blogs.msdn.com/dimeby8/archive/2006/12/11/wpd-property-retrieval-in-c.aspx">last post</a>.</p> <p>We'll take a look at a function that allows string properties to be set. </p><pre>static void SetStringValue(
    PortableDeviceApiLib.PortableDeviceClass pPortableDevice,
    string objectID,
    ref PortableDeviceApiLib._tagpropertykey propKey,
    string newValue)
{
    //
    // Retrieve IPortableDeviceContent interface required to
    // obtain the IPortableDeviceProperties interface
    //
    PortableDeviceApiLib.IPortableDeviceContent pContent;
    pPortableDevice.Content(out pContent);

    //
    // Retrieve IPortableDeviceProperties interface required
    // to get all the properties
    //
    PortableDeviceApiLib.IPortableDeviceProperties pProperties;
    pContent.Properties(out pProperties);

    //
    // Create the Values collection to hold the value to be set
    //
    PortableDeviceApiLib.IPortableDeviceValues pSetValues = 
        (PortableDeviceApiLib.IPortableDeviceValues)
            new PortableDeviceTypesLib.PortableDeviceValuesClass();

    //
    // Use the C# PropVariant definition to set the string value
    //
    PropVariant pvSet = new PropVariant();
    pvSet.variantType = 31; // VT_LPWSTR
    pvSet.pointerValue = Marshal.StringToCoTaskMemUni(newValue);

    //
    // Marshal our definition into a pointer
    //
    IntPtr ptrValue = Marshal.AllocHGlobal(Marshal.SizeOf(pvSet));
    Marshal.StructureToPtr(pvSet, ptrValue, false);

    //
    // Marshal pointer into the interop PROPVARIANT 
    //
    PortableDeviceApiLib.tag_inner_PROPVARIANT ipSet =
      (PortableDeviceApiLib.tag_inner_PROPVARIANT)
        Marshal.PtrToStructure(ptrValue, typeof(PortableDeviceApiLib.tag_inner_PROPVARIANT));

    //
    // Call the SetValues API to set the specified property
    //
    pSetValues.SetValue(ref propKey, ref ipSet);

    PortableDeviceApiLib.IPortableDeviceValues pResults;
    pProperties.SetValues(objectID, pSetValues, out pResults);
}
</pre>
<p>The example assumes that a device connection has already been opened. For this function to build, the PropVariant definition needs to be present and <a href="https://blogs.msdn.com/dimeby8/archive/2006/12/06/where-are-the-wpd-property-keys-in-c.aspx">PortableDeviceConstants.cs</a> needs to be part of the project.</p>
<p>We first acquire the <em>IPortableDeviceProperties</em>&nbsp;interface since that exposes the <em>SetValues</em> API method. Next we prepare the PROPVARIANT of vartype VT_LPWSTR that needs to be sent in. We first create an instance of the C# definition and set the pointer value to a marshalled instance of the value to be set using <em>Marshal.StringToCoTaskMemUni</em>. We next marshal our definition into a pointer and then re-marshal the pointer into the <em>tag_inner_PROPVARIANT</em> type expected by the API. This final value is then added to the values collection and this collection is sent down to the driver via the <em>SetValues</em> API.</p>
<p>This style of preparing the PROPVARIANT is common across different APIs. e.g. The <em>Delete </em>API expects a PropVariantCollection. All that needs to be done is prepare the PROPVARIANT using the style above and then add the prepared PROPVARIANT into a PropVariantCollection. This collection can then be sent down with the <em>Delete</em> API.</p>]]></content:encoded>
    </item>
    <item>
      <title>WPD property retrieval in C#</title>
      <link>https://docs.microsoft.com/archive/blogs/dimeby8/wpd-property-retrieval-in-c</link>
      <pubDate>Mon, 11 Dec 2006 15:17:53 GMT</pubDate>
      <dc:creator><![CDATA[Darene Lewis [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dimeby8/2006/12/11/wpd-property-retrieval-in-c/</guid>
      <description><![CDATA[WPD property values are retrieved as PROPVARIANTs through the WPD API. Unfortunately there is no...]]></description>
      <content:encoded><![CDATA[<p>WPD property values are retrieved as PROPVARIANTs through the WPD API. Unfortunately there is no native support for PROPVARIANTs in C#. To correctly retrieve the property values (or anything that is in a PROPVARIANT) through the WPD API in C#, we must use marshalling.</p> <p><em>PortableDeviceApiLib.tag_inner_PROPVARIANT</em> is the data-type exposed through the WPD Interop layer. This data-type exposes the <em>.vt</em> member, but it does not expose the anonymous union which is the <em>raison d'être</em> for the PROPVARIANT structure. </p> <p>To get to the union, we need to re-define the PROPVARIANT data-type in C#. We can get by with the following definition:</p><pre>using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct PropVariant
{
    [FieldOffset(0)]
    public short variantType;
    [FieldOffset(8)]
    public IntPtr pointerValue;
    [FieldOffset(8)]
    public byte byteValue;
    [FieldOffset(8)]
    public long longValue;
} 
</pre>
<p>This follows exactly the struct layout of a PROPVARIANT. We haven't included all the PROPVARIANT fields, feel free to add them as and when you need them. For our example, we'll manage with the ones above.</p>
<p>Now that we have a C# specific PROPVARIANT definition, we should be able to convert back and forth to the interop version. This isn't as easy as a simple cast - we'll have to use marshalling to do this.</p>
<p>To convert from the interop <em>tag_inner_PROPVARIANT</em> to our C# <em>PropVariant</em>: <pre>PortableDeviceApiLib.tag_inner_PROPVARIANT ipValue = 
                     new PortableDeviceApiLib.tag_inner_PROPVARIANT();

IntPtr ptrValue = Marshal.AllocHGlobal(Marshal.SizeOf(ipValue));
Marshal.StructureToPtr(ipValue, ptrValue, false);

PropVariant pv = (PropVariant)Marshal.PtrToStructure(p, typeof(PropVariant));
</pre>
<p></p>
<p>To convert from our C# <em>PropVariant</em> to the interop <em>tag_inner_PROPVARIANT</em>: <pre>PropVariant pvValue = new PropVariant();

IntPtr ptrValue = Marshal.AllocHGlobal(Marshal.SizeOf(pvValue));
Marshal.StructureToPtr(pvValue, ptrValue, false);

PortableDeviceApiLib.tag_inner_PROPVARIANT ipValue =
    (PortableDeviceApiLib.tag_inner_PROPVARIANT)
    Marshal.PtrToStructure(ptrValue, typeof(PortableDeviceApiLib.tag_inner_PROPVARIANT));
</pre>
<p>Essentially what we are doing for both cases is getting a pointer to the original structure and then casting it back (via marshalling) to the second structure.</p>
<p>Now let's see this in action - we'll attempt to retrieve all the properties for the <em>DEVICE</em> object and display the value for all string properties.</p><pre>static void DisplayProperties(
    PortableDeviceApiLib.PortableDeviceClass pPortableDevice, 
    string objectID)
{
    //
    // Retrieve IPortableDeviceContent interface required to
    // obtain the IPortableDeviceProperties interface
    //
    PortableDeviceApiLib.IPortableDeviceContent pContent;
    pPortableDevice.Content(out pContent);

    //
    // Retrieve IPortableDeviceProperties interface required
    // to get all the properties
    //
    PortableDeviceApiLib.IPortableDeviceProperties pProperties;
    pContent.Properties(out pProperties);

    //
    // Call the GetValues API, we specify null to indicate we
    // want to retrieve all properties
    //
    PortableDeviceApiLib.IPortableDeviceValues pPropValues;
    pProperties.GetValues(objectID, null, out pPropValues);

    //
    // Get count of properties
    //
    uint cPropValues = 0;
    pPropValues.GetCount(ref cPropValues);
    Console.WriteLine("Received " + cPropValues.ToString() + " properties");

    for (uint i = 0; i &lt; cPropValues; i++)
    {
        //
        // Retrieve the property at index 'i'
        //
        PortableDeviceApiLib._tagpropertykey propKey = 
                        new PortableDeviceApiLib._tagpropertykey();
        PortableDeviceApiLib.tag_inner_PROPVARIANT ipValue = 
                        new PortableDeviceApiLib.tag_inner_PROPVARIANT();
        pPropValues.GetAt(i, ref propKey, ref ipValue);

        //
        // Allocate memory for the intermediate marshalled object
        // and marshal it as a pointer
        //
        IntPtr ptrValue = Marshal.AllocHGlobal(Marshal.SizeOf(ipValue));
        Marshal.StructureToPtr(ipValue, ptrValue, false);

        //
        // Marshal the pointer into our C# object
        //
        PropVariant pvValue = 
            (PropVariant)Marshal.PtrToStructure(ptrValue, typeof(PropVariant));

        //
        // Display the property if it a string (VT_LPWSTR is decimal 31)
        //
        if (pvValue.variantType == 31 /*VT_LPWSTR*/)
        {
            Console.WriteLine("{0}: Value is \"{1}\"", 
                (i + 1).ToString(), Marshal.PtrToStringUni(pvValue.pointerValue));
        }
        else
        {
            Console.WriteLine("{0}: Vartype is {1}", 
                (i + 1).ToString(), pvValue.variantType.ToString());
        }
        //PropVariant pv = new PropVariant(ip);
    }
}
</pre>
<p>The example assumes that a device connection has already been opened. It also assumes that the PropVariant definition (from above) is present somewhere in the class definition. </p>
<p>We need to start with obtaining the <em>IPortableDeviceProperties </em>interface. Once we have the interface, we call the <em>GetValues</em> API to retrieve the properties. This is in a ValuesCollection object, so we use <em>GetAt</em> to retrieve each property. The retrieved property is of type <em>tag_inner_PROPVARIANT</em> which we convert to our C# PropVariant definition using marshalling. Once we have the data in our PropVariant structure, we can reference the string by marshalling the pointer value in the PropVariant to a <em>string</em> object.</p>
<p>As an exercise, try extending this example to display the value for properties of different vartypes.&nbsp; In our next post, we'll see how we can set property values.</p>]]></content:encoded>
    </item>
  </channel>
</rss>