⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macretr.cpp

📁 遗传算法vc++语言版源程序,台湾大学编写。
💻 CPP
字号:
/* 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 "macretr.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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -