views:

768

answers:

7

Hi, I have question how to generate unique serial number of machine in Delphi? I tried to do this using the ID the motherboard or processor, but unfortunately it's unfortunately supported. Partition serial numbers, etc. fall off, because it is changing after the formatted. I'm looking for something that doesn't change after the formatted. Has anyone any idea?

+1  A: 

I had a similar problem back in the good old DOS days. I found out that the ROM of the installed hardware ie. video card, disk controllers seriel ports etc. was accessible directly, since they are memory-mapped. This means that I was able to create a list of installed hardware, and use it to generate a "serial number", that uniquely identified each computer (until the hardware setup was changed). I'm sure something similar is possible today as well.

Check out http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map, if you want to use this approach.

Regards

  • Frank
Frank
Can a Delphi application really access arbitrary memory? As far as I know Windows applications are not supposed to be able to access memory that wasn't specifically allocated for them by the OS!
Cosmin Prund
+1  A: 

Often the MAC address of the (a) network card is used, there are several ways to query the mac address (in Delphi) but the easiest/cleanest way is probably to use the GetAdaptersInfo API.

Remko
Just be aware that wifi cards can appear/disappear at will, whne the user shutsdown a card Windows removes it from the list, and order is not always the same. Also MAC address can be changed by the user, if he has permission to change the hardware settings.
ldsandon
+1  A: 

Here is a simple solution

  • Generate a GUID
  • Save the Guid value in the registry
  • Use the value of the guid as the serial number -

If you a worried about security use a hash over the ( Guid + some secret data)

Charles Faiga
This won't satisy the need of the OP, as you could never use this to identify the machine later. i.e. if you're trying to license some software so that it can only run on "this machine", you can't generate a new GUID tomorrow (or next year, or after they re-install windows, etc..) and get that same GUID to identify the machine. Even 1 ms later, it looks like a different PC.
Chris Thornton
+2  A: 

Inside JCL library, there are several functions veru usefull for this topic:

function CPUID: TCpuInfo;
function GetMacAddresses(const Machine: string; const Addresses: TStrings): Integer;
function GetVolumeSerialNumber(const Drive: string): string;
function GetBIOSName: string;
TridenT
+2  A: 

What you're after is actually some sort of "hardware fingerprint", not an "serial number". The problem with this approach is that it's not 100% reliable. Proof: Microsoft didn't manage to find a way to properly limit OEM software to any single computer, you can actually re-install a OEM license on a new computer after a while! Once you agree there can't be a perfect solution you may look at your options and try getting something that's good enough.

For my applications I'm creating a fingerprint based on info returned by GetSystemInfo, GetVolumeInformation and (for the 'C:' partition) and a selection of registry keys from HKLM\HARDWARE (lots of registry keys actually, everything but usb, keyboard and mouse stuff). I'm reading hardware information from the registry because a Windows application can't really access hardware directly (DOS-style approaches can't work), and because I don't have time to figure out ways to determine hardware-related information for many different devices.

My approach has the following disadvantages:

  • Uses the partition serial number, as set up by Format. An format would clearly change the fingerprint.
  • Uses information about the installed drivers. Updating an driver might actually change the fingerprint! Moving a card from one PCI port to an other might change the fingerprint.

None the less, even with all of this changing information taken into account, I get collisions: Something like 1/1000 computers! There are several factors at work here:

  • Big OEM build many computers using the same hardware. They also clone HDD's in order to speed up software installation so different PC's might get the same partition serial number.
  • I'm building a very short hash from all that information, short enough so people can read it to me on the phone without too many mistakes.

This system works for me, but it will not work for you if you expect to re-identify computers once they're reinstalled.

Cosmin Prund
I think if you added a MAC address of the primary onboard ethernet adaptor (assuming there is one), then you should be able to eliminate the collisions.
Chris Thornton
+1  A: 

You can test GLibWMI that extract information of several components on Windows.
It's free and source included. You can find it on my Web or in Sourceforge.

alt text

Include components for BIOSInfo, DiskInfo, ProcessorInfo,...

With this three components you can obtain information like this:

alt text

You can find the BIN/EXE of GenericDemo (all components) here; You can test all information that you can retrive with this components.

Neftalí
A: 

I tend to agree with the "it can't be done" camp. At least not 100%, but it can probably be done "good enough" to keep the average user in line.

And if it can be done then it probably has been done. Did you check Torry's Delpi300, etc (maybe even sourceforge, although you might have to translate into Delphi).

http://www.google.com.sg/search?hl=en&source=hp&q=How+to+generate+unique+serial+number+of+machine+in+Delphi actually looks promising

Mawg