Solved

get mac address from C++ builder

Posted on 2008-10-12
8
3,649 Views
1 Endorsement
Last Modified: 2013-11-17
Please a code sample to get the PC mac address from C++ builder.
1
Comment
Question by:robballi
  • 6
  • 2
8 Comments
 
LVL 12

Expert Comment

by:jazzIIIlove
ID: 22698650
One way:
void GetMacAddress()
{
	// Ensure buffer size is big enough to hold the address
	TCHAR szBuffer[18];
	DWORD dwSize = 18;
 
	NCB ncb;
	LANA_ENUM lenum;
	UCHAR uMACAddress[6];
	int i;
	int iLEnumCnt = 1;
	UCHAR uRASAdapterAddress[6] = { 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 };  // DEST
 
	::ZeroMemory(&ncb, sizeof(NCB));
	::ZeroMemory(&lenum, sizeof(lenum));
 
        // Helper function using GetVersionEx()
	if(IsOSPlatformNT())
	{
		// NT or better supports adapter enumeration
		ncb.ncb_command = NCBENUM;
		ncb.ncb_buffer = (UCHAR *)&lenum;
		ncb.ncb_length = sizeof(lenum);
 
		UCHAR uRet = Netbios(&ncb);
 
		if(uRet == NRC_GOODRET) 
		{
			iLEnumCnt = (int)lenum.length;
		}
	}
	else
	{
		// Can't do enumeration, so we'll pretend and query the first adapter only
		lenum.length = (UCHAR)iLEnumCnt;
 
		for(i=0; i<iLEnumCnt; ++i)
			lenum.lana[i] = (UCHAR)i;
	}
 
	for(i = 0; i < iLEnumCnt; ++i) 
	{
		if(ResetAdapter(lenum.lana[i]))
		{
			if (GetAdapterStatus(lenum.lana[i], uMACAddress))
			{
				// ignore RAS adapter address, we want MAC
				if (memcmp(uMACAddress, uRASAdapterAddress, 6) != 0)
				{
					wsprintf(szBuffer, "%02X:%02X:%02X:%02X:%02X:%02X", (int)uMACAddress[0], (int)uMACAddress[1], (int)uMACAddress[2], (int)uMACAddress[3], (int)uMACAddress[4], (int)uMACAddress[5]);
 
				}
			}
		}
	}
}
 
#include <Nb30.h>
const long lNAME_SIZE = 1024;
 
BOOL ResetAdapter(UCHAR lana)
{
	NCB ncb;
 
	::ZeroMemory(&ncb, sizeof(NCB));
 
	ncb.ncb_command = NCBRESET;
	ncb.ncb_lsn = 0x00;
	ncb.ncb_callname[0] = 20;
	ncb.ncb_callname[2] = 100;
	ncb.ncb_lana_num = lana;
 
	UCHAR uRet = Netbios(&ncb);
	if(uRet == NRC_GOODRET)
		return TRUE;
 
	::SetLastError(uRet);
	return FALSE;
}
 
 
BOOL GetAdapterStatus(UCHAR lana, UCHAR uMACAddress[])
{
	NCB ncb;
	BYTE buffer[lNAME_SIZE+2];
	ADAPTER_STATUS *pAS;
 
	::ZeroMemory(&ncb, sizeof(NCB));
	::ZeroMemory(buffer, lNAME_SIZE+2);
 
	ncb.ncb_command = NCBASTAT;
	ncb.ncb_buffer = buffer;
	ncb.ncb_length = lNAME_SIZE;
	ncb.ncb_callname[0] = '*';
	ncb.ncb_lana_num = lana;
 
	UCHAR uRet = Netbios(&ncb);
	if(uRet == NRC_GOODRET)
	{
		pAS = (ADAPTER_STATUS *)buffer;
		memcpy(uMACAddress, &(pAS->adapter_address), 6);
		return TRUE;
	}
	
	::SetLastError(uRet);
	return FALSE;
}

Open in new window

0
 
LVL 12

Accepted Solution

by:
jazzIIIlove earned 500 total points
ID: 22698652
High Way:
#include <windows.h>
   #include <wincon.h>
   #include <stdlib.h>
   #include <stdio.h>
   #include <time.h>
 
   typedef struct _ASTAT_
   {
 
      ADAPTER_STATUS adapt;
      NAME_BUFFER    NameBuff [30];
 
   }ASTAT, * PASTAT;
 
   ASTAT Adapter;
 
   void main (void)
   {
      NCB Ncb;
      UCHAR uRetCode;
      char NetName[50];
      LANA_ENUM   lenum;
      int      i;
 
      memset( &Ncb, 0, sizeof(Ncb) );
      Ncb.ncb_command = NCBENUM;
      Ncb.ncb_buffer = (UCHAR *)&lenum;
      Ncb.ncb_length = sizeof(lenum);
      uRetCode = Netbios( &Ncb );
      printf( "The NCBENUM return code is: 0x%x \n", uRetCode );
 
      for(i=0; i < lenum.length ;i++)
      {
          memset( &Ncb, 0, sizeof(Ncb) );
          Ncb.ncb_command = NCBRESET;
          Ncb.ncb_lana_num = lenum.lana[i];
 
          uRetCode = Netbios( &Ncb );
          printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
                  lenum.lana[i], uRetCode );
 
          memset( &Ncb, 0, sizeof (Ncb) );
          Ncb.ncb_command = NCBASTAT;
          Ncb.ncb_lana_num = lenum.lana[i];
 
          strcpy( Ncb.ncb_callname,  "*               " );
          Ncb.ncb_buffer = (char *) &Adapter;
          Ncb.ncb_length = sizeof(Adapter);
 
          uRetCode = Netbios( &Ncb );
          printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
                  lenum.lana[i], uRetCode );
          if ( uRetCode == 0 )
          {
             printf( "The Ethernet Number on LANA %d is:
                     %02x%02x%02x%02x%02x%02x\n",
            lenum.lana[i],
                  Adapter.adapt.adapter_address[0],
                  Adapter.adapt.adapter_address[1],
                  Adapter.adapt.adapter_address[2],
                  Adapter.adapt.adapter_address[3],
                  Adapter.adapt.adapter_address[4],
                  Adapter.adapt.adapter_address[5] );
          }
       }
 
   }

Open in new window

0
 
LVL 12

Expert Comment

by:jazzIIIlove
ID: 22698654
best regards...
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Expert Comment

by:jazzIIIlove
ID: 22698708
My Way:

//kidding...Khalid Shaikh Way:

I executed under V.S. 2008 and OK!

// GetMACUuid.cpp : Defines the entry point for the console application.
//
// Author:	Khalid Shaikh [Shake@ShakeNet.com]
// Date:	April 5th, 2002
//
// This program fetches the MAC address of the localhost by creating a UUID
// and obtaining the IP address through that
//
// Prewindows 2000 one should replace the function below 
//			UuidCreateSequential with UuidCreate
// Microsoft decided that it was not wise to put the MAC address in the UUID
// hence changed the algorithm in Windows 2000 and later to not include it.
//
// Supported in Windows NT/2000/XP
// Supported in Windows 95/98/Me
//
// Supports single NIC card.
 
#include "stdafx.h"
#include <Windows.h>
#include <rpc.h>
#include <rpcdce.h>
#pragma comment(lib, "rpcrt4.lib")
 
// Prints the MAC address stored in a 6 byte array to stdout
static void PrintMACaddress(unsigned char MACData[])
{
	printf("MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n", 
		MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]);
}
 
// Fetches the MAC address and prints it
static void GetMACaddress(void)
{
	unsigned char MACData[6];
 
	UUID uuid;
    UuidCreateSequential( &uuid );				// Ask OS to create UUID
 
    for (int i=2; i<8; i++)						// Bytes 2 through 7 inclusive are MAC address
		MACData[i - 2] = uuid.Data4[i];
 
	PrintMACaddress(MACData);					// Print MAC address
}
 
int _tmain(int argc, _TCHAR* argv[])
{
	GetMACaddress();							// Obtain MAC address of adapters
 
	return 0;
}

Open in new window

MyWay.jpg
0
 
LVL 12

Expert Comment

by:jazzIIIlove
ID: 22698710
sad but i have no C++ builder by the way...
0
 

Author Closing Comment

by:robballi
ID: 31505486
Excelent i had to do some hacking to put it to work under windows but it works!!
Thanks a lot
0
 
LVL 12

Expert Comment

by:jazzIIIlove
ID: 22699751
<<Excelent i had to do some hacking to put it to work under windows but it works!!
<<Thanks a lot

Hey, could you send your modified code?
0
 

Author Comment

by:robballi
ID: 22723497
Sorry jazzIIIlove:

I had some bussy time here.
I just made a class like:

//---------------------------------------------------------------------------

#ifndef MacH
#define MacH
#include <sstream.h>

//---------------------------------------------------------------------------
class Mac {
public:
   string mac();
};
#endif

And modified your code to get the string, as i have only one mac address i used a string:

#include "Mac.h"

#include <windows.h>
#include <wincon.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

typedef struct _ASTAT_   {
  ADAPTER_STATUS adapt;
  NAME_BUFFER    NameBuff [30];

} ASTAT, * PASTAT;

ASTAT Adapter;

string Mac::mac()  {
      NCB Ncb;
      UCHAR uRetCode;
      char NetName[50];
      LANA_ENUM   lenum;
      int      i;
      char mac_addr[12];
      string macy;
      string mac_address;
     
      memset( &Ncb, 0, sizeof(Ncb) );
      Ncb.ncb_command = NCBENUM;
      Ncb.ncb_buffer = (UCHAR *)&lenum;
      Ncb.ncb_length = sizeof(lenum);
      uRetCode = Netbios( &Ncb );
      printf( "The NCBENUM return code is: 0x%x \n", uRetCode );
      int n = lenum.length;
      for(i=0; i < n ;i++)
      {


          memset( &Ncb, 0, sizeof(Ncb) );
          Ncb.ncb_command = NCBRESET;
          Ncb.ncb_lana_num = lenum.lana[i];
 
          uRetCode = Netbios( &Ncb );
          printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
                  lenum.lana[i], uRetCode );
 
          memset( &Ncb, 0, sizeof (Ncb) );
          Ncb.ncb_command = NCBASTAT;
          Ncb.ncb_lana_num = lenum.lana[i];
 
          strcpy( Ncb.ncb_callname,  "*               " );
          Ncb.ncb_buffer = (char *) &Adapter;
          Ncb.ncb_length = sizeof(Adapter);
 
          uRetCode = Netbios( &Ncb );
          printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
                  lenum.lana[i], uRetCode );
          if ( uRetCode == 0 )  {
             sprintf( mac_addr,"%02x%02x%02x%02x%02x%02x",
                  Adapter.adapt.adapter_address[0],
                  Adapter.adapt.adapter_address[1],
                  Adapter.adapt.adapter_address[2],
                  Adapter.adapt.adapter_address[3],
                  Adapter.adapt.adapter_address[4],
                  Adapter.adapt.adapter_address[5] );
          }
          macy = mac_addr;
       }

  return macy;

}
 
then you just instanciate the object on a standard window form to get the string value from the class just described!!
like

string macaddress;
Mac mac;
macaddress = mac.mac();

Thanks for your help!

 
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
c++ class logger 6 108
Fast data scrub 19 101
Delphi : could not find program, '...exe' 2 212
Copying WordPress Pages 5 93
Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

685 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