Anybody who has ever tried to create a copy protection scheme for the PalmOS ends up with the fundamental problem of trying to uniquely identify a device. Unfortunately, there is no single, unified way to do this, and what the developer is left doing is putting together a mish-mash of different methods for different devices. Here, I present a couple different ways to do that, based on device type.
Devices from palmOne:
Many palmOne devices have what is known as flash ROM, which contains a serial number that is "baked" into the hardware. Fortunately, palmOne provides an easy interface for accessing that ROM serial number:
UInt8* ptr;
UInt16 size;
Err err = SysGetROMToken(0,sysROMTokenSnum, &ptr,&size);
if (!err && size && ptr && *ptr != 0xFF)
MemMove(dest,ptr,size);
Handspring Devices:
Handspring devices (including the Treo) also utilize Flash ROM, but Handspring provided a separate API than palmOne did for accessing the ROM serial number. Now that palmOne owns the Treo line, it is possible that this method will be deprecated in favor of SysGetROMToken. Until that time, however, you can use the following:
char dest[64];
UInt16 size = sizeof(dest);
HsGetVersionString(hsVerStrSerialNo, dest, &size);
Bluetooth Devices:
Some devices ship with a Bluetooth radio built in. For those devices, one option is to use the Mac address of the Bluetooth radio. You can use the Bluetooth API provided by PalmSource to do that:
BtLibDeviceAddressType address;
Err err = BtLibGetGeneralPreference(btLibRef,
btLibPref_LocalDeviceAddress,
&address,
sizeof(address));
if (!err)
MemMove(&address.address, dest, sizeof(address));
Other Devices:
Unfortunately, the above three methods do not work on all devices. In fact, on certain devices, like the TungstenE, there is nothing that can be used that is tied specifically to the hardware. In those scenarios, it is possible to fall back to using the Hotsync user name. While this is not a perfect solution, it does allow the user to more easily move between multiple devices. To obtain the Hotsync user name, you can use the following code:
#include
DlkGetSyncInfo(NULL, NULL, NULL, dest, NULL, NULL);
SD/MMC Card Unique Identifier:
Sometimes, an application needs to provide an identifier that is generalized across multiple devices, but less breakable than the Hotsync user name. In those cases, the unique identifier can be tied to an expansion card which then functions as a sort of "dongle" that is required to run the application. The downside of this is that the device must actually have an expansion card slot, and that the SD/MMC card must actually be inserted to run the application. (These applications tend to fall into vertical markets, although they definitely aren't limited to that. ) Fortunately, the Expansion Manager provides a fairly painless way to get the unique identifier of the card:
ExpCardInfoType info;
Err err = ExpCardInfo(slotRef, &info);
if (!err)
MemMove(dest, info.deviceUniqueIDStr, sizeof(info.deviceUniqueIDStr));
There are other methods to retrieve a unique identifier on the PalmOS, but the above listed methods are the 'big hitters'. Now please understand that a unique identifier does not equal copy protection, but generally it is the first step down that road. As an aside, if you are contemplating implementing a copy protection scheme, I highly recommend you read Aaron Ardiri's white paper on the subject, available here.
And as always, if you find any of the above code helpful, I'd love to hear about it.
-Jon
|