Solved

Getting unique hardware information with VB(1000 ++ points)

Posted on 2001-08-18
91
1,085 Views
Last Modified: 2007-12-19
Hi,

I want to get some unique hardware info from a PC, but how (in VB6) ?
I'm working on a protection scheme that will lock  a program to that hardware info, but how can I get it?
How can I get some unique identifier for a certain PC, strictly hardware dependent(that will not change after OS reinstall, HDD formatting, etc)
Like something that identifies the CPU or HDD or motherboard?
But NOT! a HDD logical drive serial number, there are utilities that can change this to whatever you like.
Also do not suggest reading of the MAC address  of the LAN adapter(not all pc's have such a thing)
I'll give you 1245 points (all my EE points) for a working answer.
Thanks
0
Comment
Question by:hveld
91 Comments
 

Author Comment

by:hveld
ID: 6401528
I forgot to say I'm interested in something that will work on all Windows platforms(95 all versions/98/98SE/ME/NT4sp3 or higher/w2k/XP)
NT 3.5/ Win 3.xx is out of interest
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6402956
I WOULD Say get somecode to read the motherboard internal serial number.

hard code that in the software that will stop the program going on any other computer

i will see what i can do about the code


cheers
Andy
0
 
LVL 6

Expert Comment

by:anthony_glenwright
ID: 6403006
You could try the MAC address of the ethernet card.  It is *supposed* to be unique (and mostly is), so it should suffice for your needs.  Won't work with computers without a network card, though...  Depends if your application is for business or personal use - if it is for business use, you can probably rely on there being a network card in the machine.

Theres an example here http://support.microsoft.com/support/kb/articles/Q175/4/72.ASP
0
 
LVL 6

Expert Comment

by:anthony_glenwright
ID: 6403007
Sorry, I didn't read the but that said >> ... Also do not suggest reading of the MAC address  
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403016
have a look at this

Public Function MBSerialNumber() As String

'RETRIEVES SERIAL NUMBER OF MOTHERBOARD
'IF THERE IS MORE THAN ONE MOTHERBOARD, THE SERIAL
'NUMBERS WILL BE DELIMITED BY COMMAS

'YOU MUST HAVE WMI INSTALLED AND A REFERENCE TO
'Microsoft WMI Scripting Library IS REQUIRED

Dim objs As Object

Dim obj As Object
Dim WMI As Object
Dim sAns As String


Set WMI = GetObject("WinMgmts:")
Set objs = WMI.InstancesOf("Win32_BaseBoard")
For Each obj In objs
  sAns = sAns & obj.SerialNumber
 If sAns < objs.Count Then sAns = sAns & ","
Next
MBSerialNumber = sAns
End Function

0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403029
what you could then add is this into the code

okey lets asume your motherboard serial code was "12345-correctserialcode" then run this code making sure you insert the motherboard code EXACTLY how its dislayed at the bottom of your screen at bootup.

when your code has been compiled if the serial number doent equal the number written in your software you know that its been installed on another computer because it will not run.

but if you format your harddrive on the orginaly computer and reinstall your software it will still work because formating the harddrive doesnt change the motherboard serial number.



Public Function MBSerialNumber() As String

'RETRIEVES SERIAL NUMBER OF MOTHERBOARD
'IF THERE IS MORE THAN ONE MOTHERBOARD, THE SERIAL
'NUMBERS WILL BE DELIMITED BY COMMAS

'YOU MUST HAVE WMI INSTALLED AND A REFERENCE TO
'Microsoft WMI Scripting Library IS REQUIRED

Dim objs As Object

Dim obj As Object
Dim WMI As Object
Dim sAns As String


Set WMI = GetObject("WinMgmts:")
Set objs = WMI.InstancesOf("Win32_BaseBoard")
For Each obj In objs
  sAns = sAns & obj.SerialNumber
 If sAns < objs.Count Then sAns = sAns & ","
Next
MBSerialNumber = sAns
if sAns="12345-correctserialcode" then goto start:
if sAns<>"12345-correctserialcode" then stop
End Function


dont forget to change the sAns to your mobo serial number exactly.

hope this helps
Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403119
ps i dont wont all of your points, if you do accept my comment as anwer reward me what you think, but you may need points if you want to ask a  question later.

0
 

Author Comment

by:hveld
ID: 6403190
Thanks Andy,

but it does not work for me.
For each.. cycle loops twice and the function returns only a comma ( , )
I use vb6sp5, w2k pro with sp1, the 'Microsoft WMI Scripting Library version is 1.1
Is it working for you and on what windows?
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403261
hmmmm, im at work at the moment so i havent had chance to try it.

have you checked in your bios, on some new computers you have to turn the serial number on.

im not saying you will have but there is an option with some computers to turn it on or off.

just check that first.

it should work on any windows platform.

check in your bios first

ill try it later when i get home and let you know, but mean while maybe another EE expert could cut & paste the code and see if it works for them, if they are reading this thread

will be back soon

Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403271
that code should work, its pretty standard code for all window platforms.

anyhow this will get you processor information try to see if you can use this my friend, sorry to keep messing you around



Public Declare Sub GetSystemInfo Lib "kernel32" (lpSystemInfo As SYSTEM_INFO)
Public Type SYSTEM_INFO
   dwOemID              As Long
   dwPageSize           As Long
   lpMinimumApplicationAddress As Long
   lpMaximumApplicationAddress As Long
   dwActiveProcessorMask As Long
   dwNumberOrfProcessors As Long
   dwProcessorType      As Long
   dwAllocationGranularity As Long
   dwReserved           As Long
End Type

Private Sub Form_Load()

   Dim InfoResult       As SYSTEM_INFO
   GetSystemInfo InfoResult
   MsgBox "Your CPU type is " & InfoResult.dwProcessorType
   MsgBox "You have " & InfoResult.dwNumberOrfProcessors & " processor(s)"

End Sub




hope this helps
Andy
0
 

Author Comment

by:hveld
ID: 6403305
well this really works but which of these things is unique and unchangable? And will it work for whatever CPU?
Is dwReserved unique and what it means?
Because as I see all other things are either common for many cpu's or could change their value.
I tried your previous solution on a PC which is at least 2.5 years old and the result is the same - comma. I looked at the bios, there is no option to turn MB serial on/off
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403320
well thats strange, i will give the retrieve code a go 2nite, thats unless anybody else comes up with somthing better.

the processor type, you can set it for that machine that wont change or the parameters wont change even if you reform that hard drive because its actaully getting the data from the cpu.

the only thing is , yes it may work on other computers which has the same processor speed, it all depends on how they cpu reports it. if there is a slight discrepancy with it then the software wont work. it has to be cock on.

i can;t test any of the code become im stuck at work doing telecommunications, yes on a bloody sunday :o(

cheers
Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403323
nealy forgot to answer the other part of the question

dwreserved:-
retrieves the locally unique identifier (LUID) used

cheers
Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403350
what about just reading the bios date,

THIS WILL NOT WORK WITH NT IF YOU RUN IT ON NT IT WILL CRASH THE MACHINE

Option Explicit

Private Declare Sub GetMem1 Lib "msvbvm50.dll" (ByVal _
   MemAddress As Long, var As Byte)

'You can read Integer (2 bytes), Long and LongInteger variables
'using GetMem2, GetMem4 and GetMem8 functions
'Private Declare Sub GetMem2 Lib "msvbvm50.dll" (ByVal _
' MemAddress As Long, var As Integer)
'Private Declare Sub GetMem4 Lib "msvbvm50.dll" (ByVal _
' MemAddress As Long, var As Long)
'API has LongInteger var type 8 bytes long (FileTime is a _
' sample), VB has not

Private Function GetBIOSDate() As String
   Dim p As Byte, MemAddr As Long, sBios As String
   Dim i As Integer

   MemAddr = &HFFFF5
   For i = 0 To 7
      Call GetMem1(MemAddr + i, p)
      sBios = sBios & Chr$(p)
   Next i
   GetBIOSDate = sBios
End Function
'Using
'Text1.Text = GetBiosDate

'Private Declare Sub GetMem8 Lib "msvbvm50.dll" (ByVal _
' MemAddress As Long, var As LongInteger)

'You can also write data derectly into memory using the same
'PutMem1 - PutMem8 functions


cheers
Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403359
im running out of idea's

i will have a think if there is any other way of keeping the software unique to one computer by reading a unique hardware serial number, the code given should return to the mobo serial number, i dont understand why it isnt.

its a shame the cpu doesnt have its own unique serial number written so that you could read it.

i finish at 2pm in the UK but i've got alot to do so i will have a think and see what else i can come up with but it may be later 2nite.

cheers
andy

dont see many other EE's commenting on this one.

cheers
Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403374
you need to make sure you download the corretct WMI for the windows version you are using,

they are not all the same. i dont know where you would download the WMI but that may be the problem.

cheers
Andy
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6403389
WMI sample (MB serial) doesn't work for me either (W2k, SP2)
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403396
im out of idea's then, ill have a look later but im pretty much stuck.

sorry i tried, anybody else got any ideas

cheers
Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6403398
im sure there is another way of reading the contents in bios or memory,

iv'e done ages ago, well years ago, ill have a think about it today, theres got to be another way.


cheers
Andy
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6403416
Check this out:

http://groups.google.com/groups?hl=en&safe=off&th=919249df84d9024f,1&seekm=984352256%40p24.f176.n450.z2.FidoNet.ftn#p

Reads also serial number of HDD from HDD bios (not changeable).
Unfortunatelly in C, but if you'r WELL experienced, you could port main parts to VB.

Otherwise, I may try :)
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6403443
IDE HDD serial number

http://groups.google.com/groups?hl=en&safe=off&th=375b66ee8c2fbab4,1&seekm=963412808%40f217.n5030.z2.ftn#p

This one is little easier, but still in C. Of course works on W9x/NT/2k
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6403446
Btw... previous post talks about "hardware" serial number of HDD, not the one that is assigned to drive at format-time.
0
 

Author Comment

by:hveld
ID: 6403590
Andy,

if WMI is OS specific,will it do the job?
I mean as I know it is not a part of windows installation and may not be available on user's PC. If so, I have to include it in the setup, but if it's OS specific it will not work on some windowses.
If the above is true, a solution that uses WMI will not help.
I also tried reading the bios date which crashed VB. Maybe I did something wrong, but if as you say it will crash NT's, I can't use it.

BozzoCage, thanks for the links but I actally know almost nothing about C and can't 'translate' this code to VB

0
 
LVL 3

Expert Comment

by:andysalih
ID: 6404186
yes, it is OS specific, windows 2000 comes with it but for other versions of windows it will require the appropriate reference to it.

It was a great idea but its not going to work I dont think.


The Bios reading date one is very touchy, it kills NT and i supose it would kill anything which is NT build such as 2000.

I will have another look at this, but to befare im running out of idea's, Well idea's which will make this unique to one computer.

ill be back soon

cheers
Andy
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6404209
i might have something ill brb
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6404215
****,

it doesnt work

what i tried to do is to read a number of the hard drive and see if it changes after formating, to achive this i users a floppy disk instead of the hard drive,

this is the code

you need to add a label1 and command1 to a form and paste this code. to show an example

Option Explicit


Private Declare Function GetVolumeInformation& Lib "kernel32" _
    Alias "GetVolumeInformationA" (ByVal lpRootPathName _
    As String, ByVal pVolumeNameBuffer As String, ByVal _
    nVolumeNameSize As Long, lpVolumeSerialNumber As Long, _
    lpMaximumComponentLength As Long, lpFileSystemFlags As _
    Long, ByVal lpFileSystemNameBuffer As String, ByVal _
    nFileSystemNameSize As Long)
    Const MAX_FILENAME_LEN = 256


Private Sub Command1_Click()
    Label1.Caption = SerNum("A") 'C is the standard harddisk
End Sub


Public Function SerNum(Drive$) As Long
    Dim No&, s As String * MAX_FILENAME_LEN
    Call GetVolumeInformation(Drive + ":\", s, MAX_FILENAME_LEN, _
    No, 0&, 0&, s, MAX_FILENAME_LEN)
    SerNum = No
End Function

cheers
Andy

p.s
im not saying this is the answer i was trying somthing that was all
0
 

Author Comment

by:hveld
ID: 6404265
Thanks Andy but this returns the logical drive serial number which is a random number assigned when you format a partition. It changes after re-formatting, and there are also apps that can change this number to whatever you like(without formatting).
BTW this example didn't work for me, it returned a 9 charachter string that has nothing in common with my c: ser. number(which as I know is always a 8 chars string)
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6404276
okey, im still working on it, not much luck at moment,

cheers
Andy (with a very serious headache,)

0
 
LVL 3

Expert Comment

by:andysalih
ID: 6404312
' #VBIDEUtils#************************************************************
'
Option Explicit

Const KEY_ALL_ACCESS = &H2003F

Const HKEY_LOCAL_MACHINE = &H80000002
Const ERROR_SUCCESS = 0
Const REG_SZ = 1
Const REG_DWORD = 4

Const gREGKEYSYSINFOLOC = _
   "SOFTWARE\Microsoft\Shared Tools Location"
Const gREGVALSYSINFOLOC = "MSINFO"
Const gREGKEYSYSINFO = "SOFTWARE\Microsoft\Shared Tools\MSINFO"
Const gREGVALSYSINFO = "PATH"

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

Private Declare Function RegQueryValueEx Lib "advapi32" _
   Alias "RegQueryValueExA" (ByVal HKey As Long, _
   ByVal lpValueName As String, ByVal lpReserved As Long, _
   ByRef lpType As Long, ByVal lpData As String, _
   ByRef lpcbData As Long) As Long

Private Declare Function RegCloseKey Lib "advapi32" (ByVal HKey As Long) As Long
Public Sub StartSysInfo()
   Private Sub Form_Load()

On Error GoTo SysInfoErr
Dim rc                  As Long
Dim SysInfoPath         As String

If GetKeyValue(HKEY_LOCAL_MACHINE, gREGKEYSYSINFO, _
   gREGVALSYSINFO, SysInfoPath) Then

ElseIf GetKeyValue(HKEY_LOCAL_MACHINE, _
   gREGKEYSYSINFOLOC, gREGVALSYSINFOLOC, SysInfoPath) Then

   If (Dir(SysInfoPath & "\MSINFO32.EXE") <> "") Then
      SysInfoPath = SysInfoPath & "\MSINFO32.EXE"

   Else
      GoTo SysInfoErr
   End If

Else
   GoTo SysInfoErr
End If

Call Shell(SysInfoPath, vbNormalFocus)

Exit Sub

SysInfoErr:
MsgBox "System Information Is Unavailable At This Time", vbOKOnly
End Sub

Private Function GetKeyValue(KeyRoot As Long, _
KeyName As String, SubKeyRef As String, _
ByRef KeyVal As String) As Boolean

Dim i                   As Long
Dim rc                  As Long
Dim HKey                As Long
Dim hDepth              As Long
Dim KeyValType          As Long
Dim tmpVal              As String
Dim KeyValSize          As Long

rc = RegOpenKeyEx(KeyRoot, KeyName, 0, _
   KEY_ALL_ACCESS, HKey)

If (rc <> ERROR_SUCCESS) Then GoTo GetKeyError

tmpVal = String$(1024, 0)
KeyValSize = 1024

'------------------------------------------------------
' Retrieve Registry Key Value...
'------------------------------------------------------
rc = RegQueryValueEx(HKey, SubKeyRef, 0, _
   KeyValType, tmpVal, KeyValSize)

If (rc <> ERROR_SUCCESS) Then GoTo GetKeyError

If (Asc(Mid(tmpVal, KeyValSize, 1)) = 0) Then
   tmpVal = Left(tmpVal, KeyValSize - 1)
Else
   tmpVal = Left(tmpVal, KeyValSize)
End If

Select Case KeyValType
   Case REG_SZ
      KeyVal = tmpVal
   Case REG_DWORD
      For i = Len(tmpVal) To 1 Step -1
         KeyVal = KeyVal + Hex(Asc(Mid(tmpVal, i, 1)))
      Next
      KeyVal = Format$("&h" + KeyVal)
End Select

GetKeyValue = True
rc = RegCloseKey(HKey)
Exit Function

GetKeyError:
KeyVal = ""
GetKeyValue = False
rc = RegCloseKey(HKey)
End Function

have a play with this code and see if there is anything unique you can find which we could try and attach to

0
 
LVL 28

Expert Comment

by:AzraSound
ID: 6404421
This is why some bother with purchasing hardware of their own, usually in the form of a dongle.  See Sentinel's products:

http://www.e2s.be/Softwareprotection/sentinel_products.htm
0
 

Author Comment

by:hveld
ID: 6404443
I don't want to use dongles, these are very inconvenient and require a physical delivery. Also all commercial protection solutions, including most of the dongle protection solutions are already cracked (just do a search for 'dongle' at http://www.newscheck.cc to see a small part of the problem)
I regulary visit crack sites and I'm sure I can't protect an app using a well known commercial(or freeware) protection solution.
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6404455
Btw... if you made GOOD program, it will get cracked, no matter what you "invent" to protect it. You will have to store machined unique data somewhere... and ALL file/disk/reg access can be logged with simple programs, so if someone WANTS to get around your protection, he surelly will. And there are also nice dissasemblers ... :)

But of course - if your program is not for masses and you just want to protect it from being copied between those few interested in it, you surelly can succeed - even with simpler protection mechanisms.

Just my 2 cents :)
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 6404458
Truth is, if someone really wants to crack software, they are going to.  If there were a fool-proof solution, people would be using it by now.  People still use dongles because thats about as good as they can get.  People still use cd keys because thats about as good as they can get.  You think MS is not aware of the fact that theyre software is ripped/cracked/duplicated in mass amounts?  It is inevitable, and is why they are moving now to the online registration process where users must, every set number of weeks/months, re-register their software online.  I dont know how it all exactly works right now, but chances are, it wont hold up as 100% secure either.

Large commerical software is usually the only ones hit hard and fast.  If you feel your software is going to be that spectacular, youll probably make more money than you know what to do with before you ever feel any effects of losing revenue due to hacked versions of your product.  As much software that is ripped that is made by MS, they still make a fancy penny dont you agree?  Dont worry about it...use something that has proven to work effectively enough, and go with it.
0
 
LVL 2

Expert Comment

by:egsemsem
ID: 6404467
In 'PC 98 System desgin guide' book, I read about something called 'unique system ID structure' that is stored in first megabyte of the client&rsquo?s main memory when execution of the downloaded bootstrap is initiated (If u don't know what is this, don't ask me), do u think this may help?

Osama
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6404517
i get the impression that they may be right hveld, im not so sure that you are going to get around this with a piece of code.

if only chip manufactures made chips with a registration code burnt on and you could read it maybe that could stop people from taking the software of that computer but has they dont or they do but we cant read it i think were pretty stuffed.

its a shame that the code WMI doesnt work, because that might of been some deterant, i would give it another day or so to see who else replys, ive called all the top EE's and when they pickup on my thread leading to yours then your should have plenty of advice to go off.

I put my mind to it, and I couldnt come up with anything else, I can give you code and suggestions on how to protect your software, but it'll only be as good as the person whos trying to crack it.

and it will probley involve using the serial number not the volume name, or a registry key,

i still think your should go with the registry and use that to protect it.

anyhow good luck. If i do come across anything ill let you know.

to all the experts who came from my link , thankyou for your comments and trying to help, asoon as this is resolved, if not then i will post to a moderator to donate the points ive put up.

cheers
Andy
0
 
LVL 5

Expert Comment

by:raizon
ID: 6404543
listening
0
 
LVL 27

Expert Comment

by:Ark
ID: 6404551
Hi
Some more in direct memory reading. Don't work under NT, because NT doesn't map BIOS data addresses into process memory space. So it cause GPF

'For w95/98 via direct memory access
'
Option Explicit
Private Type BiosData
  Date As Date
  Manufacturer As String
  Version As String
End Type

'Change following declaration to fit your vb version

Private Declare Sub GetMem1 Lib "msvbvm50.dll" (ByVal MemAddress As Long, var As Byte)

Private Function GetBIOSData() As BiosData
 Dim p As Byte, MemAddr As Long, sBios As String
 Dim i As Integer
 sBios = ""
 MemAddr = &HFE061
 For i = 0 To 25
     Call GetMem1(MemAddr + i, p)
     If p = 0 Then p = 32
     sBios = sBios & Chr$(p)
 Next i
 GetBIOSData.Version = sBios
 MemAddr = &HFFFF5
 sBios = ""
 For i = 0 To 7
     Call GetMem1(MemAddr + i, p)
     If p = 0 Then p = 32
     sBios = sBios & Chr$(p)
 Next i
 GetBIOSData.Date = CDate(sBios)
 MemAddr = &HFE030
 sBios = ""
 For i = 0 To 18
     Call GetMem1(MemAddr + i, p)
     If p = 0 Then p = 32
     sBios = sBios & Chr$(p)
 Next i
 GetBIOSData.Manufacturer = sBios
End Function

Private Sub Form_Load()
 Dim bd As BiosData
 bd = GetBIOSData
 Text1 = "BIOS date = " & bd.Date & vbCrLf & "Manufacturer = " & bd.Manufacturer & vbCrLf & "BIOS ver.
= " & bd.Version
End Sub

' For w98 via registry reading. Can not check on NT, but you can just search your registry using regedit
and change data location in code:

---Bas module code---
Private Const REG_SZ As Long = 1
Private Const REG_DWORD As Long = 4
Private Const HKEY_LOCAL_MACHINE As Long = &H80000002

Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal
lpSubKey As String, phkResult 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 Function regQuery_A_Key(ByVal hKey As Long, ByVal sRegKeyPath As String, ByVal sRegSubKey As
String) As Variant
 Dim iPos As Integer
 Dim lKeyHandle As Long
 Dim lRet As Long
 Dim lDataType As Long
 Dim lBufferSize As Long
 Dim lBuffer As Long
 Dim sBuffer As String
 Dim arBuffer() As Byte
 lKeyHandle = 0
 lBufferSize = 0
 regQuery_A_Key = ""
 lRet = RegOpenKey(hKey, sRegKeyPath, lKeyHandle)
 If lKeyHandle = 0 Then GoTo FuncFail
 lRet = RegQueryValueEx(lKeyHandle, sRegSubKey, 0&, lDataType, ByVal 0&, lBufferSize)
 If lKeyHandle = 0 Then GoTo FuncFail
 Select Case lDataType
        Case REG_SZ:       ' String
             sBuffer = Space(lBufferSize)
             lRet = RegQueryValueEx(lKeyHandle, sRegSubKey, 0&, 0&, ByVal sBuffer, lBufferSize)
             If lRet = ERROR_SUCCESS Then
                iPos = InStr(1, sBuffer, Chr(0))
                If iPos > 0 Then
                    regQuery_A_Key = Left(sBuffer, iPos - 1)
                Else
                    regQuery_A_Key = sBuffer
                End If
             End If
        Case REG_DWORD:
             lRet = RegQueryValueEx(lKeyHandle, sRegSubKey, 0&, lDataType, lBuffer, 4&)            
                           ' 4& = 4-byte word (long integer)
             If lRet = ERROR_SUCCESS Then
                regQuery_A_Key = lBuffer
             End If
        Case Else:
 End Select
FuncFail:
lRet = RegCloseKey(lKeyHandle)
End Function

Public Function GetBiosVer() As String
  GetBiosVer = regQuery_A_Key(HKEY_LOCAL_MACHINE, "Enum\Root\*PNP0C01\0000", "BiosVersion")
End Function

Public Function GetBiosDate() As String
  GetBiosDate = regQuery_A_Key(HKEY_LOCAL_MACHINE, "Enum\Root\*PNP0C01\0000", "BiosDate")
End Function

Public Function GetBiosMfr() As String
GetBiosMfr = regQuery_A_Key(HKEY_LOCAL_MACHINE, "Enum\Root\*PNP0C01\0000", "BiosName")
End Function

'--- Form code---
' Add one command button at form
Private Sub Command1_Click()
Me.Print "BiosDate = "; GetBiosDate
Me.Print "BiosVersion = "; GetBiosVer
Me.Print "BiosName = "; GetBiosMfr
End Sub

Cheers
0
 
LVL 27

Expert Comment

by:Ark
ID: 6404585
0
 
LVL 14

Expert Comment

by:wsh2
ID: 6404685
<ping>
0
 
LVL 1

Expert Comment

by:superchook
ID: 6404891
My thoughts would go to collecting... say 10 identifiers from the system...  drive serials, MAC, CPU type/sn, qty RAM installed, BIOS date etc...

Then (something like personal ID) - you have to weight each value with it's relevance.   Then you can say if the machine matches with more than XX points that are the 'correct', then you accept that it is the same machine.   If LESS than YY points are the same, then you introduce your 'sorry - contact the applications developer' message.

You can put a margin in the middle to provide for that 'grey area' and give the user 30 days to re-register.


0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6405057
"How can I get some unique identifier for a certain PC, strictly hardware dependent..."
So, your end user must stick with that machine and never do an upgrade, otherwise your prog will not works?
0
 
LVL 1

Expert Comment

by:superchook
ID: 6405069
Hence my suggestion of a threshold and 'grey area' -


  >80% match = ok it's the same machine

a gray area
0
 
LVL 1

Expert Comment

by:superchook
ID: 6405072
Oops - Let's do that again

My earlier suggestion of an OK threshold, and 'grey area' -

e.g.

 More than 90% match = ok it's prolly the same machine

 80% to 90% = probably ok - give them 30 days

 Less than 80% = please contact app vendor for re-registration...  your existing data may be archived from C:\yourdata

0
 
LVL 2

Expert Comment

by:idorey
ID: 6405262
I read through this breifly so if I duplicate anything by someone else, sorry!

I had a similar problem a while ago and used the serial number of the hard disk. This is NOT something which can change unless the user swaps hard disks, or unless they are using a large RAID system.

The code below should give you an alpha-numeric code, depending on the HD itself. You should then add a code of your own to the end of it.

Dont know if it will help you but it works okay for me!

Good Luck


Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long
Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long


Function DriveSerial(TheDrive As String) As Long
Dim SerNO As Long
Dim TheResult As Long
Dim Hold1 As String
Dim Hold2 As String
Hold1 = String$(255, Chr$(0))
Hold2 = String$(255, Chr$(0))
TheResult = GetVolumeInformation(TheDrive, Hold1, Len(Hold1), SerNO, 0, 0, Hold2, Len(Hold2))
DriveSerial = SerNO
End Function


Now add this code to the button click event.
MsgBox (DriveSerial("C:\"))
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6405368
the hard drive serial does change when you format it, he doesnt want that, what he's actually saying is that if he was to fomart the hard dirve then he wants the software to still be attached to that computer only,

if he uses the hard drive serial number and he was to take the hard drive out and put in intot another comuputer then this would still work because the software is reading the code of the hard drive and not the physical computer system

he wants to software not be able to function if he takes the hard drive out and pout into another computer.


i hope that clears using the serial number part up.

thanks
Andy
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:hveld
ID: 6405534
It's not exactly like that Andy. It's OK if you get the HDD and attach it to another PC.
The problem is you can change this number easy. You can make all your 10 PC's to have the same volume serail number for their C:\ drives whithout formatting them or whatever.
So if someone knows the HDD # for which the app works, he can make his HDD to have the same number
0
 
LVL 27

Expert Comment

by:Ark
ID: 6405614
Tvichw32 (see link above) returns not serial, but MANUFACTURER's number, unique for this drive.
0
 
LVL 9

Expert Comment

by:Valliappan AN
ID: 6405655
So far, what I have come across, as a solution to this, is this:

Have your own logic to manipulate with the MAC address, HDD number, and/or Bios no. and date and time of installation, and say, the file date of some of your files, just use these things, mix up, alter, and get a number with a logic. Check for this number every time you run the program.

Hope this helps.
0
 
LVL 1

Expert Comment

by:viperlin
ID: 6405662
do you know what a dongle is?





0
 
LVL 3

Expert Comment

by:andysalih
ID: 6405785
i thoug of using the hard drive serial number and id though id submitted it, ill have to recheck.

are you trying to achive this because of licence law so that they have to pay for a licence.

there are loads of other ways of doing this, i had the same problem with some software i wrote,

i basical incorparated a matrix grid full of codes into the softwhere and every time they did an install it would give them a grid reference which would be eg. b4 ,c5 then i would look up on a grid and give them the realease code.

and it would let them start to use the software, but if they then tried to copied the pre installed software on to another computer it would the ask them for a new code, because i made it check for certain things which existed only on that computer,

woudl that help at all, maybe thats a thoought.

0
 
LVL 7

Expert Comment

by:Z_Beeblebrox
ID: 6406217
There is no easy answer to this question, even Microsoft could not find a way. If you look at how they did exactly this with Windows XP, they use the MAC address on computers that have it, and otherwise they take the approach of reading in as much hardware info as possible and as long as not too much of it changes, it is probably the same computer. So if this is the best that MS can do, it is probably the best that you can do.

Zaphod.
0
 

Author Comment

by:hveld
ID: 6411545
Thanx again,

but all these solutions that suggest collecting a lot of info and comparing will just fail if the user formats the HDD(which BTW I regularly do).
Whatever registry values, volume serials, unique identifiers, etc change after you format HDD (or just the partition where OS is installed or app is installed).
The only sure thing seems to be the LAN card MAC address, but most home PC do not have LAN cards.
BTW what of all the stuffs has a MAC address?
For example cable modems / dsl modems - do they have a MAC address?. Sorry if this sounds lame but I've never used such things.
And if there is some kind of modem installed, can I get something unique about it?
0
 
LVL 1

Expert Comment

by:superchook
ID: 6411617
ANy comments on my earlier suggestion - it is NOT dependent on the HDD serial, and allows you sto set how strict you are about minor system variations...

"...collecting... say 10 identifiers from the system...  MAC, CPU type/step, qty RAM installed, graphics card, BIOS date etc...

Then (something like personal ID check) - you have to weight each value with it's relevance.   Then you can
say if the machine matches with more than XX points that are the 'correct', then you accept that it
is the same machine.   If LESS than YY points are the same, then you introduce your 'sorry - contact
the applications developer' message.

You can put a margin in the middle to provide for that 'grey area' and give the user 30 days to re-register.


e.g.

More than 90% match = ok it's prolly the same machine

80% to 90% = probably ok - give them 30 days

Less than 80% = please contact app vendor for re-registration...  your existing data may be archived
from C:\yourdata



0
 
LVL 3

Expert Comment

by:andysalih
ID: 6411631
YOU could always read the manufacture of the modem, thats easy to do, would that be any good to you ?
0
 
LVL 7

Expert Comment

by:Z_Beeblebrox
ID: 6411637
Hi,

A network card MAC address is the only standard thing that you can obtain which is almost guaranteed to be unique and stable. Things like cable modems and such are external devices, so there is no practical way of getting at their information. Modems do not have generally available serial numbers. The only thing that does is network cards since they are needed to uniquely identify your computer on a LAN. The only approach available to you, short of requiring your users to have a network card, is to take the approach suggested by others of gathering as much data as you can about the hardware of the computer, and doing a check to make sure that not too much of it has changed.

Zaphod.
0
 
LVL 1

Expert Comment

by:superchook
ID: 6411644
If device connects via an ethernet connection, then they have a MAC address.  Getting it from the cable modem may be tricky - unless yo go in via the (RS232) terminal port. (Or it may be printed  on the bottom of the box!)

You may also be able to telnet into the device fro the PC.
0
 
LVL 27

Expert Comment

by:Ark
ID: 6411683
Manufacturer's HDD number won't change after formatting.
BTW, recently found very interesting APIs - GetThreasContext/SetThreadContext. Seems I can dive into ring0 and call DOS interrupts with them directly from VB! If I can, there will be a lot of opportunities (including HDD number, BIOS data, etc)! Plus VB will work as vxd ('totally invisible')!!! Not very familiar with debugging processes, so if anybody have links/samples I'll open a question.

Cheers
0
 
LVL 1

Expert Comment

by:superchook
ID: 6411731
Good value for 50 points !
0
 
LVL 27

Expert Comment

by:Ark
ID: 6412228
Hi
Just made small changes to my above code for get BiosData from registry.

'=======Bas module code===========
Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
End Type
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Private Const HKEY_LOCAL_MACHINE As Long = &H80000002
Private Const REG_SZ As Long = 1
Private Const REG_DWORD As Long = 4
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult 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 Function regQuery_A_Key(ByVal hKey As Long, ByVal sRegKeyPath As String, ByVal sRegSubKey As String) As Variant
    Dim iPos As Integer
    Dim lRet As Long
    Dim lKeyHandle As Long, lDataType As Long
    Dim lBufferSize As Long, lBuffer As Long
    Dim sBuffer As String
    Dim arBuffer() As Byte
    lKeyHandle = 0: lBufferSize = 0
    regQuery_A_Key = ""
    lRet = RegOpenKey(hKey, sRegKeyPath, lKeyHandle)
    If lKeyHandle = 0 Then GoTo FuncFail
    lRet = RegQueryValueEx(lKeyHandle, sRegSubKey, 0&, lDataType, ByVal 0&, lBufferSize)
    If lKeyHandle = 0 Then GoTo FuncFail
    Select Case lDataType
           Case REG_SZ:       ' String
                sBuffer = Space(lBufferSize)
                lRet = RegQueryValueEx(lKeyHandle, sRegSubKey, 0&, 0&, ByVal sBuffer, lBufferSize)
                If lRet = ERROR_SUCCESS Then
                   iPos = InStr(1, sBuffer, Chr(0))
                   If iPos > 0 Then
                       regQuery_A_Key = Left(sBuffer, iPos - 1)
                   Else
                       regQuery_A_Key = sBuffer
                   End If
                End If
            Case REG_DWORD:
                lRet = RegQueryValueEx(lKeyHandle, sRegSubKey, 0&, lDataType, lBuffer, 4&)
                If lRet = ERROR_SUCCESS Then regQuery_A_Key = lBuffer
           Case Else:
    End Select
FuncFail:
    lRet = RegCloseKey(lKeyHandle)
End Function

Public Function GetBiosVer() As String
    GetBiosVer = regQuery_A_Key(HKEY_LOCAL_MACHINE, GetBiosKey, "BiosVersion")
End Function

Public Function GetBiosDate() As String
    GetBiosDate = regQuery_A_Key(HKEY_LOCAL_MACHINE, GetBiosKey, "BiosDate")
End Function

Public Function GetBiosMfr() As String
    GetBiosMfr = regQuery_A_Key(HKEY_LOCAL_MACHINE, GetBiosKey, "BiosName")
End Function

Private Function GetBiosKey() As String
    Dim verinfo As OSVERSIONINFO
    Dim sKey As String
    verinfo.dwOSVersionInfoSize = Len(verinfo)
    If (GetVersionEx(verinfo)) = 0 Then Exit Function
    sKey = "Enum\Root\*PNP0C01\0000"
    If verinfo.dwPlatformId = 2 Then sKey = "SYSTEM\CurrentControlSet\" & sKey
    GetBiosKey = sKey
End Function

'Form code is the same.
Code above should work on all windows platforms (95/98/ME/NT/2000). This info will be updated in registry even if the user format his HDD/Reinstall windows (unless (s)he change motherboard).

Regards
Ark

0
 
LVL 7

Expert Comment

by:Z_Beeblebrox
ID: 6412238
Ark:

The problem with that code is that if the user flashes his BIOS, the date and version will change, and there are only a handful of brands of BIOS's so this would not even come close to guaranteeing uniqueness.

Zaphod.
0
 
LVL 27

Expert Comment

by:Ark
ID: 6412272
>>if the user flashes his BIOS<<
IMHO, this occures not more offten then changing hard drive.

Cheers
0
 
LVL 7

Expert Comment

by:Z_Beeblebrox
ID: 6412277
Ark:

Quite possibly, but even so there are not that many versions of BIOS, and the date corresponds to the version. If I were faced with this problem, I would use this BIOS info in conjunction with other stuff, unless there is a network card, in which case use the network card MAC address. Of course, if the user changes network cards then you have a problem... there is just no easy solution to this.

Zaphod.
0
 

Author Comment

by:hveld
ID: 6412700
Ark,

GetBiosVer, GetBiosDate and GetBiosMfr return empty strings.
GetBiosKey returns SYSTEM\CurrentControlSet\Enum\Root\*PNP0C01\0000
Under HKEY_LOCAL_Machine there is
SYSTEM\CurrentControlSet\Enum\Root\*PNP0C01, but no \0000 after it, and there is no such data there.
BTW I found a key
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\SystemBiosDate
(there is also SystemBiosVersion) but as you see it's on another place, and I'm not sure where to search for it on different versions of windows
0
 

Author Comment

by:hveld
ID: 6412708
The above is for windows2000 pro sp1, I'll test it on NT4sp6 and 95 later today
0
 
LVL 2

Expert Comment

by:egsemsem
ID: 6413028
hi hveld,
 I tested ARK code on Win98, and it gave me correct info about the BIOS.
 But I was wondering: What if someone changed these data from the registry every time he runs your software ?!!
 I think you should find out how Window origninally get BIOS info (It may have used Assembly), and do it.  

Osama
0
 

Author Comment

by:hveld
ID: 6414702
I just tested Ark's code on a triple boot win95/NT4sp6/W2Ksp1 system.
Basically, it works. For 95 without any modifications, for NT/w2k I had to change the place where the reg. key has to be searched and reg. key name(for NT/W2k it's SystemBiosDate, as for 95 it's just BiosDate). I have no access at the moment to 98/98se/ME/XP systems and I don't know how they look there.
On w2k, the BiosDate is available on 5 places in the registry, all they have a correct value(in my case 12/21/00)
On 95, it's on 3 places, two of them with a 00 value and one with a correct value(that's the place in the example code).
But on NT, it's available only at one place and does not have a correct value(for me, 04/23/90). I guess NT install can't correctly recognize this, and the subsequent sp's just don't change it. But i guess if you reinstall NT using a slipstreamed installer with embedded sp6, the date will be correct.
As a conclusion, I don't think reading BIOS info from registry is something I can rely on.
The reg. keys paths and names differ(maybe even with different sp's) and are not always correct.
If there is no way to read data from BIOS directly, maybe searching the registry for *BiosDate and retrieving all available values could help
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6415501
Is it acceptable that protection scheme requires administrator privileges on NT/2k?
Windows DOES support reading of very LOW-LEVEL details of harddisk drive (VendorUnique, SerialNumber, FirmwareRev, ModelNumber,...), working also on Win95, but ... on NT/2k this function requires Admin privileges. So... should I continue creating sample? (let's say it is VERY hard to convert complex structures that API uses to VB).


0
 

Author Comment

by:hveld
ID: 6415618
Yes, it's OK. I guess if someone buys something, he/she will use it on a PC where he/she has the appropriate priviligies.
I mean I will accept a solution that requires only admin priviligies for NT/W2K/XP to work.
0
 
LVL 1

Expert Comment

by:superchook
ID: 6415866
You certainly need to do more than BIOS / generic hardware validation.

What happens when the software is registered to a single PC in a corporate environment?, and there are 60 other PCs EXACTLY the same (except HDD/MAC/CPU serials).   Copy the original instal onto the other machines and...

This is why you need to make an ASSESSMENT of the individual machine.  The MAC address/machine name/HDD are a good starting point, but there needs to be some 'smarts' to choose the best combination for the situation you are installed in.

All the above comments are valid - but at some point, you have to take 'control'.   a one-off solution will be very unlikely to meet your needs... you need to explore the machine, and determine which variables are the most appropriate to protect your investment - without pissing the customer off completely.

Who knows ? - maybe the target system should be rescanned over a period of time, or at least several times - to catch minor migration of the attached hardware/software environment.
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6423602
i dont think that your going to get any different answer on here now vheld from what ive given and what others have, no matter of the way users on here are also giving you the down falls aswell which is great,

i would use a few methods off here and merge then into one so you have a very clever peice of software, one which like already stated learns about the computer enviroment and adapts to that profile.

i hope that some of the suggestions have helped you in your problem,

i would also like to thank all of the users who have contributed to this question, ive seen myself some very good idea's and i think its great that we can all pull together without any bitching at each other like ive seen in some past question, and help this user. its been a pleasure working with all of you and what a great team performance it was.

thanks all

Andy
ps just my two pennies

0
 
LVL 28

Expert Comment

by:AzraSound
ID: 6423705
Well stated Andy...   :-)
0
 
LVL 27

Expert Comment

by:Ark
ID: 6427100
Hi
Improved (make shorter) my code for getting BIOS data. Still worked only on w95/98/Me. Looking for a way to make it work on NT.

'=====BAS MODULE CODE===

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function CopyStringA Lib "kernel32" Alias "lstrcpyA" (ByVal NewString As String, ByVal OldString As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long

Public Function StrFromPtrA(ByVal lpszA As Long, Optional nSize As Long = 0) As String
   Dim s As String, bTrim As Boolean
   If nSize = 0 Then
      nSize = lstrlenA(lpszA)
      bTrim = True
   End If
   s = String(nSize, Chr$(0))
   CopyStringA s, ByVal lpszA
   If bTrim Then s = TrimNULL(s)
   StrFromPtrA = s
End Function

'==Not used now, just for future using with NT=====
Public Function StrFromPtrW(ByVal lpszW As Long, Optional nSize As Long = 0) As String
   Dim s As String, bTrim As Boolean
   If nSize = 0 Then
      nSize = lstrlenW(lpszW)
      bTrim = True
   End If
   s = String(nSize, Chr$(0))
   CopyMemory ByVal StrPtr(s), ByVal lpszW, nSize
   If bTrim Then s = TrimNULL(s)
   StrFromPtrW = s
End Function
'==================================================

Private Function TrimNULL(ByVal str As String) As String
    If InStr(str, Chr$(0)) > 0& Then
        TrimNULL = Left$(str, InStr(str, Chr$(0)) - 1&)
    Else
        TrimNULL = str
    End If
End Function

'=====FORM CODE===========
'Add combo box (dropdown list) and Text box to form.

Private Sub Form_Load()
   With Combo1
      .AddItem "BIOS Type"
      .ItemData(.NewIndex) = &HFE061
      .AddItem "BIOS CopyRight"
      .ItemData(.NewIndex) = &HFE091
      .AddItem "BIOS Date"
      .ItemData(.NewIndex) = &HFFFF5
      .AddItem "BIOS Extended Info"
      .ItemData(.NewIndex) = &HFEC71
   End With
End Sub

Private Sub Combo1_Click()
  Text1 = StrFromPtrA(Combo1.ItemData(Combo1.ListIndex))
End Sub

Cheers

0
 
LVL 3

Expert Comment

by:andysalih
ID: 6433664
ya getting there ARK,

:o)

Andy
0
 
LVL 1

Expert Comment

by:superchook
ID: 6434495
Ark Ark  (sound of seal clapping) <g>
0
 
LVL 1

Expert Comment

by:superchook
ID: 6434537
Ark Ark  (sound of seal clapping) <g>
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6466620
any update on this hveld ?

cheers
Andy

0
 

Author Comment

by:hveld
ID: 6467529
Well as you see nothing so far. Ark's code above works fine for 9x, but this is not enough. I also found some very cool examples at freevbcode.com  which can get CPU or HDD info, but require WMI, which is nearly 10 MB to download, and I can't force users to d/l 10 MB to make an app of 3-4 MB to work :(
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6467542
Unfortunatelly I found out I don't have enough knowledge to translate some HEAVY c++ code (structures,...) to VB for working function to get HDD's real serial number :(
0
 

Author Comment

by:hveld
ID: 6468252
BozzoCage, is it possible to make a small C exe or dll that reads the real HDD serial, then to pass a command to it from my vb app to read the serial and to return to my app the result?
0
 

Author Comment

by:hveld
ID: 6468315
BTW I tried the C code for which you posted a link for reading the HDD serial
http://groups.google.com/groups?hl=en&safe=off&th=919249df84d9024f,1&seekm=984352256%40p24.f176.n450.z2.FidoNet.ftn#p
When I compiled with MS VC++ it returned 13 errors. But I'm a real newbie in C and can't do anything to solve the problem
0
 

Author Comment

by:hveld
ID: 6468321
I now remembered that my drive is not IDE(this example is said to work for IDE only), maybe that's why these errors appear. Is it working for you for IDE HDD's ?
0
 

Author Comment

by:hveld
ID: 6468391
I tested it on IDE HDD and it works, however IDE's will become less and less popular in the future i think. Is it possible to do the same for SCSI?
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6468958
im starting to think that no matter what method you use that in the near future like you said that technology will change, thus changing the way your software needs to protect itself will prove more difficult.


you keep hittting walls with this and i feel that you will not get exactly what you require with out using some form of hardware device.

thats my 2 pennies

cheers
Andy
0
 
LVL 27

Expert Comment

by:Ark
ID: 6469269
Hi
Did you look at my previous link ( http://www.entechtaiwan.com/tvichw32.htm ) for getting HDD serial?
0
 

Author Comment

by:hveld
ID: 6469917
Yes Ark,

I did. But it's the same, their FAQ says you can do this for IDE HDD's only.
0
 

Expert Comment

by:moonrise
ID: 6741808
I am looking for something similar. I had decided on usig the MAC Address - I think makeing the users buy a $10 card is not a problem. However now I realize that you have to be connected to a network to actually get a MAC Address - is that correct?
0
 
LVL 2

Expert Comment

by:BozzoCage
ID: 6742713
It isn't correct - most of the time. WinXP "disables" access to ethernet card if they figure out it is not connected to some network. I don't know if that shows up programatically too, but standard ipconfig/all command doesn't show ehternet card and it's MAC.

Win2k detects that too (missing network), but can be "fooled" with putting only beginnning part of network cable on card (T with one terminator - talking about 10BaseT netcard).

Other windows doesn't detect "unplugged" network cable.

Regards,
 BozzoCage
0
 
LVL 27

Expert Comment

by:Ark
ID: 6745169
Hi
Almost forgot about this thread. I've improve GetBiosInfo code (http://www.freevbcode.com/ShowCode.Asp?ID=3292) for all systems. Also, made VB code for retriving HDD serial (tested with IDE drives only) - http://www.freevbcode.com/ShowCode.Asp?ID=3380

Cheers
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7202380
Hi hveld,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Save as PAQ -- No Refund.
    *** Many good answers, no way to split
    *** BTW, actual best answer is "use MAC address" but vheld rejected that.

hveld, IF YOU ARE ALIVE, GET BACK HERE AND AWARD SOME POINTS!  LIKE 1245 OF THEM AS PROMISED

EXPERTS: Post a comment if you are certain that an expert deserves credit.  Explain why.
==========
DanRollins -- EE database cleanup volunteer
0
 
LVL 5

Accepted Solution

by:
Netminder earned 0 total points
ID: 7216023
Per recommendation, points NOT refunded and question closed.

Netminder
CS Moderator
0
 
LVL 5

Expert Comment

by:Netminder
ID: 7216026
Per recommendation, points NOT refunded and question closed.

Netminder
CS Moderator
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now