1 /* 2 * PROJECT: ReactOS NetSh 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Network Shell builtin help command and support functions 5 * COPYRIGHT: Copyright 2023 Eric Kohl <eric.kohl@reactos.org> 6 */ 7 8 /* INCLUDES *******************************************************************/ 9 10 #include "precomp.h" 11 12 #define NDEBUG 13 #include <debug.h> 14 15 /* FUNCTIONS ******************************************************************/ 16 17 static 18 VOID 19 GetContextFullName( 20 _In_ PCONTEXT_ENTRY pContext, 21 _Inout_ LPWSTR pszBuffer, 22 _In_ DWORD cchLength) 23 { 24 if (pContext->pParentContext != NULL) 25 { 26 GetContextFullName(pContext->pParentContext, pszBuffer, cchLength); 27 wcscat(pszBuffer, L" "); 28 wcscat(pszBuffer, pContext->pszContextName); 29 } 30 else 31 { 32 wcscpy(pszBuffer, L"netsh"); 33 } 34 } 35 36 37 static 38 VOID 39 HelpContext( 40 PCONTEXT_ENTRY pContext) 41 { 42 PCONTEXT_ENTRY pSubContext; 43 PCOMMAND_ENTRY pCommand; 44 PCOMMAND_GROUP pGroup; 45 WCHAR szBuffer[80]; 46 47 if (pContext != pRootContext) 48 HelpContext(pContext->pParentContext); 49 50 if (pContext == pCurrentContext) 51 { 52 ConPrintf(StdOut, L"\nCommands in this context:\n"); 53 } 54 else if (pContext == pRootContext) 55 { 56 ConPrintf(StdOut, L"\nCommands in the netsh-context:\n"); 57 } 58 else 59 { 60 GetContextFullName(pContext, szBuffer, 80); 61 ConPrintf(StdOut, L"\nCommands in the %s-context:\n", szBuffer); 62 } 63 64 pCommand = pContext->pCommandListHead; 65 while (pCommand != NULL) 66 { 67 if (LoadStringW(pContext->hModule, pCommand->dwShortCmdHelpToken, szBuffer, 80) == 0) 68 szBuffer[0] = UNICODE_NULL; 69 ConPrintf(StdOut, L"%-15s - %s\n", pCommand->pwszCmdToken, szBuffer); 70 pCommand = pCommand->pNext; 71 } 72 73 pGroup = pContext->pGroupListHead; 74 while (pGroup != NULL) 75 { 76 if (LoadStringW(pContext->hModule, pGroup->dwShortCmdHelpToken, szBuffer, 80) == 0) 77 szBuffer[0] = UNICODE_NULL; 78 ConPrintf(StdOut, L"%-15s - %s\n", pGroup->pwszCmdGroupToken, szBuffer); 79 pGroup = pGroup->pNext; 80 } 81 82 pSubContext = pContext->pSubContextHead; 83 while (pSubContext != NULL) 84 { 85 GetContextFullName(pSubContext, szBuffer, 80); 86 ConPrintf(StdOut, L"%-15s - Changes to the \"%s\" context.\n", pSubContext->pszContextName, szBuffer); 87 pSubContext = pSubContext->pNext; 88 } 89 } 90 91 92 VOID 93 HelpGroup( 94 PCOMMAND_GROUP pGroup) 95 { 96 PCOMMAND_ENTRY pCommand; 97 WCHAR szBuffer[64]; 98 99 ConResPrintf(StdOut, IDS_HELP_HEADER); 100 101 ConPrintf(StdOut, L"\nCommands in this context:\n"); 102 103 pCommand = pGroup->pCommandListHead; 104 while (pCommand != NULL) 105 { 106 swprintf(szBuffer, L"%s %s", pGroup->pwszCmdGroupToken, pCommand->pwszCmdToken); 107 ConPrintf(StdOut, L"%-15s - ", szBuffer); 108 ConResPuts(StdOut, pCommand->dwShortCmdHelpToken); 109 pCommand = pCommand->pNext; 110 } 111 } 112 113 114 DWORD 115 WINAPI 116 HelpCommand( 117 LPCWSTR pwszMachine, 118 LPWSTR *ppwcArguments, 119 DWORD dwCurrentIndex, 120 DWORD dwArgCount, 121 DWORD dwFlags, 122 LPCVOID pvData, 123 BOOL *pbDone) 124 { 125 PCONTEXT_ENTRY pContext; 126 127 ConResPrintf(StdOut, IDS_HELP_HEADER); 128 129 pContext = pCurrentContext; 130 if (pContext == NULL) 131 { 132 DPRINT1("HelpCommand: invalid context %p\n", pContext); 133 return 1; 134 } 135 136 HelpContext(pContext); 137 138 if (pCurrentContext->pSubContextHead != NULL) 139 { 140 ConResPrintf(StdOut, IDS_SUBCONTEXT_HEADER); 141 pContext = pCurrentContext->pSubContextHead; 142 while (pContext != NULL) 143 { 144 ConPrintf(StdOut, L" %s", pContext->pszContextName); 145 pContext = pContext->pNext; 146 } 147 ConPuts(StdOut, L"\n"); 148 } 149 ConPuts(StdOut, L"\n"); 150 151 return ERROR_SUCCESS; 152 } 153