windows-nt/Source/XPSP1/NT/net/rras/netsh/if/ifmon.c
2020-09-26 16:20:57 +08:00

417 lines
8.8 KiB
C

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
routing\netsh\if\ifmon.c
Abstract:
If Command dispatcher.
Revision History:
AmritanR
--*/
#include "precomp.h"
#define IFMON_GUID \
{ 0x705eca1, 0x7aac, 0x11d2, { 0x89, 0xdc, 0x0, 0x60, 0x8, 0xb0, 0xe5, 0xb9 } }
GUID g_IfGuid = IFMON_GUID;
static const GUID g_NetshGuid = NETSH_ROOT_GUID;
#define IF_HELPER_VERSION 1
//
// The monitor's commands are broken into 2 sets
// - The top level commands are those which deal with the monitor
// itself (meta commands) and others which take 0 arguments
// - The rest of the commands are split into "command groups"
// i.e, commands grouped by the VERB where the VERB is ADD, DELETE,
// GET or SET. This is not for any technical reason - only for
// staying with the semantics used in other monitors and helpers
//
// A command is described using a CMD_ENTRY structure. It requires the
// command token, the handler, a short help message token and an extended
// help message token. To make it easier to create we use the
// CREATE_CMD_ENTRY macro. This, however puts restrictions on how the tokens
// are named.
//
// The command groups are simply arrays of the CMD_ENTRY structure. The
// top level commands are also grouped in a similar array.
//
// The info about a complete command group is put in a CMD_GROUP_ENTRY
// structure, all of which are put in an array.
//
//
// NOTE: Since we have only one entry per group, currently, we really didnt
// need command groups. This is done for later extensibility.
// To add a command entry to a group, simply add the command to the appropriate
// array
// To add a command group - create and array and add its info to the
// command group array
//
CMD_ENTRY g_IfAddCmdTable[] =
{
CREATE_CMD_ENTRY(IF_ADD_IF, HandleIfAddIf),
};
CMD_ENTRY g_IfDelCmdTable[] =
{
CREATE_CMD_ENTRY(IF_DEL_IF, HandleIfDelIf),
};
CMD_ENTRY g_IfSetCmdTable[] =
{
CREATE_CMD_ENTRY(IF_SET_INTERFACE, HandleIfSet),
CREATE_CMD_ENTRY(IF_SET_CREDENTIALS, HandleIfSetCredentials),
};
CMD_ENTRY g_IfShowCmdTable[] =
{
CREATE_CMD_ENTRY(IF_SHOW_IF, HandleIfShowIf),
CREATE_CMD_ENTRY(IF_SHOW_CREDENTIALS, HandleIfShowCredentials),
};
CMD_ENTRY g_IfResetCmdTable[] =
{
CREATE_CMD_ENTRY(IF_RESET_ALL, HandleIfResetAll),
};
CMD_GROUP_ENTRY g_IfCmdGroups[] =
{
CREATE_CMD_GROUP_ENTRY(GROUP_ADD, g_IfAddCmdTable),
CREATE_CMD_GROUP_ENTRY(GROUP_DELETE, g_IfDelCmdTable),
CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_IfShowCmdTable),
CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_IfSetCmdTable),
CREATE_CMD_GROUP_ENTRY(GROUP_RESET, g_IfResetCmdTable),
};
ULONG g_ulNumGroups = sizeof(g_IfCmdGroups)/sizeof(CMD_GROUP_ENTRY);
HANDLE g_hModule;
HANDLE g_hMprConfig = NULL;
HANDLE g_hMprAdmin = NULL;
HANDLE g_hMIBServer = NULL;
BOOL g_bCommit;
PWCHAR g_pwszRouter = NULL;
DWORD ParentVersion;
BOOL g_bIfDirty = FALSE;
ULONG g_ulInitCount;
NS_CONTEXT_CONNECT_FN IfConnect;
DWORD
WINAPI
IfCommit(
IN DWORD dwAction
)
{
BOOL bCommit, bFlush = FALSE;
switch(dwAction)
{
case NETSH_COMMIT:
{
if(g_bCommit)
{
return NO_ERROR;
}
g_bCommit = TRUE;
break;
}
case NETSH_UNCOMMIT:
{
g_bCommit = FALSE;
return NO_ERROR;
}
case NETSH_SAVE:
{
if(g_bCommit)
{
return NO_ERROR;
}
break;
}
case NETSH_FLUSH:
{
//
// Action is a flush. If current state is commit, then
// nothing to be done.
//
if(g_bCommit)
{
return NO_ERROR;
}
bFlush = TRUE;
break;
}
default:
{
return NO_ERROR;
}
}
//
// Switched to commit mode. So set all valid info in the
// strutures. Free memory and invalidate the info.
//
return NO_ERROR;
}
BOOL
WINAPI
IfDllEntry(
HINSTANCE hInstDll,
DWORD fdwReason,
LPVOID pReserved
)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
g_hModule = hInstDll;
DisableThreadLibraryCalls(hInstDll);
break;
}
case DLL_PROCESS_DETACH:
{
break;
}
default:
{
break;
}
}
return TRUE;
}
DWORD
WINAPI
IfStartHelper(
IN CONST GUID *pguidParent,
IN DWORD dwVersion
)
{
DWORD dwErr;
NS_CONTEXT_ATTRIBUTES attMyAttributes;
ParentVersion = dwVersion;
ZeroMemory(&attMyAttributes, sizeof(attMyAttributes));
attMyAttributes.pwszContext = L"interface";
attMyAttributes.guidHelper = g_IfGuid;
attMyAttributes.dwVersion = 1;
attMyAttributes.dwFlags = CMD_FLAG_PRIORITY;
attMyAttributes.ulPriority = 10; // very low so gets dumped first
attMyAttributes.ulNumTopCmds = 0;
attMyAttributes.pTopCmds = NULL;
attMyAttributes.ulNumGroups = g_ulNumGroups;
attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])&g_IfCmdGroups;
attMyAttributes.pfnCommitFn = IfCommit;
attMyAttributes.pfnDumpFn = IfDump;
attMyAttributes.pfnConnectFn= IfConnect;
dwErr = RegisterContext( &attMyAttributes );
return dwErr;
}
DWORD WINAPI
IfConnect(
IN LPCWSTR pwszRouter
)
{
// If context info is dirty, reregister it
if (g_bIfDirty)
{
IfStartHelper(NULL, ParentVersion);
}
return ConnectToRouter(pwszRouter);
}
DWORD WINAPI
InitHelperDll(
IN DWORD dwNetshVersion,
OUT PVOID pReserved
)
{
DWORD dwErr;
NS_HELPER_ATTRIBUTES attMyAttributes;
WSADATA wsa;
//
// See if this is the first time we are being called
//
if(InterlockedIncrement(&g_ulInitCount) != 1)
{
return NO_ERROR;
}
dwErr = WSAStartup(MAKEWORD(2,0), &wsa);
g_bCommit = TRUE;
// Register helpers
ZeroMemory( &attMyAttributes, sizeof(attMyAttributes) );
attMyAttributes.guidHelper = g_IfGuid;
attMyAttributes.dwVersion = IF_HELPER_VERSION;
attMyAttributes.pfnStart = IfStartHelper;
attMyAttributes.pfnStop = NULL;
RegisterHelper( &g_NetshGuid, &attMyAttributes );
//
// Register any sub contexts implemented in this dll
//
dwErr = IfContextInstallSubContexts();
if (dwErr isnot NO_ERROR)
{
IfUnInit(0);
return dwErr;
}
return NO_ERROR;
}
DWORD
ConnectToRouter(
IN LPCWSTR pwszRouter
)
{
DWORD dwErr = NO_ERROR;
do
{
// Change the router name if needed
//
if ((g_pwszRouter != pwszRouter) &&
(!g_pwszRouter || !pwszRouter || lstrcmpi(g_pwszRouter,pwszRouter)))
{
if (g_hMprConfig)
{
MprConfigServerDisconnect(g_hMprConfig);
g_hMprConfig = NULL;
}
if (g_hMprAdmin)
{
MprAdminServerDisconnect(g_hMprAdmin);
g_hMprAdmin = NULL;
}
if (g_hMIBServer)
{
MprAdminMIBServerDisconnect(g_hMIBServer);
g_hMIBServer = NULL;
}
}
// Cleanup the old router name
//
if (g_pwszRouter)
{
IfutlFree(g_pwszRouter);
}
// Copy the new router name in
//
if (pwszRouter)
{
g_pwszRouter = IfutlStrDup(pwszRouter);
if (g_pwszRouter == NULL)
{
dwErr = ERROR_CONNECT_REMOTE_CONFIG;
break;
}
}
else
{
g_pwszRouter = NULL;
}
if (!g_hMprConfig)
{
//
// first time connecting to router config
//
dwErr = MprConfigServerConnect((LPWSTR)pwszRouter, &g_hMprConfig);
if (dwErr isnot NO_ERROR)
{
//
// cannot connect to router config.
//
break;
}
}
//
// Check to see if router is running. If so, get the handles
//
if (MprAdminIsServiceRunning((LPWSTR)pwszRouter))
{
if(MprAdminServerConnect((LPWSTR)pwszRouter, &g_hMprAdmin) != NO_ERROR)
{
g_hMprAdmin = NULL;
}
}
} while (FALSE);
return dwErr;
}
DWORD
WINAPI
IfUnInit(
IN DWORD dwReserved
)
{
if(InterlockedDecrement(&g_ulInitCount) isnot 0)
{
return NO_ERROR;
}
return NO_ERROR;
}