[IFMON] Add SetInterfaceProperties() stub and use it in IpSetAddress

- Also move GetInterfaceProperties() around.
- Add required error messages.
This commit is contained in:
Eric Kohl
2026-06-07 23:16:18 +02:00
parent 3b58b347bc
commit 823647a38b
3 changed files with 289 additions and 218 deletions
+285 -218
View File
@@ -52,224 +52,6 @@ IpGroups[] =
};
static
DWORD
WINAPI
IpSetAddress(
LPCWSTR pwszMachine,
LPWSTR *argv,
DWORD dwCurrentIndex,
DWORD dwArgCount,
DWORD dwFlags,
LPCVOID pvData,
BOOL *pbDone)
{
TAG_TYPE pttTags[] = {{L"name", NS_REQ_ZERO, FALSE},
{L"source", NS_REQ_ZERO, FALSE},
{L"addr", NS_REQ_ZERO, FALSE},
{L"mask", NS_REQ_ZERO, FALSE},
{L"gateway", NS_REQ_ZERO, FALSE},
{L"gwmetric", NS_REQ_ZERO, FALSE}};
TOKEN_VALUE ptvSource[] = {{L"static", 1},
{L"dhcp", 2}};
GUID InterfaceGUID;
PDWORD pdwTagType = NULL;
DWORD i, dwSource = 0;
BOOL bHaveName = FALSE, bHaveSource = FALSE, bHaveAddress = FALSE,
bHaveMask = FALSE, bHaveGateway = FALSE, bHaveMetric = FALSE;
IN_ADDR Address, Mask, Gateway;
DWORD dwMetric;
PCWSTR Term;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
DPRINT1("IpSetAddress()\n");
pdwTagType = HeapAlloc(GetProcessHeap(),
0,
(dwArgCount - dwCurrentIndex) * sizeof(DWORD));
if (pdwTagType == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
dwError = MatchTagsInCmdLine(hDllInstance,
argv,
dwCurrentIndex,
dwArgCount,
pttTags,
ARRAYSIZE(pttTags),
pdwTagType);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("MatchTagsInCmdLine() failed (Error %lu)\n", dwError);
HeapFree(GetProcessHeap(), 0, pdwTagType);
return dwError;
}
for (i = 0; i < (dwArgCount - dwCurrentIndex); i++)
{
DPRINT1("Tag %lu: %lu\n", i, pdwTagType[i]);
switch (pdwTagType[i])
{
case 0: /* name */
DPRINT1("Tag: name (%S)\n", argv[i + dwCurrentIndex]);
dwError = NhGetGuidFromInterfaceName(argv[i + dwCurrentIndex],
&InterfaceGUID,
0, 0);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("NhGetGuidFromInterfaceName() failed (Error %lu)\n", dwError);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_INVALID_INTERFACE,
argv[i + dwCurrentIndex]);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("Interface: {%08lx-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
InterfaceGUID.Data1, InterfaceGUID.Data2, InterfaceGUID.Data3, InterfaceGUID.Data4[0], InterfaceGUID.Data4[1],
InterfaceGUID.Data4[2], InterfaceGUID.Data4[3], InterfaceGUID.Data4[4], InterfaceGUID.Data4[5], InterfaceGUID.Data4[6], InterfaceGUID.Data4[7]);
bHaveName = TRUE;
break;
case 1: /* source */
DPRINT1("Tag: source (%S)\n", argv[i + dwCurrentIndex]);
dwError = MatchEnumTag(hDllInstance,
argv[i + dwCurrentIndex],
ARRAYSIZE(ptvSource),
ptvSource,
&dwSource);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("MatchEnumTag() failed (Error %lu)\n", dwError);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("Source: %lu\n", dwSource);
bHaveSource = TRUE;
break;
case 2: /* addr */
DPRINT1("Tag: addr (%S)\n", argv[i + dwCurrentIndex]);
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
TRUE,
&Term,
&Address);
if (Status != 0 /*STATUS_SUCCESS*/)
{
DPRINT1("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("IP Address: %u.%u.%u.%u\n",
Address.S_un.S_un_b.s_b1, Address.S_un.S_un_b.s_b2, Address.S_un.S_un_b.s_b3, Address.S_un.S_un_b.s_b4);
bHaveAddress = TRUE;
break;
case 3: /* mask */
DPRINT1("Tag: mask (%S)\n", argv[i + dwCurrentIndex]);
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
TRUE,
&Term,
&Mask);
if (Status != 0 /*STATUS_SUCCESS*/)
{
DPRINT1("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("Subnet Mask: %u.%u.%u.%u\n",
Mask.S_un.S_un_b.s_b1, Mask.S_un.S_un_b.s_b2, Mask.S_un.S_un_b.s_b3, Mask.S_un.S_un_b.s_b4);
bHaveMask = TRUE;
break;
case 4: /* gateway */
DPRINT1("Tag: gateway (%S)\n", argv[i + dwCurrentIndex]);
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
TRUE,
&Term,
&Gateway);
if (Status != 0 /*STATUS_SUCCESS*/)
{
DPRINT1("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("Gateway: %u.%u.%u.%u\n",
Gateway.S_un.S_un_b.s_b1, Gateway.S_un.S_un_b.s_b2, Gateway.S_un.S_un_b.s_b3, Gateway.S_un.S_un_b.s_b4);
bHaveGateway = TRUE;
break;
case 5: /* gwmetric */
DPRINT1("Tag: gwmetric (%S)\n", argv[i + dwCurrentIndex]);
dwMetric = wcstoul(argv[i + dwCurrentIndex],
(wchar_t**)&Term,
10);
if (dwMetric > 9999)
{
dwError = ERROR_INVALID_PARAMETER;
break;
}
DPRINT1("Metric: %lu\n", dwMetric);
bHaveMetric = TRUE;
break;
default:
DPRINT1("Unknown tag type %lu\n", pdwTagType[i]);
break;
}
}
if (pdwTagType)
HeapFree(GetProcessHeap(), 0, pdwTagType);
if (dwError != ERROR_SUCCESS)
return dwError;
/* Check parameters */
/* The interface name is mandatory */
if (bHaveName == FALSE)
return ERROR_INVALID_SYNTAX;
if (bHaveSource)
{
if ((dwSource == 1) &&
(!bHaveAddress || !bHaveMask))
return ERROR_INVALID_SYNTAX;
if ((dwSource == 2) &&
(bHaveAddress || bHaveMask))
return ERROR_INVALID_SYNTAX;
}
if ((bHaveGateway && !bHaveMetric) ||
(!bHaveGateway && bHaveMetric))
return ERROR_INVALID_SYNTAX;
DPRINT1("IpSetAddress() done (Error %lu)\n", dwError);
return dwError;
}
static
HRESULT
GetInterfaceProperties(
@@ -420,6 +202,25 @@ exit:
}
static
HRESULT
SetInterfaceProperties(
GUID *InterfaceGuid,
PTCPIP_PROPERTIES pProperties)
{
DPRINT1("SetInterfaceProperties()\n");
DPRINT1("dwDhcp: %lx\n", pProperties->dwDhcp);
DPRINT1("IpAddress: %S\n", pProperties->pszIpAddress);
DPRINT1("SubnetMask: %S\n", pProperties->pszSubnetMask);
DPRINT1("Parameters: %S\n", pProperties->pszParameters);
DPRINT1("SetInterfaceProperties() done!\n");
return S_OK;
}
static
PWSTR
ExtractParameterValue(
@@ -457,6 +258,272 @@ ExtractParameterValue(
}
static
DWORD
WINAPI
IpSetAddress(
LPCWSTR pwszMachine,
LPWSTR *argv,
DWORD dwCurrentIndex,
DWORD dwArgCount,
DWORD dwFlags,
LPCVOID pvData,
BOOL *pbDone)
{
TAG_TYPE pttTags[] = {{L"name", NS_REQ_ZERO, FALSE},
{L"source", NS_REQ_ZERO, FALSE},
{L"addr", NS_REQ_ZERO, FALSE},
{L"mask", NS_REQ_ZERO, FALSE},
{L"gateway", NS_REQ_ZERO, FALSE},
{L"gwmetric", NS_REQ_ZERO, FALSE}};
TOKEN_VALUE ptvSource[] = {{L"static", 1},
{L"dhcp", 2}};
GUID InterfaceGUID;
PDWORD pdwTagType = NULL;
DWORD i, dwSource = 0;
BOOL bHaveName = FALSE, bHaveSource = FALSE, bHaveAddress = FALSE,
bHaveMask = FALSE, bHaveGateway = FALSE, bHaveMetric = FALSE;
IN_ADDR Address, Mask, Gateway;
PWSTR pszName = NULL, pszAddress = NULL, pszMask = NULL;
DWORD dwMetric;
PCWSTR Term;
PTCPIP_PROPERTIES pProperties = NULL;
TCPIP_PROPERTIES NewProperties;
HRESULT hr;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
DPRINT1("IpSetAddress()\n");
pdwTagType = HeapAlloc(GetProcessHeap(),
0,
(dwArgCount - dwCurrentIndex) * sizeof(DWORD));
if (pdwTagType == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
dwError = MatchTagsInCmdLine(hDllInstance,
argv,
dwCurrentIndex,
dwArgCount,
pttTags,
ARRAYSIZE(pttTags),
pdwTagType);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("MatchTagsInCmdLine() failed (Error %lu)\n", dwError);
HeapFree(GetProcessHeap(), 0, pdwTagType);
return dwError;
}
for (i = 0; i < (dwArgCount - dwCurrentIndex); i++)
{
DPRINT1("Tag %lu: %lu\n", i, pdwTagType[i]);
switch (pdwTagType[i])
{
case 0: /* name */
DPRINT1("Tag: name (%S)\n", argv[i + dwCurrentIndex]);
dwError = NhGetGuidFromInterfaceName(argv[i + dwCurrentIndex],
&InterfaceGUID,
0, 0);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("NhGetGuidFromInterfaceName() failed (Error %lu)\n", dwError);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_INVALID_INTERFACE,
argv[i + dwCurrentIndex]);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
pszName = argv[i + dwCurrentIndex];
DPRINT1("Interface: {%08lx-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
InterfaceGUID.Data1, InterfaceGUID.Data2, InterfaceGUID.Data3, InterfaceGUID.Data4[0], InterfaceGUID.Data4[1],
InterfaceGUID.Data4[2], InterfaceGUID.Data4[3], InterfaceGUID.Data4[4], InterfaceGUID.Data4[5], InterfaceGUID.Data4[6], InterfaceGUID.Data4[7]);
bHaveName = TRUE;
break;
case 1: /* source */
DPRINT1("Tag: source (%S)\n", argv[i + dwCurrentIndex]);
dwError = MatchEnumTag(hDllInstance,
argv[i + dwCurrentIndex],
ARRAYSIZE(ptvSource),
ptvSource,
&dwSource);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("MatchEnumTag() failed (Error %lu)\n", dwError);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("Source: %lu\n", dwSource);
bHaveSource = TRUE;
break;
case 2: /* addr */
DPRINT1("Tag: addr (%S)\n", argv[i + dwCurrentIndex]);
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
TRUE,
&Term,
&Address);
if (Status != 0 /*STATUS_SUCCESS*/)
{
DPRINT1("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("IP Address: %u.%u.%u.%u\n",
Address.S_un.S_un_b.s_b1, Address.S_un.S_un_b.s_b2, Address.S_un.S_un_b.s_b3, Address.S_un.S_un_b.s_b4);
pszAddress = argv[i + dwCurrentIndex];
DPRINT1("IP Address: %S\n", pszAddress);
bHaveAddress = TRUE;
break;
case 3: /* mask */
DPRINT1("Tag: mask (%S)\n", argv[i + dwCurrentIndex]);
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
TRUE,
&Term,
&Mask);
if (Status != 0 /*STATUS_SUCCESS*/)
{
DPRINT1("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("Subnet Mask: %u.%u.%u.%u\n",
Mask.S_un.S_un_b.s_b1, Mask.S_un.S_un_b.s_b2, Mask.S_un.S_un_b.s_b3, Mask.S_un.S_un_b.s_b4);
pszMask = argv[i + dwCurrentIndex];
DPRINT1("Subnat Mask: %S\n", pszMask);
bHaveMask = TRUE;
break;
case 4: /* gateway */
DPRINT1("Tag: gateway (%S)\n", argv[i + dwCurrentIndex]);
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
TRUE,
&Term,
&Gateway);
if (Status != 0 /*STATUS_SUCCESS*/)
{
DPRINT1("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
PrintMessageFromModule(hDllInstance,
IDS_ERROR_BAD_VALUE,
argv[i + dwCurrentIndex],
pttTags[pdwTagType[i]].pwszTag);
dwError = ERROR_SUPPRESS_OUTPUT;
break;
}
DPRINT1("Gateway: %u.%u.%u.%u\n",
Gateway.S_un.S_un_b.s_b1, Gateway.S_un.S_un_b.s_b2, Gateway.S_un.S_un_b.s_b3, Gateway.S_un.S_un_b.s_b4);
bHaveGateway = TRUE;
break;
case 5: /* gwmetric */
DPRINT1("Tag: gwmetric (%S)\n", argv[i + dwCurrentIndex]);
dwMetric = wcstoul(argv[i + dwCurrentIndex],
(wchar_t**)&Term,
10);
if (dwMetric > 9999)
{
dwError = ERROR_INVALID_PARAMETER;
break;
}
DPRINT1("Metric: %lu\n", dwMetric);
bHaveMetric = TRUE;
break;
default:
DPRINT1("Unknown tag type %lu\n", pdwTagType[i]);
break;
}
}
if (pdwTagType)
HeapFree(GetProcessHeap(), 0, pdwTagType);
if (dwError != ERROR_SUCCESS)
return dwError;
/* Check parameters */
/* The interface name is mandatory */
if (bHaveName == FALSE)
return ERROR_INVALID_SYNTAX;
if (bHaveSource)
{
if ((dwSource == 1) &&
(!bHaveAddress || !bHaveMask))
return ERROR_INVALID_SYNTAX;
if ((dwSource == 2) &&
(bHaveAddress || bHaveMask))
return ERROR_INVALID_SYNTAX;
}
if ((bHaveGateway && !bHaveMetric) ||
(!bHaveGateway && bHaveMetric))
return ERROR_INVALID_SYNTAX;
hr = GetInterfaceProperties(&InterfaceGUID, &pProperties);
if (FAILED(hr))
{
PrintMessageFromModule(hDllInstance,
IDS_ERROR_GET_PROPERTIES,
pszName);
return ERROR_SUPPRESS_OUTPUT;
}
if (dwSource == 1)
{
/* STATIC */
NewProperties.dwDhcp = 0;
NewProperties.pszIpAddress = pszAddress;
NewProperties.pszSubnetMask = pszMask;
// NewProperties.pszParameters =
}
else if (dwSource == 2)
{
/* DHCP */
if (pProperties->dwDhcp)
{
PrintMessageFromModule(hDllInstance,
IDS_ERROR_ALREADY_DHCP);
dwError = ERROR_SUPPRESS_OUTPUT;
goto done;
}
NewProperties.dwDhcp = 1;
NewProperties.pszIpAddress = NULL;
NewProperties.pszSubnetMask = NULL;
// NewProperties.pszParameters =
}
SetInterfaceProperties(&InterfaceGUID, &NewProperties);
done:
CoTaskMemFree(pProperties);
pProperties = NULL;
DPRINT1("IpSetAddress() done (Error %lu)\n", dwError);
return dwError;
}
static
DWORD
IpShowAdapters(
+2
View File
@@ -96,4 +96,6 @@ Parameters:\n\n\
IDS_ERROR_INVALID_INTERFACE "\nInvalid interface %s specified.\n"
IDS_ERROR_BAD_VALUE "\n%s is not an acceptable value for %s.\n"
IDS_ERROR_ALREADY_DHCP "\nDhcp is already enabled on this interface.\n"
IDS_ERROR_GET_PROPERTIES "\nError obtaining configuration for interface %s.\n"
END
+2
View File
@@ -47,3 +47,5 @@
#define IDS_ERROR_INVALID_INTERFACE 2000
#define IDS_ERROR_BAD_VALUE 2001
#define IDS_ERROR_ALREADY_DHCP 2002
#define IDS_ERROR_GET_PROPERTIES 2003