From ea189a3048c6864237dbd7e9cbf7fa1c0be121c1 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 20 Jul 2025 13:58:13 +0200 Subject: [PATCH] [IPCONFIG] Implement the /setclassid option The current implementation does not notify the dhcp client of the changed registry setting. Windows IPCONFIG calls DhcpHandlePnpEvent after setting the DhcpClassId registry value. --- base/applications/network/ipconfig/ipconfig.c | 111 +++++++++++++++++- .../network/ipconfig/lang/bg-BG.rc | 2 + .../network/ipconfig/lang/de-DE.rc | 2 + .../network/ipconfig/lang/el-GR.rc | 2 + .../network/ipconfig/lang/en-US.rc | 2 + .../network/ipconfig/lang/es-ES.rc | 2 + .../network/ipconfig/lang/fr-FR.rc | 2 + .../network/ipconfig/lang/id-ID.rc | 2 + .../network/ipconfig/lang/it-IT.rc | 2 + .../network/ipconfig/lang/ja-JP.rc | 2 + .../network/ipconfig/lang/no-NO.rc | 2 + .../network/ipconfig/lang/pl-PL.rc | 2 + .../network/ipconfig/lang/ro-RO.rc | 2 + .../network/ipconfig/lang/ru-RU.rc | 2 + .../network/ipconfig/lang/sk-SK.rc | 2 + .../network/ipconfig/lang/sq-AL.rc | 2 + .../network/ipconfig/lang/sv-SE.rc | 2 + .../network/ipconfig/lang/tr-TR.rc | 2 + .../network/ipconfig/lang/uk-UA.rc | 2 + .../network/ipconfig/lang/zh-CN.rc | 2 + .../network/ipconfig/lang/zh-TW.rc | 2 + base/applications/network/ipconfig/resource.h | 2 + 22 files changed, 149 insertions(+), 4 deletions(-) diff --git a/base/applications/network/ipconfig/ipconfig.c b/base/applications/network/ipconfig/ipconfig.c index 6993634616f..a4dbbc54ad6 100644 --- a/base/applications/network/ipconfig/ipconfig.c +++ b/base/applications/network/ipconfig/ipconfig.c @@ -1228,7 +1228,110 @@ DisplayDns(VOID) } } -VOID Usage(VOID) +VOID +ShowClassId( + LPWSTR pszAdapterName) +{ + _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n")); +} + +VOID +SetClassId( + LPWSTR pszAdapterName, + LPWSTR pszClassId) +{ + PIP_ADAPTER_INFO pAdapterInfo = NULL; + PIP_ADAPTER_INFO pAdapter = NULL, pFoundAdapter = NULL; + ULONG adaptOutBufLen = 0; + ULONG ret = 0; + WCHAR szFriendlyName[MAX_PATH]; + WCHAR szKeyName[256]; + MIB_IFROW mibEntry; + HKEY hKey; + + ConResPrintf(StdOut, IDS_HEADER); + + /* call GetAdaptersInfo to obtain the adapter info */ + ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen); + if (ret != ERROR_BUFFER_OVERFLOW) + { + DoFormatMessage(ret); + return; + } + + pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen); + if (pAdapterInfo == NULL) + { + _tprintf(_T("memory allocation error")); + return; + } + + ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen); + if (ret != NO_ERROR) + { + DoFormatMessage(0); + goto done; + } + + pAdapter = pAdapterInfo; + while (pAdapter) + { + GetAdapterFriendlyName(pAdapter->AdapterName, MAX_PATH, szFriendlyName); + + if (MatchWildcard(pszAdapterName, szFriendlyName)) + { + mibEntry.dwIndex = pAdapter->Index; + GetIfEntry(&mibEntry); + + if (mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || + mibEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL) + { + pFoundAdapter = pAdapter; + break; + } + } + + pAdapter = pAdapter->Next; + } + + if (pFoundAdapter) + { + swprintf(szKeyName, + L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%S", + pFoundAdapter->AdapterName); + + ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + szKeyName, + 0, + KEY_WRITE, + &hKey); + if (ret != ERROR_SUCCESS) + { + ConResPrintf(StdOut, IDS_DHCPSETIDERROR, szFriendlyName); + DoFormatMessage(ret); + goto done; + } + + if (pszClassId == NULL) + pszClassId = L""; + + RegSetValueExW(hKey, L"DhcpClassId", 0, REG_SZ, (LPBYTE)pszClassId, (wcslen(pszClassId) + 1) * sizeof(WCHAR)); + RegCloseKey(hKey); + + ConResPrintf(StdOut, IDS_DHCPSETIDSUCCESS, szFriendlyName); + } + else + { + ConResPrintf(StdOut, IDS_DHCPNOADAPTER); + } + +done: + if (pAdapterInfo) + HeapFree(ProcessHeap, 0, pAdapterInfo); +} + +VOID +Usage(VOID) { ConResPrintf(StdOut, IDS_USAGE); } @@ -1321,15 +1424,15 @@ int wmain(int argc, wchar_t *argv[]) else if (DoRenew) Renew(argv[2]); else if (DoShowclassid) - _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n")); + ShowClassId(argv[2]); else if (DoSetclassid) - _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n")); + SetClassId(argv[2], NULL); else Usage(); break; case 4: /* Process all the options that can have 2 parameters */ if (DoSetclassid) - _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n")); + SetClassId(argv[2], argv[3]); else Usage(); break; diff --git a/base/applications/network/ipconfig/lang/bg-BG.rc b/base/applications/network/ipconfig/lang/bg-BG.rc index d49d87fe15c..00f74bc580a 100644 --- a/base/applications/network/ipconfig/lang/bg-BG.rc +++ b/base/applications/network/ipconfig/lang/bg-BG.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/de-DE.rc b/base/applications/network/ipconfig/lang/de-DE.rc index 1643c84ef32..dfa925fb59b 100644 --- a/base/applications/network/ipconfig/lang/de-DE.rc +++ b/base/applications/network/ipconfig/lang/de-DE.rc @@ -93,6 +93,8 @@ BEGIN IDS_DHCPRELEASED "Die IP-Adresse für den Adapter %ls wurde bereits freigegeben.\n" IDS_DHCPRELEASEERROR "Beim Freigeben der Schnittstelle %ls ist folgender Fehler aufgetreten: " IDS_DHCPRENEWERROR "Beim Aktualisieren der Schnittstelle %ls ist folgender Fehler aufgetreten: " + IDS_DHCPSETIDERROR "Fehler beim Festlegen der Klassenkennung für Adapter %ls: " + IDS_DHCPSETIDSUCCESS "Klassenkennung für Adapter %ls festgelegt." END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/el-GR.rc b/base/applications/network/ipconfig/lang/el-GR.rc index 6f40182c569..c8a150acf23 100644 --- a/base/applications/network/ipconfig/lang/el-GR.rc +++ b/base/applications/network/ipconfig/lang/el-GR.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/en-US.rc b/base/applications/network/ipconfig/lang/en-US.rc index e83bc2d31e1..093fc8e5c95 100644 --- a/base/applications/network/ipconfig/lang/en-US.rc +++ b/base/applications/network/ipconfig/lang/en-US.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/es-ES.rc b/base/applications/network/ipconfig/lang/es-ES.rc index f4fa84a78a6..4b9d5d606eb 100644 --- a/base/applications/network/ipconfig/lang/es-ES.rc +++ b/base/applications/network/ipconfig/lang/es-ES.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/fr-FR.rc b/base/applications/network/ipconfig/lang/fr-FR.rc index 156d9946cc2..50c962b1461 100644 --- a/base/applications/network/ipconfig/lang/fr-FR.rc +++ b/base/applications/network/ipconfig/lang/fr-FR.rc @@ -94,6 +94,8 @@ BEGIN IDS_DHCPRELEASED "L'adresse IP de l'adaptateur %ls a déjà été libérée.\n" IDS_DHCPRELEASEERROR "Une erreur est survenue lors de la libération de l'interface %ls : " IDS_DHCPRENEWERROR "Une erreur est survenue lors du renouvellement de l'interface %ls : " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/id-ID.rc b/base/applications/network/ipconfig/lang/id-ID.rc index 341b8b45382..2ab47ae240c 100644 --- a/base/applications/network/ipconfig/lang/id-ID.rc +++ b/base/applications/network/ipconfig/lang/id-ID.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/it-IT.rc b/base/applications/network/ipconfig/lang/it-IT.rc index fe5d31775d0..5c2cd2a5ef1 100644 --- a/base/applications/network/ipconfig/lang/it-IT.rc +++ b/base/applications/network/ipconfig/lang/it-IT.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/ja-JP.rc b/base/applications/network/ipconfig/lang/ja-JP.rc index b1e1a6f8071..8b36a72ceb9 100644 --- a/base/applications/network/ipconfig/lang/ja-JP.rc +++ b/base/applications/network/ipconfig/lang/ja-JP.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "アダプタ %ls に対する IP アドレス はすでに解放されています。\n" IDS_DHCPRELEASEERROR "インターフェース %ls の解放中にエラーが起きました: " IDS_DHCPRENEWERROR "インターフェース %ls の更新中にエラーが起きました: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/no-NO.rc b/base/applications/network/ipconfig/lang/no-NO.rc index 2498c04c025..a07ad6e3b26 100644 --- a/base/applications/network/ipconfig/lang/no-NO.rc +++ b/base/applications/network/ipconfig/lang/no-NO.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/pl-PL.rc b/base/applications/network/ipconfig/lang/pl-PL.rc index 6009b4252de..b1fd2e79223 100644 --- a/base/applications/network/ipconfig/lang/pl-PL.rc +++ b/base/applications/network/ipconfig/lang/pl-PL.rc @@ -70,6 +70,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/ro-RO.rc b/base/applications/network/ipconfig/lang/ro-RO.rc index 13d879da4e3..7368348274c 100644 --- a/base/applications/network/ipconfig/lang/ro-RO.rc +++ b/base/applications/network/ipconfig/lang/ro-RO.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "Adresa IP pentru adaptorul %ls a fost deja eliberată.\n" IDS_DHCPRELEASEERROR "A apărut o eroare în timpul eliberării interfeței %ls: " IDS_DHCPRENEWERROR "A apărut o eroare în timpul reînnoirii interfeței %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/ru-RU.rc b/base/applications/network/ipconfig/lang/ru-RU.rc index c76cf9ee95e..c29b8a81c45 100644 --- a/base/applications/network/ipconfig/lang/ru-RU.rc +++ b/base/applications/network/ipconfig/lang/ru-RU.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "IP-адрес для адаптера ""%ls"" уже освобождён.\n" IDS_DHCPRELEASEERROR "Произошла ошибка при освобождении интерфейса ""%ls"": " IDS_DHCPRENEWERROR "Произошла ошибка при обновлении интерфейса ""%ls"": " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/sk-SK.rc b/base/applications/network/ipconfig/lang/sk-SK.rc index d356a7247ba..5cf0e637673 100644 --- a/base/applications/network/ipconfig/lang/sk-SK.rc +++ b/base/applications/network/ipconfig/lang/sk-SK.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/sq-AL.rc b/base/applications/network/ipconfig/lang/sq-AL.rc index e825017d4e5..83990d3f1bc 100644 --- a/base/applications/network/ipconfig/lang/sq-AL.rc +++ b/base/applications/network/ipconfig/lang/sq-AL.rc @@ -91,6 +91,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/sv-SE.rc b/base/applications/network/ipconfig/lang/sv-SE.rc index f78e22ea6a1..2234fa131b1 100644 --- a/base/applications/network/ipconfig/lang/sv-SE.rc +++ b/base/applications/network/ipconfig/lang/sv-SE.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/tr-TR.rc b/base/applications/network/ipconfig/lang/tr-TR.rc index 5383d78d2b7..5574ddfff5f 100644 --- a/base/applications/network/ipconfig/lang/tr-TR.rc +++ b/base/applications/network/ipconfig/lang/tr-TR.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/uk-UA.rc b/base/applications/network/ipconfig/lang/uk-UA.rc index 0f2ed270477..61f6b4c3816 100644 --- a/base/applications/network/ipconfig/lang/uk-UA.rc +++ b/base/applications/network/ipconfig/lang/uk-UA.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/zh-CN.rc b/base/applications/network/ipconfig/lang/zh-CN.rc index c212233f41a..0af1a302841 100644 --- a/base/applications/network/ipconfig/lang/zh-CN.rc +++ b/base/applications/network/ipconfig/lang/zh-CN.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/lang/zh-TW.rc b/base/applications/network/ipconfig/lang/zh-TW.rc index 6d9e01d264f..83897b4bddd 100644 --- a/base/applications/network/ipconfig/lang/zh-TW.rc +++ b/base/applications/network/ipconfig/lang/zh-TW.rc @@ -92,6 +92,8 @@ BEGIN IDS_DHCPRELEASED "IP address for adapter %ls has already been released.\n" IDS_DHCPRELEASEERROR "An error occurred while releasing interface %ls: " IDS_DHCPRENEWERROR "An error occurred while renewing interface %ls: " + IDS_DHCPSETIDERROR "Attempt to set the class id for adapter %ls failed: " + IDS_DHCPSETIDSUCCESS "Successfully set the class id for adapter %ls.\n" END STRINGTABLE diff --git a/base/applications/network/ipconfig/resource.h b/base/applications/network/ipconfig/resource.h index 678e677f084..84e568664f0 100644 --- a/base/applications/network/ipconfig/resource.h +++ b/base/applications/network/ipconfig/resource.h @@ -77,3 +77,5 @@ #define IDS_DHCPRELEASED 207 #define IDS_DHCPRELEASEERROR 208 #define IDS_DHCPRENEWERROR 209 +#define IDS_DHCPSETIDERROR 210 +#define IDS_DHCPSETIDSUCCESS 211