Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Getting the Network Adaptor MAC Address with WMI

3.60/5 (5 votes)
25 Mar 2007CPOL 1   1.4K  
Getting the network adaptor MAC address with WMI

Introduction

This sample piece of code has two purposes:

  1. It will give you a general background on why to use all this rich set of WMI classes in C++.
  2. It will demonstrate an alternative method for obtaining a MAC address of the network card of the computer.

Background

I stumbled upon this problem while I was using the RPC function UuidCreateSequential from Platform SDK when suddenly on several computers it began to give different MACs every time. Then I found this statement on MSDN:

"For security reasons, UuidCreate was modified so that it no longer uses a machine's MAC address to generate UUIDs."

So I had to find an alternative method. One was to use the NetBIOS function, but firstly, it's quite complicated and secondly, not every machine has NetBIOS installed. So I turned to the WMI alternative which turned to be quite simple.

Using the Code

In the attached ZIP file, you will find a console application that just prints out all the network cards MACs. All the code is in the main function, so here it is with some explanations:

C++
int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);    // Initialize COM 
    try   
    { 
        //Create the locator object through which we will 
        //access all the other WMI functions
        WbemScripting::ISWbemLocatorPtr locator;
        
        locator.CreateInstance(WbemScripting::CLSID_SWbemLocator);
        
        if (locator != NULL)
        {
            // Get the pointer to the WMI service on the active computer 
	   // (the local machine)
            WbemScripting::ISWbemServicesPtr services = 
		locator->ConnectServer(".","root\\cimv2","","","","",0,NULL);
            // Get the list of objects of interest, in our case the network adaptors
            WbemScripting::ISWbemObjectSetPtr objects = 
		services->ExecQuery("Select * from Win32_NetworkAdapter",
		"WQL",0x10,NULL);
            // Create the enumerator for the collection 
            IEnumVARIANTPtr obj_enum = objects->Get_NewEnum();             
            ULONG fetched;            
            VARIANT var;
            // Iterate through the collection
            while (obj_enum->Next(1,&var,&fetched) == S_OK)
            {
                // Get an object (an instance of Network adaptor WMI class)
                WbemScripting::ISWbemObjectPtr object = var;
                // Retrieve the properties
                WbemScripting::ISWbemPropertySetPtr properties = object->Properties_;
                // Check the adaptor's type by retrieving the "AdapterTypeID" property
                WbemScripting::ISWbemPropertyPtr prop = 
				properties->Item("AdapterTypeID",0);
                _variant_t value = prop->GetValue();
                if (value.vt == VT_I4 && (int)value == 0) // If LAN adaptor
                {
                    //Retrieve the "MACAddress" property
                    prop = properties->Item("MACAddress",0);
                    // And print it out
                    printf("MAC address found: %s\n",
			(const char*)_bstr_t(prop->GetValue()));                
                }
            }
        }
    }
    // In case there was an error, print it out...
    catch (_com_error err)
    {
        printf("Error occurred: %S",err.ErrorMessage());
    }
    CoUninitialize();
    return 0;
}

History

  • 25th March, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)