MAC Address with multiple Ethernet-cards (solved) lazarus / 34-Windows ---------------------------------------------------------------------- Marcelo Santos · 2015-10-21 19:32 Hello everybody! Here we have a solution of how to get the Mac Address: http://forum.lazarus.freepascal.org/index.php/topic,10465.msg160793.ht ml#msg160793 It works on Windows XP and Windows 7, but now is not working in Windows 10. Any ideas? Thanks! ---------------------------------------------------------------------- rvk · 2015-10-21 20:33 I just tried the example.zip from that topic and here, on Windows 10 with Laz1.4.2, it works perfectly. So it's not Windows 10 that's at fault. (What exactly isn't working? What do you get as a result?) ---------------------------------------------------------------------- Marcelo Santos · 2015-10-21 21:00 Quote from: rvk on October 21, 2015, 10:33:12 pm(What exactly isn't working? What do you get as a result?) Thank you  by the test, rvk We perform exempla.zip program in Windows 10 the message is blank, only in the windows 10, but on 7 and XP works perfectly. ---------------------------------------------------------------------- Jurassic Pork · 2015-10-21 21:09 hello, under windows , to get all the MAC addresses of your computer , you can try the command getmac /v and to have the result in your lazarus program, a code like that : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testMacAddress;uses  Process; var reponse : string; beginRunCommand('getmac',['/v'],reponse);writeln(reponse);end.     Friendly, J.P ---------------------------------------------------------------------- rvk · 2015-10-21 21:11 In that case you might need to debug the procedure and see where it goes wrong. Set a breakpoint on the line 201 Result := ''; in the GetWinMacAddress procedure in utils.pas and let it run to that. Next step through the code with F8 and see if the GetIfTable-function gives correct results. Does it error out on line 212 or 222? If it runs to 222, what is the value of ErrCode in that moment? ---------------------------------------------------------------------- Marcelo Santos · 2015-10-21 21:18 Quote from: Jurassic Pork on October 21, 2015, 11:09:22 pmhello, under windows , to get all the MAC addresses of your computer Friendly, J.P Thanks, J.P, I will try it! Quote from: rvk on October 21, 2015, 11:11:28 pmDoes it error out on line 212 or 222? If it runs to 222, what is the value of ErrCode in that moment? rvk, Lazarus is not installed on the machine with Windows 10. I'll install it and find out what's going on. ---------------------------------------------------------------------- Marcelo Santos · 2015-10-21 22:13 Quote from: rvk on October 21, 2015, 11:11:28 pmIn that case you might need to debug the procedure and see where it goes wrong. It is not presenting error. I added breakpoints around code and everything worked normally except enter the IF : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i          if (pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET) and             (pIfTable^.ifRow[i].dwOutOctets <> 0) then         begin            tmp := '';            for j:=0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do            begin               tmp := tmp + format('%.2x:',                    [ pIfTable^.ifRow[i].bPhysAddr[j] ] );            end; // for-end.            //-------------------------------------          if Length(tmp)>0 then            begin              Result := Copy(tmp, 1, Length(tmp) - 1);              Exit;            end;       end        else           MessageDlg('Error', mtinformation, [mbok], 0); He showed MessageDlgs 22 times. And continues to present MAC Address blank ---------------------------------------------------------------------- rvk · 2015-10-22 08:09 Quote from: Marcelo Santos on October 22, 2015, 12:13:21 amHe showed MessageDlgs 22 times. And continues to present MAC Address blank Uuuh... you got 22 messages. That's quite a lot of network-interfaces. First of all... in your util.pas you have a limit of 20 in _MAX_ROWS_. If your number of interfaces are more than 20 it could be that the correct one is above this number. So you need to increase the _MAX_ROWS_. Otherwise you access something out of range for that 20. It doesn't throw an error because your range-checking is off. And because pIfTable is automatically created from the size of what GetIfTable gives back, it doesn't really matter if you make _MAX_ROWS_ a really high number because it will only really reserve the memory it gets from GetIfTable (TableSize). So: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   _MAX_ROWS_ = 999; Next you could check what's really in the ifRows. You could do this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       // Read the ETHERNET addresses.      for i := 1 to pIfTable^.nRows do    try         //if (pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET) and         //    (pIfTable^.ifRow[i].dwOutOctets <> 0) then         begin            tmp := '';            for j:=0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do            begin               tmp := tmp + format('%.2x:',                      [ pIfTable^.ifRow[i].bPhysAddr[j] ] );            end; // for-end.          //-------------------------------------            if Length(tmp)>0 then            begin              MessageDlg(tmp + ' ' + inttostr(pIfTable^.ifRow[i].dwType), mtinformation, [mbok], 0);            Result := Copy(tmp, 1, Length(tmp) - 1);              //Exit;            end;         end; // if-end.      except         Exit;      end; // if-try-except-end. Have none of the interfaces a dwType of MIB_IF_TYPE_ETHERNET (6)? What number do they have (after the mac address)? Another thought... I take it this is a computer with a Ethernet-cards and not one with only a wireless-card ? Otherwise you also need to check for IF_TYPE_IEEE80211 (71). See: https://msdn.microsoft.com/en- us/library/windows/desktop/aa366062(v=vs.85).aspx Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  MIB_IF_TYPE_OTHER          =  1; // Some other type of network interface.  MIB_IF_TYPE_ETHERNET       =  6; // An Ethernet network interface.  IF_TYPE_ISO88025_TOKENRING =  9; // MIB_IF_TYPE_TOKENRING  MIB_IF_TYPE_PPP            = 23; // A PPP network interface.  MIB_IF_TYPE_LOOPBACK       = 24; // A software loopback network interface.  MIB_IF_TYPE_SLIP           = 28; // An ATM network interface.  IF_TYPE_IEEE80211          = 71; // An IEEE 802.11 wireless network interface.     // Note  This adapter type is returned on Windows Vista and later.     // On Windows Server 2003 and Windows XP , an IEEE 802.11 wireless network interface     // returns an adapter type of MIB_IF_TYPE_ETHERNET.You see that on Windows Vista and later, IF_TYPE_IEEE80211 is returned for a wireless card instead of MIB_IF_TYPE_ETHERNET. So you would need: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i          if (pIfTable^.ifRow[i].dwType in [MIB_IF_TYPE_ETHERNET, IF_TYPE_IEEE80211]) and             (pIfTable^.ifRow[i].dwOutOctets <> 0) then If a computer has both a Ethernet-card and wireless, I'm not sure how to determine which one is actually connected to the internet. I'm also not sure it's necessary for you to make that distinction. (For me it seems to take the correct one when having the Ethernet with cable unplugged and a working wireless connection). Edit (correction): Now it keeps giving me my Wireless Mac while I'm connected via wire. So it doesn't give you the Mac from the internet- connected device, necessarily. It you need that, you need to check if the device is really connected. For that you could check the pIfTable^.ifRow[ i ].dwOperStatus (for instance). So, this works for me (it filters out disabled and unplugged interfaces): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  IF_OPER_STATUS_NON_OPERATIONAL = 0; // LAN adapter has been disabled, for example because of an address conflict.  IF_OPER_STATUS_UNREACHABLE     = 1; // WAN adapter that is not connected.  IF_OPER_STATUS_DISCONNECTED    = 2; // For LAN adapters: network cable disconnected. For WAN adapters: no carrier.  IF_OPER_STATUS_CONNECTING      = 3; // WAN adapter that is in the process of connecting.  IF_OPER_STATUS_CONNECTED       = 4; // WAN adapter that is connected to a remote peer.  IF_OPER_STATUS_OPERATIONAL     = 5; // Default status for LAN adapters...         if (pIfTable^.ifRow[i].dwType in [MIB_IF_TYPE_ETHERNET, IF_TYPE_IEEE80211]) and            (pIfTable^.ifRow[i].dwOutOctets <> 0) and            (pIfTable^.ifRow[i].dwOperStatus = IF_OPER_STATUS_OPERATIONAL) then ---------------------------------------------------------------------- Marcelo Santos · 2015-10-22 14:21 Many thanks for the reply. First, did a test about it: Quote from: rvk on October 22, 2015, 10:09:39 am I take it this is a computer with a Ethernet-cards and not one with only a wireless-card ? PC with 7 Cable =  ok OFF = ok Notebook with XP WIFI = Ok Cable = Ok Off = Ok (always the same MAC) Notebook with Windows 10 (The same) WiFi on = blank After WiFi off = blank Cable = ok After Cable off = ok Other Notebook with 7 7 with WiFI  = Blank 7 after WiFi off = Blank 7 with cable = ok 7 after cable off = ok By the test made me try this: Quote from: rvk on October 22, 2015, 10:09:39 amCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i          if (pIfTable^.ifRow[i].dwType in [MIB_IF_TYPE_ETHERNET, IF_TYPE_IEEE80211]) and             (pIfTable^.ifRow[i].dwOutOctets <> 0) then With this change the MAC Address was caught in all circumstances! Thanks! And no matter what connection it always returns the same MAC Address. The results of other suggestions: About changing the MAX_ROWS to 99 the result remained the same. Quote from: rvk on October 22, 2015, 10:09:39 amWhat number do they have (after the mac address)? None, so I tried it: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if (pIfTable^.ifRow[i].dwType in [MIB_IF_TYPE_ETHERNET]) and             (pIfTable^.ifRow[i].dwOutOctets <> 0) then         begin            tmp := '';            for j:=0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do            begin               tmp := tmp + format('%.2x:',                    [ pIfTable^.ifRow[i].bPhysAddr[j] ] );            end; // for-end.            //-------------------------------------          if Length(tmp)>0 then            begin              MessageDlg(inttostr(pIfTable^.ifRow[i].dwType), mtinformation, [mbok], 0);              Result := Copy(tmp, 1, Length(tmp) - 1);            Exit;            end;         end         else         MessageDlg(inttostr(pIfTable^.ifRow[i].dwType), mtinformation, [mbok], 0);    // if-end.   In each appears different numbers ... 1, 71, 131 and many are repeated ... It seems to me that the problem was not with Windows 10, but computer with more than one Ethernet-card. That's it? Do you think it would be better to change the topic name to be more correct? Very much thanks for the help! ---------------------------------------------------------------------- rvk · 2015-10-22 14:36 Quote from: Marcelo Santos on October 22, 2015, 04:21:50 pmWith this change the MAC Address was caught in all circumstances! Thanks! ... And no matter what connection it always returns the same MAC Address. ... In each appears different numbers ... 1, 71, 131 and many are repeated ... Yes, with multiple Ethernet-cards you get multiple 6 numbers. 71 is for Wireless-cards. 131 is probably a IPv6 tunnel interface (IF_TYPE_TUNNEL). All the numbers are on this page (for MIB_IFROW): https://msdn.microsoft.com/en- us/library/windows/desktop/aa366836(v=vs.85).aspx Also... all interfaces are probably in RANDOM order. So the fact that, for you, now the MAC is always caught, is good, but it might still return the wrong one on other systems. With the line you quoted it loops ALL the MAC of Ethernet-cards and ALL Wireless-adapters. But because the function returns always the first it encounters you can never be sure if that's the one you want. If you add the check on dwOperStatus = IF_OPER_STATUS_OPERATIONAL then at least you know you have a network-card that's in operation. (Unless it's not necessary for you to know which adapter is really connected) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  IF_OPER_STATUS_OPERATIONAL     = 5; // Default status for LAN adapters...         if (pIfTable^.ifRow[i].dwType in [MIB_IF_TYPE_ETHERNET, IF_TYPE_IEEE80211]) and            (pIfTable^.ifRow[i].dwOutOctets <> 0) and            (pIfTable^.ifRow[i].dwOperStatus = IF_OPER_STATUS_OPERATIONAL) then B.T.W. Setting MAX_ROWS to 999 is just for neatness. If you ever decide to switch range-checking on it will not give an error. Otherwise it will. (But you will probably never enable range-check for this unit) ---------------------------------------------------------------------- Marcelo Santos · 2015-10-22 14:45 Okay, now I understand more clearly how it works. I'll check on my application which is exactly appropriate. Thank you for most of these details.