How to Programatically Get MAC Address of Physical Network Card?

This post is a bit off topic, in the sense that it is related to a problem that I am facing in programming.

A little background. When I started SYCODE, our software licensing mechanism used the hard disk serial number as a unique identifier of a computer and tied the product license to it. That became a problem because the serial number is really not a fixed thing. It changes every time you format a hard disk. And every time a customer formatted or changed his hard disk the serial number changed and our product stopped working. So we changed our licensing mechanism to use the MAC (Media Access Control) address of the network card on the computer as a unique identifier. A MAC address is a much better option because it cannot be changed and people don’t change network cards as often as they change or format hard disks.

However, off late, we have been facing issues with the MAC address as well. Here is the thing. We are using the GetAdaptersInfo function to get the MAC addresses of the network cards on the computer. The problem is that the IP_ADAPTER_INFO structure used by this function does not tell the programmer whether the MAC address belongs to an actual physical network card (something which you plug your network cable into) or a virtual network interface created by things like a VPN or WiFi connection. The problem with the MAC addresses of these virtual devices is that they are anything but constant. You get a new one every time you log on. So now we have customers coming to us asking for keys for new MAC addresses every time they restart their computer or network connection.

I have searched the internet far and wide to find a solution to this problem and have come up with nothing. Basically I am looking for C/C++ code (not .NET) to get the MAC address of the primary physical network card on a computer. Someone suggested to pick the MAC address with the fastest speed. I don’t think that is a wise idea.

I am not sure how many programmers read this blog. If any of you have any idea or could point me to some place where I might find a solution, I would greatly appreciate it.

Update

I just found out that Windows stores the description of the physical network cards in the registry at HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionNetworkCards. The same description is also listed in the “Description” member of the IP_ADAPTER_INFO structure. So I guess I can check whether this value figures in the registry to determine whether the MAC address belongs to a physical network card or not. What do you think?

  • Kevin Quigley

    I'm not a programmer Deelip but seeing as how your products are intended to work with a host applocation can you not piggy back on the license of the host app. For example for SolidWorks plug ins tie the plug in to the SolidWorks serial number?

    From a user's perspective I personally find the licensing options from smaller specialist companies very restrictive as more often than not they are tied to a single machine. These days many users are mobile and use a desktop and a laptop so internet based activation is a better solution as licenses can be checked in and out automatically.

    Over at the Bunkspeed forum this issue has cropped up time and time again to the extent that I ended up posting some links to seemingly off the shelf solutions! I have no idea if they are any good or what is involved but maybe you can mimic them!

    http://www.reprisesoftware.com/index.htm

    http://www.aladdin.com/HASP/solutions/software-

    http://www.logicprotect.com/index.asp

  • Kevin,

    Piggy-backing on the host application will need us to develop and maintain several licensing mechanisms. Moreover, not all host applications give developers access to their licensing information.

    We offer a free key for a portable computer for every purchase of a license for a desktop computer.

    Internet activation needs something fixed on the computer as well. The host server needs to keep track of the hardware where the software is being used. Otherwise the user will need to activate every time he uses the software.

    Shall take a look at your links. Thanks.

  • You could always go the way that Valve's digital content delivery system Steam works.
    http://store.steampowered.com/about/
    It has the advantage of working on only one machine at any given time.

    I'm not 100% sure but I believe the process would go something like this:
    User logs on program at startup with username and password (this is stored for future use but easily cleared out by the user).
    Program sends the username and password along with the MAC address, IP, and or other system specific info to the server and asks for OK (session ID) to run.
    Program gets OK to run if username and password are correct and the server closes out any previously open sessions.
    Program regularly checks if MAC/IP address and session ID pair are valid.
    If not it alerts the user, stops working, and logs out; therefor the program can only can work on on at a time. I would also keep a log of how many times it happens. More than a few over a period of time probably means the username and password are public and should be disabled.

    FYI; some hack may exist that circumvents this but none that I know of.

    Steam does have an offline mode but I'm unsure how that works at this time.

    Your users will thank you for the freedom this gives them and most will keep their info secret for fear of loosing access to it.

  • Interesting.

    However, quite a few of our customers have computers that are completely offline, mostly in large companies.

  • Yes the offline area is where I run into problems too. Users want to be able to switch it to other computers or even just upgrade them. Many say to use hardware dongles for this but a quick search shows cheap hardware emulated dongles available.

  • Hardware dongles are not an option for me. All my software is available as download only. I have never shipped anything to my customers and I do not intend to start anytime soon.

  • torsten_moses

    Dear Deelip,
    that code to retrieve the hard disk serial number as you wrote about seems to return the *PARTITION* serial number only 🙂

    That's why it can change or can even be cloned …

    But in fact there is also code to retrieve the *real* hardware serial number … I used (and still use) this for my software;
    so if you are interested, I can send you the code – a small C/C++ piece of code.

  • I would greatly appreciate that. Please send the code to deelip (at) sycode (dot) com.

  • eprincipe01

    Torsten,
    Could I also get a copy of that piece of code?? I am facing a similar challenge. eprincipe01 (at) hotmail (dot) com. I have my own software that I am distributing to users for data reduction after they use the hardware located at a synchrotron. I am searching for the same solution. Thanks!!

  • roelv

    I would really like to have that code also.

    Please send to roel (at) vlemmings (dot) info.

    Roel

  • We at Agilis supply licensing solutions, and have dealt with all the issues you mentioned: activating on disconnected systems, locking on systems where system parameters can legitimately change over time, and more. Details are at: http://agilis-sw.com/. If we can be of any help do get in touch.

    Dominic Haigh
    Agilis Software
    http://www.agilis-sw.com

  • Pavan T

    Hi Torsten..
    We are also facing similar problem for one of our products.
    Would greatly appreciate if you can send details on how to retrieve the real hardware serial number to me – pavankumar.thatha (at) gmail (dot) com

  • I think this post will be useful for many people. Thanks

  • Srikanth2908

    Hi, Could you please mail  the code to srikanth2908 (at) gmail (dot) com . That would be really grateful.