GetDeviceUniqueID
There is a new API available for retrieving a device id in Windows Mobile 5.0 for both Pocket PC and Smartphone. The first question: why do we need a new way of getting the device ID, what’s wrong with the old? To answer this you need to know what a device ID is. There is a very good and detailed explanation here, but in essence it’s a 16 byte code derived from hardware specific information that is unique to each device. This ID is not the same as an IMEI or a phone number found on a phone based device, both of which can be changed, but instead this code lives and dies with the device.
So the device ID is a very useful thing for software that wants to target just your device, e.g. copy protection, or to provide immutable identity to web service calls. Equally so it’s a resource that should be protected to mitigate the risk of identity theft.
Getting at the device id is relatively straight forward but requires either some C++ or a reasonable amount of interop code. The api is something like this:
KernelIoControl(IOCTL_HAL_GET_DEVICEID, 0, 0, buffer, GuidLength,out, bytesReturned);
Protecting Device ID has always been present as part of the Smartphone security model by making the KernelIoControl API a privileged operation, meaning your code must be running in the trusted code group to be able to access this API. But there are two problems with this:
1> Up to and including Pocket PC 2003SE there is no security model to protect the API, so Pocket PC didn’t have any protection on the Device ID.
2> what do untrusted applications do when they want to get access to this API?
3> having lots of applications read and use the device id potentially increases the attack surface for identity theft.
GetDeviceUniqueID attempts to address these issues and to reduce applications dependency on the precious device id. Firstly GetDeviceUniqueID can be called from the trusted or untrusted code group, but the code returned is not the same as a call to KernelIoControl, its a 20 byte code not a 16 byte code. GetDeviceUniqueID takes an additional parameters of an application defined char array, and uses a one way hash to combine the real device id and the char array parameter to generate the new 20 byte code. This means that an application will always get the same 20 byte code if it calls GetDeviceUniqueID on the same device, with the same char array. It also means there is no practical way of asserting the true device id from the 20 byte key an application uses.
This is a native API exposed by coredll.dll so here is a managed code snippet showing how to get the info through interop. Standard Code disclaimer applies
/*
HRESULT GetDeviceUniqueID(
LPBYTE pbApplicationData,
DWORD cbApplictionData,
DWORD dwDeviceIDVersion,
LPBYTE pbDeviceIDOutput,
DWORD* pcbDeviceIDOutput
);
*/
[DllImport("coredll.dll")]
private extern static int GetDeviceUniqueID([In, Out] byte[] appdata,
int cbApplictionData,
int dwDeviceIDVersion,
[In, Out] byte[] deviceIDOuput,
out uint pcbDeviceIDOutput);
private byte[] GetDeviceID(string AppString)
{
// Call the GetDeviceUniqueID
byte[] AppData = new byte[AppString.Length];
for (int count = 0; count < AppString.Length; count++)
AppData[count] = (byte)AppString[count];
int appDataSize = AppData.Length;
byte[] DeviceOutput = new byte[20];
uint SizeOut = 20;
GetDeviceUniqueID(AppData, appDataSize, 1, DeviceOutput, out SizeOut);
return DeviceOutput;
}
The full project code is here.
Marcus
Comments
Anonymous
January 19, 2006
Hi
Thanks for this, it's working without any problem. For a project I need to have this in VB.NET but I can't seem to convert it correctly with some tools on the net...
Could you post the VB.NET-Code of this?
Thanks
SvenAnonymous
January 20, 2006
Using the same salt but on 3 different smartphone mobile 5 devices I'm getting back the exact same ID. I do not have that problem on CE mobile 5 devices. Has anyone seen this problem? Thanks.Anonymous
January 20, 2006
Hi Joe, Can you e-mail me and tell me which models of smartphones you're seeing this behavior with? (scyost at microsoft.com) Thanks, ScottAnonymous
January 20, 2006
Scott, I just did. Let me know if you don't received it. Thanks.Anonymous
February 01, 2006
Thanks for the couple of references and the information. The documentation in CE5.0 for IOCTL_HAL_GET_DEVICEID is incorrect. They have transposed the description of the Platform and Preset ID and there is no restriction/recommendation to the length of the returned ID. This created some incompatibilities for our device with other third party SW until we implemented it as a standard GUID with the description of Platform and Preset ID as per 4.1 documentation.Anonymous
February 02, 2006
HI,
I have the same problem too. The GetDeviceUniqueID returns the same number on O2 Atom even for different devices. But the same routine works perfectly fine on Dell X51V.
Is there any solution ?Anonymous
February 03, 2006
The unique part of the data that goes into that function comes out of the BSP for the platform. The OEM implements that code, so I can't comment that behavior.Anonymous
February 08, 2006
Has anyone found a solution to this? We really need to find a way to uniquely identify the device so that we can protect our software... and we have found several devices giving the same results using GetDeviceUniqueId.
So, it seems that the OEMs have once again spoiled the party.
We then thought of combining the results from GetDeviceUniqueId with the "old" KernelIoControl(IOCTL_HAL_GET_DEVICEID), but still that shows the same results on some devices.
So, what else is left to determine the uniqueness of the device? We are thinking of the Bluetooth Address and the WIFI card MAC... but is that guaranteed to be unique? I mean, if the OEMs can't correctly implement GetDeviceUniqueId() then how can we be sure that they haven't done the same mistake with any piece of hardware that comes inside the device.
Advise anyone?Anonymous
February 09, 2006
I was able to use KernelIoControl(IOCTL_HAL_GET_DEVICEID), instead of GetDeviceUniqueId(), to get a unique ID on SP mobile 5 devices. Of course the app has to be signed or it won't work.Anonymous
February 14, 2006
The comment has been removedAnonymous
February 17, 2006
use windowsAnonymous
February 23, 2006
Sorry to digress from device id. I just remembered mid last year there were news that Flextronics was making ready (nearly complete) a lowcost WM5 unit code name Peabody.
I cannot find any more news regarding that development? Has it evaporated?
Thanks for sharing your infoAnonymous
March 14, 2006
Is it possible to get the IMEI number for windows mobile 2003 for smartphones?Anonymous
April 05, 2006
At our Technet Mobility event we asked the attendees to text questions to us for the Q&amp;A session......Anonymous
May 18, 2006
I am developing an application for the smartphone platform (windows mobile 2003, second edition), in my case a secure phone. I need to get an unique device information in order to implement a copy protection for my application.The GetDeviceUniqueID is a very nice solution, but only works with windows mobile 5.
Do you have an easy solution for this kind of problem that doesn't need the privileged access to the kernel functions using certificates?Anonymous
May 21, 2006
is there any guarantee that an application, using the same AppData, will always get a different DeviceID when calling GetDeviceUniqueID an different devices?
Or is there a mathematical chance that two different devices will return the same DeviceID ?Anonymous
July 09, 2006
Can this code work with windows mobile2.0..?Anonymous
July 17, 2006
Is it a IMEI of Pocket PC and SmartPhone
Can it work on all deviceAnonymous
July 26, 2006
When I run this code within my VB .Net (CF 1.0) Application for WM 5.0 on Pocket PC, I just get back an empty Byte Array. Anyone an Idea why this might happen?Anonymous
August 10, 2006
智能设备的唯一编号,可以用于实现更好的智能设备软件的授权机制,还可以利用它来限制智能设备客户端软件访问后台服务的权限,从而提高系统的安全性。本文介绍了获取智能设备唯一编号的各种方法。Anonymous
August 10, 2006
http://www.cnblogs.com/upto/archive/2006/08/11/GetDeviceUniqueID.htmlAnonymous
August 22, 2006
Thanks for the code snippet to get the unique ID...
Not sure where to ask this, so I'll ask here. How does one programmatically check for presence of the following hardware on a given WM device?
- infrared
- bluetooth
- wi-fi
- camera
I would've also added 'keyboard' to this list, but I already saw your post on how to do this.
Any insight is greatly appreciated!
KeithAnonymous
September 22, 2006
private byte[] GetDeviceID(string AppString)
what's parameter AppString used?
what's "AppString" means?How can I catch it?Anonymous
September 23, 2006
It's a string that identifies the caller of the API. It gets hashed into the data that is returned, so different callers will get different results. There's more explanation on the MSDN page.Anonymous
September 27, 2006
How do you retrieve the imei from a Pocket PC Phone Edition or smartphone?Anonymous
October 26, 2006
Anyone know whether MS have fixed the problems with this API call? If not should we be reverting back to KernelIoControl() call with signed applications?Anonymous
November 29, 2006
How does knowing a deviceID pose an identity theft threat? Mike Landis http://pnmx.comAnonymous
December 20, 2006
iam having the same problem with GetDeviceUniqueID. It is always the same on my Qtek 8310 and Orange C600, the ID i get is: 8EE62802387C5E9E2B7892DDAED3ECE6AB0CE2E2 please paste yours!Anonymous
January 03, 2007
Feel free to a free trial of LicenseKey2Go.Anonymous
January 29, 2007
Is there any way out to retrieve Pocket PC DeviceID from a desktop application? Please help me in this context iff any solution exists.Anonymous
February 12, 2007
Any way to Get Owner name for deviceAnonymous
April 16, 2007
The comment has been removedAnonymous
April 17, 2007
GetDeviceUniqueId and the IOCTL method will give you different data back. That's expected.Anonymous
June 11, 2007
is there any problem using GetDeviceUniqueID() native call in Windows Mobile 5.0 I'm getting always the same result a list of 0000000000, in my emulator. is there any difference using KernelIoControl() I heard that the function returns a 16 bytes instead of the 20 on GetDeviceId, but how really affects my software, that issue? My mail is jpena@isthmusit.com Thanks,Anonymous
June 19, 2007
I got the device ID by using your code. But I still have another problem. I want to get the device ID via desktop programm. How can I do? I want use it like this: There is a winform has a button and a textbox in it. When click the button,the win programm to get the device ID and show it in the textbox(device already connected to the PC by ActiveSync). Is there has a solution? Thanks. My mail is burningsnow@163.comAnonymous
June 21, 2007
获取 Windows Mobile 设备的唯一标识各种方法。Anonymous
September 07, 2007
thanks a lot, i am get the guid successfuly!Anonymous
October 14, 2007
It's not the problem with OEMs. It is problem with Microsoft who didn't controlled OEMs. This would never happen on Symbian devices. Someone should pay for GetDeviceUniqueID non working.Anonymous
October 18, 2007
Anyone who have managed to use the GetDeviceUniqueID or the IOCTL_HAL_GET_DEVICEID so that it corresponds to the device id shown in Exchange 2003/2007?Anonymous
October 25, 2007
is the deviceid that shows up in the exchange 2003 interface related to the imei or meid of that device? is there a way to find the device id based on the imei/meid or vice versa?Anonymous
October 30, 2007
Can I use the hashed output of KernelIoControl as the unique identifier of the mobile device? Thanks.Anonymous
October 31, 2007
You can do that if you want, but don't count on being able to call IOCTL_HAL_GET_DEVICEID on Windows Mobile Standard/Smartphone or in future versions. GetDeviceUniqueId is the supported way to do it.Anonymous
February 21, 2008
Thanks for this post. I would like to access the "Device Serial No" on our Windows Mobile 5 device programmatically. This is the number that can be found in settings->system->systemInformation->identity->device serial no. Can anyone tell me how to access that number? It doesn't seem to be in the registry. We need to access it to do inventory tracking. It matches the bar code on the device. Thanks!Anonymous
February 21, 2008
@MK: That control panel is provided by the OEM, not Microsoft, so I don't actually know what it's doing. Does it match anything like what IOCTL_HAL_GET_DEVICEID returns?Anonymous
February 29, 2008
Thanks, Scott. No, it doesn't match any part of the value returned by IOCTL_HAL_GET_DEVICEID. There may be some hidden relationship there, but I don't see it in any case. There is a file call SystemInfo.cpl in Windows, but it appears to be a ROMMODULE file and hence I can't seem to read it. Any suggestions there?Anonymous
March 01, 2008
No, you won't be able to easily read the contents of the in-rom binaries. Try calling that IOCTL with both the sizeof(UNIQUE_DEVICEID) and the sizeof(DEVICE_ID). Sometimes it's implemented to return a different value in those cases. Maybe one of those values is the one you're looking for.Anonymous
March 28, 2008
Can someone tell me if the results of GetDeviceUniqueID remain the same after a device is upgraded from wm5 to 6/6.1?Anonymous
March 28, 2008
The simple answer is "yes" The complicated answer is: We require of our partners that the results of that API are consistent in the field. If you buy a WM5 device and the OEM provides an upgrade to WM6, it is one of our requirements that the ID does not change. We have some certification tests around it. There are cases where it would have to change, like if the WM5 version were returning inconsistent results. In those cases we waive the test in favor of fixing the behavior.Anonymous
March 28, 2008
Thanks for the info, Scott. I appreciate it.Anonymous
March 30, 2008
We have two E-TEN Glofiish X600 devices here and GetDeviceUniqueID returns exactly the same value for them. This method is definitely not reliable.Anonymous
April 22, 2008
The comment has been removedAnonymous
May 10, 2008
Hi, this function is not supported by WM because the file Pkfuncs.h is missing. Where can i get this file ?Anonymous
May 20, 2008
Translation for vb.net Declare Function GetDeviceUniqueID Lib "Coredll" (ByVal appdata As Byte(), ByVal cbApplictionData As Integer, ByVal dwDeviceIDVersion As Integer, ByVal deviceIDOuput As Byte(), ByRef pcbDeviceIDOutput As Integer) As Integer Private Function GetUniqueDeviceId() As String Dim AppString As String = "Appication Name" Dim AppData(AppString.Length) As Byte Dim count As Integer = 0 While count < AppString.Length AppData(count) = Convert.ToByte(AppString.Chars(count)) count += 1 End While Dim appDataSize As Integer = AppData.Length Dim DeviceOutput(20) As Byte Dim SizeOut As UInteger = 20 GetDeviceUniqueID(AppData, appDataSize, 1, DeviceOutput, SizeOut) Dim sb As StringBuilder = New StringBuilder() Dim x As Integer = 0 While x < DeviceOutput.Length sb.Append(String.Format("{0:x2}", DeviceOutput(x))) x += 1 End While Return sb.ToString() End FunctionAnonymous
June 04, 2008
This code compiles OK but produced zeros. I found success using an 11+ AppString. Carriers want to hide the natural ID and don't want it found out too easily. using System; using System.Runtime.InteropServices; //needed to use [dllimport], <dllimport> in vb.net namespace sdGetID { public class GetDeviceIdentity_Class { [DllImport("coredll.dll")] private extern static int GetDeviceUniqueID([In, Out] byte[] AppData, int cbApplictionData, int dwDeviceIDVersion, [In, Out] byte[] deviceIDOuput, out uint pcbDeviceIDOutput); // The article shows getting more then one ID so I added // IDVer as an integer - only 1 works but left it in. public byte[] GetDeviceID(string AppString, int IDVer) { // Call the GetDeviceUniqueID byte[] AppData = new byte[AppString.Length]; for (int count = 0; count < AppString.Length; count++) AppData[count] = (byte)AppString[count]; int AppDataSize = AppData.Length; byte[] DeviceOutput = new byte[20]; uint SizeOut = 20; GetDeviceUniqueID(AppData, AppDataSize, IDVer, DeviceOutput, out SizeOut); return DeviceOutput; } } }Anonymous
August 05, 2008
im using this code to get device unique id. it works well in wm5.0 and 6.0 but it not works on windows mobile 2003(pocketpc and smartphone). it throws missing method exception.. is there any other way?Anonymous
December 13, 2008
Thanks for your info... the Vb.NET sample will help me a lot.Anonymous
February 09, 2009
I've read through all these comments and the question is... Does GetUniqueDeviceID return a unique ID or not? At least 3 people are saying the ID's returned from different devices are the same, but the author has not commented on this?Anonymous
February 28, 2009
The comment has been removedAnonymous
March 01, 2009
While there is not a comprehensive list of devices affected, we are aware of some older device models that do not have a unique device ID. Since the rollout of our certification tests (during the Windows Mobile 6.x era), OEM devices are now required by Microsoft to have a unique device ID. This blog entry is thus only relevant for getting the unique device ID of properly certified devices.Anonymous
March 03, 2009
GetUniqueDeviceID and IOCTL_HAL_GET_DEVICEID gives the same values on different devices Gigabyte GSmart MS802 with WM6 (5.2.1623).Anonymous
March 10, 2009
Got this link from google on searching for "retrieve imei windows mobile" . http://www.venkydude.com/?p=31 Will this work?