xref: /reactos/base/applications/network/netsh/help.c (revision f7d612f3)
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