My Assistant
![]() ![]() |
|
|
Jan 18 2005, 03:03 PM
Post
#1
|
|
|
UdderAccess Admin + UA Ruler Posts: 15,662 From: Upper MI |
What is the most unique hardware ID obtainable from a PC with Access, and how is it obtained?
The object is to lock an Access application to ONE machine and one machine only. |
|
|
|
Jan 18 2005, 03:19 PM
Post
#2
|
|
|
UtterAccess Enthusiast Posts: 89 From: Maine |
Why dont you just lock it to the pc's mac address?
|
|
|
|
Jan 18 2005, 03:26 PM
Post
#3
|
|
|
UtterAccess Enthusiast Posts: 89 From: Maine |
Hres an example of a vb6 program that obtains the mac address from the network card. I haven't tested it, so good luck.
|
|
|
|
Jan 18 2005, 05:27 PM
Post
#4
|
|
|
UtterAccess VIP Posts: 3,752 From: Australia (NSW) |
Moo,
The Mac Address is (supposed) to be almost gauranteed to NOT be repeated for apprx 50 years (last I knew), so makes it PRETTY UNIQUE. Here is some (Access) code that will get it for you ..... CODE Private Const msMODULE_NAME As String = "CNetInfo"
''' declarations for MACAddress Private Const errMemoryAllocFailed = 47900 Private Const NCBASTAT = &H33 Private Const NCBNAMSZ = 16 Private Const HEAP_ZERO_MEMORY = &H8 Private Const HEAP_GENERATE_EXCEPTIONS = &H4 Private Const NCBRESET = &H32 Private Type NCB ncb_command As Byte ncb_retcode As Byte ncb_lsn As Byte ncb_num As Byte ncb_buffer As Long ncb_length As Integer ncb_callname As String * NCBNAMSZ ncb_name As String * NCBNAMSZ ncb_rto As Byte ncb_sto As Byte ncb_post As Long ncb_lana_num As Byte ncb_cmd_cplt As Byte ncb_reserve(9) As Byte ' Reserved, must be 0 ncb_event As Long End Type ' Private Type ADAPTER_STATUS adapter_address(5) As Byte rev_major As Byte reserved0 As Byte adapter_type As Byte rev_minor As Byte Duration As Integer frmr_recv As Integer frmr_xmit As Integer iframe_recv_err As Integer xmit_aborts As Integer xmit_success As Long recv_success As Long iframe_xmit_err As Integer recv_buff_unavail As Integer t1_timeouts As Integer ti_timeouts As Integer Reserved1 As Long free_ncbs As Integer max_cfg_ncbs As Integer max_ncbs As Integer xmit_buf_unavail As Integer max_dgram_size As Integer pending_sess As Integer max_cfg_sess As Integer max_sess As Integer max_sess_pkt_size As Integer name_count As Integer End Type ' Private Type NAME_BUFFER Name As String * NCBNAMSZ name_num As Integer name_flags As Integer End Type ' Private Type ASTAT adapt As ADAPTER_STATUS NameBuff(30) As NAME_BUFFER End Type ' Private Declare Function Netbios Lib "netapi32.dll" (pncb As NCB) As Byte ' Private Declare Function GetProcessHeap Lib "kernel32" () As Long ' Private Declare Function HeapAlloc Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long ' Private Declare Sub RtlMoveMemory Lib "kernel32" (hpvDest As Any, ByVal hpvSource&, ByVal cbCopy&) ' Private Declare Function HeapFree Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, lpMem As Any) As Long ' Public Function MACAddress() As String Const sPROC_NAME As String = "MACAddress" Dim myNcb As NCB Dim bRet As Byte On Error GoTo ErrorHandler myNcb.ncb_command = NCBRESET bRet = Netbios(myNcb) myNcb.ncb_command = NCBASTAT myNcb.ncb_lana_num = 0 myNcb.ncb_callname = "* " Dim myASTAT As ASTAT Dim pASTAT As Long myNcb.ncb_length = Len(myASTAT) pASTAT = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS Or HEAP_ZERO_MEMORY, myNcb.ncb_length) If pASTAT = 0 Then Err.Raise errMemoryAllocFailed, msMODULE_NAME & "." & sPROC_NAME, "Memory allocation failed" Exit Function End If myNcb.ncb_buffer = pASTAT bRet = Netbios(myNcb) RtlMoveMemory myASTAT, myNcb.ncb_buffer, Len(myASTAT) MACAddress = Hex(myASTAT.adapt.adapter_address(0)) & ":" & _ Hex(myASTAT.adapt.adapter_address(1)) & ":" & _ Hex(myASTAT.adapt.adapter_address(2)) & ":" & _ Hex(myASTAT.adapt.adapter_address(3)) & ":" & _ Hex(myASTAT.adapt.adapter_address(4)) & ":" & _ Hex(myASTAT.adapt.adapter_address(5)) HeapFree GetProcessHeap(), 0, ByVal pASTAT Exit Function ErrorHandler: ' MACAddress = "00:00:00:00:00:00" |
|
|
|
Jan 18 2005, 06:46 PM
Post
#5
|
|
|
UdderAccess Admin + UA Ruler Posts: 15,662 From: Upper MI |
Hmmmm, interesting . . .
Thanks R-Cubed ! ! What if the PC doesn't have a NIC? Any ideas? |
|
|
|
Jan 18 2005, 07:45 PM
Post
#6
|
|
|
UtterAccess Addict Posts: 213 From: Australia |
You could use the volume serial!
just specify the drive ie: C:\ and it returns the volumes hardware serial. Attached is a module to do it. |
|
|
|
Jan 18 2005, 10:46 PM
Post
#7
|
|
|
Utterly Crispy UA Forum Administrator Posts: 7,096 From: Edmonton,Alberta,Canada |
A Nic card is not the best thing to use as nic's although they have a very unique number do not last as long as drives usually do these days. The Drive Serial Number which is embeded into the drive will not change so what ever computer your program is running on will need this drive or it will not run. You can then have the program read that serial number then decide if to let the program run or you can save it to the registry and check that the value is there and run it. What I do is to record all the hard drive serial numbers not volume numbers and write them to the registry then I have the program read the current hard drives compare it to the registry enetries and if they are the same run the program. I'll let you figure out the code for that. Here is some code to read the drive letter and serial number. Save it to a .vbs file using note pad and run it. it will show you the fixed drives installed and the serial numbers. in access you would use message boxes or write it to where ever you want.
Have fun! CODE Set objFSO = CreateObject("Scripting.FileSystemObject") Set colDrives = objFSO.Drives For Each objDrive in colDrives If objDrive.DriveType = 2 Then Wscript.Echo "Drive letter: " & objDrive.DriveLetter Wscript.Echo "Serial number: " & objDrive.SerialNumber End If Next |
|
|
|
Jan 19 2005, 02:29 AM
Post
#8
|
|
|
Utterly Crispy UA Forum Administrator Posts: 7,096 From: Edmonton,Alberta,Canada |
Hi Rob,
If you are using Windows 2000 or up this works nicely too. CODE Public Function GetInfo()
Dim Manufacturer As String Dim ProductName As String Dim MACAddress As String On Error Resume Next ' To use a computer on a network use the full path otherwise "." refer's to the 'local computer. strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkAdapter", , 48) For Each objItem In colItems If objItem.NetConnectionID = objItem.NetConnectionID Then Manufacturer = objItem.Manufacturer ProductName = objItem.ProductName MACAddress = objItem.MACAddress Call MsgBox(Manufacturer, vbInformation, "Mac Address Demo") Call MsgBox(ProductName, vbInformation, "Mac Address Demo") Call MsgBox(MACAddress, vbInformation, "Mac Address Demo") End If Next End Function |
|
|
|
Jan 19 2005, 08:19 AM
Post
#9
|
|
|
UdderAccess Admin + UA Ruler Posts: 15,662 From: Upper MI |
Glen & Trip,
Thank you for your input and assistance. I will play with these today! |
|
|
|
Jan 19 2005, 10:19 AM
Post
#10
|
|
|
UtterAccess Ruler Posts: 1,884 From: Cleveland, OH |
You might want to check on some of the Environ variables, environ can find a allot of different things. Just a thought for you to think about. hth.
|
|
|
|
Jan 19 2005, 11:57 AM
Post
#11
|
|
|
Utterly Crispy UA Forum Administrator Posts: 7,096 From: Edmonton,Alberta,Canada |
If you need more help don't hesitate to ask moo.
|
|
|
|
Jan 19 2005, 02:56 PM
Post
#12
|
|
|
UdderAccess Admin + UA Ruler Posts: 15,662 From: Upper MI |
Glen,
Happy to take you up on that offer . . . • What are the other fields available in the objItem collection? {When you used the "Select * from Win32_NetworkAdapter" query string to acuire the data, what are (or how do I see) the entire list of field names?} • I'm also focusing on Set objWMIService = GetObject("winmgmts:\" & strComputer & "rootcimv2") because I've never ancountered that before. What is that? • In your first response, you used Wscript. WHat should that be Dim'd and Set as? (IMG:http://www.endprod.com/images/emoticons/dunce.gif) Thanks man! |
|
|
|
Jan 19 2005, 03:13 PM
Post
#13
|
|
|
UtterAccess VIP / UA Clown Posts: 25,084 From: LI, NY |
Glen,
I was looking for code like this a while back, where were you then? (IMG:http://www.utteraccess.com/forum/style_emoticons/default/frown.gif) Seriously, with almost all new motherboards having onboard Ethernet adapters, there is a MAC built in to the motherboard. Wouldn't this make the MAC a more static ID to look for? The problem I see with using a drive SN is what if the user wants to move the app to an external drive or needs to replace the drive. This would disable the app. I understand you are saying the same thing could happen with replacing a NIC, but like I said, they are built into motherboards now. Though there is an issue of some PCs having multiple NICs. How could that be dealt with? |
|
|
|
Jan 19 2005, 04:51 PM
Post
#14
|
|
|
Utterly Crispy UA Forum Administrator Posts: 7,096 From: Edmonton,Alberta,Canada |
The first one uses the file system object So you need to set references to the MS Scripting dll. Instead of using Wscript.Echo "Available space: " & objDrive.AvailableSpace in Access use
MsgBox objDrive.AvailableSpace The same goes for the second one. CODE Set objFSO = CreateObject("Scripting.FileSystemObject") Set colDrives = objFSO.Drives For Each objDrive in colDrives Wscript.Echo "Available space: " & objDrive.AvailableSpace Wscript.Echo "Drive letter: " & objDrive.DriveLetter Wscript.Echo "Drive type: " & objDrive.DriveType Wscript.Echo "File system: " & objDrive.FileSystem Wscript.Echo "Free space: " & objDrive.FreeSpace Wscript.Echo "Is ready: " & objDrive.IsReady Wscript.Echo "Path: " & objDrive.Path Wscript.Echo "Root folder: " & objDrive.RootFolder Wscript.Echo "Serial number: " & objDrive.SerialNumber Wscript.Echo "Share name: " & objDrive.ShareName Wscript.Echo "Total size: " & objDrive.TotalSize Wscript.Echo "Volume name: " & objDrive.VolumeName Next The second use's Windows WMI script which is how windows 2000 and up queries the operating system instead of using API Calls. You need to set a reference to the WMI Scripting dll. CODE strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set colItems = objWMIService.ExecQuery("Select * from Win32_Volume") For Each objItem In colItems WScript.Echo "Automount: " & objItem.Automount WScript.Echo "Block Size: " & objItem.BlockSize WScript.Echo "Capacity: " & objItem.Capacity WScript.Echo "Caption: " & objItem.Caption WScript.Echo "Compressed: " & objItem.Compressed WScript.Echo "Device ID: " & objItem.DeviceID WScript.Echo "Dirty Bit Set: " & objItem.DirtyBitSet WScript.Echo "Drive Letter: " & objItem.DriveLetter WScript.Echo "Drive Type: " & objItem.DriveType WScript.Echo "File System: " & objItem.FileSystem WScript.Echo "Free Space: " & objItem.FreeSpace WScript.Echo "Indexing Enabled: " & objItem.IndexingEnabled WScript.Echo "Label: " & objItem.Label WScript.Echo "Maximum File Name Length: " & objItem.MaximumFileNameLength WScript.Echo "Name: " & objItem.Name WScript.Echo "Quotas Enabled: " & objItem.QuotasEnabled WScript.Echo "Quotas Incomplete: " & objItem.QuotasIncomplete WScript.Echo "Quotas Rebuilding: " & objItem.QuotasRebuilding WScript.Echo "Serial Number: " & objItem.SerialNumber WScript.Echo "Supports Disk Quotas: " & objItem.SupportsDiskQuotas WScript.Echo "Supports File-Based Compression: " & objItem.SupportsFileBasedCompression WScript.Echo Next Both are saved as .vbs files if you want to run them as stand alone scripts. WMI scripts can be run on any computers running Windows 98 or Windows ME with WMI Scripting installed or on any computer running Windows 2000 and up. The Scripts are used mainly to help network administrators accomplish unattented tasks but i have found them to be usefull in Access programming as well as VB. This site will allow you to download a help file list a variatey of scripts. Once you understand how they work you will be writing your own. http://www.microsoft.com/technet/scriptcenter Edited by: GlenKruger on Wed Jan 19 17:26:31 EST 2005. Edited by: GlenKruger on Mon Jan 24 13:27:43 EST 2005. |
|
|
|
Jan 19 2005, 05:14 PM
Post
#15
|
|
|
Utterly Crispy UA Forum Administrator Posts: 7,096 From: Edmonton,Alberta,Canada |
Well actually I have been ill for the last while and don't really search the site very much anymore.
To answer your question simpely no the on board Nic is not the best to use as it can be disabled in the bios and won't even show up in a scan of hardware. I understand your concern about someone replacing a drive but that is where looking at what was origionally there when you installed your app and what is there now will come into play. The code required is not for the weak at heart because you are manipulating the users registry and that is why I will not go further into detail on the site about doing that. In an unexpierenced programmers hands that type of code could cause severe damage to someones computer. To properly restrict user's from copying software from one computer to another you need to use registration key's and code in your program that sends certain data back to your server every time your program is started and connected to the internet as well as code in your install program that writes to the registry. You have to have a server running 24 hours a day to catch people trying to do this sort of activeity again to complicated to get into on the site besides if I give all my trade secrets away what good would I be to my clients .... (IMG:http://www.utteraccess.com/forum/style_emoticons/default/laugh.gif) As far as having more than one Nic installed this sample will return all the Nic's installed in the computer so then you would just record them somewhere. http://members.shaw.ca/glenk/NicCardMacAddy.zip HTH Glen Edited by: GlenKruger on Wed Jan 19 17:18:17 EST 2005. |
|
|
|
May 16 2007, 05:48 AM
Post
#16
|
|
|
UtterAccess Addict Posts: 293 |
Hi all,
Does anyone have a demo of security based on the drive serial number? The module posted in page 1 of this thread by trip is no longer available to download!! Thanks |
|
|
|
![]() ![]() |
|
Go to Top · Lo-Fi Version | Time is now: 22nd May 2013 - 11:49 PM |