?
Solved

Differentiating dummy adaptor from actual NIC

Posted on 2005-03-01
7
Medium Priority
?
694 Views
Last Modified: 2013-12-03
Is it possible to identify from MAC address whether it is address of physical NIC on machine or address of a dummy adaptor installed by modem installation/RAS adaptor on NT or something like that. I've noticed that the RAS adaptor always has xx-xx-xx-00-00-00 address where x is different on every reboot.
If not possible from MAC address, how can we identify this programatically?
0
Comment
Question by:bansaldeep
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
7 Comments
 
LVL 11

Expert Comment

by:KurtVon
ID: 13440240
You could try a call to SetupDiGetDriverInfoDetail, if there is no HardwareID: http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q259695 (you will have to change the inner call).

If that fails (a false HardwareID) then see if the PCI bus location exists using SetupDiGetDeviceRegistryProperty and SPDRP_BUSNUMBER.

Hope this helps.

0
 

Author Comment

by:bansaldeep
ID: 13447803
Couldn't get SetupDiGetDriverInfoDetail to work. It requires DeviceInfoData and DriverInfoData.
DeviceInfoData is retrieved from SetupDiEnumDeviceInfo().
Trying to get DriverInfoData from SetupDiEnumDriverInfo() which always returns error 257 (i.e. no more items) even with index 0.

Code snippet:
================================
for(i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
      &DeviceInfoData);i++)
{
SetupDiEnumDriverInfo(hDevInfo,&DeviceInfoData,
      SPDIT_COMPATDRIVER ,i,
      &DriverInfoData);
SetupDiGetDriverInfoDetail(
      hDevInfo,
      &DeviceInfoData,
      &DriverInfoData,
      DriverInfoDetailData,
      buffersize,
      &buffersize);
=================================
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 13449580
Hmm, odd.  Did you try the SetupDiGetDeviceRegistryProperty?  That matches the code in the MS link exactly.  You just need to change the SPDRP_DEVICEDESC to SPDRP_BUSNUMBER.  You can also get the driver name to identify the driver, a physical device object name (which may be valid even if the device is virtual) and a bunch of other data on the device.  Here's Microsoft's list of properties: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/install/hh/install/di-rtns_a60fa017-1c15-45bf-a178-37516bc0aea1.xml.asp

Also, you could try using SetupDiGetSelectedDriver to get the DriverInfoData.  That should return the driver actually used for the device, rather than a list of compatible drivers.  Unfortunately this is a rather touchy area of the windows API, and much of what Microsoft says needs to be taken with a big grain of salt.  Short of experimentation, there's no way to be sure what is going to be returned.
0
 

Author Comment

by:bansaldeep
ID: 13457861
It doesn't work. After changing SPDRP_DEVICEDESC to SPDRP_BUSNUMBER it doesn't put anything in buffer, just null.

1st 3 bytes of NIC MAC address are vendor code. Is there any standard using which vendors assign last 3 bytes? e.g. could they start with 00-00-00 and 00-00-01 and so on?
Could we just safely test last 3 byte values with some minimum value to verify whether it is actual NIC or wage?
0
 
LVL 11

Accepted Solution

by:
KurtVon earned 1000 total points
ID: 13459500
The vendor is allowed to choose any last three bytes they want, and I doubt there is any universal way of deciding.  Also, the owner of the card can change the MAC address whenever they want.  I do it because my ISP filters on MAC address, and I need to  keep the same address when I change computers (unless I want to call them every time).  In general, relying on a pattern in the MAC address is dangerous.

My test program worked, by the way.  The get property for the BUS returns false with GetLastError() of 13 when the device is not a BUS device, but when it is a bus device, it works fine.  I did note that you have to pass in a DWORD to the property function, not a string.  Here's the code I wrote:

void CMainFrame::OnEditCopy()
{
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i;

    // Create a HDEVINFO with all present devices.
    hDevInfo = SetupDiGetClassDevs(NULL,
       0, // Enumerator
       0,
       DIGCF_PRESENT | DIGCF_ALLCLASSES );

    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
       // Insert error handling here.
    }

    // Enumerate through all devices in Set.

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
       &DeviceInfoData);i++)
    {
        DWORD DataT;
        LPTSTR buffer = NULL;
        DWORD buffersize = 0;

        //
        // Call function with null to begin with,
        // then use the returned buffer size
        // to Alloc the buffer. Keep calling until
        // success or an unknown failure.
        //
        while (!SetupDiGetDeviceRegistryProperty(
           hDevInfo,
           &DeviceInfoData,
           SPDRP_DEVICEDESC,
           &DataT,
           (PBYTE)buffer,
           buffersize,
           &buffersize))
        {
           if (GetLastError() ==
               ERROR_INSUFFICIENT_BUFFER)
           {
               // Change the buffer size.
               if (buffer) LocalFree(buffer);
               buffer = (char*)LocalAlloc(LPTR,buffersize);
           }
           else
           {
               // Insert error handling here.
               break;
           }
        }

        CString strMessage;

        DWORD dwBus, dwSize;
        dwSize = sizeof(DWORD);
        if (!SetupDiGetDeviceRegistryProperty(
           hDevInfo,
           &DeviceInfoData,
           SPDRP_BUSNUMBER,
           &DataT,
           (PBYTE)&dwBus,
           dwSize,
           &dwSize))
        {
            // Not a bus device?
            strMessage.Format("Result:[%s] error %d\n",buffer, GetLastError());
        }
        else
            strMessage.Format("Result:[%s] bus %d\n",buffer, dwBus);

        if (buffer)
           LocalFree(buffer);

        MessageBox(strMessage, "Results", MB_OK);
    }


    if ( GetLastError()!=NO_ERROR &&
        GetLastError()!=ERROR_NO_MORE_ITEMS )
    {
       // Insert error handling here.
    }

    //  Cleanup
    SetupDiDestroyDeviceInfoList(hDevInfo);
}
0

Featured Post

 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question