以编程方式重命名网络连接失败

时间:2015-07-17 13:01:54

标签: c networking windows-10

我已经编写了一些C ++代码来自动重命名 ncpa.cpl 中的网络连接。它在Win7和Win8上工作正常但在 Win10 中失败。我使用的函数是 INetConnection :: Rename ,它的返回值是 0x80071a90 ,这意味着:

HRESULT_FROM_WIN32( ERROR_TRANSACTIONAL_CONFLICT ):该函数尝试使用保留供其他交易使用的名称。

但我使用的新连接名称类似于“Npcap Loopback Adapter”,它似乎不是Windows的“保留”名称。

有人告诉我,内置的 netsh.exe 工具也使用这种方式重命名界面,我试过命令为“ netsh.exe interface set interface name =”以太网5“newname =”Npcap环回适配器“”和“以太网5”接口已成功重命名为“Npcap环回适配器”。所以我认为这种方式应该可行,我的代码中肯定存在问题。

我想在C / C ++中实现它,所以不要告诉我包装netsh.exe命令,我想知道我的函数调用代码有什么问题?感谢。

我的代码是:

/*++

Copyright (c) Nmap.org.  All rights reserved.

Module Name:

    LoopbackRename.cpp

Abstract:

    This is used for enumerating our "Npcap Loopback Adapter" using NetCfg API, if found, we changed its name from "Ethernet X" to "Npcap Loopback Adapter".
    Also, we need to make a flag in registry to let the Npcap driver know that "this adapter is ours", so send the loopback traffic to it.

This code is modified based on example: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364686.aspx
--*/

#pragma warning(disable: 4311 4312)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <objbase.h>
#include <netcon.h>
#include <stdio.h>

#include "LoopbackRename.h"

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")

#define         NPCAP_LOOPBACK_INTERFACE_NAME           NPF_DRIVER_NAME_NORMAL_WIDECHAR L" Loopback Adapter11"
#define         BUF_SIZE                                255

BOOL DoTheWork(INetSharingManager *pNSM, wchar_t strDeviceName[])
{   // add a port mapping to every firewalled or shared connection 
    BOOL bFound = FALSE;
    INetSharingEveryConnectionCollection * pNSECC = NULL;
    HRESULT hr = pNSM->get_EnumEveryConnection (&pNSECC);
    if (!pNSECC)
        wprintf (L"failed to get EveryConnectionCollection!\r\n");
    else {

        // enumerate connections
        IEnumVARIANT * pEV = NULL;
        IUnknown * pUnk = NULL;
        hr = pNSECC->get__NewEnum (&pUnk);
        if (pUnk) {
            hr = pUnk->QueryInterface (__uuidof(IEnumVARIANT),
                (void**)&pEV);
            pUnk->Release();
        }
        if (pEV) {
            VARIANT v;
            VariantInit (&v);

            while ((S_OK == pEV->Next (1, &v, NULL)) && (bFound == FALSE)) {
                if (V_VT (&v) == VT_UNKNOWN) {
                    INetConnection * pNC = NULL;
                    V_UNKNOWN (&v)->QueryInterface (__uuidof(INetConnection),
                        (void**)&pNC);
                    if (pNC) {
                        NETCON_PROPERTIES *pNETCON_PROPERTIES;
                        pNC->GetProperties(&pNETCON_PROPERTIES);

                        wchar_t currentGUID[BUF_SIZE];
                        GUID guid = pNETCON_PROPERTIES->guidId;
                        wsprintf(currentGUID, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 
                            guid.Data1, guid.Data2, guid.Data3, 
                            guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
                            guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);

                        if (wcscmp(currentGUID, strDeviceName) == 0)
                        {
                            hr = pNC->Rename(NPCAP_LOOPBACK_INTERFACE_NAME);
                            bFound = TRUE;
                            if (hr != S_OK)
                            {
                                wprintf(L"failed to create rename NPCAP_LOOPBACK_INTERFACE_NAME\r\n");
                            }
                        }

                        pNC->Release();
                    }
                }
                VariantClear(&v);
            }
            pEV->Release();
        }
        pNSECC->Release();
    }

    return bFound;
}

BOOL RenameLoopbackNetwork(wchar_t strDeviceName[])
{
    BOOL bResult = FALSE;
/*  CoInitialize (NULL);*/

    // init security to enum RAS connections
    CoInitializeSecurity (NULL, -1, NULL, NULL, 
        RPC_C_AUTHN_LEVEL_PKT, 
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL);

    INetSharingManager * pNSM = NULL;    
    HRESULT hr = ::CoCreateInstance (__uuidof(NetSharingManager),
        NULL,
        CLSCTX_ALL,
        __uuidof(INetSharingManager),
        (void**)&pNSM);
    if (!pNSM)
    {
        wprintf (L"failed to create NetSharingManager object\r\n");
        return bResult;
    }
    else {

        // add a port mapping to every shared or firewalled connection.
        bResult = DoTheWork(pNSM, strDeviceName);

        pNSM->Release();
    }

/*  CoUninitialize ();*/

    return bResult;
}

更新

我在循环中尝试了100次这个函数调用,但都失败了。

if (wcscmp(currentGUID, strDeviceName) == 0)
{
    int iTime = 0;
aaa:
    hr = pNC->Rename(NPCAP_LOOPBACK_INTERFACE_NAME);
    bFound = TRUE;
    if (hr == HRESULT_FROM_WIN32(ERROR_TRANSACTIONAL_CONFLICT) && iTime < 100)
    {
        iTime ++;
        goto aaa;
    }
    else if (hr != S_OK)
    {
        wprintf(L"failed to create rename NPCAP_LOOPBACK_INTERFACE_NAME\r\n");
    }
}

pNC->Release();

代码是github中的开源代码:

https://github.com/nmap/npcap/tree/master/packetWin7/NPFInstall,这是一个 Visual Studio 2005 项目,但实际上您可以在其他Visual Studio版本中构建它。编译完NPFInstall.exe后,使用命令“ NPFInstall.exe -il ”安装新的环回适配器并将其重命名为“Npcap Loopback Adapter”,“ NPFInstall.exe -ul “卸载。重命名适配器的来源是: LoopbackRename.cpp 。我希望这可以帮助解决问题。

0 个答案:

没有答案