|
reply by luis ... refer http://forums.devx.com/archive/index.php/t-89890.html[^]
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( (char *) Ncb.ncb_callname, "* " );
Ncb.ncb_buffer = (unsigned 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] );
}
} //for
}
|
|
|
|
|
1. When i am using NetBios function it will return the ErrorCode like (Data error (cyclic redundancy check). )how can i solve .
2.Can i take the Disable NIC or Wireless MAC-Address using this API
VC++ ,COM,MFC
|
|
|
|
|
Hi,
I am using a MAC address as a mechanism of recognizing unique system key. This API works fine for Windows XP.
But, this API is giving different values under Windows Vista.
Can you please provide an alternate method/API for Windows Vista.
Thanks in Advance.
Ankush Gupta
|
|
|
|
|
How can I get the sNetBiosName??
|
|
|
|
|
I did link netapi32.lib etc. and still got the problem, that no MAC is displayed.
Some other people here got the same problem. How to fix it ?
|
|
|
|
|
Please use this :
CString MAC;
MAC GetMacAddress("* ");
You will get 1st Adapter 's MAC .
Joe
|
|
|
|
|
hello
can anyone please send me the nb30.h and netapi32.lib used in the code provided by Ryszard Krakowiak.
Thanks in advance
jagmal
|
|
|
|
|
What I Pass to sNetBiosName when calling GetMacAddress function.
equebal
|
|
|
|
|
|
For NetBiosName, what string would I pass in? I've got a 1394 Net Adapter
Intel(R) PRO/100 VE Network Connection
|
|
|
|
|
Dear Sir
I want to get mac address with Foxpro 2.6 that is run under Ms-dos
please help me
my Email address is : morteza_mousavi@yahoo.com
|
|
|
|
|
I programing in VFP ,I need to get MAC Address for develop my network group it very important and usful if i have ActiveX Control or DLL Library
Please tell me
Thank you very much for help
|
|
|
|
|
what is the way that
detect my NIC device is connected to the LAN or not?
tangming
|
|
|
|
|
If I disconnect the board from the net I cannot get the Mac Address.
Why is it so?
Thanks.
|
|
|
|
|
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q118/6/23.asp&NoWebContent=1
and here, compile will works
|
|
|
|
|
See the first line in my article.
"... This article is based on Q118623."
|
|
|
|
|
error LNK2001: unresolved external symbol _Netbios@4
what's meaning?
the code :
#include "afx.h"
#include "Nb30.h"
typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff[30];
} ASTAT, * PASTAT;
CString GetMacAddress(CString sNetBiosName)
{
ASTAT Adapter;
NCB ncb;
UCHAR uRetCode;
memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBRESET;
ncb.ncb_lana_num = 0;
uRetCode = Netbios(&ncb);
memset(&ncb, 0, sizeof(ncb));
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = 0;
sNetBiosName.MakeUpper();
FillMemory(ncb.ncb_callname, NCBNAMSZ - 1, 0x20);
strcpy((char *)ncb.ncb_callname, (LPCTSTR) sNetBiosName);
ncb.ncb_callname[sNetBiosName.GetLength()] = 0x20;
ncb.ncb_callname[NCBNAMSZ] = 0x0;
ncb.ncb_buffer = (unsigned char *) &Adapter;
ncb.ncb_length = sizeof(Adapter);
uRetCode = Netbios(&ncb);
CString sMacAddress;
if (uRetCode == 0)
{
sMacAddress.Format(_T("%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]);
}
return sMacAddress;
}
void main()
{
CString macaddr = GetMacAddress("marcopeng");
afxDump << macaddr << "\n";
}
|
|
|
|
|
link with netapi32.lib
|
|
|
|
|
You can get MAC addr using IP helper API (iphlpapi.dll). It works with multiple interfaces and is independent of NETBIOS and SNMP. There is no need for IP address so you can get MAC even if the cable is disconected. Possible problem is that it works only on win2000 and above, and win98 and above (source: Microsoft). Somewhere on Internet I read it should work on NT+SP4 and above but I did not test this.
Code should be something like this:
<br />
#include <windows.h><br />
#include <iphlpapi.h><br />
<br />
PIP_ADAPTER_INFO pInf; <br />
LPBYTE pbBuf; <br />
ULONG ulSize = 0; <br />
<br />
GetAdaptersInfo(NULL, &ulSize); <br />
pbBuf = new BYTE[ulSize]; <br />
GetAdaptersInfo((PIP_ADAPTER_INFO)pbBuf, &ulSize);<br />
pInf = (PIP_ADAPTER_INFO)pbBuf; <br />
do<br />
{ <br />
printf("%s\n", pInfo->Description);<br />
printf("MAC: %02X %02X %02X %02X %02X %02X\n", pInf->Address[0], pInf->Address[1], pInf->Address[2], pInf->Address[3], pInf->Address[4], pInf->Address[5]); <br />
pInf = pInf->Next; <br />
} while (pInf != NULL);<br />
delete [] pbBuffer;<br />
Goran
|
|
|
|
|
SSUUUUUPEEERRRRR !
This is what I was looking for..
I got many errors, untill I decided to download the latest platform SDK.
I made a nice class which allow running of my app on selected computers only,
( selected by registered NICs )..
|
|
|
|
|
Just don't forget this (MSDN quote):
Remarks
Windows XP/Windows .NET Server or later: The list of adapters returned by GetAdaptersInfo includes unidirectional adapters. To generate a list of adapters that can both send and receive data, call GetUniDirectionalAdapterInfo, and exclude the returned adapters from the list returned by GetAdaptersInfo.
Requirements
Windows NT/2000/XP: Included in Windows 2000; Windows XP Pro; and Windows .NET Server.
Windows 95/98/Me: Included in Windows 98 and later.
Header: Declared in Iphlpapi.h.
Library: Use Iphlpapi.lib.
Now I don't know if Windows 95 interests you, but Windows NT... You may need to do a runtime check using a sequence like
typedef DWORD (WINAPI *FN_GetAdaptersInfo)(PIP_ADAPTERS_INFO, PULONG);
HMODULE hIpHlpApi = LoadLibrary(_T("IpHlpApi.dll"));
if(hIpHlpApi != NULL) {
FN_GetAdaptersInfo fnGetAdaptersInfo = (FN_GetAdaptersInfo)GetProcAddress(hIpHlpApi, "GetAdaptersInfo");
if(fnGetAdaptersInfo != NULL) {
// prepare parameters and call (* fnGetAdaptersInfo)(pip, &ul);
}
else {
// should not happen....
}
if(FreeLibrary(hIpHlpApi)) {
hIpHlpApi = NULL;
}
}
else {
// IplpApi.dll not installed or not found
}
|
|
|
|
|
For the people that come after me the include files are
windows.h
iphlpapi.h
---
www.funvill.com, www.Abluestar.com
|
|
|
|
|
Ryszard,
An excellent idea to post this to Code Project... I ran into this problem last year and have re-used the following code many times since. One problem with the NetBIOS method is that not all computers have NetBIOS installed. I have found that most machines do have SNMP installed, so that is the one that I use most often. In any case, maybe you can incorporate some of this code into an updated article. If you would like me to send the original .h and .cpp files send me your e-mail address and I will pass them along.
Header File starts here.
__________________________________________________________________________
/* MacRetriever.h
* Author: Peter Donahue
* Contact (709) 891-1129 (ask for Peter)
* peter.donahue@comdev.ca
* techinterface@yahoo.ca
*
* This class simplifies the task of retrieving the MAC address of a particular
* card under MS Windows.
*/
#pragma once
#include <winsock2.h>
#include <windows.h>
#include <snmp.h>
#include <nb30.h>
typedef SNMPAPI (WINAPI *t_SnmpExtensionInit)(DWORD dwUptimeReference, HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion);
typedef SNMPAPI (WINAPI *t_SnmpExtensionQuery)(BYTE bPduType, SnmpVarBindList *pVarBindList, AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex);
typedef SNMPAPI (WINAPI *t_SnmpUtilOidCpy)(AsnObjectIdentifier * pOidDst, AsnObjectIdentifier * pOidSrc);
typedef int (WINAPI *t_WSAStartup)(WORD wVersionRequested, LPWSADATA lpWSAData);
typedef int (WINAPI *t_WSACleanup)();
typedef UCHAR (WINAPI *t_Netbios)(PNCB pncb);
typedef HRESULT (WINAPI *t_UuidCreate)(UUID *puuid);
class CMacRetriever{
public:
CMacRetriever(void);
~CMacRetriever(void);
bool GetMacUsingGuid(char *address, int cardIndex);
bool GetMacUsingNetBIOS(char *address, int cardIndex);
bool GetMacUsingSNMP(char *address, int cardIndex); // The call to get the MAC address.
const char* GetErrorMessage() {return m_error;}; // Returns the most recent error (should only be called after a function fails)
static void CopyAddressToString(unsigned char hexAddr[6], char *strAddr);
// These will be called automatically, but are public in case you would like to
// unload the DLLs before this object goes out of scope.
bool InitializeSNMP();
void UnInitializeSNMP();
bool InitializeNetBIOS();
void UnInitializeNetBIOS();
bool InitializeGuid();
void UnInitializeGuid();
protected:
// function pointers for SNMP and winsock
t_SnmpExtensionInit m_ptrSnmpExtensionInit;
t_SnmpExtensionQuery m_ptrSnmpExtensionQuery;
t_SnmpUtilOidCpy m_ptrSnmpUtilOidCpy;
t_WSAStartup m_ptrWSAStartup;
t_WSACleanup m_ptrWSACleanup;
// dll handles for SNMP and winsock
HINSTANCE m_snmpApiDll;
HINSTANCE m_inetDll;
HINSTANCE m_wsockDll;
bool m_snmpInitialized;
// function pointer for Netbios
bool m_netbiosInitialized;
HINSTANCE m_netbiosDll;
t_Netbios m_ptrNetbios;
//function pointer for UuidCreate
bool m_uuidInitialized;
HINSTANCE m_uuidDll;
t_UuidCreate m_ptrUuidCreate;
char m_error[256]; // This string will contain an error message if any function fails.
};
Source File starts here.
__________________________________________________________________________
/* MacRetriever.cpp
* Author: Peter Donahue
* Contact (709) 891-1129 (ask for Peter)
* peter.donahue@comdev.ca
* techinterface@yahoo.ca
*
* This class simplifies the task of retrieving the MAC address of a particular
* card under MS Windows.
*/
// Uncomment this line if you are using VC++ precompiled headers through stdafx.h.
//#include "stdafx.h"
#include "MacRetriever.h"
CMacRetriever::CMacRetriever(void){
m_ptrSnmpExtensionInit=NULL;
m_ptrSnmpExtensionQuery=NULL;
m_ptrSnmpUtilOidCpy=NULL;
m_ptrWSAStartup=NULL;
m_ptrWSACleanup=NULL;
m_snmpApiDll=NULL;
m_inetDll=NULL;
m_wsockDll=NULL;
m_snmpInitialized=false;
m_ptrNetbios=NULL;
m_netbiosDll=NULL;
m_netbiosInitialized=false;
m_ptrUuidCreate=NULL;
m_uuidDll=NULL;
m_uuidInitialized=false;
}
CMacRetriever::~CMacRetriever(void){
UnInitializeSNMP();
UnInitializeNetBIOS();
UnInitializeGuid();
}
// Address must be at least 13 characters long.
bool CMacRetriever::GetMacUsingSNMP(char *address, int cardIndex){
// This function used to be implemented using GUID, but that approach doesn't work
// for Win2000... This new approach uses SNMP. Hopefully it will be a little more
// robust.
address[0]='\0';
if (!InitializeSNMP()) return false;
// Get the <addressNum> MAC address
long errorStatus=0;
long errorIndex=0;
SnmpVarBindList bindList;
SnmpVarBind bindVar;
AsnObjectIdentifier tmpName;
memset(&bindVar, 0, sizeof(bindVar));
memset(&bindVar, 0, sizeof(bindList));
bindList.len=1;
bindList.list=&bindVar;
const UINT MAC_ADDRESS_OID[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 6};
tmpName.idLength=10;
tmpName.ids=(UINT*)MAC_ADDRESS_OID;
m_ptrSnmpUtilOidCpy(&bindVar.name, &tmpName);
for(int i=0;i<cardIndex;++i){
if (!m_ptrSnmpExtensionQuery(ASN_RFC1157_GETNEXTREQUEST, &bindList, &errorStatus, &errorIndex)){
strcpy(m_error, "Error getting address from SNMP");
return false;
}
}
// bindVar should now have the address.
unsigned char *addr=bindVar.value.asnValue.address.stream;
if (!addr || addr==(UCHAR*)1){
strcpy(m_error, "No address found at this index");
return false;
}
// Copy addr into address
address[0]='\0';
CopyAddressToString(addr,address);
return true;
}
void CMacRetriever::UnInitializeSNMP(void){
if (m_ptrWSACleanup) m_ptrWSACleanup();
if (m_inetDll) FreeLibrary(m_inetDll);
if (m_snmpApiDll) FreeLibrary(m_snmpApiDll);
if (m_wsockDll) FreeLibrary(m_wsockDll);
m_ptrWSACleanup=NULL;
m_inetDll=NULL;
m_snmpApiDll=NULL;
m_wsockDll=NULL;
m_snmpInitialized=false;
}
// Load the SNMP and winsock dlls and get the required function pointers.
bool CMacRetriever::InitializeSNMP(void){
if (m_snmpInitialized) return true;
// Load DLLs
m_wsockDll=LoadLibrary("ws2_32.dll");
if (!m_wsockDll){
strcpy(m_error,"Unable to load inetmib1.dll (SNMP dll)");
return false;
}
m_inetDll = LoadLibrary("inetmib1.dll");
if (!m_inetDll){
strcpy(m_error,"Unable to load inetmib1.dll (SNMP dll)");
return false;
}
m_snmpApiDll=LoadLibrary("snmpapi.dll");
if (!m_snmpApiDll){
strcpy(m_error,"Unable to load snmpapi.dll (SNMP dll)");
return false;
}
// Get the SNMP function pointers.
m_ptrSnmpExtensionInit=(t_SnmpExtensionInit)::GetProcAddress(m_inetDll, "SnmpExtensionInit");
m_ptrSnmpExtensionQuery=(t_SnmpExtensionQuery)::GetProcAddress(m_inetDll, "SnmpExtensionQuery");
m_ptrSnmpUtilOidCpy=(t_SnmpUtilOidCpy)::GetProcAddress(m_snmpApiDll, "SnmpUtilOidCpy");
if (!m_ptrSnmpExtensionInit || !m_ptrSnmpExtensionQuery
|| !m_ptrSnmpUtilOidCpy){
strcpy(m_error, "Error getting functions from SNMP dll. You may not have the correct version of SNMP installed.");
return false;
}
// Get the winsock pointers.
m_ptrWSAStartup=(t_WSAStartup)::GetProcAddress(m_wsockDll, "WSAStartup");
m_ptrWSACleanup=(t_WSACleanup)::GetProcAddress(m_wsockDll, "WSACleanup");
if (!m_ptrWSAStartup || !m_ptrWSACleanup){
strcpy(m_error, "Error getting functions from winsock dll. Your winsock libs may not be installed properly.");
// Set to null so they won't be called from UnInitialize
m_ptrWSACleanup=NULL;
return false;
}
// Call init routine for winsock.
WSADATA sockData;
if (m_ptrWSAStartup(MAKEWORD(2, 0), &sockData)){
strcpy(m_error,"Winsock init failed.");
m_ptrWSACleanup=NULL;
return false;
}
// Call init routine for SNMP
HANDLE eventTrap;
AsnObjectIdentifier id;
if (!m_ptrSnmpExtensionInit(0, &eventTrap, &id)){
strcpy(m_error, "SNMP init failed.");
return false;
}
m_snmpInitialized=true;
return true;
}
typedef struct tagASTAT{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
}ASTAT;
// This function can only handle a single address for the machine.
bool CMacRetriever::GetMacUsingGuid(char *address, int cardIndex){
if (!InitializeGuid()) return false;
address[0]='\0';
if (cardIndex){
strcpy(m_error, "CardIndex must be 0 when calling GetMacUsingGuid. If you need other MACs use GetMacUsingNetBIOS or GetMacUsingSNMP.");
return false;
}
UUID uuid;
if (m_ptrUuidCreate(&uuid) != RPC_S_OK){
strcpy(m_error, "UuidCreate returned an invalid GUID");
return false;
}
CopyAddressToString(&uuid.Data4[2], address);
return true;
}
bool CMacRetriever::GetMacUsingNetBIOS(char *address, int cardIndex){
// Taken from MSDN article on finding the MAC address through NetBios.
address[0]='\0';
if (!InitializeNetBIOS()) return false;
NCB ncb;
ASTAT Adapter;
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBRESET;
ncb.ncb_lana_num=cardIndex;
if (m_ptrNetbios(&ncb) != NRC_GOODRET){
switch(ncb.ncb_retcode){
case 0x23:
strcpy(m_error, "No NetBIOS interface found at this index");
break;
default:
strcpy(m_error, "Error calling NetBIOS reset function");
}
return false;
}
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBASTAT;
ncb.ncb_lana_num=cardIndex;
strcpy((char*)ncb.ncb_callname,"* ");
ncb.ncb_buffer=(unsigned char*)&Adapter;
ncb.ncb_length=sizeof(Adapter);
if (m_ptrNetbios(&ncb) != NRC_GOODRET){
strcpy(m_error, "MAC address retrieval from NetBIOS failed");
return false;
}
CopyAddressToString(Adapter.adapt.adapter_address, address);
return true;
}
void CMacRetriever::CopyAddressToString(unsigned char hexAddr[6], char *strAddr){
char tmp[3];
strAddr[0]='\0';
for(int i=0;i<6;++i){
itoa(hexAddr[i], tmp, 16);
if (hexAddr[i] <= 0x0f) strcat(strAddr, "0");
strcat(strAddr, tmp);
}
}
void CMacRetriever::UnInitializeNetBIOS(void){
if (m_netbiosDll) FreeLibrary(m_netbiosDll);
m_netbiosDll=NULL;
m_netbiosInitialized=false;
}
bool CMacRetriever::InitializeNetBIOS(void){
if (m_netbiosInitialized) return true;
// Load DLLs
m_netbiosDll=LoadLibrary("Netapi32.dll");
if (!m_netbiosDll){
strcpy(m_error,"Unable to load Netapi32.dll (Netbios dll)");
return false;
}
// Get the NetBIOS function pointer.
m_ptrNetbios=(t_Netbios)::GetProcAddress(m_netbiosDll, "Netbios");
if (!m_ptrNetbios){
strcpy(m_error, "Error getting function from NetBIOS dll");
return false;
}
m_netbiosInitialized=true;
return true;
}
void CMacRetriever::UnInitializeGuid(void){
if (m_uuidDll) FreeLibrary(m_uuidDll);
m_uuidDll=NULL;
m_uuidInitialized=false;
}
bool CMacRetriever::InitializeGuid(void){
// We need a function to return a valid GUID (UUID including MAC address)
if (m_uuidInitialized) return true;
// Load DLLs
m_uuidDll=LoadLibrary("rpcrt4.dll");
if (!m_uuidDll){
strcpy(m_error,"Unable to load rpcrt.dll (RPC dll for UuidCreate)");
return false;
}
// Get the UuidCreate function pointer.
m_ptrUuidCreate=(t_UuidCreate)::GetProcAddress(m_uuidDll, "UuidCreateSequential");
if (!m_ptrUuidCreate){
// We may be on an older OS. Try to get old function
m_ptrUuidCreate=(t_UuidCreate)::GetProcAddress(m_uuidDll, "UuidCreate");
}
if (!m_ptrUuidCreate){
strcpy(m_error, "Error getting UuidCreate function from rpcrt4.dll");
return false;
}
m_uuidInitialized=true;
return true;
}
Test Program starts here.
____________________________________________________________________________
#include "MacRetriever.h"
#include <stdio.h>
int main(){
CMacRetriever mac;
int i;
char address[13];
printf("SNMP:\n");
for(i=0;i<6;++i){
if (mac.GetMacUsingSNMP(address,i)){
printf("mac address: %s\n", address);
}else{
printf("Error: %s\n", mac.GetErrorMessage());
}
}
printf("\nNetBIOS:\n");
for(i=0;i<6;++i){
if (mac.GetMacUsingNetBIOS(address,i)){
printf("mac address: %s\n", address);
}else{
printf("Error: %s\n", mac.GetErrorMessage());
}
}
printf("\nGUID:\n");
for(i=0;i<6;++i){
if (mac.GetMacUsingGuid(address,i)){
printf("mac address: %s\n", address);
}else{
printf("Error: %s\n", mac.GetErrorMessage());
}
}
#ifdef _DEBUG
Sleep(10000);
#endif
}
____________________________
Peter Donahue
Code Monkey
COM DEV International R&D
Cambridge, ON, Canada
|
|
|
|
|
I have tested it. it works fine.
Thank you very much.
|
|
|
|
|
Your code is useful. Thanks.
However, I've got a question here.
In the main function, why do we have to make loop for 6 times for each approach???
i know any number less than 6 is not enough, but why?
|
|
|
|
|