www.gusucode.com > 一个VC++网卡接口类代码源码程序 > 一个VC++网卡接口类代码/APIAdapterInfo/APIAdapterInfo/Adapter/Adapter/NetworkAdapter.cpp

    //////////////////////////////////////////////////////////////////////////
// 文件名:NetworkAdapter.cpp
// 功能描述:网络适配器接口实现
// Download by http://www.codesc.net
#include "StdAfx.h"
#include "NetworkAdapter.h"
#include <Iphlpapi.h>
#include <Setupapi.h>
#include <Regstr.h>
#include <cfgmgr32.h>   // DDK
#include <Rpc.h>

#pragma comment( lib, "Iphlpapi.lib" )
#pragma comment( lib, "Setupapi.lib" )
#pragma comment( lib, "Rpcrt4.lib" )

#ifdef UNICODE
#define RPC_TSTR    RPC_WSTR
#else
#define RPC_TSTR    RPC_CSTR
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// 全局函数
BOOL ChangeStatus( DWORD dwNewStatus, DWORD dwSelectedItem, HDEVINFO hDevInfo );
BOOL ControlAdapter( DWORD dwStatus );
BOOL GetDeviceRegistryProperty( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDeviceInfoData, DWORD dwProperty, CString& strProperty );

CNetworkAdapter::CNetworkAdapter(void)
{
    InitLocalAdapterInfo();
}

CNetworkAdapter::~CNetworkAdapter(void)
{
}

void CNetworkAdapter::InitLocalAdapterInfo()
{
    m_vecAdapterInfo.clear();
    ULONG ulOutBufLen = 0;
    PIP_ADAPTER_INFO pAdapterInfo = NULL;
    if ( ERROR_SUCCESS != GetAdaptersInfo( pAdapterInfo, &ulOutBufLen ) )
    {
        pAdapterInfo = ( PIP_ADAPTER_INFO )new BYTE[ ulOutBufLen ];
        if ( NULL == pAdapterInfo )
        {
            return;
        }
    }

    DWORD dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
    if ( ERROR_SUCCESS == dwRetVal )
    {
        PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
        while ( pAdapter )
        {
            if ( MIB_IF_TYPE_ETHERNET == pAdapter->Type )
            {
                ADAPTER_INFO stcAdapter;

                CString strText;
                for ( UINT i = 0; i < pAdapter->AddressLength; ++i )
                {
                    strText.Format( _T("%02X"), pAdapter->Address[i] );
                    stcAdapter.m_strMAC += strText;
                }
                stcAdapter.m_strIP = pAdapter->IpAddressList.IpAddress.String;
                stcAdapter.m_strNetMask = pAdapter->IpAddressList.IpMask.String;
                stcAdapter.m_strAdapterName = pAdapter->AdapterName;

                m_vecAdapterInfo.push_back( stcAdapter );
            }

            pAdapter = pAdapter->Next;
        }
    }
    else
    {
        TRACE( _T("\nGet network info failed.\n") );
        ASSERT( 0 );
    }

    delete[] pAdapterInfo;

}

CString CNetworkAdapter::GetIPAddress() const
{
    CString strIP;
    if ( !m_vecAdapterInfo.empty() )
    {
        strIP = m_vecAdapterInfo[0].m_strIP;
    }

    return strIP;
}

CString CNetworkAdapter::GetMACAddress() const
{
    CString strMAC;
    if ( !m_vecAdapterInfo.empty() )
    {
        strMAC = m_vecAdapterInfo[0].m_strMAC;
    }

    return strMAC;
}

void CNetworkAdapter::SetIPAddress( CString strIP )
{
    if ( !m_vecAdapterInfo.empty() )
    {
        m_vecAdapterInfo[0].m_strIP = strIP;
    }
}

void CNetworkAdapter::SetMACAddress( CString strMAC )
{
    if ( !m_vecAdapterInfo.empty() )
    {
        m_vecAdapterInfo[0].m_strMAC = strMAC;
    }
}

BOOL CNetworkAdapter::RegSetIP( CString strAdapterName, CString strIPAddress, CString strNetMask )
{
    BOOL bRet = TRUE;
    HKEY hKey;
    CString strKeyName = _T("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
    strKeyName += strAdapterName;
    if ( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, strKeyName, 0, KEY_WRITE, &hKey ) )
    {
        TRACE( _T("\nRegOpenKeyEx failed\n") );
        return FALSE;
    }

    const int MAX_SIZE = 100;
    TCHAR mszIPAddress[ MAX_SIZE ];
    TCHAR mszNetMask[ MAX_SIZE ];

    _tcsncpy_s( mszIPAddress, strIPAddress, MAX_SIZE - 2 );
    _tcsncpy_s( mszNetMask, strNetMask, MAX_SIZE - 2 );

    mszIPAddress[ MAX_SIZE - 2 ] = 0;
    mszNetMask[ MAX_SIZE - 2 ] = 0;

    int nIP = 0, nMask = 0;
    nIP = _tcslen( mszIPAddress );
    nMask = _tcslen( mszNetMask );

    *( mszIPAddress + nIP + 1 ) = 0x00;         // REG_MULTI_SZ数据需要在后面再加个0
    nIP += 2;

    *( mszNetMask + nMask + 1 ) = 0x00;
    nMask += 2;

    nIP = nIP * sizeof( TCHAR );
    nMask = nMask * sizeof( TCHAR );

    if ( ERROR_SUCCESS != RegSetValueEx( hKey, _T("IPAddress"), 0, 
        REG_MULTI_SZ, ( unsigned char* )mszIPAddress, nIP ) )
    {
        bRet = FALSE;
    }

    if ( ERROR_SUCCESS != RegSetValueEx( hKey, _T("SubnetMask"), 0,
        REG_MULTI_SZ, ( unsigned char* )mszNetMask, nMask ) )
    {
        bRet = FALSE;
    }

    RegCloseKey( hKey );

    return bRet;
}

BOOL CNetworkAdapter::RegSetMAC( CString strAdapterName, CString strMACAddress )
{
    BOOL bRet = FALSE;
    HKEY hKey;
    CString strKeyName = _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
    if ( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, strKeyName, 0, 
        KEY_WRITE | KEY_READ, &hKey ) ) 
    {
        TRACE( _T("\nRegOpenKeyEx failed.\n") );
        return FALSE;
    }

    const int BUFSIZE = 255;
    TCHAR szSubKeyName[ BUFSIZE ];
    DWORD dwIndex = 0, dwSubKeyName = BUFSIZE;
    FILETIME fileTime;

    while ( ERROR_SUCCESS == RegEnumKeyEx( hKey, dwIndex, szSubKeyName, 
        &dwSubKeyName, NULL, NULL, NULL, &fileTime ) )
    {
        dwIndex ++;
        dwSubKeyName = BUFSIZE;

        HKEY hSubKey;
        CString strSubKeyName;
        strSubKeyName = strKeyName + CString( szSubKeyName ) + _T("\\");
        if ( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, strSubKeyName, 0, 
            KEY_WRITE | KEY_READ, &hSubKey ) )
        {
            continue;
        }

        TCHAR szValue[ BUFSIZE ];
        DWORD dwType = 0, dwValueSize = sizeof( szValue );
        if ( ERROR_SUCCESS == RegQueryValueEx( hSubKey, _T("NetCfgInstanceId"), NULL, 
            &dwType, ( unsigned char* )szValue, &dwValueSize ) )
        {
            CString strValueText( szValue );
            if ( strValueText == strAdapterName )
            {
                _tcsncpy_s( szValue, strMACAddress, BUFSIZE );
                DWORD dwDataSize = ( strMACAddress.GetLength() + 1 ) * sizeof( TCHAR );

                if ( ERROR_SUCCESS == RegSetValueEx( hSubKey, _T("NetworkAddress"), 0, 
                    REG_SZ, ( unsigned char* )szValue, dwDataSize ) )
                {
                    bRet = TRUE;
                }
                RegCloseKey( hSubKey );
                break;
            }
        }

        RegCloseKey( hSubKey );
    }

    RegCloseKey( hKey );

    return bRet;
}

BOOL CNetworkAdapter::MakeChange()
{
    BOOL bRet = TRUE;

    CString strAdapterName, strIPAddress, strNetMask, strMACAddress;
    if ( !m_vecAdapterInfo.empty() )
    {
        strAdapterName = m_vecAdapterInfo[0].m_strAdapterName;
        strIPAddress = m_vecAdapterInfo[0].m_strIP;
        strNetMask = m_vecAdapterInfo[0].m_strNetMask;
        strMACAddress = m_vecAdapterInfo[0].m_strMAC;
    }

    if ( !RegSetIP( strAdapterName, strIPAddress, strNetMask ) )
    {
        bRet = FALSE;
    }

    if ( !RegSetMAC( strAdapterName, strMACAddress ) )
    {
        bRet = FALSE;
    }

    if ( !ControlAdapter( DICS_PROPCHANGE ) )
    {
        bRet = FALSE;
    }

    return bRet;
}

BOOL ChangeStatus( DWORD dwNewStatus, DWORD dwSelectedItem, HDEVINFO hDevInfo )
{
    BOOL bRet = TRUE;

    TRY 
    {
        SP_DEVINFO_DATA DeviceInfoData;
        ZeroMemory( &DeviceInfoData, sizeof( SP_DEVINFO_DATA ) );
        DeviceInfoData.cbSize = sizeof( SP_DEVINFO_DATA );

        // Get a handle to the Selected Item
        if ( !SetupDiEnumDeviceInfo( hDevInfo, dwSelectedItem, &DeviceInfoData ) )
        {
            bRet = FALSE;
        }
        else
        {
            SP_PROPCHANGE_PARAMS PropChangeParams;
            ZeroMemory( &PropChangeParams, sizeof( SP_PROPCHANGE_PARAMS ) );
            PropChangeParams.ClassInstallHeader.cbSize = sizeof( SP_CLASSINSTALL_HEADER );

            // Set the PropChangeParams structure
            PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
            PropChangeParams.Scope = DICS_FLAG_GLOBAL;
            PropChangeParams.StateChange = dwNewStatus;

            if ( !SetupDiSetClassInstallParams( hDevInfo, &DeviceInfoData, ( SP_CLASSINSTALL_HEADER* )&PropChangeParams, sizeof( PropChangeParams ) ) )
            {
                bRet = FALSE;
            }
            else
            {
                // Call the ClassInstaller and perform the change
                if ( !SetupDiCallClassInstaller( DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData ) )
                {
                    bRet = FALSE;
                }
                else
                {
                    // 判断是否需要重新启动
                    SP_DEVINSTALL_PARAMS devParams;
                    ZeroMemory( &devParams, sizeof( SP_DEVINSTALL_PARAMS ) );
                    devParams.cbSize = sizeof( SP_DEVINSTALL_PARAMS );

                    if ( !SetupDiGetDeviceInstallParams( hDevInfo, &DeviceInfoData, &devParams ) )
                    {
                        bRet = FALSE;
                    }
                    else
                    {
                        if ( devParams.Flags & ( DI_NEEDRESTART | DI_NEEDREBOOT ) )
                        {
                            TRACE( _T("\nNeed Restart Computer\n") );
                        }
                    }
                }
            }
        }
    }
    CATCH_ALL( e )
    {
    	e->ReportError();
        bRet = FALSE;
    }
    END_CATCH_ALL

    return bRet;
}

BOOL GetDeviceRegistryProperty( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDeviceInfoData, DWORD dwProperty, CString& strProperty )
{
    BOOL bRet = TRUE;
    DWORD dwDataType = 0;
    LPTSTR pszBuf = NULL;
    DWORD dwBuffersize = 0;
    
    while ( !SetupDiGetDeviceRegistryProperty( hDevInfo, pDeviceInfoData, dwProperty, &dwDataType, ( PBYTE )pszBuf, dwBuffersize, &dwBuffersize ) )
    {
        if ( ERROR_INVALID_DATA == GetLastError() )
        {
            // 不存在 Device desc
            bRet = FALSE;
            break;
        }
        else if ( ERROR_INSUFFICIENT_BUFFER == GetLastError() )
        {
            // buffer size 不对
            if ( NULL != pszBuf )
            {
                LocalFree( LocalHandle( pszBuf ) );
                pszBuf = NULL;
            }

            pszBuf = ( LPTSTR )LocalAlloc( LPTR, dwBuffersize );
            if ( NULL == pszBuf )
            {
                bRet = FALSE;
                break;
            }
        }
        else
        {
            // 未知错误
            bRet = FALSE;
            break;
        }
    }

    if ( bRet )
    {
        strProperty = pszBuf;
    }

    if ( NULL != pszBuf )
    {
        LocalFree( LocalHandle( pszBuf ) );
        pszBuf = NULL;
    }

    return bRet;
}

BOOL ControlAdapter( DWORD dwStatus )
{
    BOOL bRet = FALSE;
    
    if ( 0 == dwStatus )
    {
        return FALSE;
    }
    
    TCHAR* GUIDString = _T("4D36E972-E325-11CE-BFC1-08002BE10318");
    GUID guid;
    ZeroMemory( &guid, sizeof( GUID ) );
    if ( RPC_S_OK != UuidFromString( (RPC_TSTR)GUIDString, &guid ) )
    {
        bRet = FALSE;
    }
    else
    {
        HDEVINFO hDevInfo = NULL;
        hDevInfo = SetupDiGetClassDevs( &guid, REGSTR_KEY_PCIENUM, NULL, DIGCF_PRESENT );
        if ( INVALID_HANDLE_VALUE == hDevInfo )
        {
            bRet = FALSE;
        }
        else
        {
            DWORD i = 0;
            SP_DEVINFO_DATA DeviceInfoData;
            ZeroMemory( &DeviceInfoData, sizeof( SP_DEVINFO_DATA ) );
            DeviceInfoData.cbSize = sizeof( SP_DEVINFO_DATA );

            for ( i = 0; SetupDiEnumDeviceInfo( hDevInfo, i, &DeviceInfoData ); ++i )
            {
                // 获得设备的状态
                DWORD dwProblem = 0, dwDeviceStatus = 0;
                if ( CR_SUCCESS != CM_Get_DevNode_Status( &dwDeviceStatus, &dwProblem, DeviceInfoData.DevInst, 0 ) )
                {
                    continue;
                }

                // 获取设备注册表项描述
                CString strText;
                if ( !GetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_CLASS, strText ) )
                {
                    continue;
                }

                TRACE( _T("\n The %d device instance handle : %d, Class : %s\n"), i, DeviceInfoData.DevInst, strText );

                if ( 0 == lstrcmp( strText, _T("Net") ) )
                {
                    TRACE( _T("This is the adapter device that I want.\n") );

                    //////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
                    if ( GetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, strText ) )
                    {
                        TRACE( _T("SPDRP_DEVICEDESC : %s\n"), strText );
                    }
#endif
                    //////////////////////////////////////////////////////////////////////////

                    if ( ChangeStatus( dwStatus, i, hDevInfo ) )
                    {
                        bRet = TRUE;
                    }
                }
            }

            // 释放 device information set
            bRet = SetupDiDestroyDeviceInfoList( hDevInfo );
        }
    }

    return bRet;
}