Skip to content

Commit

Permalink
[IPCONFIG] Improvements to Release and Renew functions
Browse files Browse the repository at this point in the history
- Reimplement the Release and Renew functions using GetAdaptersInfo().
- Check for enabled DHCP and connected medium
- Check for already released Lease in the Release function
- Add required messages
  • Loading branch information
EricKohl committed Jul 2, 2023
1 parent 12e1919 commit ed80df2
Show file tree
Hide file tree
Showing 21 changed files with 398 additions and 219 deletions.
195 changes: 147 additions & 48 deletions base/applications/network/ipconfig/ipconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,10 @@ PrintAdapterTypeAndName(
}
}

VOID ShowInfo(BOOL bAll)
VOID
ShowInfo(
BOOL bShowHeader,
BOOL bAll)
{
MIB_IFROW mibEntry;
PIP_ADAPTER_INFO pAdapterInfo = NULL;
Expand Down Expand Up @@ -602,7 +605,8 @@ VOID ShowInfo(BOOL bAll)

pAdapter = pAdapterInfo;

ConResPrintf(StdOut, IDS_HEADER);
if (bShowHeader)
ConResPrintf(StdOut, IDS_HEADER);

if (bAll)
{
Expand Down Expand Up @@ -805,120 +809,215 @@ MatchWildcard(
return TRUE;
}

static
VOID
BuildAdapterMap(
PIP_ADAPTER_INDEX_MAP pAdapterMap,
PIP_ADAPTER_INFO pAdapterInfo)
{
int i, l1, l2;

pAdapterMap->Index = pAdapterInfo->Index;

wcscpy(pAdapterMap->Name, L"\\DEVICE\\TCPIP_");
l1 = wcslen(pAdapterMap->Name);
l2 = strlen(pAdapterInfo->AdapterName);
for (i = 0; i < l2; i++)
pAdapterMap->Name[i + l1] = (WCHAR)pAdapterInfo->AdapterName[i];
pAdapterMap->Name[i + l1] = UNICODE_NULL;
}

VOID
Release(
LPWSTR pszAdapterName)
{
IP_ADAPTER_INDEX_MAP AdapterInfo;
DWORD i, ret;
PIP_INTERFACE_INFO pInfo = NULL;
ULONG ulOutBufLen = 0;
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pAdapter = NULL;
ULONG adaptOutBufLen = 0;
ULONG ret = 0;
WCHAR szFriendlyName[MAX_PATH];
MIB_IFROW mibEntry;
IP_ADAPTER_INDEX_MAP AdapterMap;
BOOL bFoundAdapter = FALSE;

ConResPrintf(StdOut, IDS_HEADER);

if (GetInterfaceInfo(pInfo, &ulOutBufLen) != ERROR_INSUFFICIENT_BUFFER)
/* call GetAdaptersInfo to obtain the adapter info */
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
if (ret != ERROR_BUFFER_OVERFLOW)
{
_tprintf(_T("\nGetInterfaceInfo failed : "));
DoFormatMessage(0);
DoFormatMessage(ret);
return;
}

pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
if (pInfo == NULL)
pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
if (pAdapterInfo == NULL)
{
_tprintf(_T("memory allocation error"));
return;
}

if (GetInterfaceInfo(pInfo, &ulOutBufLen) != NO_ERROR)
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
if (ret != NO_ERROR)
{
_tprintf(_T("\nGetInterfaceInfo failed : "));
DoFormatMessage(0);
goto done;
}

for (i = 0; i < pInfo->NumAdapters; i++)
pAdapter = pAdapterInfo;

while (pAdapter)
{
GetInterfaceFriendlyName(pInfo->Adapter[i].Name, MAX_PATH, szFriendlyName);
GetAdapterFriendlyName(pAdapterInfo->AdapterName, MAX_PATH, szFriendlyName);

if ((pszAdapterName == NULL) || MatchWildcard(pszAdapterName, szFriendlyName))
{
/* TODO: Check for enabled DHCP and connected medium */
bFoundAdapter = TRUE;

CopyMemory(&AdapterInfo, &pInfo->Adapter[i], sizeof(IP_ADAPTER_INDEX_MAP));
_tprintf(_T("name - %ls\n"), pInfo->Adapter[i].Name);
mibEntry.dwIndex = pAdapter->Index;
GetIfEntry(&mibEntry);

/* Call IpReleaseAddress to release the IP address on the specified adapter. */
ret = IpReleaseAddress(&AdapterInfo);
if (ret != NO_ERROR)
if (mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
{
if (pAdapter->DhcpEnabled)
{
if (strcmp(pAdapter->IpAddressList.IpAddress.String, "0.0.0.0"))
{
BuildAdapterMap(&AdapterMap, pAdapter);

/* Call IpReleaseAddress to release the IP address on the specified adapter. */
ret = IpReleaseAddress(&AdapterMap);
if (ret != NO_ERROR)
{
_tprintf(_T("\nAn error occured while releasing interface %ls : \n"), szFriendlyName);
DoFormatMessage(ret);
}
}
else
{
ConResPrintf(StdOut, IDS_DHCPRELEASED);
}
}
else
{
ConResPrintf(StdOut, IDS_DHCPNOTENABLED, szFriendlyName);
}
}
else
{
_tprintf(_T("\nAn error occured while releasing interface %ls : \n"), szFriendlyName);
DoFormatMessage(ret);
ConResPrintf(StdOut, IDS_DHCPNOTCONNECTED, szFriendlyName);
}
}

pAdapter = pAdapter->Next;
}

if (bFoundAdapter == FALSE)
{
ConResPrintf(StdOut, IDS_DHCPNOADAPTER);
}
else
{
ShowInfo(FALSE, FALSE);
}

done:
HeapFree(ProcessHeap, 0, pInfo);
if (pAdapterInfo)
HeapFree(ProcessHeap, 0, pAdapterInfo);
}

VOID
Renew(
LPWSTR pszAdapterName)
{
IP_ADAPTER_INDEX_MAP AdapterInfo;
DWORD i, ret;
PIP_INTERFACE_INFO pInfo = NULL;
ULONG ulOutBufLen = 0;
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pAdapter = NULL;
ULONG adaptOutBufLen = 0;
ULONG ret = 0;
WCHAR szFriendlyName[MAX_PATH];
MIB_IFROW mibEntry;
IP_ADAPTER_INDEX_MAP AdapterMap;
BOOL bFoundAdapter = FALSE;

ConResPrintf(StdOut, IDS_HEADER);

if (GetInterfaceInfo(pInfo, &ulOutBufLen) != ERROR_INSUFFICIENT_BUFFER)
/* call GetAdaptersInfo to obtain the adapter info */
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
if (ret != ERROR_BUFFER_OVERFLOW)
{
_tprintf(_T("\nGetInterfaceInfo failed : "));
DoFormatMessage(0);
DoFormatMessage(ret);
return;
}

pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
if (pInfo == NULL)
pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
if (pAdapterInfo == NULL)
{
_tprintf(_T("memory allocation error"));
return;
}

/* Make a second call to GetInterfaceInfo to get the actual data we want */
if (GetInterfaceInfo(pInfo, &ulOutBufLen) != NO_ERROR)
ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
if (ret != NO_ERROR)
{
_tprintf(_T("\nGetInterfaceInfo failed : "));
DoFormatMessage(0);
goto done;
}

for (i = 0; i < pInfo->NumAdapters; i++)
pAdapter = pAdapterInfo;

while (pAdapter)
{
GetInterfaceFriendlyName(pInfo->Adapter[i].Name, MAX_PATH, szFriendlyName);
GetAdapterFriendlyName(pAdapterInfo->AdapterName, MAX_PATH, szFriendlyName);

if ((pszAdapterName == NULL) || MatchWildcard(pszAdapterName, szFriendlyName))
{
/* TODO: Check for enabled DHCP and connected medium */
bFoundAdapter = TRUE;

CopyMemory(&AdapterInfo, &pInfo->Adapter[i], sizeof(IP_ADAPTER_INDEX_MAP));
mibEntry.dwIndex = pAdapter->Index;
GetIfEntry(&mibEntry);

/* Call IpRenewAddress to renew the IP address on the specified adapter. */
ret = IpRenewAddress(&AdapterInfo);
if (ret != NO_ERROR)
if (mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
{
_tprintf(_T("\nAn error occured while renew interface %ls : "), szFriendlyName);
DoFormatMessage(ret);
if (pAdapter->DhcpEnabled)
{
BuildAdapterMap(&AdapterMap, pAdapter);

/* Call IpRenewAddress to renew the IP address on the specified adapter. */
ret = IpRenewAddress(&AdapterMap);
if (ret != NO_ERROR)
{
_tprintf(_T("\nAn error occured while renew interface %ls : "), szFriendlyName);
DoFormatMessage(ret);
}
}
else
{
ConResPrintf(StdOut, IDS_DHCPNOTENABLED, szFriendlyName);
}
}
else
{
ConResPrintf(StdOut, IDS_DHCPNOTCONNECTED, szFriendlyName);
}
}

pAdapter = pAdapter->Next;
}

if (bFoundAdapter == FALSE)
{
ConResPrintf(StdOut, IDS_DHCPNOADAPTER);
}
else
{
ShowInfo(FALSE, FALSE);
}

done:
HeapFree(ProcessHeap, 0, pInfo);
if (pAdapterInfo)
HeapFree(ProcessHeap, 0, pAdapterInfo);
}

VOID
Expand Down Expand Up @@ -1175,13 +1274,13 @@ int wmain(int argc, wchar_t *argv[])
switch (argc)
{
case 1: /* Default behaviour if no options are given*/
ShowInfo(FALSE);
ShowInfo(TRUE, FALSE);
break;
case 2: /* Process all the options that take no parameters */
if (DoUsage)
Usage();
else if (DoAll)
ShowInfo(TRUE);
ShowInfo(TRUE, TRUE);
else if (DoRelease)
Release(NULL);
else if (DoRenew)
Expand Down
22 changes: 13 additions & 9 deletions base/applications/network/ipconfig/lang/bg-BG.rc
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ END

STRINGTABLE
BEGIN
IDS_UNKNOWNADAPTER "\nUnknown Adapter: %ls\n"
IDS_OTHER "\nДруг вид карта: %ls\n"
IDS_ETH "\nКарта Ethernet: %ls\n"
IDS_TOKEN "\nКарта Token Ring: %ls\n"
IDS_FDDI "\nКарта FDDI: %ls\n"
IDS_PPP "\nКарта PPP: %ls\n"
IDS_LOOP "\nКарта Loopback: %ls\n"
IDS_SLIP "\nКарта SLIP: %ls\n"
IDS_WIFI "\nWireless Network Adapter: %ls\n"
IDS_UNKNOWNADAPTER "\nUnknown Adapter: %ls\n\n"
IDS_OTHER "\nДруг вид карта: %ls\n\n"
IDS_ETH "\nКарта Ethernet: %ls\n\n"
IDS_TOKEN "\nКарта Token Ring: %ls\n\n"
IDS_FDDI "\nКарта FDDI: %ls\n\n"
IDS_PPP "\nКарта PPP: %ls\n\n"
IDS_LOOP "\nКарта Loopback: %ls\n\n"
IDS_SLIP "\nКарта SLIP: %ls\n\n"
IDS_WIFI "\nWireless Network Adapter: %ls\n\n"
END

STRINGTABLE
Expand Down Expand Up @@ -85,6 +85,10 @@ BEGIN
IDS_DNSNONAME "\tName does not exist.\n\n"
IDS_DNSFLUSHERROR "Could not flush the DNS Resolver Cache: "
IDS_DNSFLUSHSUCCESS "Successfully flushed the DNS Resolver Cache.\n"
IDS_DHCPNOTCONNECTED "No operation can be performed on %ls while it has its media disconnected.\n"
IDS_DHCPNOTENABLED "Adapter %ls is not enabled for DHCP.\n"
IDS_DHCPNOADAPTER "The operation failed as no adapter is in the state permissible for \nthis operation.\n"
IDS_DHCPRELEASED "IP Address for adapter %ls has already been released.\n"
END

STRINGTABLE
Expand Down
22 changes: 13 additions & 9 deletions base/applications/network/ipconfig/lang/de-DE.rc
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ END

STRINGTABLE
BEGIN
IDS_UNKNOWNADAPTER "\nUnbekannter Adapter: %ls\n"
IDS_OTHER "\nAnderer Adapter: %ls\n"
IDS_ETH "\nEthernet-Adapter: %ls\n"
IDS_TOKEN "\nToken-Ring-Adapter: %ls\n"
IDS_FDDI "\nFDDI-Adapter: %ls\n"
IDS_PPP "\nPPP-Adapter: %ls\n"
IDS_LOOP "\nLoopback-Adapter: %ls\n"
IDS_SLIP "\nSLIP-Adapter: %ls\n"
IDS_WIFI "\nDrahtlos-LAN-Adapter: %ls\n"
IDS_UNKNOWNADAPTER "\nUnbekannter Adapter: %ls\n\n"
IDS_OTHER "\nAnderer Adapter: %ls\n\n"
IDS_ETH "\nEthernet-Adapter: %ls\n\n"
IDS_TOKEN "\nToken-Ring-Adapter: %ls\n\n"
IDS_FDDI "\nFDDI-Adapter: %ls\n\n"
IDS_PPP "\nPPP-Adapter: %ls\n\n"
IDS_LOOP "\nLoopback-Adapter: %ls\n\n"
IDS_SLIP "\nSLIP-Adapter: %ls\n\n"
IDS_WIFI "\nDrahtlos-LAN-Adapter: %ls\n\n"
END

STRINGTABLE
Expand Down Expand Up @@ -87,6 +87,10 @@ BEGIN
IDS_DNSNONAME "\tName existiert nicht.\n\n"
IDS_DNSFLUSHERROR "Der DNS-Auflösungscache konnte nicht geleert werden: "
IDS_DNSFLUSHSUCCESS "Der DNS-Auflösungscache wurde geleert.\n"
IDS_DHCPNOTCONNECTED "Es kann kein Vorgang auf %ls ausgeführt werden, solange dessen Medium nicht verbunden ist.\n"
IDS_DHCPNOTENABLED "Der Adapter %ls ist nicht für DHCP aktiviert.\n"
IDS_DHCPNOADAPTER "Der Vorgang ist fehlgeschlagen, weil kein Adapter sich in einem für diesen\nVorgang zulässigen Zustand befindet.\n"
IDS_DHCPRELEASED "Die IP-Adresse für den Adapter %ls wurde bereits freigegeben.\n"
END

STRINGTABLE
Expand Down
Loading

0 comments on commit ed80df2

Please sign in to comment.