https://git.reactos.org/?p=reactos.git;a=commitdiff;h=edd332c9525b183284277…
commit edd332c9525b18328427784f65eb90e607db5abf
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sat Jul 1 10:28:33 2023 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sat Jul 1 10:28:33 2023 +0200
[IPCONFIG] Implement globbing for the Release and Renew options
- Add a simple Wildcard Matcher.
- Use the Wildcard Matcher in the Release and Renew functions.
---
base/applications/network/ipconfig/ipconfig.c | 277 +++++++++++++++++---------
1 file changed, 178 insertions(+), 99 deletions(-)
diff --git a/base/applications/network/ipconfig/ipconfig.c
b/base/applications/network/ipconfig/ipconfig.c
index d4cdeb7a84c..a3db75726eb 100644
--- a/base/applications/network/ipconfig/ipconfig.c
+++ b/base/applications/network/ipconfig/ipconfig.c
@@ -8,7 +8,6 @@
* TODO:
* fix renew / release
* implement registerdns, showclassid, setclassid
- * allow globbing on adapter names
*/
#define WIN32_NO_STATUS
@@ -225,7 +224,7 @@ VOID
GetAdapterFriendlyName(
_In_ LPSTR lpClass,
_In_ DWORD cchFriendlyNameLength,
- _Out_ PWSTR pszFriendlyName)
+ _Out_ LPWSTR pszFriendlyName)
{
HKEY hKey = NULL;
CHAR Path[256];
@@ -261,6 +260,49 @@ GetAdapterFriendlyName(
RegCloseKey(hKey);
}
+VOID
+GetInterfaceFriendlyName(
+ _In_ LPWSTR lpDeviceName,
+ _In_ DWORD cchFriendlyNameLength,
+ _Out_ LPWSTR pszFriendlyName)
+{
+ HKEY hKey = NULL;
+ WCHAR Path[256];
+ LPWSTR PrePath =
L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
+ LPWSTR PostPath = L"\\Connection";
+ LPWSTR DevicePrefix = L"\\DEVICE\\TCPIP_";
+ DWORD PathSize;
+ DWORD dwType;
+ DWORD dwDataSize;
+
+ DWORD dwPrefixLength = wcslen(DevicePrefix);
+
+ /* don't overflow the buffer */
+ PathSize = wcslen(PrePath) + wcslen(lpDeviceName) - dwPrefixLength + wcslen(PostPath)
+ 1;
+ if (PathSize >= 255)
+ return;
+
+ swprintf(Path, L"%s%s%s", PrePath, &lpDeviceName[dwPrefixLength],
PostPath);
+
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ Path,
+ 0,
+ KEY_READ,
+ &hKey) == ERROR_SUCCESS)
+ {
+ dwDataSize = cchFriendlyNameLength * sizeof(WCHAR);
+ RegQueryValueExW(hKey,
+ L"Name",
+ NULL,
+ &dwType,
+ (PBYTE)pszFriendlyName,
+ &dwDataSize);
+ }
+
+ if (hKey != NULL)
+ RegCloseKey(hKey);
+}
+
static
VOID
PrintAdapterDescription(LPSTR lpClass)
@@ -716,129 +758,167 @@ done:
HeapFree(ProcessHeap, 0, pAdapterInfo);
}
-VOID Release(LPTSTR Index)
+static
+BOOL
+MatchWildcard(
+ _In_ PWSTR pszExpression,
+ _In_ PWSTR pszName)
{
- IP_ADAPTER_INDEX_MAP AdapterInfo;
- DWORD ret;
- DWORD i;
+ WCHAR *pCharE, *pCharN, charE, charN;
- /* if interface is not given, query GetInterfaceInfo */
- if (Index == NULL)
- {
- PIP_INTERFACE_INFO pInfo = NULL;
- ULONG ulOutBufLen = 0;
+ if (pszExpression == NULL)
+ return TRUE;
- if (GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
- {
- pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
- if (pInfo == NULL)
- return;
+ if (pszName == NULL)
+ return FALSE;
- if (GetInterfaceInfo(pInfo, &ulOutBufLen) == NO_ERROR )
- {
- for (i = 0; i < pInfo->NumAdapters; i++)
- {
- CopyMemory(&AdapterInfo, &pInfo->Adapter[i],
sizeof(IP_ADAPTER_INDEX_MAP));
- _tprintf(_T("name - %ls\n"), pInfo->Adapter[i].Name);
-
- /* Call IpReleaseAddress to release the IP address on the specified
adapter. */
- if ((ret = IpReleaseAddress(&AdapterInfo)) != NO_ERROR)
- {
- _tprintf(_T("\nAn error occured while releasing interface
%ls : \n"), AdapterInfo.Name);
- DoFormatMessage(ret);
- }
- }
+ pCharE = pszExpression;
+ pCharN = pszName;
+ while (*pCharE != UNICODE_NULL)
+ {
+ charE = towlower(*pCharE);
+ charN = towlower(*pCharN);
- HeapFree(ProcessHeap, 0, pInfo);
- }
+ if (charE == L'*')
+ {
+ if (*(pCharE + 1) != charN)
+ pCharN++;
else
- {
- DoFormatMessage(0);
- HeapFree(ProcessHeap, 0, pInfo);
- return;
- }
+ pCharE++;
+ }
+ else if (charE == L'?')
+ {
+ pCharE++;
+ pCharN++;
+ }
+ else if (charE == charN)
+ {
+ pCharE++;
+ pCharN++;
}
else
{
- DoFormatMessage(0);
- return;
+ return FALSE;
}
}
- else
- {
- ;
- /* FIXME:
- * we need to be able to release connections by name with support for globbing
- * i.e. ipconfig /release Eth* will release all cards starting with Eth...
- * ipconfig /release *con* will release all cards with 'con' in
their name
- */
- }
+
+ return TRUE;
}
-VOID Renew(LPTSTR Index)
+VOID
+Release(
+ LPWSTR pszAdapterName)
{
IP_ADAPTER_INDEX_MAP AdapterInfo;
- DWORD i;
+ DWORD i, ret;
+ PIP_INTERFACE_INFO pInfo = NULL;
+ ULONG ulOutBufLen = 0;
+ WCHAR szFriendlyName[MAX_PATH];
+
+ ConResPrintf(StdOut, IDS_HEADER);
- /* if interface is not given, query GetInterfaceInfo */
- if (Index == NULL)
+ if (GetInterfaceInfo(pInfo, &ulOutBufLen) != ERROR_INSUFFICIENT_BUFFER)
{
- PIP_INTERFACE_INFO pInfo;
- ULONG ulOutBufLen = 0;
+ _tprintf(_T("\nGetInterfaceInfo failed : "));
+ DoFormatMessage(0);
+ return;
+ }
- pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0,
sizeof(IP_INTERFACE_INFO));
- if (pInfo == NULL)
- {
- _tprintf(_T("memory allocation error"));
- return;
- }
+ pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
+ if (pInfo == NULL)
+ {
+ _tprintf(_T("memory allocation error"));
+ return;
+ }
+
+ if (GetInterfaceInfo(pInfo, &ulOutBufLen) != NO_ERROR)
+ {
+ _tprintf(_T("\nGetInterfaceInfo failed : "));
+ DoFormatMessage(0);
+ goto done;
+ }
+
+ for (i = 0; i < pInfo->NumAdapters; i++)
+ {
+ GetInterfaceFriendlyName(pInfo->Adapter[i].Name, MAX_PATH, szFriendlyName);
- /* Make an initial call to GetInterfaceInfo to get
- * the necessary size into the ulOutBufLen variable */
- if (GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
+ if ((pszAdapterName == NULL) || MatchWildcard(pszAdapterName, szFriendlyName))
{
- HeapFree(ProcessHeap, 0, pInfo);
- pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
- if (pInfo == NULL)
+ /* TODO: Check for enabled DHCP and connected medium */
+
+ CopyMemory(&AdapterInfo, &pInfo->Adapter[i],
sizeof(IP_ADAPTER_INDEX_MAP));
+ _tprintf(_T("name - %ls\n"), pInfo->Adapter[i].Name);
+
+ /* Call IpReleaseAddress to release the IP address on the specified adapter.
*/
+ ret = IpReleaseAddress(&AdapterInfo);
+ if (ret != NO_ERROR)
{
- _tprintf(_T("memory allocation error"));
- return;
+ _tprintf(_T("\nAn error occured while releasing interface %ls :
\n"), szFriendlyName);
+ DoFormatMessage(ret);
}
}
+ }
- /* Make a second call to GetInterfaceInfo to get the actual data we want */
- if (GetInterfaceInfo(pInfo, &ulOutBufLen) == NO_ERROR)
- {
- for (i = 0; i < pInfo->NumAdapters; i++)
- {
- CopyMemory(&AdapterInfo, &pInfo->Adapter[i],
sizeof(IP_ADAPTER_INDEX_MAP));
- _tprintf(_T("name - %ls\n"), pInfo->Adapter[i].Name);
+done:
+ HeapFree(ProcessHeap, 0, pInfo);
+}
- /* Call IpRenewAddress to renew the IP address on the specified adapter.
*/
- if (IpRenewAddress(&AdapterInfo) != NO_ERROR)
- {
- _tprintf(_T("\nAn error occured while renew interface %s :
"), _T("*name*"));
- DoFormatMessage(0);
- }
- }
- }
- else
- {
- _tprintf(_T("\nGetInterfaceInfo failed : "));
- DoFormatMessage(0);
- }
+VOID
+Renew(
+ LPWSTR pszAdapterName)
+{
+ IP_ADAPTER_INDEX_MAP AdapterInfo;
+ DWORD i, ret;
+ PIP_INTERFACE_INFO pInfo = NULL;
+ ULONG ulOutBufLen = 0;
+ WCHAR szFriendlyName[MAX_PATH];
- HeapFree(ProcessHeap, 0, pInfo);
+ ConResPrintf(StdOut, IDS_HEADER);
+
+ if (GetInterfaceInfo(pInfo, &ulOutBufLen) != ERROR_INSUFFICIENT_BUFFER)
+ {
+ _tprintf(_T("\nGetInterfaceInfo failed : "));
+ DoFormatMessage(0);
+ return;
}
- else
+
+ pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
+ if (pInfo == NULL)
{
- ;
- /* FIXME:
- * we need to be able to renew connections by name with support for globbing
- * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
- * ipconfig /renew *con* will renew all cards with 'con' in their
name
- */
+ _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)
+ {
+ _tprintf(_T("\nGetInterfaceInfo failed : "));
+ DoFormatMessage(0);
+ goto done;
+ }
+
+ for (i = 0; i < pInfo->NumAdapters; i++)
+ {
+ GetInterfaceFriendlyName(pInfo->Adapter[i].Name, MAX_PATH, szFriendlyName);
+
+ if ((pszAdapterName == NULL) || MatchWildcard(pszAdapterName, szFriendlyName))
+ {
+ /* TODO: Check for enabled DHCP and connected medium */
+
+ CopyMemory(&AdapterInfo, &pInfo->Adapter[i],
sizeof(IP_ADAPTER_INDEX_MAP));
+
+ /* Call IpRenewAddress to renew the IP address on the specified adapter. */
+ ret = IpRenewAddress(&AdapterInfo);
+ if (ret != NO_ERROR)
+ {
+ _tprintf(_T("\nAn error occured while renew interface %ls : "),
szFriendlyName);
+ DoFormatMessage(ret);
+ }
+ }
+ }
+
+done:
+ HeapFree(ProcessHeap, 0, pInfo);
}
VOID
@@ -1112,10 +1192,9 @@ int wmain(int argc, wchar_t *argv[])
break;
case 3: /* Process all the options that can have 1 parameter */
if (DoRelease)
- _tprintf(_T("\nSorry /release [adapter] is not implemented
yet\n"));
- //Release(argv[2]);
+ Release(argv[2]);
else if (DoRenew)
- _tprintf(_T("\nSorry /renew [adapter] is not implemented
yet\n"));
+ Renew(argv[2]);
else if (DoShowclassid)
_tprintf(_T("\nSorry /showclassid adapter is not implemented
yet\n"));
else if (DoSetclassid)