Hi All,
I want to be able to uniquely identify a mobile device. I've discovered that devices have a Device ID but is only accessible via the Win API through PInvoke() calls. The article I found is here:
http://msdn2.microsoft.com/en-us/library/ms172516.aspx
PInvoking is not a problem for me. I actually found this article through a message board where someone actually had problems using it.
1) Is this article up to date and compatible with WM 5.0 devices
Most Importantly
2) Is the device ID a GUID Or is it something else The article indicates it converts the final result into a string not a native GUID. This doesn't actually mean that the string doesn't contain a GUID though. I haven't run it through yet to see, but I don't want to get bogged down with this if this ID is not a GUID.
I ideally want to have a GUID for a device to identfiy it. If it is not available in the device itself I'll have to supply an encrypted file containing a GUID instead.
Thanks

Device ID Data Type
Quincunx55555
Hi Andrew,
Thanks for your response.
I was guessing this ID was some other form of ID over a GUID. Thanks for confirming this for me. I suppose this is not a problem as long as I can use them consistantly and and they are actually unique. Can I assume the length is the length of the ID I retrieved in my example, I suppose I would have to check this with another device. I was also reading a few minutes ago (I don't know if it applies) that SMS services rely on these Hardware ID's and sometimes they are not accessible or are invalid and need regenerating ! I maybe just confusing things here.
Based on my lack of knowledge on this Device ID subject, do you think it best that I generate GUID's myself for devices running my application. If so what would be best practice (Using .NET) in ensuring these generated GUID's are only usable by the device that it was generated for. (I suppose the hardware ID, lol) Am I worrying myself too much here I just want to use some form of ID to validate (authenticate) the device on the web server hosting application data for the .NETCF app.
Thanks
Richard
RafaDom
Hi Again,
Ok so I've run the code to retrieve the ID. The string result I got back is:
50006F0063006B0065007400500043000000-00
This is certainly not a formatted GUID string and it is also a little too large to be one as well. Now is this string Device ID Globally Unique Can it be interpreted as a GUID If not, should I store this ID as a VARCHAR datatype in SQL Server 2005 instead of a UniqueIdentifier
Any advice would be greatly appreciated.
Many Thanks
Richard
BarataMota
I believe that ID is an ESN -- electronic serial number -- or an IMEI -- international mobile equipment identity -- though the length doesn't seem quite right for either of those, either. No, I don't believe it can be cast as a GUID without losing information. Yes, store it as a varchar, or a fixed length char, since you know the length.
spelger
Hi Richard
In case the device ID is larger than the buffer your are supplying (20 bytes) the KernelIoControl call will fail. If the reason is a too small buffer, the GetLastError is set to ERROR_INSUFFICIENT_BUFFER.
in this case - simply try again with a larger buffer (probably double its size).
More details: http://msdn.microsoft.com/library/default.asp url=/library/en-us/wcehardware5/html/wce50lrfioctlhalgetdeviceid.asp
Michael
dtorg1955
Hi Michael,
Thank you for your invaluable help on this subject. I will update my code and handle these errors correctly. One last question if I may, the ID's at the moment are being converted into strings of 40 characters in length. I will be storing these characters in a SQL Table using a varchar type. What should I set the size to As I'm using SQL 2005 should I use varchar(MAX) or is this a lazy inefficiant solution to this
I'm really starting to get into Mobile development with .NETCF2.0 and have deployed my current app on a real HP IPaq to test so far. It works a charm and I am really excited about the potential of this platform! I think I gonna get hooked on this stuff <g>
Many Thanks
Richard
Isonduil
Hi Richard
The Windows Media DRM system required that a device supports the IOCTL_HAL_GET_DEVICEID KernelIoContol call. That means you can savely assume that any Windows Mobile device will support this (as all WM devices I know do support DRM)
You should be cautious about any type of assumption concering length and format of the returned ID. The returned ID is only guaranteed to be unique - everything else is up to the OEM.
Michael
becklighter
Hi Michael,
Thanks again for your reply, very much appreciated.
The example I used when calling GetDeviceUniqueID() states that the size of the hash can be no smaller than 20 bytes. The buffer used to retrieve this hash in my code is 20 bytes. Are you saying that even though I specify a buffer size of 20 bytes that I may get back a truncated result without knowing it How would I handle this situation, or can I
Thanks
Richard
mariek
i am using Kernel Io Control to retrieve the Device ID .when i try to get the device Id with the following code in T-mobile HTC Dash , its showing WIN 32 EXCEPTION :
the code :
private static Int32 METHOD_BUFFERED = 0;
private static Int32 FILE_ANY_ACCESS = 0;
private static Int32 FILE_DEVICE_HAL = 0x00000101;
private const Int32 ERROR_NOT_SUPPORTED = 0x32;
private const Int32 ERROR_INSUFFICIENT_BUFFER = 0x7A;
private static Int32 IOCTL_HAL_GET_DEVICEID = ((FILE_DEVICE_HAL) << 16) | ((FILE_ANY_ACCESS) << 14) | ((21) << 2) | (METHOD_BUFFERED);
[DllImport("coredll.dll", SetLastError=true)]
private static extern bool KernelIoControl(Int32 dwIoControlCode, IntPtr lpInBuf, Int32 nInBufSize, byte[] lpOutBuf, Int32 nOutBufSize, ref Int32 lpBytesReturned);
public DeviceID()
{
}
public string GetDeviceID()
{
byte[] outbuff = new byte[20];
Int32 dwOutBytes;
bool done = false;
Int32 nBuffSize = outbuff.Length;
// Set DEVICEID.dwSize to size of buffer. Some platforms look at
// this field rather than the nOutBufSize param of KernelIoControl
// when determining if the buffer is large enough.
//
BitConverter.GetBytes(nBuffSize).CopyTo(outbuff, 0);
dwOutBytes = 0;
// Loop until the device ID is retrieved or an error occurs
while (! done)
{
if (KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero, 0, outbuff, nBuffSize, ref dwOutBytes))
{
done = true;
}
else
{
int error = Marshal.GetLastWin32Error();
switch (error)
{
case ERROR_NOT_SUPPORTED:
throw new NotSupportedException("IOCTL_HAL_GET_DEVICEID is not supported on this device", new Win32Exception(error));
case ERROR_INSUFFICIENT_BUFFER:
// The buffer wasn't big enough for the data. The
// required size is in the first 4 bytes of the output
// buffer (DEVICE_ID.dwSize).
nBuffSize = BitConverter.ToInt32(outbuff, 0);
outbuff = new byte[nBuffSize];
// Set DEVICEID.dwSize to size of buffer. Some
// platforms look at this field rather than the
// nOutBufSize param of KernelIoControl when
// determining if the buffer is large enough.
//
BitConverter.GetBytes(nBuffSize).CopyTo(outbuff, 0);
break;
default:
throw new Win32Exception(error, "Unexpected error");
}
}
}
Int32 dwPresetIDOffset = BitConverter.ToInt32(outbuff, 0x4); // DEVICE_ID.dwPresetIDOffset
Int32 dwPresetIDSize = BitConverter.ToInt32(outbuff, 0x8); // DEVICE_ID.dwPresetSize
Int32 dwPlatformIDOffset = BitConverter.ToInt32(outbuff, 0xc); // DEVICE_ID.dwPlatformIDOffset
Int32 dwPlatformIDSize = BitConverter.ToInt32(outbuff, 0x10); // DEVICE_ID.dwPlatformIDBytes
StringBuilder sb = new StringBuilder();
for (int i = dwPresetIDOffset; i < dwPresetIDOffset + dwPresetIDSize; i++)
{
sb.Append(String.Format("{0:X2}", outbuff
}
for (int i = dwPlatformIDOffset; i < dwPlatformIDOffset + dwPlatformIDSize; i ++ )
{
sb.Append( String.Format("{0:X2}", outbuff
}
return sb.ToString();
}
Moreover ,In my application i used Device Id to do some calculation , only if the calculation becomes positive , the app will run . so the user has to input the device Id . how do the user get the device Id for his real device . moreover will that Id matches Id created by the using above code ...
thanks
sadiq
bryanedds
Hi Michael,
Ok, this meakes sense but does this explicitly apply to the GetDeviceUniqueID() API call I'm currently avoiding using the KernelIoControl() call due to the trusted code requirement. I looked at the MSDN docs for the GetDeviceUniqueID call:
http://msdn.microsoft.com/library/default.asp url=/library/en-us/mobilesdk5/html/wce51lrfGetDeviceUniqueID.asp
Even though it does return ERROR_INSUFFICIENT_BUFFER, would it only do this if the buffer is smaller than 20 bytes. The doc does not state a warning of a variance in sizes but the section on insufficient buffer does say the result will truncate. The example in the docs is not checking for these errors but these examples never do ;) Is this a worry with this function
Basically all I'm saying here is even though the smallest hashed device ID will be 20 bytes, depending on the OEM and the size of the Rela ID provided could a larger hash value be produced
Richard
Matthijs Koopman
Hi Richard
Generally speaking: Samples are hardly ever 'production ready' - they usually just illustrate the usage of an API.
It is good practice to check the error code in production code and implement the appropriate error handling.
The documentation stats that you do need at least 20 bytes for the ID. To be on the save side your implementation should be able to handle IDs larger than the minimun size.
Michael
Srikanth Raghupathy
Hi Michael,
Thanks for your reply. These blogs are exactly what I've been after.
I've used the GetDeviceUniqueID() API call to get a 20 byte hashed Device ID. This so far looks good, I realise people have had problems using this, should I be cautious
When you mention 'All devices with a DRM enabled Windows Media Player support this' what do you mean
Thanks
Richard
Christoffer Skjoldborg
Hi Richard
The following blog has in deep information on the 'Device ID' story:
http://blogs.msdn.com/jehance/archive/2004/07/12/181116.aspx and http://blogs.msdn.com/jehance/archive/2004/07/12/181067.aspx and
http://blogs.msdn.com/windowsmobile/archive/2006/01/09/510997.aspx
This means: dont assume a particular length of the ID - this might vary on different devices.
I'd be calculating a hash value (for instance using the SHA hashing algoritm) based on the Device ID. All devices having a DRM enabled Windows Media Player do support this.
Because of this, there should be no need to provide your own implementation.
Hope this helps
Michael