what property/method will return a computer-unique identifier?

H

heidstar pacific

i need a vba property or method that will return an
identifier that is unique to the computer that the
application is running on - in other words, a number or
string that belongs to that particular computer, and not
to any other computer in the world.

the purpose of this is so that i can program the
application to run only on that particular computer, so
that it cannot be pirated onto other computers (don't
worry about the details of that, i have it all figured
out, and just need a computer unique identifier for my
idea to work).

alternatively, an identifier that is unique to the windows
or office registration would do, because i don't mind if
the application is copied onto other computers that are
covered by the same windows or office registration,
because that means that it will still belong to the same
customer.

(the productcode property will not do, because all but the
first eight digits of the product code are identical - and
the first eight digits are far from unique)

(the environ command will not work, because the required
variable is not automatically in the environment - it was
not in my environment)
 
G

Graham R Seach

H

heidstar pacific

in the rare instance that they changed the disk drive or
motherboard or processor, then the key that i sell them
would not work anymore, so i could give them a new one for
free if they send me a photocopy of a docket that proves
that they have had the component replaced. so it is not a
bad idea to fall back on, if nothing else works.

or maybe a combination of all three ids, and if the key i
give them matches (very loose sense of the word...) with
just one of the component serial numbers, it is ok, so
they would have to get all three components replaced
before my application would cease to work. then only two
pirates could be made from each proper one, and only by
going to all the effort of swapping two of the components.

but the preferable option would be the windows product id
or something like that.
 
H

heidstar pacific

when i first posted this thread in another newsgroup, i
got the following reply:
'If (as you say) "an identifier that is unique to the
windows or office registration would do", you best bet
would be to get the Windows Product ID from the registry.'

i would be more than happy with that solution - and i
noticed from some googling that you people at mvp know how
to do that? thanks in advance...
 
T

TC

Nope - that is NOT the disk driver serial number! (though it is widely &
incorrectly described as such)

It is the VOLUME serial number - a completely different beast.

An end user can easily change the volume serial # with a simple DOS command.

In versions of windows up to win98(?), it was possible to get the disk
serial number by using a specially crafted CreateFile API call on WIN32.VMM
(or somesuch - I can't quite remember). But in later versions, it is only
possible by writing a kernel mode driver, AFAIK.

HTH,
TC
 
G

Graham R Seach

Public Const HKEY_LOCAL_MACHINE As Long = &H80000002
Public Const KEY_QUERY_VALUE As Long = &H1
Public Const READ_CONTROL As Long = &H20000
Public Const STANDARD_RIGHTS_READ As Long = (READ_CONTROL)
Public Const KEY_ENUMERATE_SUB_KEYS As Long = &H8
Public Const KEY_NOTIFY As Long = &H10
Public Const SYNCHRONIZE As Long = &H100000
Public Const REG_SZ As Long = 1
Public Const ERROR_SUCCESS As Long = 0&

Public Const KEY_READ As Long = (( _
STANDARD_RIGHTS_READ _
Or KEY_QUERY_VALUE _
Or KEY_ENUMERATE_SUB_KEYS _
Or KEY_NOTIFY) _
And (Not SYNCHRONIZE))

Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" ( _
ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long

Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long

Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
Alias "RegQueryValueExA" ( _
ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
lpType As Long, _
lpData As Any, _
lpcbData As Long) As Long

Private lngReturn As Long

Public Function GetWindowsProductID() As Variant
Dim lngRootKey As Long
Dim hKey As Long
Dim strSubKey As String
Dim strValueName As String
Dim strBuffer As String
Dim lngSize As Long

On Error GoTo Proc_Err

lngRootKey = HKEY_LOCAL_MACHINE
strSubKey = "Software\Microsoft\Windows\CurrentVersion"
strValueName = "ProductId"

'Open the key and get its handle
lngReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strSubKey, _
0&, KEY_READ, hKey)

'Check that the call succeeded
If lngReturn <> ERROR_SUCCESS Then
Err.Raise vbObjectError + 1, , "Could not open key."
End If

'Initialize the variables
strBuffer = Space(255)
lngSize = Len(strBuffer)

'Read the key value
lngReturn = RegQueryValueEx(hKey, _
strValueName, _
0&, _
REG_SZ, _
ByVal strBuffer, _
lngSize)

'Check that the call succeeded
If lngReturn <> ERROR_SUCCESS Then
Err.Raise vbObjectError + 1, , "Could not read value."
End If

'Return the key value
GetWindowsProductID = Left(strBuffer, lngSize - 1)

Proc_Exit:
On Error Resume Next
'Close the key
lngReturn = RegCloseKey(hKey)
Exit Function

Proc_Err:
GetWindowsProductID = Null
DoCmd.Beep
MsgBox "Error " & Err.Number & vbCrLf & _
Err.Description, vbOKOnly + vbExclamation, _
"Could not retrieve the key"

Resume Proc_Exit
End Function

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia

Microsoft Access 2003 VBA Programmer's Reference
http://www.wiley.com/WileyCDA/WileyTitle/productCd-0764559036.html
 
H

heidstar pacific

actually, my original question seems to have been answered
in this newsgroup. the other newsgroup (access modules)
only pointed to the answer.
 
H

heidstar pacific

ok, i've pasted that code into access, and it all runs
nice and smoothly and instantaneously, and it gives me an
id that looks something like "12345-ABC-1234567-12345",
and that is supposed to be my windows product id, ja?

thanks heaps, Graham and TC!
(g for the solution, and tc for pointing me in the right
direction)
 
T

TC

That's not the point. You mustn't post the same question seperately to
different newsgroups. Instead, CROSS-post. That means posting the question
once<, to all the relevant newsgroups, simultaneously, by putting all the
relevant newsgroup names in the Newsgroups: line of just one post.

Multiposting is BAD & wastes everyones' time. Check the web for the terms
multipost, crosspost and netiquette for more information on how to use the
groups effectively.

Cheers,
TC
 
H

heidstar pacific

ok, i getchya. but it couldn't be helped this time,
because i didn't know to post it to this newsgroup until
after a lady in the other newsgroup (access modules)
suggested it. but i'll keep your advice in mind in future.
 
H

heidstar pacific

ok, i've got the vba function for returning the windows
product id, but a bit of googling has revealed the
worrying situation that the windows product id can be
changed at will - eg
http://www.mywebattack.com/gnomeapp.php?id=105626 (ID-
Blaster Plus 2.0 - change Windows ID numbers)

so basically what this means, is if i give my customer an
activation number that will match with their windows
product id, then people can easily pirate my product by
using their friend's windows product id and the same
activation code.

tc, did you say that hardware ids have the same
vulnerabilities to being changed?

are there any ids on the computer that cannot be changed?

but if not, then perhaps i can use a sneaky combination of
windows product id and various hardware ids. in that case,
how much trouble would it be to change all your ids to the
same as your friend's ids?
 
G

Graham R Seach

The real problem is that it's possible to install the same ProductID on many
computers. For example, many companies purchase several licenses of the same
product, but only actually install one of them (many times), leaving the
others in their original unopened packaging. Other companies purchase a bulk
license, copying the installation disk to a server. So theoretically,
thousands of users can have the same ProductID.

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia

Microsoft Access 2003 VBA Programmer's Reference
http://www.wiley.com/WileyCDA/WileyTitle/productCd-0764559036.html
 
T

TC

Understood. Thanks for explaining.

Cheers,
TC


heidstar pacific said:
ok, i getchya. but it couldn't be helped this time,
because i didn't know to post it to this newsgroup until
after a lady in the other newsgroup (access modules)
suggested it. but i'll keep your advice in mind in future.
 
T

TC

True - but so can most of the other values that you might use for a machine
ID. Even the hardware based ones can be changed by replacing the relevant
piece of hardware.

I personally feel that it boils down to the 80/20 rule - which I will rename
to the 99/1 rule for the sake of this discussion! 99% of your users will not
have the skills to defeat even the simplest copy-protection scheme; eg.
creating a hidden file, or storing a value in the registry. (How many
general users can even >open< the registry? Or determine what values a
program may have stored in there?) The other 1% of users will crack your
scheme, no matter how good it may be. It is >impossible to prevent this<,
when you are working on a desktop system where a sufficiently skilled user
can patch the application codefiles. So, unless that 1% of users is going to
distirubte multiple cracked versions of your product, you might as well
forget about them.

Some years ago, I considered a scheme which eventually came into being as MS
product activation! Collect a series of attributes (about the PC) which >in
combination< are fairly unique. Eg. BIOS info. (brand, date, serial #), disk
volume serial # (GetVolumeInfo API), MAC address (if any), etc. etc. Then
check those values on each start of your application. If any >one< value has
changed, note the new value but continue regardless. If more than one have
changed, assume this is a different PC, & spit the dummy. Change 'one' to
'two' (or whatever), for whatever level of sensitivity you want to impose.

But that all got too complicated, so I ditched it & went to a much simpler
system, on the basis of the 99/1 rule.

HTH,
TC
 
H

heidstar pacific

are you talking about companies that own many computers,
or companies that sell computers to end users?
 
H

heidstar pacific

ID. Even the hardware based ones can be changed by
replacing the relevant piece of hardware.

can the hardware based values be changed without replacing
the hardware?
99% of your users will not
have the skills to defeat even the simplest copy-
protection scheme... The other 1% of users will crack your
scheme, no matter how good it may be.

you're right, and with the budget products i have in mind,
i think only 1% of those 1% could be bothered cracking it
to save the piffling amount of money to buy the activation
code off me.
when you are working on a desktop system where a sufficiently skilled user
can patch the application codefiles.

do you mean just copying and pasting the vba code from an
mdb file (which i wouldn't dream of distributing like
that), or cracking into the compiled code in an mde file?
So, unless that 1% of users is going to
distirubte multiple cracked versions of your product, you
might as well forget about them.

they could distribute a utility to temporarily change the
windows product id to match a known activation code,
that's what they could do if i used only the windows
product id.
Some years ago, I considered a scheme which eventually
came into being as MS product activation!

that's funny, because that's what's happened to me over
the past few days - i decided that each customer could
have an activation code derived from a combination of
windows product id and several hardware ids, and soon
after i found out that that is pretty much what microsoft
does (and if that is the best microsoft can do, then that
means i must be on the right track).
But that all got too complicated, so I ditched it & went to a much simpler
system, on the basis of the 99/1 rule.

the complexity doesn't bother me at all for what i'm
trying to do, although i should keep the 99/1 rule in mind
to make sure things don't get too complex.
 
G

Graham R Seach

Companies that own multiple computers. TC's comment is also salient in terms
of developing strategies for copyright protection. It is very difficult to
secure your rights, particularly in several countries where they believe
they are doing no wrong by copying and using (and even reselling) almost
anything.

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia

Microsoft Access 2003 VBA Programmer's Reference
http://www.wiley.com/WileyCDA/WileyTitle/productCd-0764559036.html
 
T

TC

heidstar pacific said:
replacing the relevant piece of hardware.

can the hardware based values be changed without replacing
the hardware?

It would clearly depend on the hardware in question. For example, srerials
#s stored in EEPROMS could perhaps be changed; those stored in ROMs could
probably not. I think you're really going into "1& territory" if you worry
about hardware IDs being changed.

related to this, be aware that the commonly posted code to get the "hard
disk serial #", does not get that # at all. It gets the >volume< serial #,
which is an entirely different thing, & easily changed by any user with a
simple DOS command.

protection scheme... The other 1% of users will crack your

you're right, and with the budget products i have in mind,
i think only 1% of those 1% could be bothered cracking it
to save the piffling amount of money to buy the activation
code off me.

Then I would definitely go for a simple solution: registry entry, hidden
file, or off-the-shelf protection product.

do you mean just copying and pasting the vba code from an
mdb file (which i wouldn't dream of distributing like
that), or cracking into the compiled code in an mde file?

No, I mean things like altering the *Access* (or related) codefiles. For
example, there is at least one product which patches certain system files,
so Access will accept anything as a username & password. That product would
start Access, find the relevant code in memory, and alter it dynamically to
disable the checks in question! Clearly this needs a high level of skill.
Only 1% of your 1%-ers will be doing that!

might as well forget about them.

they could distribute a utility to temporarily change the
windows product id to match a known activation code,
that's what they could do if i used only the windows
product id.

Then, match it with a random number that is generated by the installation
process. Ie. Joe, who tries to register, gets random # 465132. Fred gets
906643. You generate your unlock codes from the product ID >and random
number<. Thus, Joe's unlock code will not work for Fred, & vice versa, evemn
if they have the same windows product ID before or after the event.

came into being as MS product activation!

that's funny, because that's what's happened to me over
the past few days - i decided that each customer could
have an activation code derived from a combination of
windows product id and several hardware ids, and soon
after i found out that that is pretty much what microsoft
does (and if that is the best microsoft can do, then that
means i must be on the right track).

Not sure about that last (bracketed) sentence! :)

the complexity doesn't bother me at all for what i'm
trying to do, although i should keep the 99/1 rule in mind
to make sure things don't get too complex

From what you've said, I would try to keep it simple.

Cheers,
TC
 
P

Peter De Baets

You could use the MAC address of the Network Interface Card (NIC), or
the hard-drive serial number to generate a semi-unique identifier for
a given PC. The GetAdaptersInfo API will return MAC addresses of any
attached NICs on the computer. Here's a link to some code to retrieve
this address: http://vbnet.mvps.org/index.html?code/network/getadaptersinfo-localipaddress.htm

You also may want to check out our KeyedAccess product which uses a
similar identifier to create an Installation Serial Number and
requires that the users enter a corresponding Unlock Code to unlock
your Access application. More info is here:
http://www.peterssoftware.com/ka.htm

Hope this helps,

Peter De Baets
Peter's Software - MS Access Tools for Developers
http://www.peterssoftware.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top