Nadav and the wonders of the web


Posts Tagged ‘native call’

How to: Get unique device id in C# (Windows Mobile)

Friday, March 28th, 2008

While looking for a full article about this I found out it won’t hurt to have another quick explanation about this process.

Sometimes when creating an application you want some sort of verification about which phone is accessing your service (service-client application). A good way to do this is to use the unique device id.

Now I will explain how we do it, we are going to get a 40 char string that is hashed with an AppString we will provide which will be unique to each and every device, and will be constant for this device and AppString.

First we define the P/Invoke signature:

[DllImport("coredll.dll")]
private static extern int GetDeviceUniqueID([In, Out] byte[] appdata, int cbApplictionData,
                                            int dwDeviceIDVersion,
                                            [In, Out] byte[] deviceIDOuput, ref uint pcbDeviceIDOutput);

Now we are going to define a private static member so we don’t go through the entire process every time we need this and then create it with a public static method:

private static string s_UniqueDeviceID;

/// <summary>
/// Gets the unique device id, this is an unique id of the phone
/// which is hashed with the AppString
/// </summary>
/// <returns>a 40 characters unique id</returns>
public static string GetUniqueDeviceID()
{
    if (string.IsNullOrEmpty(s_UniqueDeviceID))
    {
        // define AppString
        string AppString = "MyAppString";

        // get the byte array for the string
        byte[] AppData = Encoding.ASCII.GetBytes(AppString);

        // some parameters for the native call
        int appDataSize = AppData.Length;
        uint SizeOut = 20;

        // our out parameter
        byte[] DeviceOutput = new byte[20];

        // Call the native GetDeviceUniqueID method from coredll.dll
        GetDeviceUniqueID(AppData, appDataSize, 1, DeviceOutput, ref SizeOut);

        // check that we got something
        if (SizeOut > 0)
        {
            // build text from received bytes
            StringBuilder resultText = new StringBuilder();
            for (int i = 0; i < DeviceOutput.Length; i++)
            {
                resultText.Append(string.Format("{0:x2}", DeviceOutput[i]));
            }

            // set up result
            s_UniqueDeviceID = resultText.ToString();
        }
    }

    return s_UniqueDeviceID;
}

As you can see the AppString can really be whatever we want it to be. the rest is a little work in order to transform it all from bytes to string but that is why we do it only once!

The only important thing I can see about the AppString is that it won’t be null\empty and that it will be constant throughout your application and usage.

Hope this was clear.

Cheers,

Nadav

Jajah is the VoIP player that brought you web-activated telephony.