mirror of
https://github.com/reactos/reactos.git
synced 2026-05-28 03:44:02 +08:00
[NETSH] Context stack and helper improvements
- Add the context stack including the PUSHD and POPD commands. - Add the required changes to the HELP command and command execution to support the context stack. - Add support for sub helpers.
This commit is contained in:
@@ -14,9 +14,21 @@
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
typedef struct _CONTEXT_STACK_ENTRY
|
||||
{
|
||||
struct _CONTEXT_STACK_ENTRY *pPrev;
|
||||
struct _CONTEXT_STACK_ENTRY *pNext;
|
||||
|
||||
PCONTEXT_ENTRY pContext;
|
||||
} CONTEXT_STACK_ENTRY, *PCONTEXT_STACK_ENTRY;
|
||||
|
||||
|
||||
PCONTEXT_ENTRY pRootContext = NULL;
|
||||
PCONTEXT_ENTRY pCurrentContext = NULL;
|
||||
|
||||
PCONTEXT_STACK_ENTRY pContextStackHead = NULL;
|
||||
PCONTEXT_STACK_ENTRY pContextStackTail = NULL;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
PCONTEXT_ENTRY
|
||||
@@ -135,6 +147,8 @@ AddCommandGroup(
|
||||
{
|
||||
PCOMMAND_GROUP pEntry;
|
||||
|
||||
DPRINT("AddCommandGroup(%S %lu)\n", pwszCmdGroupToken, dwShortCmdHelpToken);
|
||||
|
||||
/* Allocate the entry */
|
||||
pEntry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(COMMAND_GROUP));
|
||||
if (pEntry == NULL)
|
||||
@@ -220,10 +234,68 @@ AddGroupCommand(
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
RemoveContextFromStack(
|
||||
_In_ PCONTEXT_ENTRY pContextEntry)
|
||||
{
|
||||
PCONTEXT_STACK_ENTRY pStackEntry, pNextEntry;
|
||||
|
||||
if (pContextStackHead == NULL)
|
||||
return;
|
||||
|
||||
pStackEntry = pContextStackHead;
|
||||
while (1)
|
||||
{
|
||||
if (pStackEntry->pContext == pContextEntry)
|
||||
{
|
||||
if (pStackEntry == pContextStackHead && pStackEntry == pContextStackHead)
|
||||
{
|
||||
pContextStackHead = NULL;
|
||||
pContextStackTail = NULL;
|
||||
HeapFree(GetProcessHeap(), 0, pStackEntry);
|
||||
return;
|
||||
}
|
||||
else if (pStackEntry == pContextStackHead)
|
||||
{
|
||||
pStackEntry->pNext->pPrev = NULL;
|
||||
pContextStackHead = pStackEntry->pNext;
|
||||
HeapFree(GetProcessHeap(), 0, pStackEntry);
|
||||
pStackEntry = pContextStackHead;
|
||||
}
|
||||
else if (pStackEntry == pContextStackTail)
|
||||
{
|
||||
pStackEntry->pPrev->pNext = NULL;
|
||||
pContextStackTail = pStackEntry->pPrev;
|
||||
HeapFree(GetProcessHeap(), 0, pStackEntry);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNextEntry = pStackEntry->pNext;
|
||||
pStackEntry->pPrev->pNext = pStackEntry->pNext;
|
||||
pStackEntry->pNext->pPrev = pStackEntry->pPrev;
|
||||
HeapFree(GetProcessHeap(), 0, pStackEntry);
|
||||
pStackEntry = pNextEntry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pStackEntry == pContextStackTail)
|
||||
return;
|
||||
|
||||
pStackEntry = pStackEntry->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
DeleteContext(
|
||||
PWSTR pszName)
|
||||
{
|
||||
/* Remove the context from the stack */
|
||||
/* RemoveContextFromStack(); */
|
||||
|
||||
/* Delete all commands */
|
||||
/* Delete the context */
|
||||
}
|
||||
@@ -278,6 +350,81 @@ RemCommand(
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
PopdCommand(
|
||||
LPCWSTR pwszMachine,
|
||||
LPWSTR *argv,
|
||||
DWORD dwCurrentIndex,
|
||||
DWORD dwArgCount,
|
||||
DWORD dwFlags,
|
||||
LPCVOID pvData,
|
||||
BOOL *pbDone)
|
||||
{
|
||||
PCONTEXT_STACK_ENTRY pEntry;
|
||||
|
||||
DPRINT("PopdCommand()\n");
|
||||
|
||||
if (pContextStackHead == NULL)
|
||||
return 0;
|
||||
|
||||
pEntry = pContextStackHead;
|
||||
|
||||
pCurrentContext = pEntry->pContext;
|
||||
|
||||
if (pContextStackTail == pEntry)
|
||||
{
|
||||
pContextStackHead = NULL;
|
||||
pContextStackTail = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pContextStackHead = pEntry->pNext;
|
||||
pContextStackHead->pPrev = NULL;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pEntry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
PushdCommand(
|
||||
LPCWSTR pwszMachine,
|
||||
LPWSTR *argv,
|
||||
DWORD dwCurrentIndex,
|
||||
DWORD dwArgCount,
|
||||
DWORD dwFlags,
|
||||
LPCVOID pvData,
|
||||
_Out_ BOOL *pbDone)
|
||||
{
|
||||
PCONTEXT_STACK_ENTRY pEntry;
|
||||
|
||||
DPRINT("PushdCommand()\n");
|
||||
|
||||
pEntry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONTEXT_STACK_ENTRY));
|
||||
if (pEntry == NULL)
|
||||
return 1;
|
||||
|
||||
pEntry->pContext = pCurrentContext;
|
||||
if (pContextStackHead == NULL)
|
||||
{
|
||||
pContextStackHead = pEntry;
|
||||
pContextStackTail = pEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntry->pNext = pContextStackHead;
|
||||
pContextStackHead->pPrev = pEntry;
|
||||
pContextStackHead = pEntry;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
CreateRootContext(VOID)
|
||||
{
|
||||
@@ -290,12 +437,14 @@ CreateRootContext(VOID)
|
||||
|
||||
pRootContext->hModule = GetModuleHandle(NULL);
|
||||
|
||||
AddContextCommand(pRootContext, L"..", UpCommand, IDS_HLP_UP, IDS_HLP_UP_EX, 0);
|
||||
AddContextCommand(pRootContext, L"?", HelpCommand, IDS_HLP_HELP, IDS_HLP_HELP_EX, 0);
|
||||
AddContextCommand(pRootContext, L"bye", ExitCommand, IDS_HLP_EXIT, IDS_HLP_EXIT_EX, 0);
|
||||
AddContextCommand(pRootContext, L"exit", ExitCommand, IDS_HLP_EXIT, IDS_HLP_EXIT_EX, 0);
|
||||
AddContextCommand(pRootContext, L"help", HelpCommand, IDS_HLP_HELP, IDS_HLP_HELP_EX, 0);
|
||||
AddContextCommand(pRootContext, L"quit", ExitCommand, IDS_HLP_EXIT, IDS_HLP_EXIT_EX, 0);
|
||||
AddContextCommand(pRootContext, L"..", UpCommand, IDS_HLP_UP, IDS_HLP_UP_EX, 0);
|
||||
AddContextCommand(pRootContext, L"?", NULL, IDS_HLP_HELP, IDS_HLP_HELP_EX, 0);
|
||||
AddContextCommand(pRootContext, L"bye", ExitCommand, IDS_HLP_EXIT, IDS_HLP_EXIT_EX, 0);
|
||||
AddContextCommand(pRootContext, L"exit", ExitCommand, IDS_HLP_EXIT, IDS_HLP_EXIT_EX, 0);
|
||||
AddContextCommand(pRootContext, L"help", NULL, IDS_HLP_HELP, IDS_HLP_HELP_EX, 0);
|
||||
AddContextCommand(pRootContext, L"popd", PopdCommand, IDS_HLP_POPD, IDS_HLP_POPD_EX, 0);
|
||||
AddContextCommand(pRootContext, L"pushd", PushdCommand, IDS_HLP_PUSHD, IDS_HLP_PUSHD_EX, 0);
|
||||
AddContextCommand(pRootContext, L"quit", ExitCommand, IDS_HLP_EXIT, IDS_HLP_EXIT_EX, 0);
|
||||
|
||||
pGroup = AddCommandGroup(pRootContext, L"add", IDS_HLP_GROUP_ADD, 0);
|
||||
if (pGroup)
|
||||
@@ -326,8 +475,10 @@ WINAPI
|
||||
RegisterContext(
|
||||
_In_ const NS_CONTEXT_ATTRIBUTES *pChildContext)
|
||||
{
|
||||
PHELPER_ENTRY pHelper;
|
||||
PCONTEXT_ENTRY pContext;
|
||||
DWORD i;
|
||||
PCOMMAND_GROUP pGroup;
|
||||
DWORD i, j;
|
||||
|
||||
DPRINT1("RegisterContext(%p)\n", pChildContext);
|
||||
if (pChildContext == NULL)
|
||||
@@ -345,30 +496,59 @@ RegisterContext(
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
DPRINT1("Name: %S\n", pChildContext->pwszContext);
|
||||
DPRINT("Name: %S\n", pChildContext->pwszContext);
|
||||
DPRINT("Groups: %lu\n", pChildContext->ulNumGroups);
|
||||
DPRINT("Top commands: %lu\n", pChildContext->ulNumTopCmds);
|
||||
|
||||
pHelper = FindHelper(&pChildContext->guidHelper, pHelperListHead);
|
||||
|
||||
pContext = AddContext(pRootContext, pChildContext->pwszContext, (GUID*)&pChildContext->guidHelper);
|
||||
if (pContext != NULL)
|
||||
{
|
||||
if ((pHelper != NULL) && (pHelper->pDllEntry != NULL))
|
||||
{
|
||||
pContext->hModule = pHelper->pDllEntry->hModule;
|
||||
}
|
||||
|
||||
for (i = 0; i < pChildContext->ulNumTopCmds; i++)
|
||||
{
|
||||
AddContextCommand(pContext,
|
||||
pChildContext->pTopCmds[i].pwszCmdToken,
|
||||
pChildContext->pTopCmds[i].pfnCmdHandler,
|
||||
pChildContext->pTopCmds[i].dwShortCmdHelpToken,
|
||||
pChildContext->pTopCmds[i].dwCmdHlpToken,
|
||||
pChildContext->pTopCmds[i].dwFlags);
|
||||
pChildContext->pTopCmds[i].pwszCmdToken,
|
||||
pChildContext->pTopCmds[i].pfnCmdHandler,
|
||||
pChildContext->pTopCmds[i].dwShortCmdHelpToken,
|
||||
pChildContext->pTopCmds[i].dwCmdHlpToken,
|
||||
pChildContext->pTopCmds[i].dwFlags);
|
||||
}
|
||||
|
||||
/* Add command groups */
|
||||
for (i = 0; i < pChildContext->ulNumGroups; i++)
|
||||
{
|
||||
AddCommandGroup(pContext,
|
||||
pChildContext->pCmdGroups[i].pwszCmdGroupToken,
|
||||
pChildContext->pCmdGroups[i].dwShortCmdHelpToken,
|
||||
pChildContext->pCmdGroups[i].dwFlags);
|
||||
pGroup = AddCommandGroup(pContext,
|
||||
pChildContext->pCmdGroups[i].pwszCmdGroupToken,
|
||||
pChildContext->pCmdGroups[i].dwShortCmdHelpToken,
|
||||
pChildContext->pCmdGroups[i].dwFlags);
|
||||
if (pGroup != NULL)
|
||||
{
|
||||
for (j = 0; j < pChildContext->pCmdGroups[i].ulCmdGroupSize; j++)
|
||||
{
|
||||
AddGroupCommand(pGroup,
|
||||
pChildContext->pCmdGroups[i].pCmdGroup[j].pwszCmdToken,
|
||||
pChildContext->pCmdGroups[i].pCmdGroup[j].pfnCmdHandler,
|
||||
pChildContext->pCmdGroups[i].pCmdGroup[j].dwShortCmdHelpToken,
|
||||
pChildContext->pCmdGroups[i].pCmdGroup[j].dwCmdHlpToken,
|
||||
pChildContext->pCmdGroups[i].pCmdGroup[j].dwFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CleanupContext(VOID)
|
||||
{
|
||||
/* Delete the context stack */
|
||||
|
||||
}
|
||||
|
||||
@@ -36,17 +36,11 @@ GetContextFullName(
|
||||
|
||||
static
|
||||
VOID
|
||||
HelpContext(
|
||||
PCONTEXT_ENTRY pContext)
|
||||
PrintCurrentContextHeader(
|
||||
_In_ PCONTEXT_ENTRY pContext)
|
||||
{
|
||||
PCONTEXT_ENTRY pSubContext;
|
||||
PCOMMAND_ENTRY pCommand;
|
||||
PCOMMAND_GROUP pGroup;
|
||||
WCHAR szBuffer[80];
|
||||
|
||||
if (pContext != pRootContext)
|
||||
HelpContext(pContext->pParentContext);
|
||||
|
||||
if (pContext == pCurrentContext)
|
||||
{
|
||||
ConPrintf(StdOut, L"\nCommands in this context:\n");
|
||||
@@ -60,6 +54,16 @@ HelpContext(
|
||||
GetContextFullName(pContext, szBuffer, 80);
|
||||
ConPrintf(StdOut, L"\nCommands in the %s-context:\n", szBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintShortCommands(
|
||||
_In_ PCONTEXT_ENTRY pContext)
|
||||
{
|
||||
PCOMMAND_ENTRY pCommand;
|
||||
WCHAR szBuffer[80];
|
||||
|
||||
pCommand = pContext->pCommandListHead;
|
||||
while (pCommand != NULL)
|
||||
@@ -69,6 +73,16 @@ HelpContext(
|
||||
ConPrintf(StdOut, L"%-15s - %s\n", pCommand->pwszCmdToken, szBuffer);
|
||||
pCommand = pCommand->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintShortGroups(
|
||||
_In_ PCONTEXT_ENTRY pContext)
|
||||
{
|
||||
PCOMMAND_GROUP pGroup;
|
||||
WCHAR szBuffer[80];
|
||||
|
||||
pGroup = pContext->pGroupListHead;
|
||||
while (pGroup != NULL)
|
||||
@@ -78,6 +92,16 @@ HelpContext(
|
||||
ConPrintf(StdOut, L"%-15s - %s\n", pGroup->pwszCmdGroupToken, szBuffer);
|
||||
pGroup = pGroup->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintShortSubContexts(
|
||||
_In_ PCONTEXT_ENTRY pContext)
|
||||
{
|
||||
PCONTEXT_ENTRY pSubContext;
|
||||
WCHAR szBuffer[80];
|
||||
|
||||
pSubContext = pContext->pSubContextHead;
|
||||
while (pSubContext != NULL)
|
||||
@@ -88,29 +112,203 @@ HelpContext(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
HelpGroup(
|
||||
PCOMMAND_GROUP pGroup)
|
||||
PrintShortGroupCommands(
|
||||
_In_ PCONTEXT_ENTRY pContext,
|
||||
_In_ PCOMMAND_GROUP pGroup)
|
||||
{
|
||||
PCOMMAND_ENTRY pCommand;
|
||||
WCHAR szBuffer[64];
|
||||
|
||||
ConResPrintf(StdOut, IDS_HELP_HEADER);
|
||||
|
||||
ConPrintf(StdOut, L"\nCommands in this context:\n");
|
||||
WCHAR szBuffer1[64];
|
||||
WCHAR szBuffer2[80];
|
||||
|
||||
pCommand = pGroup->pCommandListHead;
|
||||
while (pCommand != NULL)
|
||||
{
|
||||
swprintf(szBuffer, L"%s %s", pGroup->pwszCmdGroupToken, pCommand->pwszCmdToken);
|
||||
ConPrintf(StdOut, L"%-15s - ", szBuffer);
|
||||
ConResPuts(StdOut, pCommand->dwShortCmdHelpToken);
|
||||
swprintf(szBuffer1, L"%s %s", pGroup->pwszCmdGroupToken, pCommand->pwszCmdToken);
|
||||
LoadStringW(pContext->hModule, pCommand->dwShortCmdHelpToken, szBuffer2, 80);
|
||||
|
||||
ConPrintf(StdOut, L"%-15s - %s\n", szBuffer1, szBuffer2);
|
||||
pCommand = pCommand->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintLongCommand(
|
||||
_In_ PCONTEXT_ENTRY pContext,
|
||||
_In_ PCOMMAND_ENTRY pCommand)
|
||||
{
|
||||
WCHAR szBuffer[80];
|
||||
|
||||
LoadStringW(pContext->hModule, pCommand->dwCmdHlpToken, szBuffer, 80);
|
||||
ConPrintf(StdOut, szBuffer);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintContext(
|
||||
_In_ PCONTEXT_ENTRY pContext)
|
||||
{
|
||||
DPRINT1("PrintContext()\n");
|
||||
|
||||
if (pContext != pRootContext)
|
||||
PrintContext(pContext->pParentContext);
|
||||
|
||||
PrintCurrentContextHeader(pContext);
|
||||
|
||||
PrintShortCommands(pContext);
|
||||
|
||||
PrintShortGroups(pContext);
|
||||
|
||||
PrintShortSubContexts(pContext);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintGroup(
|
||||
_In_ PCONTEXT_ENTRY pContext,
|
||||
_In_ LPWSTR pszGroupName,
|
||||
_In_ BOOL bRecurse)
|
||||
{
|
||||
PCOMMAND_GROUP pGroup;
|
||||
|
||||
if (bRecurse)
|
||||
{
|
||||
if (pContext != pRootContext)
|
||||
PrintGroup(pContext->pParentContext, pszGroupName, bRecurse);
|
||||
}
|
||||
|
||||
pGroup = pContext->pGroupListHead;
|
||||
while (pGroup != NULL)
|
||||
{
|
||||
if (_wcsicmp(pszGroupName, pGroup->pwszCmdGroupToken) == 0)
|
||||
{
|
||||
PrintCurrentContextHeader(pContext);
|
||||
PrintShortGroupCommands(pContext, pGroup);
|
||||
}
|
||||
pGroup = pGroup->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintSubcontexts(
|
||||
_In_ PCONTEXT_ENTRY pContext)
|
||||
{
|
||||
if (pCurrentContext->pSubContextHead != NULL)
|
||||
{
|
||||
ConResPrintf(StdOut, IDS_SUBCONTEXT_HEADER);
|
||||
pContext = pCurrentContext->pSubContextHead;
|
||||
while (pContext != NULL)
|
||||
{
|
||||
ConPrintf(StdOut, L" %s", pContext->pszContextName);
|
||||
pContext = pContext->pNext;
|
||||
}
|
||||
ConPuts(StdOut, L"\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
ProcessHelp(
|
||||
_In_ PCONTEXT_ENTRY pContext,
|
||||
_In_ DWORD dwArgCount,
|
||||
_In_ LPWSTR *argv,
|
||||
_In_ DWORD dwCurrentIndex,
|
||||
_In_ DWORD dwHelpLevel)
|
||||
{
|
||||
PCONTEXT_ENTRY pSubContext;
|
||||
PCOMMAND_ENTRY pCommand;
|
||||
PCOMMAND_GROUP pGroup;
|
||||
|
||||
DPRINT("ProcessHelp(dwCurrentIndex %lu dwArgCount %lu dwHelpLevel %lu)\n", dwCurrentIndex, dwArgCount, dwHelpLevel);
|
||||
|
||||
if (dwHelpLevel == dwCurrentIndex)
|
||||
{
|
||||
ConResPrintf(StdOut, IDS_HELP_HEADER);
|
||||
PrintContext(pContext);
|
||||
PrintSubcontexts(pContext);
|
||||
ConResPrintf(StdOut, IDS_HELP_FOOTER);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pCommand = pContext->pCommandListHead;
|
||||
while (pCommand != NULL)
|
||||
{
|
||||
if (_wcsicmp(argv[dwCurrentIndex], pCommand->pwszCmdToken) == 0)
|
||||
{
|
||||
if (dwHelpLevel == dwCurrentIndex + 1)
|
||||
{
|
||||
PrintLongCommand(pContext, pCommand);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
pCommand = pCommand->pNext;
|
||||
}
|
||||
|
||||
pGroup = pContext->pGroupListHead;
|
||||
while (pGroup != NULL)
|
||||
{
|
||||
if (_wcsicmp(argv[dwCurrentIndex], pGroup->pwszCmdGroupToken) == 0)
|
||||
{
|
||||
if (dwHelpLevel == dwCurrentIndex + 1)
|
||||
{
|
||||
ConResPrintf(StdOut, IDS_HELP_HEADER);
|
||||
PrintGroup(pContext, argv[dwCurrentIndex], (dwHelpLevel == 1));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pCommand = pGroup->pCommandListHead;
|
||||
while (pCommand != NULL)
|
||||
{
|
||||
if ((dwArgCount > dwCurrentIndex + 1) && (_wcsicmp(argv[dwCurrentIndex + 1], pCommand->pwszCmdToken) == 0))
|
||||
{
|
||||
if (dwHelpLevel == dwCurrentIndex + 2)
|
||||
{
|
||||
PrintLongCommand(pContext, pCommand);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
pCommand = pCommand->pNext;
|
||||
}
|
||||
|
||||
// ConResPrintf(StdOut, IDS_HELP_HEADER);
|
||||
// PrintGroup(pContext, pGroup);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pGroup = pGroup->pNext;
|
||||
}
|
||||
|
||||
if (pContext == pCurrentContext)
|
||||
{
|
||||
pSubContext = pContext->pSubContextHead;
|
||||
while (pSubContext != NULL)
|
||||
{
|
||||
if (_wcsicmp(argv[dwCurrentIndex], pSubContext->pszContextName) == 0)
|
||||
{
|
||||
return ProcessHelp(pSubContext,
|
||||
dwArgCount,
|
||||
argv,
|
||||
dwCurrentIndex + 1,
|
||||
dwHelpLevel);
|
||||
}
|
||||
|
||||
pSubContext = pSubContext->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
HelpCommand(
|
||||
@@ -122,31 +320,5 @@ HelpCommand(
|
||||
LPCVOID pvData,
|
||||
BOOL *pbDone)
|
||||
{
|
||||
PCONTEXT_ENTRY pContext;
|
||||
|
||||
ConResPrintf(StdOut, IDS_HELP_HEADER);
|
||||
|
||||
pContext = pCurrentContext;
|
||||
if (pContext == NULL)
|
||||
{
|
||||
DPRINT1("HelpCommand: invalid context %p\n", pContext);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HelpContext(pContext);
|
||||
|
||||
if (pCurrentContext->pSubContextHead != NULL)
|
||||
{
|
||||
ConResPrintf(StdOut, IDS_SUBCONTEXT_HEADER);
|
||||
pContext = pCurrentContext->pSubContextHead;
|
||||
while (pContext != NULL)
|
||||
{
|
||||
ConPrintf(StdOut, L" %s", pContext->pszContextName);
|
||||
pContext = pContext->pNext;
|
||||
}
|
||||
ConPuts(StdOut, L"\n");
|
||||
}
|
||||
ConPuts(StdOut, L"\n");
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ PDLL_LIST_ENTRY pCurrentDll = NULL;
|
||||
|
||||
static
|
||||
VOID
|
||||
StartHelpers(VOID)
|
||||
StartHelpers(
|
||||
PHELPER_ENTRY pHelper)
|
||||
{
|
||||
PHELPER_ENTRY pHelper;
|
||||
PHELPER_ENTRY pSubHelper;
|
||||
DWORD dwError;
|
||||
|
||||
pHelper = pHelperListHead;
|
||||
while (pHelper != NULL)
|
||||
{
|
||||
if (pHelper->bStarted == FALSE)
|
||||
@@ -44,6 +44,13 @@ StartHelpers(VOID)
|
||||
}
|
||||
}
|
||||
|
||||
pSubHelper = pHelper->pSubHelperHead;
|
||||
while (pSubHelper != NULL)
|
||||
{
|
||||
StartHelpers(pSubHelper);
|
||||
pSubHelper = pSubHelper->pNext;
|
||||
}
|
||||
|
||||
pHelper = pHelper->pNext;
|
||||
}
|
||||
}
|
||||
@@ -310,7 +317,7 @@ done:
|
||||
|
||||
RegCloseKey(hKey);
|
||||
|
||||
StartHelpers();
|
||||
StartHelpers(pHelperListHead);
|
||||
}
|
||||
|
||||
|
||||
@@ -336,16 +343,21 @@ UnloadHelpers(VOID)
|
||||
|
||||
PHELPER_ENTRY
|
||||
FindHelper(
|
||||
_In_ const GUID *pguidHelper)
|
||||
_In_ const GUID *pguidHelper,
|
||||
_In_ PHELPER_ENTRY pHelper)
|
||||
{
|
||||
PHELPER_ENTRY pHelper;
|
||||
PHELPER_ENTRY pFoundHelper;
|
||||
|
||||
pHelper = pHelperListHead;
|
||||
// pHelper = pHelperListHead;
|
||||
while (pHelper != NULL)
|
||||
{
|
||||
if (IsEqualGUID(pguidHelper, &pHelper->Attributes.guidHelper))
|
||||
return pHelper;
|
||||
|
||||
pFoundHelper = FindHelper(pguidHelper, pHelper->pSubHelperHead);
|
||||
if (pFoundHelper)
|
||||
return pFoundHelper;
|
||||
|
||||
pHelper = pHelper->pNext;
|
||||
}
|
||||
|
||||
@@ -364,7 +376,7 @@ RegisterHelper(
|
||||
|
||||
DPRINT("RegisterHelper(%p %p)\n", pguidParentHelper, pHelperAttributes);
|
||||
|
||||
if (FindHelper(&pHelperAttributes->guidHelper) != NULL)
|
||||
if (FindHelper(&pHelperAttributes->guidHelper, pHelperListHead) != NULL)
|
||||
{
|
||||
DPRINT1("The Helper has already been registered!\n");
|
||||
return 1;
|
||||
@@ -397,9 +409,12 @@ RegisterHelper(
|
||||
}
|
||||
else
|
||||
{
|
||||
pParentHelper = FindHelper(&pHelperAttributes->guidHelper);
|
||||
pParentHelper = FindHelper(pguidParentHelper, pHelperListHead);
|
||||
if (pParentHelper == NULL)
|
||||
{
|
||||
DPRINT("Parent helper not found!\n");
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (pParentHelper->pSubHelperHead == NULL && pParentHelper->pSubHelperTail == NULL)
|
||||
{
|
||||
@@ -446,7 +461,7 @@ AddHelperCommand(
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
StartHelpers();
|
||||
StartHelpers(pHelperListHead);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -528,13 +543,15 @@ PrintSubContext(
|
||||
WCHAR szPrefix[22];
|
||||
DWORD i;
|
||||
|
||||
DPRINT("PrintSubContext(%p %lu)\n", pParentContext, dwLevel);
|
||||
|
||||
if (pParentContext == NULL)
|
||||
return;
|
||||
|
||||
pContext = pParentContext->pSubContextHead;
|
||||
while (pContext != NULL)
|
||||
{
|
||||
pHelper = FindHelper(&pContext->Guid);
|
||||
pHelper = FindHelper(&pContext->Guid, pHelperListHead);
|
||||
if (pHelper != NULL)
|
||||
{
|
||||
if (dwLevel > 10)
|
||||
@@ -542,7 +559,9 @@ PrintSubContext(
|
||||
|
||||
for (i = 0; i < dwLevel * 2; i++)
|
||||
szPrefix[i] = L' ';
|
||||
szPrefix[i] = UNICODE_NULL;
|
||||
szPrefix[dwLevel * 2] = UNICODE_NULL;
|
||||
|
||||
DPRINT("Level %lu \"%S\" %S\n", dwLevel, szPrefix, pContext->pszContextName);
|
||||
|
||||
ConPrintf(StdOut, L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X} %-16s %s%s\n",
|
||||
pHelper->Attributes.guidHelper.Data1,
|
||||
|
||||
@@ -15,15 +15,17 @@
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOL
|
||||
InterpretCommand(
|
||||
ProcessCommand(
|
||||
_In_ PCONTEXT_ENTRY pContext,
|
||||
_In_ DWORD dwArgCount,
|
||||
_In_ LPWSTR *argv,
|
||||
_In_ DWORD dwArgCount)
|
||||
_In_ DWORD dwCurrentIndex,
|
||||
_In_ DWORD dwHelpLevel,
|
||||
_Inout_ PBOOL bDone)
|
||||
{
|
||||
PCONTEXT_ENTRY pContext, pSubContext;
|
||||
PCONTEXT_ENTRY pSubContext;
|
||||
PCOMMAND_ENTRY pCommand;
|
||||
PCOMMAND_GROUP pGroup;
|
||||
BOOL bDone = FALSE;
|
||||
DWORD dwHelpLevel = 0;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
/* If no args provided */
|
||||
@@ -51,21 +53,13 @@ InterpretCommand(
|
||||
{
|
||||
if (_wcsicmp(argv[0], pCommand->pwszCmdToken) == 0)
|
||||
{
|
||||
if (dwHelpLevel == 1)
|
||||
dwError = pCommand->pfnCmdHandler(NULL, argv, dwCurrentIndex, dwArgCount, 0, NULL, bDone);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
ConPrintf(StdOut, L"Error: %lu\n\n", dwError);
|
||||
ConResPrintf(StdOut, pCommand->dwCmdHlpToken);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwError = pCommand->pfnCmdHandler(NULL, argv, 0, dwArgCount, 0, NULL, &bDone);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
ConPrintf(StdOut, L"Error: %lu\n\n");
|
||||
ConResPrintf(StdOut, pCommand->dwCmdHlpToken);
|
||||
}
|
||||
return !bDone;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pCommand = pCommand->pNext;
|
||||
@@ -76,40 +70,33 @@ InterpretCommand(
|
||||
{
|
||||
if (_wcsicmp(argv[0], pGroup->pwszCmdGroupToken) == 0)
|
||||
{
|
||||
if (dwHelpLevel == 1)
|
||||
if (dwArgCount == 1)
|
||||
{
|
||||
HelpGroup(pGroup);
|
||||
ProcessHelp(pContext, dwArgCount, argv, dwCurrentIndex, dwHelpLevel + 1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pCommand = pGroup->pCommandListHead;
|
||||
while (pCommand != NULL)
|
||||
else
|
||||
{
|
||||
if ((dwArgCount > 1) && (_wcsicmp(argv[1], pCommand->pwszCmdToken) == 0))
|
||||
pCommand = pGroup->pCommandListHead;
|
||||
while (pCommand != NULL)
|
||||
{
|
||||
if (dwHelpLevel == 2)
|
||||
if ((dwArgCount > 1) && (_wcsicmp(argv[1], pCommand->pwszCmdToken) == 0))
|
||||
// if ((dwArgCount > dwCurrentIndex + 1) && (wcsicmp(argv[dwCurrentIndex + 1], pCommand->pwszCmdToken) == 0))
|
||||
{
|
||||
ConResPrintf(StdOut, pCommand->dwCmdHlpToken);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwError = pCommand->pfnCmdHandler(NULL, argv, 1, dwArgCount, 0, NULL, &bDone);
|
||||
dwError = pCommand->pfnCmdHandler(NULL, argv, dwCurrentIndex + 1, dwArgCount, 0, NULL, bDone);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
ConPrintf(StdOut, L"Error: %lu\n\n");
|
||||
ConPrintf(StdOut, L"Error: %lu\n\n", dwError);
|
||||
ConResPrintf(StdOut, pCommand->dwCmdHlpToken);
|
||||
return TRUE;
|
||||
}
|
||||
return !bDone;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pCommand = pCommand->pNext;
|
||||
}
|
||||
|
||||
pCommand = pCommand->pNext;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HelpGroup(pGroup);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pGroup = pGroup->pNext;
|
||||
@@ -122,8 +109,21 @@ InterpretCommand(
|
||||
{
|
||||
if (_wcsicmp(argv[0], pSubContext->pszContextName) == 0)
|
||||
{
|
||||
pCurrentContext = pSubContext;
|
||||
return TRUE;
|
||||
DPRINT("%S ==> dwCurrentIndex: %lu dwArgCount: %lu\n", argv[dwCurrentIndex], dwCurrentIndex, dwArgCount);
|
||||
if (dwArgCount == dwCurrentIndex + 1)
|
||||
{
|
||||
pCurrentContext = pSubContext;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ProcessCommand(pSubContext,
|
||||
dwArgCount,
|
||||
argv,
|
||||
dwCurrentIndex + 1,
|
||||
dwHelpLevel,
|
||||
bDone);
|
||||
}
|
||||
}
|
||||
|
||||
pSubContext = pSubContext->pNext;
|
||||
@@ -136,9 +136,44 @@ InterpretCommand(
|
||||
pContext = pContext->pParentContext;
|
||||
}
|
||||
|
||||
ConResPrintf(StdErr, IDS_INVALID_COMMAND, argv[0]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
BOOL
|
||||
InterpretCommand(
|
||||
_In_ LPWSTR *argv,
|
||||
_In_ DWORD dwArgCount,
|
||||
_Inout_ PBOOL bDone)
|
||||
{
|
||||
/* If no args provided */
|
||||
if (dwArgCount == 0)
|
||||
return TRUE;
|
||||
|
||||
if (pCurrentContext == NULL)
|
||||
{
|
||||
DPRINT("InterpretCmd: invalid context %p\n", pCurrentContext);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((_wcsicmp(argv[dwArgCount - 1], L"?") == 0) ||
|
||||
(_wcsicmp(argv[dwArgCount - 1], L"help") == 0))
|
||||
{
|
||||
return ProcessHelp(pCurrentContext,
|
||||
dwArgCount,
|
||||
argv,
|
||||
0,
|
||||
dwArgCount - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ProcessCommand(pCurrentContext,
|
||||
dwArgCount,
|
||||
argv,
|
||||
0,
|
||||
0,
|
||||
bDone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,6 +188,7 @@ InterpretScript(
|
||||
LPWSTR args_vector[MAX_ARGS_COUNT];
|
||||
DWORD dwArgCount = 0;
|
||||
BOOL bWhiteSpace = TRUE;
|
||||
BOOL bDone = FALSE;
|
||||
LPWSTR ptr;
|
||||
|
||||
memset(args_vector, 0, sizeof(args_vector));
|
||||
@@ -180,7 +216,7 @@ InterpretScript(
|
||||
}
|
||||
|
||||
/* sends the string to find the command */
|
||||
return InterpretCommand(args_vector, dwArgCount);
|
||||
return InterpretCommand(args_vector, dwArgCount, &bDone) == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -191,16 +227,15 @@ InterpretInteractive(VOID)
|
||||
LPWSTR args_vector[MAX_ARGS_COUNT];
|
||||
DWORD dwArgCount = 0;
|
||||
BOOL bWhiteSpace = TRUE;
|
||||
BOOL bRun = TRUE;
|
||||
BOOL bDone = FALSE;
|
||||
LPWSTR ptr;
|
||||
|
||||
while (bRun != FALSE)
|
||||
for (;;)
|
||||
{
|
||||
dwArgCount = 0;
|
||||
memset(args_vector, 0, sizeof(args_vector));
|
||||
|
||||
/* Shown just before the input where the user places commands */
|
||||
// ConResPuts(StdOut, IDS_APP_PROMPT);
|
||||
ConPuts(StdOut, L"netsh");
|
||||
if (pCurrentContext != pRootContext)
|
||||
{
|
||||
@@ -233,6 +268,12 @@ InterpretInteractive(VOID)
|
||||
}
|
||||
|
||||
/* Send the string to find the command */
|
||||
bRun = InterpretCommand(args_vector, dwArgCount);
|
||||
if (InterpretCommand(args_vector, dwArgCount, &bDone) == FALSE)
|
||||
{
|
||||
ConResPrintf(StdErr, IDS_INVALID_COMMAND, input_line);
|
||||
}
|
||||
|
||||
if (bDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,20 @@ END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_HELP_HEADER "\nThe following commands are available:\n"
|
||||
IDS_HELP_HEADER "\nThe following commands are available:\n"
|
||||
IDS_HELP_FOOTER "\nHelp Footer\n\n"
|
||||
IDS_SUBCONTEXT_HEADER "\nThe following sub-contexts are available:\n"
|
||||
|
||||
IDS_HLP_UP "Goes up one context level."
|
||||
IDS_HLP_UP_EX "Syntax: ..\n\n Goes up one context level.\n\n"
|
||||
IDS_HLP_EXIT "Exits the program."
|
||||
IDS_HLP_EXIT_EX "Syntax: exit\n\n Exits the program.\n\n"
|
||||
IDS_HLP_HELP "Displays a list of commands."
|
||||
IDS_HLP_HELP_EX "Syntax: help\n\n Displays a list of commands.\n\n"
|
||||
IDS_HLP_POPD "Changes to the context on the stack."
|
||||
IDS_HLP_POPD_EX "Syntax: popd\n\n Changes to the context on the stack.\n\n"
|
||||
IDS_HLP_PUSHD "Stores the current context on the stack."
|
||||
IDS_HLP_PUSHD_EX "Syntax: pushd\n\n Stores the current context on the stack.\n\n"
|
||||
|
||||
IDS_HLP_ADD_HELPER "Installs a helper DLL."
|
||||
IDS_HLP_ADD_HELPER_EX "Syntax: add helper <dll file name>\n\n Installs the specified helper DLL in netsh.\n\n"
|
||||
|
||||
@@ -58,8 +58,9 @@ wmain(
|
||||
LPCWSTR pszFileName = NULL;
|
||||
int index;
|
||||
int result = EXIT_SUCCESS;
|
||||
BOOL bDone = FALSE;
|
||||
|
||||
DPRINT("main()\n");
|
||||
DPRINT("wmain(%S)\n", GetCommandLineW());
|
||||
|
||||
/* Initialize the Console Standard Streams */
|
||||
ConInitStdStreams();
|
||||
@@ -93,7 +94,7 @@ wmain(
|
||||
}
|
||||
|
||||
/* Run a command from the command line */
|
||||
if (InterpretCommand((LPWSTR*)&argv[index], argc - index) == FALSE)
|
||||
if (InterpretCommand((LPWSTR*)&argv[index], argc - index, &bDone) != ERROR_SUCCESS)
|
||||
result = EXIT_FAILURE;
|
||||
goto done;
|
||||
}
|
||||
@@ -186,6 +187,7 @@ wmain(
|
||||
|
||||
done:
|
||||
/* FIXME: Cleanup code goes here */
|
||||
CleanupContext();
|
||||
UnloadHelpers();
|
||||
|
||||
return result;
|
||||
@@ -247,7 +249,7 @@ PrintMessage(
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, pwszFormat);
|
||||
Length = ConPrintf(StdOut, pwszFormat);
|
||||
Length = ConPrintfV(StdOut, pwszFormat, ap);
|
||||
va_end(ap);
|
||||
|
||||
return Length;
|
||||
|
||||
@@ -100,6 +100,7 @@ typedef struct _CONTEXT_ENTRY
|
||||
struct _CONTEXT_ENTRY *pNext;
|
||||
|
||||
struct _CONTEXT_ENTRY *pParentContext;
|
||||
// PHELPER_ENTRY pHelper;
|
||||
|
||||
PWSTR pszContextName;
|
||||
GUID Guid;
|
||||
@@ -121,6 +122,7 @@ typedef struct _CONTEXT_ENTRY
|
||||
extern PCONTEXT_ENTRY pRootContext;
|
||||
extern PCONTEXT_ENTRY pCurrentContext;
|
||||
|
||||
extern PHELPER_ENTRY pHelperListHead;
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
|
||||
@@ -129,8 +131,21 @@ extern PCONTEXT_ENTRY pCurrentContext;
|
||||
BOOL
|
||||
CreateRootContext(VOID);
|
||||
|
||||
VOID
|
||||
CleanupContext(VOID);
|
||||
|
||||
|
||||
/* help.c */
|
||||
|
||||
BOOL
|
||||
ProcessHelp(
|
||||
_In_ PCONTEXT_ENTRY pContext,
|
||||
_In_ DWORD dwCurrentIndex,
|
||||
_In_ LPWSTR *argv,
|
||||
_In_ DWORD dwArgCount,
|
||||
_In_ DWORD dwHelpLevel);
|
||||
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
HelpCommand(
|
||||
@@ -142,10 +157,21 @@ HelpCommand(
|
||||
LPCVOID pvData,
|
||||
BOOL *pbDone);
|
||||
|
||||
#if 0
|
||||
VOID
|
||||
HelpGroup(
|
||||
PCOMMAND_GROUP pGroup);
|
||||
PCONTEXT_ENTRY pContext,
|
||||
LPWSTR pszGroupName,
|
||||
BOOL bRecurse);
|
||||
|
||||
VOID
|
||||
HelpContext(
|
||||
PCONTEXT_ENTRY pContext);
|
||||
|
||||
VOID
|
||||
HelpSubcontexts(
|
||||
PCONTEXT_ENTRY pContext);
|
||||
#endif
|
||||
|
||||
/* helper.c */
|
||||
VOID
|
||||
@@ -154,6 +180,10 @@ LoadHelpers(VOID);
|
||||
VOID
|
||||
UnloadHelpers(VOID);
|
||||
|
||||
PHELPER_ENTRY
|
||||
FindHelper(
|
||||
_In_ const GUID *pguidHelper,
|
||||
_In_ PHELPER_ENTRY pHelper);
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
@@ -192,12 +222,13 @@ ShowHelperCommand(
|
||||
/* interpreter.c */
|
||||
BOOL
|
||||
InterpretScript(
|
||||
LPWSTR pszFileName);
|
||||
_In_ LPWSTR pszFileName);
|
||||
|
||||
BOOL
|
||||
InterpretCommand(
|
||||
LPWSTR *argv,
|
||||
DWORD dwArgCount);
|
||||
_In_ LPWSTR *argv,
|
||||
_In_ DWORD dwArgCount,
|
||||
_Inout_ PBOOL bDone);
|
||||
|
||||
VOID
|
||||
InterpretInteractive(VOID);
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#define IDS_INVALID_SYNTAX 104
|
||||
|
||||
#define IDS_HELP_HEADER 200
|
||||
#define IDS_SUBCONTEXT_HEADER 201
|
||||
#define IDS_HELP_FOOTER 201
|
||||
#define IDS_SUBCONTEXT_HEADER 202
|
||||
|
||||
#define IDS_HLP_EXIT 300
|
||||
#define IDS_HLP_EXIT_EX 301
|
||||
@@ -24,6 +25,10 @@
|
||||
#define IDS_HLP_HELP_EX 303
|
||||
#define IDS_HLP_UP 304
|
||||
#define IDS_HLP_UP_EX 305
|
||||
#define IDS_HLP_POPD 306
|
||||
#define IDS_HLP_POPD_EX 307
|
||||
#define IDS_HLP_PUSHD 308
|
||||
#define IDS_HLP_PUSHD_EX 309
|
||||
|
||||
#define IDS_HLP_ADD_HELPER 310
|
||||
#define IDS_HLP_ADD_HELPER_EX 311
|
||||
|
||||
Reference in New Issue
Block a user