https://git.reactos.org/?p=reactos.git;a=commitdiff;h=edd332c9525b18328427784f65eb90e607db5abf

commit edd332c9525b18328427784f65eb90e607db5abf
Author:     Eric Kohl <[email protected]>
AuthorDate: Sat Jul 1 10:28:33 2023 +0200
Commit:     Eric Kohl <[email protected]>
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)

Reply via email to