Page 1 of 1

GetMac

Posted: Sun Dec 23, 2007 5:06 am
by SFSxOI
If you open up a command prompt and type 'GetMac' you get the MAC address of the network card and the card GUID. there was something a while back i saw posted that would retrieve the GUID of the network card but can't find it now, anyone know where its at or have it?

Posted: Sun Dec 23, 2007 9:04 pm
by ABBKlaus
is it this ? :

Code: Select all

; ABBKlaus Mon May 17, 2004 20:16 
; http://msdn2.microsoft.com/en-us/library/aa365917.aspx 
; with the help of IPHlpAPI.inc from the Powerbasic include-file for the structures 
; Microsoft isn´t quite a help here :-) 
; modified by PSW Wed Sep 06, 2006 07:49 
; PB4.02 compatible since 29.05.2007 19:48 
; PB4.10 compatible on 23.12.2007 21:03 

ImportC "msvcrt.lib" 
  asctime.l(a.l) 
  localtime.l(a.l) 
  strftime.l(a.l,b.l,c.p-ascii,d.l) 
EndImport 

Structure IP_ADDR_STRING 
  pNext.l 
  IpAddress.b[16] 
  IpMask.b[16] 
  Context.l 
EndStructure 

Structure TM 
  tm_sec.l 
  tm_min.l 
  tm_hour.l 
  tm_mday.l 
  tm_mon.l 
  tm_year.l 
  tm_wday.l 
  tm_yday.l 
  tm_isdst.l 
EndStructure 

#MAX_ADAPTER_NAME_LENGTH=256 
#MAX_ADAPTER_DESCRIPTION_LENGTH=128 
#MAX_ADAPTER_ADDRESS_LENGTH=8 

#MIB_IF_TYPE_OTHER     = 0 
#MIB_IF_TYPE_ETHERNET  = 1 
#MIB_IF_TYPE_TOKENRING = 2 
#MIB_IF_TYPE_FDDI      = 3 
#MIB_IF_TYPE_PPP       = 4 
#MIB_IF_TYPE_LOOPBACK  = 5 
#MIB_IF_TYPE_SLIP      = 6 

Structure IP_ADAPTER_INFO 
  pNext.l 
  ComboIndex.l 
  AdapterName.b[#MAX_ADAPTER_NAME_LENGTH+4] 
  Description.b[#MAX_ADAPTER_DESCRIPTION_LENGTH+4] 
  AddressLength.l 
  Address.b[#MAX_ADAPTER_ADDRESS_LENGTH] 
  Index.l 
  Type.l 
  DhcpEnabled.l 
  CurrentIpAddressPTR.l 
  IpAddressList.IP_ADDR_STRING 
  GatewayList.IP_ADDR_STRING 
  DhcpServer.IP_ADDR_STRING 
  HaveWins.l 
  PrimaryWinsServer.IP_ADDR_STRING 
  SecondaryWinsServer.IP_ADDR_STRING 
  LeaseObtained.l 
  LeaseExpires.l 
EndStructure 

Structure MyIP_ADAPTER_INFO
  AdapterName.s
  Description.s
  MACAddress.s
  IPAdress.s
EndStructure

length.l=0 
Result=GetAdaptersInfo_(0,@length) ; Get the length for Buffer 
If Result=#ERROR_BUFFER_OVERFLOW And length 
  *Buffer=AllocateMemory(length) 
  If *Buffer And GetAdaptersInfo_(*Buffer,@length)=#ERROR_SUCCESS 
    *ipinfo.IP_ADAPTER_INFO=*Buffer 
    
    Global NewList MyIPAdapterList.MyIP_ADAPTER_INFO() ; declare list here
    
    While *ipinfo 
      
      AddElement(MyIPAdapterList()) ; add one element
      
      Debug "Index : "+Str(*ipinfo\Index) 
      Select *ipinfo\Type 
        Case #MIB_IF_TYPE_OTHER 
          Debug "Type : #MIB_IF_TYPE_OTHER" 
        Case #MIB_IF_TYPE_ETHERNET 
          Debug "Type : #MIB_IF_TYPE_ETHERNET" 
        Case #MIB_IF_TYPE_TOKENRING 
          Debug "Type : #MIB_IF_TYPE_TOKENRING" 
        Case #MIB_IF_TYPE_FDDI 
          Debug "Type : #MIB_IF_TYPE_FDDI" 
        Case #MIB_IF_TYPE_PPP 
          Debug "Type : #MIB_IF_TYPE_PPP" 
        Case #MIB_IF_TYPE_LOOPBACK 
          Debug "Type : #MIB_IF_TYPE_LOOPBACK" 
        Case #MIB_IF_TYPE_SLIP 
          Debug "Type : #MIB_IF_TYPE_SLIP" 
        Default 
          Debug "Type : unknown" 
      EndSelect 
      Debug "Name : "+PeekS(@*ipinfo\AdapterName,-1,#PB_Ascii) 
      MyIPAdapterList()\AdapterName=PeekS(@*ipinfo\AdapterName,-1,#PB_Ascii)
      MyIPAdapterList()\Description=PeekS(@*ipinfo\Description,-1,#PB_Ascii)
      Debug "Desc : "+PeekS(@*ipinfo\Description,-1,#PB_Ascii) 
      ;IP-Adress 
      *iplist.IP_ADDR_STRING=*ipinfo\IpAddressList 
      While *iplist 
        Debug "IP-Adress : "+PeekS(@*iplist\IpAddress,-1,#PB_Ascii)
        MyIPAdapterList()\IPAdress+PeekS(@*iplist\IpAddress,-1,#PB_Ascii)+Chr(13)
        *iplist.IP_ADDR_STRING=*iplist\pNext 
      Wend 
      ;Gateway 
      *iplist.IP_ADDR_STRING=*ipinfo\GatewayList 
      While *iplist 
        Debug "Gateway : "+PeekS(@*iplist\IpAddress,-1,#PB_Ascii) 
        *iplist.IP_ADDR_STRING=*iplist\pNext 
      Wend 
      ;Wins 
      If *ipinfo\HaveWins 
        ;PrimaryWinsServer 
        *iplist.IP_ADDR_STRING=*ipinfo\PrimaryWinsServer 
        While *iplist 
          Debug "P-Wins : "+PeekS(@*iplist\IpAddress,-1,#PB_Ascii) 
          *iplist.IP_ADDR_STRING=*iplist\pNext 
        Wend 
        ;SecondaryWinsServer 
        *iplist.IP_ADDR_STRING=*ipinfo\SecondaryWinsServer 
        While *iplist 
          Debug "S-Wins : "+PeekS(@*iplist\IpAddress,-1,#PB_Ascii) 
          *iplist.IP_ADDR_STRING=*iplist\pNext 
        Wend 
      EndIf 
      ;DHCP 
      If *ipinfo\DhcpEnabled 
        ;DhcpServer 
        *iplist.IP_ADDR_STRING=*ipinfo\DhcpServer 
        While *iplist 
          Debug "DHCP Server Adress : " +PeekS(@*iplist\IpAddress,-1,#PB_Ascii) 
          *iplist.IP_ADDR_STRING=*iplist\pNext 
        Wend 
        ;LeaseObtained 
        *Buffer2=AllocateMemory(#MAXCHAR) 
        If *Buffer2 
          strftime(*Buffer2,#MAXCHAR,"%d.%m.%Y %H:%M:%S",localtime(@*ipinfo\LeaseObtained)) 
          Debug "Lease optained : "+PeekS(*Buffer2,-1,#PB_Ascii) 
          FreeMemory(*Buffer2) 
        EndIf 
        ;LeaseExpires 
        *Buffer2=AllocateMemory(#MAXCHAR) 
        If *Buffer2 
          strftime(*Buffer2,#MAXCHAR,"%d.%m.%Y %H:%M:%S",localtime(@*ipinfo\LeaseExpires)) 
          Debug "Lease expires : "+PeekS(*Buffer2,-1,#PB_Ascii) 
          FreeMemory(*Buffer2) 
        EndIf 
      Else 
        Debug "STATIC IP Configuration" 
      EndIf 
      ;MAC-Adress 
      If *ipinfo\AddressLength 
        mac$="" 
        For i=0 To *ipinfo\AddressLength-1
          If i 
            mac$+":" 
          EndIf 
          byte.b=PeekB(@*ipinfo\Address+i) 
          If byte>=0 
            mac$+RSet(Hex(byte),2,"0") 
          Else 
            mac$+RSet(Hex(byte+256),2,"0") 
          EndIf 
        Next 
        Debug "MAC-Address "+mac$
        MyIPAdapterList()\MACAddress=mac$
      EndIf 
      
      *ipinfo.IP_ADAPTER_INFO=*ipinfo\pNext 
    Wend
    
    ForEach MyIPAdapterList()
      Debug "-------------------------------------------"
      Debug ListIndex(MyIPAdapterList())
      Debug MyIPAdapterList()\AdapterName
      Debug MyIPAdapterList()\Description
      Debug MyIPAdapterList()\IPAdress
      Debug MyIPAdapterList()\MACAddress
    Next
    
  Else 
    Debug "GetLastError="+Str(GetLastError_()) 
  EndIf 
  
  If *Buffer 
    FreeMemory(*Buffer) 
  EndIf 
EndIf

Posted: Sun Dec 23, 2007 9:31 pm
by SFSxOI
ABBKlaus;

thanks for your reply. I am using part of your code in a project. I was looking for was also the GUID of the installed NIC cards associated with the MAC.

On WinXp SP 2 or Windows Vista systems If you open up a command promt and type 'getmac', your presented with something like this:

Code: Select all

Physical Address    Transport Name
=================== ==========================================================
00-1A-FC-DB-1B-19   \Device\Tcpip_{AD0EFA5A-16F0-4128-B844-0EDF78FD75C5}
The physical Address is the MAC and the 'AD0EFA5A-16F0-4128-B844-0EDF78FD75C5' is the GUID associated with that MAC, the GUID is what what I was trying to get for display in a GUI.

I was sure that I saw something that would help with retrieving the GUID's of NIC/MAC associations, your code fills the need perfectly. Thank You :)

Posted: Fri Dec 28, 2007 7:04 pm
by SFSxOI
ABBKlaus;

just wondering, since I'm not on a machine that has multiple network cards installed, will this code as it is in your post get the information of all adapters in a machine with multiple network cards? If so, are additional structures needed?

i was looking at the MSDN at the GetAdaptersInfo function and it says this:

Code: Select all

DWORD GetAdaptersInfo(
  __out    PIP_ADAPTER_INFO pAdapterInfo,
  __inout  PULONG pOutBufLen
);

Parameters:
pAdapterInfo 
A pointer to a buffer that receives a linked list of IP_ADAPTER_INFO structures.
Does this mean that one structure for each adapter is needed? If so then what would a pointer to a buffer that receives a linked list of IP_ADAPTER_INFO structures look like?

Of course, if this code already does this then these ae stupid questions.

Posted: Sat Dec 29, 2007 12:50 am
by ABBKlaus
just wondering, since I'm not on a machine that has multiple network cards installed, will this code as it is in your post get the information of all adapters in a machine with multiple network cards? If so, are additional structures needed?
Yes, i changed my code above to reflect this things better. Should be easy to copy things needed to a PB-Linked list.

Regards Klaus

Posted: Sat Dec 29, 2007 3:59 am
by SFSxOI
Thanks ABBKlaus,

A little something wrong with the MAC address part, add an extra ':00' to the end of the MAC, the original function works here tho:

Code: Select all

;MAC-Adress 
      If *ipinfo\AddressLength 
        mac$="" 
        ;For i=0 To *ipinfo\AddressLength ; <<<<old line
        For i=0 To 5 ;*ipinfo\AddressLength ; <<<<<changed here
          If i 
            mac$+":" 
          EndIf 
          byte.b=PeekB(@*ipinfo\Address+i) 
          If byte>=0 
            mac$+RSet(Hex(byte),2,"0") 
          Else 
            mac$+RSet(Hex(byte+256),2,"0") 
          EndIf 
        Next 
        Debug "MAC-Address "+mac$ 
      EndIf

but...this works also maybe:

If *ipinfo\AddressLength 
        mac$="" 
        For i=0 To *ipinfo\AddressLength -1 ; <<<< subtract 1?
          If i 
            mac$+":" 
          EndIf 
          byte.b=PeekB(@*ipinfo\Address+i) 
          If byte>=0 
            mac$+RSet(Hex(byte),2,"0") 
          Else 
            mac$+RSet(Hex(byte+256),2,"0") 
          EndIf 
        Next 
        Debug "MAC-Address "+mac$ 
      EndIf

 

*ipinfo.IP_ADAPTER_INFO=*Buffer
OK, got the pointer to the buffer thing here I guess, but I still don't get the linked list thing exactly...its something like (in the PB help file) this isn't it?

Code: Select all

NewList MyList.s()
  
  AddElement(MyList())
  MyList() = PeekS(@*ipinfo\AdapterName,-1,#PB_Ascii)
  
  AddElement(MyList())
  MyList() = PeekS(@*ipinfo\Description,-1,#PB_Ascii)
  
  AddElement(MyList())
  MyList() = PeekS(@*ipinfo\IpAddressList+4,-1,#PB_Ascii)
  
  ForEach MyList()
    Debug MyList()
  Next
Maybe i'm mis-understanding the msdn part a little where it says "A pointer to a buffer that receives a linked list of IP_ADAPTER_INFO structures." It sounds to me like its saying multiple-IP_ADAPTER_INFO structures that are in a linked list instead of individual items from a single structure put into a linked list. I'm probably mis-understanding.

Posted: Sat Dec 29, 2007 11:39 am
by Thalius

Maybe i'm mis-understanding the msdn part a little where it says "A pointer to a buffer that receives a linked list of IP_ADAPTER_INFO structures." It sounds to me like its saying multiple-IP_ADAPTER_INFO structures that are in a linked list instead of individual items from a single structure put into a linked list. I'm probably mis-understanding.
Sounds to me like a pointer TO a Structured-IP_ADAPTER_INFO - Linkedlist. :?
Then on the otehr hand i didnt have my coffee yet!

Thalius

Posted: Sat Dec 29, 2007 11:49 am
by ABBKlaus
you are right :)

Code: Select all

For i=0 To *ipinfo\AddressLength -1
It sounds to me like its saying multiple-IP_ADAPTER_INFO structures that are in a linked list instead of individual items from a single structure put into a linked list. I'm probably mis-understanding.
Its more complex as the MSDN says, you can´t compare that to a PB-Linked list :wink:
Its a big buffer that holds not only the structures of IP_ADAPTER_INFO, it holds multiple adresses to an apapter too. The list itselft is linked throught the pNext (its a pointer to the next element). As you can see in my example i am browsing through all elements until pNext is 0.
As i am doing it for the multiple IP-Adresses too :wink:

PS : added a self made PB-Linked list that reflects your needs better in my example above
Regards Klaus

Posted: Sun Nov 23, 2008 12:30 pm
by Michael Vogel
Questions and Answers...

Some constants in ABBs code did not match with my results (Win XP), so I searched around and found...

Code: Select all

#MIB_IF_TYPE_OTHER     = 0
#MIB_IF_TYPE_ETHERNET  = 6
#MIB_IF_TYPE_TOKENRING = 9
#MIB_IF_TYPE_FDDI      = 15
#MIB_IF_TYPE_PPP       = 23
#MIB_IF_TYPE_LOOPBACK  = 24
#MIB_IF_TYPE_SLIP      = 28

Now, I'm trying to start the property window for the first ethernet card in the PC where the program will be used:

Code: Select all

					Structure IP_ADDR_STRING
						pNext.l
						IpAddress.b[16]
						IpMask.b[16]
						Context.l
					EndStructure

					#MAX_ADAPTER_NAME_LENGTH=256
					#MAX_ADAPTER_DESCRIPTION_LENGTH=128
					#MAX_ADAPTER_ADDRESS_LENGTH=8

					#MIB_IF_TYPE_ETHERNET  = 6

					Structure IP_ADAPTER_INFO
						pNext.l
						ComboIndex.l
						AdapterName.b[#MAX_ADAPTER_NAME_LENGTH+4]
						Description.b[#MAX_ADAPTER_DESCRIPTION_LENGTH+4]
						AddressLength.l
						Address.b[#MAX_ADAPTER_ADDRESS_LENGTH]
						Index.l
						Type.l
						DhcpEnabled.l
						CurrentIpAddressPTR.l
						IpAddressList.IP_ADDR_STRING
						GatewayList.IP_ADDR_STRING
						DhcpServer.IP_ADDR_STRING
						HaveWins.l
						PrimaryWinsServer.IP_ADDR_STRING
						SecondaryWinsServer.IP_ADDR_STRING
						LeaseObtained.l
						LeaseExpires.l
					EndStructure

					i=0
					If (GetAdaptersInfo_(0,@i)=#ERROR_BUFFER_OVERFLOW) And i
						j=AllocateMemory(i)

						If j And GetAdaptersInfo_(j,@i)=#ERROR_SUCCESS
							Protected *ipinfo.IP_ADAPTER_INFO=j

							While *ipinfo
								If (*ipinfo\Type=#MIB_IF_TYPE_ETHERNET) And (FindString(LCase(PeekS(@*ipinfo\Description,-1,#PB_Ascii)),"ethernet",1))
									WinExec_("cmd.exe /D /C start ::{208D2C60-3AEA-1069-A2D7-08002B30309D}\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\::"+PeekS(@*ipinfo\AdapterName,-1,#PB_Ascii),#SW_HIDE)
									*ipinfo=0
								Else
									*ipinfo.IP_ADAPTER_INFO=*ipinfo\pNext
								EndIf
							Wend
						EndIf

						If j : FreeMemory(j) : EndIf
					EndIf
But the program does not work :cry:

I tried to start the page with RunProgram() and WinExec_() used "explorer.exe" and "cmd.exe" and there is only one way (I found) to get the property window onto the screen:

Code: Select all

WinExec_("cmd.exe /D /K start ::{208D2C60-3AEA-1069-A2D7-08002B30309D}\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\::{YOUR NETWORK CARD ID}",#SW_SHOW)
But the "/K" keeps the cmd.exe in memory :evil: and "/C" does not work :shock:

Any ideas?

SMALL UPDATE - since I've rebooted my PC the "cmd /k ..." command does not work either :?