Chris De Herrera's Windows CE Website

About
Discuss.Pocket PC FAQ Forum

Add Pocket PC FAQ to your Favorites
RSS    RSS Feeds
Wiki    Lost?
Custom Search
Subscribe    Print
Miscellaneous
Table of Contents
Mobile Format
News

Pocket PC Blast


 
Pocket PC Magazine Best Site

Website Awards
Website Updates

By Chris De Herrera 
Copyright 1998-2007
 All Rights Reserved
A member of the Talksites Family of Websites

Windows and Windows CE are trademarks of Microsoft
Corporation
and are used
under license from owner.
CEWindows.NET is not
associated with Microsoft 
Corporation.

All Trademarks are owned
by their respective companies.

CEWindows.NET Logo
Homemade Asset Management with the iPAQ
By Terence "Dr. CE" Goggin, Information Appliance Associates
Copyright 2001, All Rights Reserved

Shop unique and cheap iPhone cases on DHgate.com

One of the most commonly asked questions on the Windows CE/PocketPC forums and newsgroups these days is about the Compaq iPaq and its serial number feature.

As you probably know, every iPaq in existence has its own unique serial number. That means that, for example, if a developer were to couple an installation of his/her software with a particular iPaq serial number, that software would not work on any other iPaqs.

Additionally, a unique serial number also makes it possible to integrate the iPaqs into an existing corporate (software-based) asset management system.

So far, so good, right? Wrong.

That's because Compaq didn't tell the developers how to read this serial number from within their own programs. In other words, it's there, and you can use it, but only if you happen to work for a small computer concern located in the general Dallas area known as Compaq. 

However, all is not lost. It turns out that there are actually two different ways for you as  a developer to read this information for yourself!

I've collected a bit of sample code from two very generous individuals who did the research for these solutions themselves and were then good enough to post the solutions on one or another forums.  I'll give a short explanation of each below, but for the most part, if you have the code and comments, it should be self-explanatory.

Of course, you may wonder why there are two solutions to begin with; after all, one solution would be plenty. It turns out that the first solution we'll look at works very well on the iPaq 1550s and the iPaq 36xx devices with the new ROM, but not so well on the 36xx series with the old ROM. Similarly, the second solution should work on all iPaq devices but it a bit of a hack.

Let's take a look at each of these solutions...

The first solution is the simpler and more straightforward approach. It uses a semi-undocumented function called KernelIoControl(), which allows you to query the system for certain "low-level" data. In this example, we'll pass a 64-byte TCHAR array into the function, along with a predefined constant that tells the system we're looking for a serial number (also known as a UUID, or universally unique identifier). [Listing 1, below.]

The second solution is a little bit trickier. It turns out that there is a program in the \Windows directory of the iPaq called CreateAssetFile.exe. When you run this program, it creates a binary file called cpqAssetData.dat which contains all of the useful information the device has to offer. (This is how the Asset Viewer control panel applet seems to get its data, incidentally.) So, by parsing the .DAT file, we too can have access to all of this useful data.[Listing 2, below.]

All of this is immediately visible from the code listings below and the sample project provided along with this article. Hopefully, this will be helpful and save some time for those of us who are just now discovering a use for the iPaq's serial number feature.

Listing 1.

/*Solution generously provided on http://www.PocketProjects.com by "Nusorn" at [email protected] */

#define IOCTL_HAL_GET_UUID CTL_CODE(FILE_DEVICE_HAL, 13,   METHOD_BUFFERED, FILE_ANY_ACCESS)

unsigned long Len;
Len = 64;
TCHAR rgtcAsset[64];
memset(rgtcAsset, 0, 64 * sizeof(TCHAR));
KernelIoControl(IOCTL_HAL_GET_UUID, NULL, 0, (LPVOID)rgtcAsset, 64, &Len);

Listing 2.

  /*This approach was generously suggested by Christophe Menard at [email protected] on the groups.yahoo.com "windowsce-dev" list.*/

PROCESS_INFORMATION pi;
CreateProcess(TEXT("\\windows\\CreateAssetFile.exe"), NULL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
HANDLE hInFile;// = INVALID_HANDLE_VALUE;
TCHAR strSN[65];
DWORD dwBytesRead;  
hInFile = CreateFile(TEXT("\\windows\\cpqAssetData.dat"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hInFile == INVALID_HANDLE_VALUE)
{
    MessageBox(hWnd, TEXT("Unable to open asset data file."), TEXT("Error!"), MB_OK);
    break;
}
SetFilePointer(hInFile, 976, NULL, FILE_BEGIN);
memset(strSN, 0, 64 * sizeof(TCHAR));
ReadFile(hInFile, &strSN, 64, &dwBytesRead, NULL);
CloseHandle(hInFile);

Sample Serial Number Application

 

Get the Latest Tablet PC News

Click here for Advertising Information

Return to Chris De Herrera's Windows CE Website