设置静态网络适配器IP地址

操作Windows网络连接相关的API,貌似没有暴漏出设置静态IP的方法,搜索了些资料最后,借助Windows的WMI(Windows Management Instruction) 来操控网络适配器了。

方法如下:

How to disable dhcp for a specific network adapter?


Recently, I am programming of android USB reverse tether. On the windows platform, a Remote NDIS network adapter was created. By default, it turns on the DHCP, however I want to disable it in codes. Is there any Win32 API to do it?

Use the WMI to fix it.

I coded one helper class to query or modify the network adapter settings

Here is the class defination

//Header file
#include <string>
struct NetWorkAdapterSetting
{
     unsigned int nIfIndex;
     bool bEnableDHCP;
     std::wstring strIPAddress;
     std::wstring strNetsubMask;

     NetWorkAdapterSetting()
     {
        nIfIndex = 0;
        bEnableDHCP = false;
     }
 };

 struct IWbemServices;
 struct IWbemLocator;
 class UsbReverseTether
 {
    public:
        UsbReverseTether(void);
        ~UsbReverseTether(void);

        bool Init();
        void Uninit();

        bool getConnectedNetworkAdapterSettings( NetWorkAdapterSetting& adapterSetting );

        bool enableStaticIPAddress(
              unsigned int nIfIndex, 
              const std::wstring& strIPAddress,
              const std::wstring& strNetsubMask );

    private:
        IWbemServices* m_pWbemSvc;
        IWbemLocator*  m_pWbemLoc;
    };

The source file

//COM init + Prepare the WMI Service + COM unit

bool UsbReverseTether::Init()
{
        HRESULT hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
        if ( FAILED( hr ) ) 
        {
            LOG_ERR( "Failed to initialize COM library. Error code = 0x%x", hr );
            return false;
        }

        hr = CoInitializeSecurity(
                     NULL,                      // Security descriptor
                     -1,                        // COM negotiates authentication service
                     NULL,                      // Authentication services
                     NULL,                      // Reserved
                     RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies
                     RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation level for proxies
                     NULL,                        // Authentication info
                     EOAC_NONE,          // Additional capabilities of the client or server
                     NULL);                // Reserved

        if ( FAILED( hr ) )
        {
           LOG_ERR( "Failed to initialize security. Error code = 0x%x", hr );
           CoUninitialize();
           return false;
        }

        hr = CoCreateInstance( 
              CLSID_WbemLocator,
              0,
              CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &m_pWbemLoc );
        if (FAILED(hr))
        {
            LOG_ERR( "Failed to create IWbemLocator object. Err code = 0x%x", hr );
            CoUninitialize();
            return false;
        }

         // Connect to the local root\cimv2 namespace
        // and obtain pointer m_pWbemSvc to make IWbemServices calls.
        hr = m_pWbemLoc->ConnectServer(
            L"ROOT\\CIMV2", 
            NULL,
            NULL, 
            0, 
            NULL, 
            0, 
            0, 
            &m_pWbemSvc
        );

        if (FAILED(hr))
        {
            LOG_ERR( "Could not connect. Error code = 0x%x", hr );
            m_pWbemLoc->Release();
            m_pWbemLoc = NULL;
            CoUninitialize();
            return false;
        }

        LOG_TRACE( "Connected to ROOT\\CIMV2 WMI namespace" );

        // Set the proxy so that impersonation of the client occurs.
        hr = CoSetProxyBlanket(m_pWbemSvc,
           RPC_C_AUTHN_WINNT,
           RPC_C_AUTHZ_NONE,
           NULL,
           RPC_C_AUTHN_LEVEL_CALL,
           RPC_C_IMP_LEVEL_IMPERSONATE,
           NULL,
           EOAC_NONE
        );

        if (FAILED(hr))
        {
            LOG_ERR( "Could not set proxy blanket. Error code = 0x%x", hr );
           m_pWbemSvc->Release();
           m_pWbemLoc->Release();
           CoUninitialize();
           return false; 
        }

        return true;
    }

    void UsbReverseTether::Uninit()
    {
        if ( NULL != m_pWbemSvc )
        {
            m_pWbemSvc->Release();
            m_pWbemSvc = NULL;
        }
        if ( NULL != m_pWbemLoc )
        {
            m_pWbemLoc->Release();
            m_pWbemLoc = NULL;
        }
        CoUninitialize();
    }

Query the USB Remote RNDIS network adapter setting

   bool UsbReverseTether::getConnectedNetworkAdapterSettings( NetWorkAdapterSetting& adapterSetting )
    {
        HRESULT hr = S_OK;
        IEnumWbemClassObject* pEnumerator = NULL;

        hr = m_pWbemSvc->ExecQuery( _bstr_t("WQL"),
            _bstr_t("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE AND ServiceName=\'usb_rndisx\'"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL,
            &pEnumerator );
        if ( FAILED( hr ) )
        {
            LOG_ERR( "ExecQuery. Error code = 0x%x", hr );
            return false;
        }

        bool bOK = false;
        IWbemClassObject* pclsObj = NULL;
        ULONG uReturn = 0;
        int nCount = 0;
        while ( pEnumerator )
        {
            hr = pEnumerator->Next( WBEM_INFINITE, 1, &pclsObj, &uReturn );
            if(0 == uReturn)
            {
                break;
            }
            ++nCount;
            if ( nCount > 1 )
            {
                LOG_WARN( "There is more than 1 connected usb network adapter" );
                break;
            }

            VARIANT vtProp;

            hr = pclsObj->Get(L"Index", 0, &vtProp, 0, 0);
            if ( FAILED( hr ) )
            {
                LOG_ERR( "IWbemClassObject::Getproperty(Index). Error code = 0x%x", hr );
                break;
            }
            adapterSetting.nIfIndex = vtProp.uintVal;
            VariantClear(&vtProp);

            hr = pclsObj->Get(L"DHCPEnabled", 0, &vtProp, 0, 0);
            if ( FAILED( hr ) )
            {
                LOG_ERR( "IWbemClassObject::Getproperty(DHCPEnabled). Error code = 0x%x", hr );
                break;
            }
            adapterSetting.bEnableDHCP = vtProp.boolVal;
            VariantClear(&vtProp);

            hr = pclsObj->Get(L"IPAddress", 0, &vtProp, 0, 0);
            if ( FAILED( hr ) )
            {
                LOG_ERR( "IWbemClassObject::Getproperty(IPAddress). Error code = 0x%x", hr );
                break;
            }
            SAFEARRAY* psa = vtProp.parray;
            if( psa )
            {
                void **p = (void **)psa->pvData;
                wchar_t *wstr = (wchar_t *)*p;
                adapterSetting.strIPAddress = wstr;
            }
            VariantClear(&vtProp);

            hr = pclsObj->Get(L"IPSubnet", 0, &vtProp, 0, 0);
            if ( FAILED( hr ) )
            {
                LOG_ERR( "IWbemClassObject::Getproperty(SubnetMask). Error code = 0x%x", hr );
                break;
            }
            if( psa )
            {
                void **p = (void **)psa->pvData;
                wchar_t *wstr = (wchar_t *)*p;
                adapterSetting.strNetsubMask = wstr;
            }
            VariantClear(&vtProp);

            bOK = true;
        }
        return bOK;
    }

Enable static IP Address

bool UsbReverseTether::enableStaticIPAddress( unsigned int nIfIndex, const std::wstring& strIPAddress, const std::wstring& strNetsubMask )
{
    HRESULT hr = S_OK;
    BSTR MethodName = _bstr_t(L"EnableStatic");
    BSTR ClassName = _bstr_t(L"Win32_NetworkAdapterConfiguration");

    IWbemClassObject* pClass = NULL;
    hr = m_pWbemSvc->GetObject( ClassName, 0, NULL, &pClass, NULL);
    if ( FAILED( hr ) )
    {
        LOG_ERR( "GetObject. Error code = 0x%x", hr );
        return false;
    }
    IWbemClassObject* ppInSignature  = NULL;
    hr = pClass->GetMethod( L"EnableStatic",0, &ppInSignature, NULL );
    if ( FAILED( hr ) )
    {
        LOG_ERR( "GetMethod. Error code = 0x%x", hr );
        return false;
    }

    IWbemClassObject* pInputParaInstance = NULL;
    hr = ppInSignature->SpawnInstance(0, &pInputParaInstance);
    if ( FAILED( hr ) )
    {
        LOG_ERR( "SpawnInstance. Error code = 0x%x", hr );
        return false;
    }

    long aindex[]={0};

    BSTR ipaddress = SysAllocString( strIPAddress.c_str() );
    SAFEARRAY *ip_list = SafeArrayCreateVector(VT_BSTR,0,1);
    SafeArrayPutElement(ip_list,aindex, ipaddress );

    VARIANT varIPAddress;
    varIPAddress.vt =  VT_ARRAY|VT_BSTR;
    varIPAddress.parray = ip_list;
    hr = pInputParaInstance->Put( L"IPAddress", 0, &varIPAddress, 0 );
    if ( FAILED( hr ) )
    {
        LOG_ERR( "Put(IPAddress). Error code = 0x%x", hr );
        SysFreeString( ipaddress );
        return false;
    }
    SAFEARRAY *mask_list = SafeArrayCreateVector(VT_BSTR,0,1);
    BSTR netsubMask = SysAllocString( strNetsubMask.c_str() );
    SafeArrayPutElement(mask_list,aindex, netsubMask );

    VARIANT varSubnetMask;
    varSubnetMask.vt = VT_ARRAY|VT_BSTR;
    varSubnetMask.parray = mask_list;
    hr = pInputParaInstance->Put(L"SubnetMask", 0,
    &varSubnetMask, 0);
    if ( FAILED( hr ) )
    {
        SysFreeString( netsubMask );
        LOG_ERR( "Put(SubnetMask). Error code = 0x%x", hr );
        return false;
    }

    wchar_t className[100] = {0};
    swprintf( className, 100, L"Win32_NetworkAdapterConfiguration.Index=%d", nIfIndex );
    BSTR indexClassName = _bstr_t(className);
    IWbemClassObject* ppOutSignature = NULL;
    hr = m_pWbemSvc->ExecMethod(indexClassName, _bstr_t(L"EnableStatic"), 0,
    NULL, pInputParaInstance, &ppOutSignature, NULL);
    if ( FAILED( hr ) )
    {
        SysFreeString( ipaddress );
        SysFreeString( netsubMask );
        LOG_ERR( "ExecMethod(EnableStatic). Error code = 0x%x", hr );
        return false;
    }
    VARIANT ret_value;
    hr = ppOutSignature->Get(L"ReturnValue", 0, &ret_value, 0, 0);
    int bResult = V_I4(&ret_value);
    SysFreeString( ipaddress );
    SysFreeString( netsubMask );
    return true;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值