Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Get CPU ID, MAC Address, Volume Serial Number 4

Status
Not open for further replies.

craigsboyd

IS-IT--Management
Nov 9, 2002
2,839
US
There have been a lot of questions regarding creating a hardware locking scheme using the CPU ID, MAC Address(es), and/or Volume Serial Number(s)...I realize that some of this has been laid out in FAQs and threads, but I thought I would start this thread to encompass all 3. Here is runnable code using Windows Script that will give you the information needed (cut-n-paste the code below into a prg and run it from within VFP):

Code:
*!* Let's get the CPU ID
LOCAL lcComputerName, loWMI, lowmiWin32Objects, lowmiWin32Object
lcComputerName = GETWORDNUM(SYS(0),1)
loWMI = GETOBJECT("WinMgmts://" + lcComputerName)
lowmiWin32Objects = loWMI.InstancesOf("Win32_Processor")
FOR EACH lowmiWin32Object IN lowmiWin32Objects
	WITH lowmiWin32Object
		? "ProcessorId: " + TRANSFORM(.ProcessorId)
	ENDWITH
ENDFOR

?
?

*!* Let's get the MAC Address(es)
LOCAL lcComputerName, loWMIService, loItems, loItem, lcMACAddress
lcComputerName = "."
loWMIService = GETOBJECT("winmgmts:\\" + lcComputerName + "\root\cimv2")
loItems = loWMIService.ExecQuery("Select * from Win32_NetworkAdapter",,48)
FOR EACH loItem IN loItems
	lcMACAddress = loItem.MACAddress
	IF !ISNULL(lcMACAddress)
		? "MAC Address: " + loItem.MACAddress
		?
	ENDIF
ENDFOR

?
?
*!* Let's get the Volume Serial Number(s)
LOCAL lcComputerName, loWMIService, loItems, loItem, lcVolumeSerial
lcComputerName = "."
loWMIService = GETOBJECT("winmgmts:\\" + lcComputerName + "\root\cimv2")
loItems = loWMIService.ExecQuery("Select * from Win32_LogicalDisk")
FOR EACH loItem IN loItems
	lcVolumeSerial = loItem.VolumeSerialNumber
	IF !ISNULL(lcVolumeSerial)
		? "Name: " + loItem.NAME
		? "Volume Serial Number: " + loItem.VolumeSerialNumber
		?
	ENDIF
ENDFOR

BPeisch made a very good suggestion in a previous thread regarding this, and mentioned the SYS(2007) function. This can be used to allow you to give the user a serial number to use to unlock your application.

?SYS(2007, lcMyHardwareInfo)

Slighthaze = NULL
[sub]craig1442@mchsi.com[/sub][sup]
"Whom computers would destroy, they must first drive mad." - Anon​
[/sup]
 
Note: This code only seems to work under VFP 7 & 8 (on XP), and not at all on Win 98SE.

Rick
 
Rick,

i appreciate your testing this...can you tell me if you installed WMI on the Win 98SE machine that you tried this on?

Slighthaze = NULL
[sub]craig1442@mchsi.com[/sub][sup]
"Whom computers would destroy, they must first drive mad." - Anon​
[/sup]
 
In light of Rick's post and knowing that some developers may not want to have to install the WMI core components on their users machines in order to run the above script...I am trying to accomplish this with more compatible code. Haven't found a good way to do this for the CPU ID, but here is the code for getting the Volume Serial Number and the MAC address:

Code:
?GetVolumeSerial("C")

FUNCTION GetVolumeSerial(tcDrive)
	IF PCOUNT() = 0
		tcDrive = "C:\"
	ELSE
		tcDrive = STRTRAN(tcDrive, ":\", "") + ":\"
	ENDIF
	LOCAL lcName, lcFSName, lnVolumeSerial, ;
		lnFMaxLen, lnFSFlags, ;
		lcVolumeSerial, lnNameLen, lnFSNameLen

	STORE SPACE(255) TO lcName, lcFSName
	STORE 0 TO lnVolumeSerial, lnFMaxLen, lnFSFlags
	STORE 255 TO lnNameLen, lnFSNameLen

	DECLARE GetVolumeInformation IN win32api STRING, STRING @, ;
		INTEGER, INTEGER @, INTEGER @, INTEGER @, STRING @, INTEGER

	=GetVolumeInformation(tcDrive, @lcName, lnNameLen, ;
		@lnVolumeSerial, @lnFMaxLen, @lnFSFlags, @lcFSName, lnFSNameLen)
		
	CLEAR DLLS GetVolumeInformation
	
	IF EMPTY(lnVolumeSerial)
		RETURN ""
	ELSE
		IF lnVolumeSerial < 0
			lnVolumeSerial = 4294967296 + lnVolumeSerial
		ENDIF
		lcVolumeSerial = SUBSTR(TRANSFORM(lnVolumeSerial,&quot;@0&quot;), 3)
		RETURN lcVolumeSerial
	ENDIF
ENDFUNC

?GetMACAddress()

FUNCTION GetMACAddress()
lcFile = ADDBS(SYS(2023)) + &quot;_&quot;+SUBSTR(SYS(2015), 4)  + &quot;.tmp&quot;
lcCommand = &quot;ipconfig /all >&quot; + lcFile
DECLARE INTEGER WinExec IN win32api ;
   STRING command, INTEGER param
=WinExec(SYS(2004) + &quot;FOXRUN.PIF /C &quot; + lcCommand, 0)
CLEAR DLLS WinExec
*!* This next line may not be necessary on all computers...included JIC
=INKEY(1, &quot;H&quot;) &&Slow VFP down so windows can make the file first
IF FILE(lcFile)
	lcOutput = FILETOSTR(lcFile)
	ERASE (lcFile)
ELSE
	RETURN &quot;&quot; &&Couldn't create file
ENDIF

lnAt = AT('Physical Address. . . . . . . . . : ', lcOutput)
IF lnAt > 0
	lcMAC = UPPER(STRTRAN(SUBSTR(lcOutput, lnAt + 36 , 17), '-',''))
ENDIF

RETURN lcMAC

Slighthaze = NULL
[sub]craig1442@mchsi.com[/sub][sup]
&quot;Whom computers would destroy, they must first drive mad.&quot; - Anon​
[/sup]
 


Excellent stuff SlightHaze!!

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
* Concur - Excellent work and thanks for sharing.

It reinforces one my recent posts a while back when I stated I preferred a registry read (API) over the scripting host because the host is not on all pc, or has been disabled by the network gurus.

Jim Osieczonek
Delta Business Group, LLC
 
Another thing you can use for creating a hardware lock for an application is the MotherBoard. Either the Product ID or the Serial Number of the board. It has the added benefit of being a piece of hardware that is very seldom changed (though yes it does happen).

loWMI = GETOBJECT(&quot;WinMgmts://./root/cimv2&quot;)
BaseBoards = loWMI.InstancesOf(&quot;Win32_BaseBoard&quot;)
FOR EACH MotherBoard IN BaseBoards
?&quot;Product: &quot; + MotherBoard.Product
?&quot;SerialNumber: &quot; + MotherBoard.SerialNumber
NEXT


Slighthaze = NULL
[sub]craig1442@mchsi.com[/sub][sup]
&quot;Whom computers would destroy, they must first drive mad.&quot; - Anon​
[/sup]
 
slighthaze,

just tested, but I get

Product: MS-6728
SerialNumber: 00000000

Can you explain what is happening?

My mainboard is a MSI 865PE-Neo2 (internal MSI code 6728)

Thanks
 
thesofty,

I cannot explain what is happening. The product and serial number returned for the baseboard is, according to the documentation, defined/allocated by the manufacturer.

Slighthaze = NULL
[sub]craig1442@mchsi.com[/sub][sup]
&quot;Whom computers would destroy, they must first drive mad.&quot; - Anon​
[/sup]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top