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!

Getting MAC address 2

Status
Not open for further replies.

Eguy

Programmer
Dec 22, 2000
566
US
Hi all;

I need to create a UUID (Universal Unique ID) that will withstand 'Ghosting'. I currently generate a 36 byte UUID during install and store it in the registry and in a dbf for comparison at startup. This is fairly secure copy protection until you put Norton Ghost into the mix. My primitive ape brain thinks that using the MAC address of the network card would be more secure. However, I'll be dipped in @#$% if I can find a way to get it in VFP.

===> Note to rgbean <===
Rick;
I did a search in this forum and saw your thread from about a year ago. Unfortunatly some of the links mentioned are broken now. Did you ever solve your problem?

TIA
Ed Please let me know if the suggestion(s) I provide are helpful to you.
Sometimes you're the windshield... Sometimes you're the bug.
smallbug.gif
 
FWIW, below is a MACAddress routine I wrote a while ago. This is quick & dirty and could use some cleaning up, but you get the idea. This had the advantage of working across all OS's without requiring any extras. It also let's you retrieve not only your MACAddress, but any MACAddress on the network based on the IP Address or Machine name.

Usage:
? GetMac()
? GetMac(&quot;192.168.2.3&quot;)
? GetMac(&quot;OtherMachineName&quot;)

Andy


** GETMAC.PRG
** Pass in an IP Address or Name or leave blank for local
** workstation.

LPARAMETERS zcIPAddrOrName
IF TYPE(&quot;zcIPAddrOrName&quot;) != &quot;C&quot;
zcIPAddrOrName = SUBSTR(SYS(0), 1, AT(&quot;#&quot;, SYS(0)) - 1)
ENDIF

** Declare some API functions.
DECLARE INTEGER ShellExecute ;
IN SHELL32.DLL ;
INTEGER nWinHandle,;
STRING cOperation,;
STRING cFileName,;
STRING cParameters,;
STRING cDirectory,;
INTEGER nShowWindow
DECLARE INTEGER DeleteFile IN win32api STRING
=DeleteFile(&quot;c:\getmac.txt&quot;)
=DeleteFile(&quot;c:\getmac.bat&quot;)

** Create the batch file and run it.
=STRTOFILE(&quot;nbtstat -a &quot; + zcIPAddrOrName + &quot; >c:\getmac.txt&quot;, &quot;c:\getmac.bat&quot;, .F.)
=ShellExecute(0, &quot;open&quot;, &quot;c:\getmac.bat&quot;, &quot;&quot;, &quot;&quot;, 0)

** Wait until the file is created
lnSeconds = SECONDS()
lnHandle = FOPEN(&quot;c:\getmac.txt&quot;)
DO WHILE lnHandle <= 0 AND SECONDS() - lnSeconds <= 5
** Wait until file created...
=INKEY(.1, &quot;H&quot;)
lnHandle = FOPEN(&quot;c:\getmac.txt&quot;)
ENDDO
IF lnHandle > 0
=FCLOSE(lnHandle)
ENDIF

** Parse through the file.
lcReturn = &quot;&quot;
IF FILE(&quot;c:\getmac.txt&quot;)
lcTempFile = UPPER(FILETOSTR(&quot;c:\getmac.txt&quot;))
lnStart = AT(&quot;MAC ADDRESS = &quot;, lcTempFile)
IF lnStart > 0
lnStart = lnStart + 14
lcReturn = SUBSTR(lcTempFile, lnStart, 17)
ENDIF
ENDIF

** Clean up.
=DeleteFile(&quot;c:\getmac.txt&quot;)
=DeleteFile(&quot;c:\getmac.bat&quot;)
RETURN lcReturn

 
It's certainly an alternative... but somehow nbtstat.exe reliably can retrieve the IP address, MAC address, etc, so VFP should be able to, too!
 
hi all,

if using win2000 or xp use this code for getmac address,

**************************
LOCAL gcMacAddress
gcMacAddress = .null.
loloc = CREATEOBJECT(&quot;WbemScripting.SWbemLocator&quot;)
lowmi = loloc.connectServer()
lomac = lowmi.InstancesOf(&quot;Win32_NetworkAdapterConfiguration&quot;)
FOR EACH loMacAddr IN lomac
IF loMacAddr.IPEnabled
gcMacAddress = loMacAddr.MACAddress
EXIT
ENDIF
NEXT
STORE .null. to loloc,lowmi,lomac,loMacAddr
? &quot;MAC ADDRESS:&quot; + gcMacAddress
********************


if you use win95 or win98 you must download,
wmi9x.exe and setup.
(Windows Management Instrumentation (WMI) CORE 1.5 (Windows 95/98)

after use getmac source.

Regards,
Osman Beyaz.
cheers.gif
 
Could someone send me a copy of the getmac routeine and ocx as well. Please send to jmcfarlane@globalbeveragegroup.com

Thanks

Jason
 
jmcfarlane

You do not need to OCX, just use the information in faq184-3356
or this function:
Code:
function GetMacAddress
Local pGUID,rGUID,lcOldError, lnResult
Declare integer CoCreateGuid in 'OLE32.dll' string @pguid
Declare integer StringFromGUID2 in 'OLE32.dll' ;
  string rguid, string @lpsz, integer cchMax
Declare integer UuidCreateSequential in 'RPCRT4.dll'  string @ Uuid

pGUID=replicate(chr(0),16)
rGUID=replicate(chr(0),80)

lcOldError = On('error')
On Error lnResult = CoCreateGuid(@pGUID)
lnResult = UuidCreateSequential(@pGUID) 
On Error &lcOldError

return substr( iif( lnResult = 0 and ;
	StringFromGUID2(pGUID,@rGUID,40) # 0, ;
    StrConv(left(rGUID,76),6), &quot;&quot; ), 26,12)
Cetin

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike, I tried your function, but it did not return the correct address.

I am using windows XP and when doing an ipconfig/all, it reports back 2 MAC addresses.

The actual adapter is one, and the other I think is used when I am connecting to my VPN (description says Nortel).

Jason
 
jmcfarlane

I used the GetMacAddress function and it returns the same address as the &quot;ipconfig /all&quot; physical address which is the MAC address (On Windows XP)



Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike, when I do ipconfig/all I get 2 addresses.

One is the internal NIC and the second is a MAC address added by Nortel's Contivity VPN software.

Using the code you gave, it returned to me the MAC address created by the vpn software. I only want the actual hardware.

Any ideas?

On another note, I have also tried using snmptools.dll which works great with vfp7 and installshield, but when I try to use it in a vfp6 app and using the setup wizard I get a 'Cannot find entry point InitSNMP in the dll'. Any idea what I am missing in the setup wizard?

Jason
 
How about this?:
Code:
#DEFINE ERROR_SUCCESS           0
#DEFINE ERROR_NOT_SUPPORTED     50
#DEFINE ERROR_INVALID_PARAMETER 87
#DEFINE ERROR_BUFFER_OVERFLOW   111
#DEFINE ERROR_NO_DATA           232

DECLARE INTEGER GetAdaptersInfo IN iphlpapi;
	STRING @pAdapterInfo, LONG @pOutBufLen

LOCAL lcBuffer, lnBufsize
lnBufsize = 0
lcBuffer = &quot;&quot;

* this call usually returns the ERROR_BUFFER_OVERFLOW
* with lnBufsize set to the required amount of memory
= GetAdaptersInfo(@lcBuffer, @lnBufsize)

lcBuffer = Repli(Chr(0), lnBufsize)
IF GetAdaptersInfo(@lcBuffer, @lnBufsize) <> ERROR_SUCCESS
* still something is wrong
	RETURN
ENDIF

*|typedef struct _IP_ADAPTER_INFO {
*|  struct _IP_ADAPTER_INFO* Next;         0:4
*|  DWORD ComboIndex;                      4:4
*|  char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];          8:260
*|  char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]; 268:132
*|  UINT AddressLength;                       400:4
*|  BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]; 404:8
*|  DWORD Index;                              412:4
*|  UINT Type;                                416:4
*|  UINT DhcpEnabled;                         420:4
*|  PIP_ADDR_STRING CurrentIpAddress;         424:...
*|  IP_ADDR_STRING IpAddressList;
*|  IP_ADDR_STRING GatewayList;
*|  IP_ADDR_STRING DhcpServer;
*|  BOOL HaveWins;
*|  IP_ADDR_STRING PrimaryWinsServer;
*|  IP_ADDR_STRING SecondaryWinsServer;
*|  time_t LeaseObtained;
*|  time_t LeaseExpires;
*|} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;

#DEFINE MAX_ADAPTER_NAME_LENGTH        256
#DEFINE MAX_ADAPTER_DESCRIPTION_LENGTH 128
#DEFINE MAX_ADAPTER_ADDRESS_LENGTH     8

? &quot;Adapter name:&quot;,;
	STRTRAN(SUBSTR(lcBuffer, 9, 260), Chr(0), &quot;&quot;)
? &quot;Description:&quot;,;
	STRTRAN(SUBSTR(lcBuffer, 269, 132), Chr(0), &quot;&quot;)

LOCAL lnAddrlen, lcAddress, ii, ch
lnAddrlen = Asc(SUBSTR(lcBuffer, 401, 1))
lcAddress = SUBSTR(lcBuffer, 405, lnAddrlen)

? &quot;MAC Address: &quot;
FOR ii=1 TO lnAddrlen
	?? Asc(SUBSTR(lcAddress, ii,1)), &quot; &quot;
ENDFOR

? &quot;Index?:&quot;, Asc(SUBSTR(lcBuffer, 413,1))
? &quot;Type:&quot;, Asc(SUBSTR(lcBuffer, 417,1))
? &quot;Current IP address:&quot;, STRTRAN(SUBSTR(lcBuffer, 433,15), Chr(0),&quot;&quot;)

* storing the buffer to a cursor, so you can review each byte of it
CREATE CURSOR cs (asc I, ch C(1))
FOR ii=1 TO lnBufsize
	ch = SUBSTR(lcBuffer, ii,1)
	INSERT INTO cs VALUES (Asc(m.ch), m.ch)
ENDFOR



Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
It is getting a MAC address, but how can it tell whether the address is a network adapter versus a virtual one? What about the active network card?

Any ideas?

Jason
 
For the &quot;lurkers&quot; - I sent the MACADDRESS.OCX and GETMAC.PRG to Jason, and he replied:
&quot;Hi Rick, unfortunately it returned the Nortel virtual MAC address.

Have you ever used snmptools.dll? I am having some trouble with it. When using vfp7 and installshield everything is fine. When trying to run a vfp6 app and the setup wizard I get a “cannot find entry point InitSNMP in the dll” at the customer site, but not here on my development machine.

Any ideas?

Jason&quot;


I replied:
&quot;Jason,
You should note that the DLL I gave you will return ALL the MAC addresses available, however because we just wanted a &quot;unique&quot; ID, the included .PRG file just picks off the last good one in the returned list. Feel free to change the GETMAC.PRG to return them all, or the first good one, etc.

While I've played with the snmptools.dll, I don't use it in any production apps - I haven't got any ideas on it not working. However, normally when you've got missing entry points, it's due to having a different (older?) version of the .DLL already registered, or that the .DLL depends on another (system?) .DLL that may vary based on the OS and service patch levels or even other applications that may have installed yet another variant.&quot;

Anyone have additional ideas on this situation?

Rick
 
Try this little routine:
Code:
****************************************************
CREATE CURSOR AdapterDetail;
   (adProperty c(50),;
    adValue    c(120))
      
oManager = Getobject(&quot;winmgmts:&quot;)
oadaptcolconf = ;
  oManager.InstancesOf(&quot;Win32_NetworkAdapterConfiguration&quot;)

FOR EACH Qualifier IN oadaptcolconf
  APPEND BLANK 
  FOR EACH Property IN Qualifier.Properties_
     op = Property
     IF op.IsArray
         av = Property.Value
         FOR zzz = 1 TO Alen(av)
            APPEND BLANK 
            REPLACE adProperty WITH Property.name  
            REPLACE adValue    WITH Transform(av[zzz])
         NEXT
      ELSE 
        APPEND BLANK 
        REPLACE adProperty WITH Property.name  
        REPLACE adValue    WITH Transform(Property.Value)
      ENDIF 
  NEXT
NEXT
***********************************************

The 'Caption' tells what the adapter is, and the MAC address will be farther down. There will be sections for each adapter you have whether physical or logical.


-Dave S.-
[cheers]
Even more Fox stuff at:
 
Dave,
The only problem with using &quot;winmgmts&quot;, is that I believe it's only available on Win 2000 and XP (and probably Server 2003). :-(

Rick
 
Rick,

Yes you right. ME also support WinMgmt.

Btw, it already mentioned by one post above (obeyaz). And he also give the link to get the WMI for Win9X

-- AirCon --
 
Thanks, I missed that because I was looking explicitly for &quot;winmgmts&quot; and I didn't see it!

Rick
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top