我编写了一些 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="Ethernet 5" newname="Npcap Loopback Adapter" ”接口“Ethernet 5”成功重命名为“Npcap Loopback Adapter”。所以我认为这种方式应该可行,我的代码一定有问题。
我想用 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。我希望这可以帮助解决问题。