DMProcessConfigXML CM_MAPPINGS

P

Peter Morris

Hi all

I am using the following code to try to add a URL exception to the networks
list on my PocketPC 2003.

================
public enum ConfigFlag : uint
{
/// <summary>
/// The configuration management service and the
/// Configuration Service Providers (CSPs) process
/// the input data.
/// </summary>
Process = 1,

/// <summary>
/// The configuration management service gathers
/// and returns metadata for any XML parm elements
/// it encounters.
/// </summary>
Metadata = 2
}

public class ConfigWrapper
{
[DllImport("aygshell.dll")]
private extern static UInt32 DMProcessConfigXML(string xmlIn, UInt32
flag, out IntPtr xmlOutPtr);

[DllImport("coredll.dll")]
private extern static IntPtr LocalFree(IntPtr hMem);

public static string ProcessXml(string xml)
{
return ProcessXml(xml, ConfigFlag.Process);
}

/// <summary>
/// This function wraps acts as a managed interface to the
/// DMProcessConfigXML in Pocket PC 2003+ and Smartphone 2002+
/// The DMProcessConfigXML function grants remote access to the
/// configuration management functionality of the mobile device.
/// This function enables the submission of Extensible Markup
/// Language (XML) information that causes the settings of a
/// mobile device to change. See "Configuration Service Providers"
/// in the API for details on the XML schema.
/// </summary>
/// <param name="xml">
/// String of valid XML containing configuration data
/// </param>
/// <param name="flag">
/// Action flag (see ConfigFlag for details)
/// </param>
/// <returns>
/// String of valid XML containing the result of this operation
/// </returns>
public static string ProcessXml(string xml, ConfigFlag flag)
{
IntPtr xmlOutPtr;
string xmlOutStr;
long result;

result = DMProcessConfigXML(xml, (uint)flag, out xmlOutPtr);

// marshal the output string
xmlOutStr = Marshal.PtrToStringUni(xmlOutPtr);

// free the memory allocated by the API
LocalFree(xmlOutPtr);

// throw an exception if an error code was returned
if (result != 0)
{
throw new ArgumentException(String.Format(
"DMProcessConfigXML returned error code {0}", result),
xml);
}

return xmlOutStr;
}
}
================================


I have also tried this



=================================
internal static class XmlConfig
{
[DllImport("aygshell.dll")]
private static extern int DMProcessConfigXML(string pszWXMLin, int
dwFlags, IntPtr ppszwXmlOut);

[DllImport("coredll.dll")]
private static extern void free(int buffer);

unsafe static public void ProcessXml(string Xml)
{
fixed (int* OutPtr = new int[1])
{
IntPtr outptr = (IntPtr)OutPtr;
int result = DMProcessConfigXML(Xml, 1, outptr);
if (result != 0)
throw new Exception("Could not set network preferences");
else
free(*OutPtr);
}
}
==============================



The XML being sent is as follows:
<wap-provisioningdoc>

<characteristic type="CM_Mappings">

<characteristic type="1005">

<param name="pattern"
value="http://myserver.com/MyWebServiceFolder/SyncService.asmx" />

<param name="network" value="{A1182988-0D73-439e-87AD-2A5B369F808B}" />

</characteristic>

</characteristic>

</wap-provisioningdoc>







If I manually add an exception then my app does not invoke the GPRS dialler
and connects to the server through the WORK connection, if I remove this
manual exception and try to add it using either of the two above methods the
dialler dialog still appears and the Internet connection is used. As far as
I can see from all sources on the web I am doing this correctly, but it just
isn't working. Can anyone help me with this? I saw Peter Foot asking how
to do the same thing quite some time ago so I hope he at least has achieved
his goal and might share the answer :)





Thanks in advance!





Pete
 
P

Peter Foot [MVP]

My guess is the issue is with the mapping index you are using (1005).
Suggest you add a mapping manually, then call the provisioning API to query
the current mappings and see how it is setup e.g.

<wap-provisioningdoc>
<characteristic-query type="CM_Mappings"/>
</wap-provisioningdoc>

Also while the first code example is 99% correct, you should free the
returned string pointer with free not LocalFree e.g.
[DllImport("coredll.dll", SetLastError = true)]
private static extern void free(IntPtr ptr);

Peter

--
Peter Foot
Device Application Development MVP
www.peterfoot.net | www.inthehand.com


Peter Morris said:
Hi all

I am using the following code to try to add a URL exception to the
networks list on my PocketPC 2003.

================
public enum ConfigFlag : uint
{
/// <summary>
/// The configuration management service and the
/// Configuration Service Providers (CSPs) process
/// the input data.
/// </summary>
Process = 1,

/// <summary>
/// The configuration management service gathers
/// and returns metadata for any XML parm elements
/// it encounters.
/// </summary>
Metadata = 2
}

public class ConfigWrapper
{
[DllImport("aygshell.dll")]
private extern static UInt32 DMProcessConfigXML(string xmlIn, UInt32
flag, out IntPtr xmlOutPtr);

[DllImport("coredll.dll")]
private extern static IntPtr LocalFree(IntPtr hMem);

public static string ProcessXml(string xml)
{
return ProcessXml(xml, ConfigFlag.Process);
}

/// <summary>
/// This function wraps acts as a managed interface to the
/// DMProcessConfigXML in Pocket PC 2003+ and Smartphone 2002+
/// The DMProcessConfigXML function grants remote access to the
/// configuration management functionality of the mobile device.
/// This function enables the submission of Extensible Markup
/// Language (XML) information that causes the settings of a
/// mobile device to change. See "Configuration Service Providers"
/// in the API for details on the XML schema.
/// </summary>
/// <param name="xml">
/// String of valid XML containing configuration data
/// </param>
/// <param name="flag">
/// Action flag (see ConfigFlag for details)
/// </param>
/// <returns>
/// String of valid XML containing the result of this operation
/// </returns>
public static string ProcessXml(string xml, ConfigFlag flag)
{
IntPtr xmlOutPtr;
string xmlOutStr;
long result;

result = DMProcessConfigXML(xml, (uint)flag, out xmlOutPtr);

// marshal the output string
xmlOutStr = Marshal.PtrToStringUni(xmlOutPtr);

// free the memory allocated by the API
LocalFree(xmlOutPtr);

// throw an exception if an error code was returned
if (result != 0)
{
throw new ArgumentException(String.Format(
"DMProcessConfigXML returned error code {0}", result),
xml);
}

return xmlOutStr;
}
}
================================


I have also tried this



=================================
internal static class XmlConfig
{
[DllImport("aygshell.dll")]
private static extern int DMProcessConfigXML(string pszWXMLin, int
dwFlags, IntPtr ppszwXmlOut);

[DllImport("coredll.dll")]
private static extern void free(int buffer);

unsafe static public void ProcessXml(string Xml)
{
fixed (int* OutPtr = new int[1])
{
IntPtr outptr = (IntPtr)OutPtr;
int result = DMProcessConfigXML(Xml, 1, outptr);
if (result != 0)
throw new Exception("Could not set network preferences");
else
free(*OutPtr);
}
}
==============================



The XML being sent is as follows:
<wap-provisioningdoc>

<characteristic type="CM_Mappings">

<characteristic type="1005">

<param name="pattern"
value="http://myserver.com/MyWebServiceFolder/SyncService.asmx" />

<param name="network" value="{A1182988-0D73-439e-87AD-2A5B369F808B}" />

</characteristic>

</characteristic>

</wap-provisioningdoc>







If I manually add an exception then my app does not invoke the GPRS
dialler and connects to the server through the WORK connection, if I
remove this manual exception and try to add it using either of the two
above methods the dialler dialog still appears and the Internet connection
is used. As far as I can see from all sources on the web I am doing this
correctly, but it just isn't working. Can anyone help me with this? I
saw Peter Foot asking how to do the same thing quite some time ago so I
hope he at least has achieved his goal and might share the answer :)





Thanks in advance!





Pete
 
P

Peter Foot [MVP]

For example this is what I get back:-

<wap-provisioningdoc>
<characteristic type="CM_Mappings">
<characteristic type="16777216">
<parm name="Pattern"
value="http://myserver.com/MyWebServiceFolder/SyncService.asmx/*" />
<parm name="Network" value="{A1182988-0D73-439E-87AD-2A5B369F808B}" />
</characteristic>
<characteristic type="536870912">
<parm name="Pattern" value="wsp://*/*" />
<parm name="Network" value="{7022E968-5A97-4051-BC1C-C578E2FBA5D9}" />
</characteristic>
<characteristic type="553648128">
<parm name="Pattern" value="wsps://*/*" />
<parm name="Network" value="{F28D1F74-72BE-4394-A4A7-4E296219390C}" />
</characteristic>
<characteristic type="570425344">
<parm name="Pattern" value="*://*.*/*" />
<parm name="Network" value="{436EF144-B4FB-4863-A041-8F905A62C572}" />
</characteristic>
<characteristic type="587202560">
<parm name="Pattern" value="*://*/*" />
<parm name="Network" value="{A1182988-0D73-439E-87AD-2A5B369F808B}" />
</characteristic>
</characteristic>
</wap-provisioningdoc>

From this I can deduce that the mapping indexes are nothing like what the
documentation says is used for the standard mappings - and user mappings
start at 0x1000000. Also both Pattern and Network parm names are capitalized
though I'm not sure if the API is case sensitive.

Peter

--
Peter Foot
Device Application Development MVP
www.peterfoot.net | www.inthehand.com

Peter Foot said:
My guess is the issue is with the mapping index you are using (1005).
Suggest you add a mapping manually, then call the provisioning API to
query the current mappings and see how it is setup e.g.

<wap-provisioningdoc>
<characteristic-query type="CM_Mappings"/>
</wap-provisioningdoc>

Also while the first code example is 99% correct, you should free the
returned string pointer with free not LocalFree e.g.
[DllImport("coredll.dll", SetLastError = true)]
private static extern void free(IntPtr ptr);

Peter

--
Peter Foot
Device Application Development MVP
www.peterfoot.net | www.inthehand.com


Peter Morris said:
Hi all

I am using the following code to try to add a URL exception to the
networks list on my PocketPC 2003.

================
public enum ConfigFlag : uint
{
/// <summary>
/// The configuration management service and the
/// Configuration Service Providers (CSPs) process
/// the input data.
/// </summary>
Process = 1,

/// <summary>
/// The configuration management service gathers
/// and returns metadata for any XML parm elements
/// it encounters.
/// </summary>
Metadata = 2
}

public class ConfigWrapper
{
[DllImport("aygshell.dll")]
private extern static UInt32 DMProcessConfigXML(string xmlIn, UInt32
flag, out IntPtr xmlOutPtr);

[DllImport("coredll.dll")]
private extern static IntPtr LocalFree(IntPtr hMem);

public static string ProcessXml(string xml)
{
return ProcessXml(xml, ConfigFlag.Process);
}

/// <summary>
/// This function wraps acts as a managed interface to the
/// DMProcessConfigXML in Pocket PC 2003+ and Smartphone 2002+
/// The DMProcessConfigXML function grants remote access to the
/// configuration management functionality of the mobile device.
/// This function enables the submission of Extensible Markup
/// Language (XML) information that causes the settings of a
/// mobile device to change. See "Configuration Service Providers"
/// in the API for details on the XML schema.
/// </summary>
/// <param name="xml">
/// String of valid XML containing configuration data
/// </param>
/// <param name="flag">
/// Action flag (see ConfigFlag for details)
/// </param>
/// <returns>
/// String of valid XML containing the result of this operation
/// </returns>
public static string ProcessXml(string xml, ConfigFlag flag)
{
IntPtr xmlOutPtr;
string xmlOutStr;
long result;

result = DMProcessConfigXML(xml, (uint)flag, out xmlOutPtr);

// marshal the output string
xmlOutStr = Marshal.PtrToStringUni(xmlOutPtr);

// free the memory allocated by the API
LocalFree(xmlOutPtr);

// throw an exception if an error code was returned
if (result != 0)
{
throw new ArgumentException(String.Format(
"DMProcessConfigXML returned error code {0}", result),
xml);
}

return xmlOutStr;
}
}
================================


I have also tried this



=================================
internal static class XmlConfig
{
[DllImport("aygshell.dll")]
private static extern int DMProcessConfigXML(string pszWXMLin, int
dwFlags, IntPtr ppszwXmlOut);

[DllImport("coredll.dll")]
private static extern void free(int buffer);

unsafe static public void ProcessXml(string Xml)
{
fixed (int* OutPtr = new int[1])
{
IntPtr outptr = (IntPtr)OutPtr;
int result = DMProcessConfigXML(Xml, 1, outptr);
if (result != 0)
throw new Exception("Could not set network preferences");
else
free(*OutPtr);
}
}
==============================



The XML being sent is as follows:
<wap-provisioningdoc>

<characteristic type="CM_Mappings">

<characteristic type="1005">

<param name="pattern"
value="http://myserver.com/MyWebServiceFolder/SyncService.asmx" />

<param name="network" value="{A1182988-0D73-439e-87AD-2A5B369F808B}" />

</characteristic>

</characteristic>

</wap-provisioningdoc>







If I manually add an exception then my app does not invoke the GPRS
dialler and connects to the server through the WORK connection, if I
remove this manual exception and try to add it using either of the two
above methods the dialler dialog still appears and the Internet
connection is used. As far as I can see from all sources on the web I am
doing this correctly, but it just isn't working. Can anyone help me with
this? I saw Peter Foot asking how to do the same thing quite some time
ago so I hope he at least has achieved his goal and might share the
answer :)





Thanks in advance!





Pete
 
P

Peter Morris

Hi Peter

I really appreciate your input on this, I am really stuck and as usual on a
very tight deadline (I have about 2 more hours to fix it)!
<wap-provisioningdoc>
<characteristic-query type="CM_Mappings"/>
</wap-provisioningdoc>

Do I just pass that as the XML but instead of "1" (process) I pass "2"
(metadata)? How do I find the result of that query? The XML returned to me
from that first routine seems to be identical to the XML I send it.

Also while the first code example is 99% correct, you should free the
returned string pointer with free not LocalFree e.g.
[DllImport("coredll.dll", SetLastError = true)]
private static extern void free(IntPtr ptr);

Changed!


Thanks very much!


Pete
 
P

Peter Morris

Hi Peter

Would you mind posting the source code you used to retrieve that XML please?

Thanks

Pete
 
P

Peter Foot [MVP]

Pass in 3 to process and return metadata. I used:-

System.Xml.XmlDocument d2 =
Microsoft.WindowsMobile.Configuration.ConfigurationManager.ProcessConfiguration(d,
true);

I also have an exact equivalent of this class to also support WM2003 in this
library - http://www.inthehand.com/WindowsMobile.aspx (including the free
community edition).

Peter

--
Peter Foot
Device Application Development MVP
www.peterfoot.net | www.inthehand.com

Peter Morris said:
Hi Peter

I really appreciate your input on this, I am really stuck and as usual on
a very tight deadline (I have about 2 more hours to fix it)!
<wap-provisioningdoc>
<characteristic-query type="CM_Mappings"/>
</wap-provisioningdoc>

Do I just pass that as the XML but instead of "1" (process) I pass "2"
(metadata)? How do I find the result of that query? The XML returned to
me from that first routine seems to be identical to the XML I send it.

Also while the first code example is 99% correct, you should free the
returned string pointer with free not LocalFree e.g.
[DllImport("coredll.dll", SetLastError = true)]
private static extern void free(IntPtr ptr);

Changed!


Thanks very much!


Pete
 
P

Peter Morris

Hi Peter, thanks for the tips!

Before manual addition:
<wap-provisioningdoc>
<characteristic type="CM_Mappings">
<characteristic type="536870912">
<parm name="Pattern" value="wsp://*/*" />
<parm name="Network" value="{7022E968-5A97-4051-BC1C-C578E2FBA5D9}" />
</characteristic>
<characteristic type="553648128">
<parm name="Pattern" value="wsps://*/*" />
<parm name="Network" value="{F28D1F74-72BE-4394-A4A7-4E296219390C}" />
</characteristic>
<characteristic type="570425344">
<parm name="Pattern" value="*://*.*/*" />
<parm name="Network" value="{436EF144-B4FB-4863-A041-8F905A62C572}" />
</characteristic>
<characteristic type="587202560">
<parm name="Pattern" value="*://*/*" />
<parm name="Network" value="{A1182988-0D73-439E-87AD-2A5B369F808B}" />
</characteristic>
</characteristic>
</wap-provisioningdoc>

After manual addition I do the following:
string query = "<wap-provisioningdoc><characteristic-query
type=\"CM_Mappings\"/></wap-provisioningdoc>";
query = ConfigWrapper.ProcessXml(query, 1);

and see the following additional information:
<characteristic type="16777216">
<parm name="Pattern" value="*://myserver.com/*" />
<parm name="Network" value="{A1182988-0D73-439E-87AD-2A5B369F808B}" />
</characteristic>

So now I manually remove that exception and execute the following:
string networkAddress = "{A1182988-0D73-439E-87AD-2A5B369F808B}";
string xml =
"<wap-provisioningdoc>" +
"<characteristic type=\"CM_Mappings\">" +
"<characteristic type=\"16777216\">" +
"<parm name=\"Pattern\" value=\"*://myserver.com/*\" />" +
"<parm name=\"Network\" value=\"{A1182988-0D73-439E-87AD-2A5B369F808B}\"
/>" +
"</characteristic>" +
"</characteristic>" +
"</wap-provisioningdoc>";
ConfigWrapper.ProcessXml(xml, 2);

But when I execute the query again I see the original values in the return
string and no sign my myserver.com

No matter how many websites I read they all suggest what I am doing is
correct, yet it simply isn't working. Any ideas/help etc you can offer is
very gratefully received, thank you so much!


Pete
 
P

Peter Foot [MVP]

I tried this and it adds to the list in the UI:-
System.Xml.XmlDocument d = new System.Xml.XmlDocument();
d.LoadXml("<wap-provisioningdoc><characteristic
type=\"CM_Mappings\"><characteristic type=\"16777217\"><parm
name=\"Pattern\" value=\"*://myserver.com/*\" /><parm name=\"Network\"
value=\"{A1182988-0D73-439E-87AD-2A5B369F808B}\"
/></characteristic></characteristic></wap-provisioningdoc>");
System.Xml.XmlDocument d2 =
Microsoft.WindowsMobile.Configuration.ConfigurationManager.ProcessConfiguration(d,
true);

Excuse the messy formatting :)

Peter
 
P

Peter Morris

Hi Peter

The tip to query the values already there was what I needed. The problems
were

01: I should always pass "1" for flags
02: I need a type with a high number for the type to give it a high priority
03: The full URL doesn't seem to work, whereas a url with a wildcard does

It now correctly avoids the GPRS modem, and all a fraction of time within my
deadline.


I'd just like to thank you very much for your time on this, I cannot express
how grateful I am!


Cheers

Pete
 
P

Peter Foot [MVP]

No problem, it was a bit of fun as I'm in the process of writing a piece
about the ConfigurationManager class at the moment so was good to dig into
the CM_* providers.

Peter
 
P

Peter Morris

Despite my initial teething problems I do really like the idea of using XML
to query/update the device's configuration!


Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top