From 420799228d8e4e2d9dcd588110f2bde77a2cd837 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 2 Nov 2025 22:37:16 +0100 Subject: [PATCH] [NETSH] Implement the -r (remote) option and set machine command Also: - Start all usage texts with a newline. - Add some error messages. - Fix a bug in the command interpreter. --- base/applications/network/netsh/context.c | 49 +++++++++++++++++-- base/applications/network/netsh/interpreter.c | 13 +++-- base/applications/network/netsh/lang/en-US.rc | 35 +++++++------ base/applications/network/netsh/netsh.c | 31 ++++++++++-- base/applications/network/netsh/precomp.h | 3 ++ base/applications/network/netsh/resource.h | 14 +++--- 6 files changed, 111 insertions(+), 34 deletions(-) diff --git a/base/applications/network/netsh/context.c b/base/applications/network/netsh/context.c index 86f17cf1ee2..379415d407b 100644 --- a/base/applications/network/netsh/context.c +++ b/base/applications/network/netsh/context.c @@ -29,6 +29,8 @@ PCONTEXT_ENTRY pCurrentContext = NULL; PCONTEXT_STACK_ENTRY pContextStackHead = NULL; PCONTEXT_STACK_ENTRY pContextStackTail = NULL; +PWSTR pszMachine = NULL; + static BOOL bOnline = TRUE; /* FUNCTIONS ******************************************************************/ @@ -707,6 +709,43 @@ PushdCommand( } +DWORD +WINAPI +SetMachineCommand( + _In_ LPCWSTR pwszMachine, + _In_ LPWSTR *argv, + _In_ DWORD dwCurrentIndex, + _In_ DWORD dwArgCount, + _In_ DWORD dwFlags, + _In_ LPCVOID pvData, + _Out_ BOOL *pbDone) +{ + DWORD dwError = ERROR_SUCCESS; + + DPRINT("SetMachineCommand(pwszMachine %S dwCurrentIndex %lu dwArgCount %lu)\n", + pwszMachine, dwCurrentIndex, dwArgCount); + + if ((dwArgCount - dwCurrentIndex) > 1) + return ERROR_SHOW_USAGE; + + if (pszMachine != NULL) + { + HeapFree(GetProcessHeap(), 0, pszMachine); + pszMachine = NULL; + } + + if ((dwArgCount - dwCurrentIndex) == 1) + { + pszMachine = HeapAlloc(GetProcessHeap(), 0, (sizeof(argv[dwCurrentIndex]) + 1) * sizeof(WCHAR)); + if (pszMachine == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + wcscpy(pszMachine, argv[dwCurrentIndex]); + } + + return dwError; +} + + DWORD WINAPI SetModeCommand( @@ -720,9 +759,10 @@ SetModeCommand( { DWORD dwError = ERROR_SUCCESS; - DPRINT("SetModeCommand()\n"); + DPRINT("SetModeCommand(pwszMachine %S dwCurrentIndex %lu dwArgCount %lu)\n", + pwszMachine, dwCurrentIndex, dwArgCount); - if (dwArgCount != 3) + if ((dwArgCount - dwCurrentIndex) != 1) return ERROR_SHOW_USAGE; if (!_wcsicmp(argv[dwCurrentIndex], L"offline")) @@ -771,7 +811,7 @@ CreateRootContext(VOID) if (pRootContext == NULL) return FALSE; - pRootContext->hModule = GetModuleHandle(NULL); + pRootContext->hModule = hModule; AddContextCommand(pRootContext, L"..", UpCommand, IDS_HLP_UP, IDS_HLP_UP_EX, 0); AddContextCommand(pRootContext, L"?", NULL, IDS_HLP_HELP, IDS_HLP_HELP_EX, 0); @@ -803,7 +843,8 @@ CreateRootContext(VOID) pGroup = AddCommandGroup(pRootContext, L"set", IDS_HLP_GROUP_SET, 0); if (pGroup) { - AddGroupCommand(pGroup, L"mode", SetModeCommand, IDS_HLP_SET_MODE, IDS_HLP_SET_MODE_EX, 0); + AddGroupCommand(pGroup, L"machine", SetMachineCommand, IDS_HLP_SET_MACHINE, IDS_HLP_SET_MACHINE_EX, 0); + AddGroupCommand(pGroup, L"mode", SetModeCommand, IDS_HLP_SET_MODE, IDS_HLP_SET_MODE_EX, 0); } pGroup = AddCommandGroup(pRootContext, L"show", IDS_HLP_GROUP_SHOW, 0); diff --git a/base/applications/network/netsh/interpreter.c b/base/applications/network/netsh/interpreter.c index f3e039e4563..d5503fc7592 100644 --- a/base/applications/network/netsh/interpreter.c +++ b/base/applications/network/netsh/interpreter.c @@ -205,7 +205,7 @@ InterpretCommand( if (pCommand->pfnCmdHandler != NULL) { dwArgIndex++; - dwError = pCommand->pfnCmdHandler(NULL, argv, dwArgIndex, dwArgCount, 0, NULL, bDone); + dwError = pCommand->pfnCmdHandler(pszMachine, argv, dwArgIndex, dwArgCount, 0, NULL, bDone); if (dwError != ERROR_SUCCESS) { if (dwError == ERROR_SHOW_USAGE) @@ -317,7 +317,8 @@ InterpretCommand( } } - return ERROR_CMD_NOT_FOUND; + /* Done */ + return ERROR_SUCCESS; } @@ -365,7 +366,7 @@ InterpretLine( VOID PrintPrompt( - PCONTEXT_ENTRY pContext) + _In_ PCONTEXT_ENTRY pContext) { if (pContext != pRootContext) { @@ -394,6 +395,8 @@ InterpretInteractive(VOID) memset(args_vector, 0, sizeof(args_vector)); /* Shown just before the input where the user places commands */ + if (pszMachine) + ConPrintf(StdOut, L"[%s] ", pszMachine); PrintPrompt(pCurrentContext); ConPuts(StdOut, L">"); @@ -423,7 +426,9 @@ InterpretInteractive(VOID) dwError = InterpretCommand(args_vector, dwArgCount, &bDone); if (dwError == ERROR_CMD_NOT_FOUND) { - ConResPrintf(StdErr, IDS_INVALID_COMMAND, input_line); + PWSTR pszCommandString = MergeStrings(args_vector, dwArgCount); + ConResPrintf(StdErr, IDS_INVALID_COMMAND, pszCommandString); + HeapFree(GetProcessHeap(), 0, pszCommandString); } if (bDone) diff --git a/base/applications/network/netsh/lang/en-US.rc b/base/applications/network/netsh/lang/en-US.rc index bb474ac7812..8cdaac1f666 100644 --- a/base/applications/network/netsh/lang/en-US.rc +++ b/base/applications/network/netsh/lang/en-US.rc @@ -26,47 +26,50 @@ BEGIN IDS_SUBCONTEXT_HEADER "\nThe following sub-contexts are available:\n" IDS_HLP_UP "Goes up one context level.\n" - IDS_HLP_UP_EX "Usage: %1!s!\n\n Goes up one context level.\n" + IDS_HLP_UP_EX "\nUsage: %1!s!\n\n Goes up one context level.\n" IDS_HLP_EXIT "Exits the program.\n" - IDS_HLP_EXIT_EX "Usage: %1!s!\n\n Exits the program.\n" + IDS_HLP_EXIT_EX "\nUsage: %1!s!\n\n Exits the program.\n" IDS_HLP_HELP "Displays a list of commands.\n" - IDS_HLP_HELP_EX "Usage: %1!s!\n\n Displays a list of commands.\n" + IDS_HLP_HELP_EX "\nUsage: %1!s!\n\n Displays a list of commands.\n" IDS_HLP_POPD "Changes to the context on the stack.\n" - IDS_HLP_POPD_EX "Usage: %1!s!\n\n Changes to the context on the stack.\n" + IDS_HLP_POPD_EX "\nUsage: %1!s!\n\n Changes to the context on the stack.\n" IDS_HLP_PUSHD "Stores the current context on the stack.\n" - IDS_HLP_PUSHD_EX "Usage: %1!s!\n\n Stores the current context on the stack.\n" + IDS_HLP_PUSHD_EX "\nUsage: %1!s!\n\n Stores the current context on the stack.\n" IDS_HLP_EXEC "Runs a script file.\n" - IDS_HLP_EXEC_EX "Usage: %1!s!