windows-nt/Source/XPSP1/NT/net/rras/netsh/if/utils.c

1171 lines
25 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "precomp.h"
BOOL g_bRouterRunning;
ULONG g_ulNumChecks;
VOID
IfutlGetInterfaceName(
IN PWCHAR pwszIfDesc,
OUT PWCHAR pwszIfName,
IN PDWORD pdwSize
)
/*++
Routine Description:
Gets Guid Interface Name from Friendly Interface Name
Arguments:
pwszIfDesc - Buffer holding Friendly Interace Name
pwszIfName - Buffer to hold the Guid Interface Name
pdwSize - Pointer to the size (in Bytes) of pwszIfName buffer
--*/
{
DWORD dwErr;
dwErr = GetIfNameFromFriendlyName(pwszIfDesc,
pwszIfName,
pdwSize);
if(dwErr isnot NO_ERROR)
{
wcsncpy(pwszIfName,
pwszIfDesc,
(*pdwSize)/sizeof(WCHAR));
}
}
VOID
IfutlGetInterfaceDescription(
IN PWCHAR pwszIfName,
OUT PWCHAR pwszIfDesc,
IN PDWORD pdwSize
)
/*++
Routine Description:
Gets Friendly Interface Name from Guid Interface Name
Arguments:
pwszIfName - Buffer holding Guid Interace Name
pwszIfDesc - Buffer to hold the Friendly Interface Name
pdwSize - Pointer to the size (in Bytes) of pwszIfDesc buffer
--*/
{
DWORD dwErr;
DWORD dwLen = (*pdwSize)/sizeof(WCHAR) - 1;
dwErr = GetFriendlyNameFromIfName(pwszIfName,
pwszIfDesc,
pdwSize);
if(dwErr isnot NO_ERROR)
{
wcsncpy(pwszIfDesc,
pwszIfName,
dwLen);
pwszIfDesc[dwLen] = 0;
}
}
DWORD
IfutlGetTagToken(
IN HANDLE hModule,
IN PWCHAR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN PTAG_TYPE pttTagToken,
IN DWORD dwNumTags,
OUT PDWORD pdwOut
)
/*++
Routine Description:
Identifies each argument based on its tag. It assumes that each argument
has a tag. It also removes tag= from each argument.
Arguments:
ppwcArguments - The argument array. Each argument has tag=value form
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is first arg.
dwArgCount - ppwcArguments[dwArgCount - 1] is last arg.
pttTagToken - Array of tag token ids that are allowed in the args
dwNumTags - Size of pttTagToken
pdwOut - Array identifying the type of each argument.
Return Value:
NO_ERROR, ERROR_INVALID_PARAMETER, ERROR_INVALID_OPTION_TAG
--*/
{
DWORD i,j,len;
PWCHAR pwcTag,pwcTagVal,pwszArg;
BOOL bFound = FALSE;
//
// This function assumes that every argument has a tag
// It goes ahead and removes the tag.
//
for (i = dwCurrentIndex; i < dwArgCount; i++)
{
len = wcslen(ppwcArguments[i]);
if (len is 0)
{
//
// something wrong with arg
//
pdwOut[i] = (DWORD) -1;
continue;
}
pwszArg = HeapAlloc(GetProcessHeap(),0,(len + 1) * sizeof(WCHAR));
if (pwszArg is NULL)
{
DisplayError(NULL,
ERROR_NOT_ENOUGH_MEMORY);
return ERROR_NOT_ENOUGH_MEMORY;
}
wcscpy(pwszArg, ppwcArguments[i]);
pwcTag = wcstok(pwszArg, NETSH_ARG_DELIMITER);
//
// Got the first part
// Now if next call returns NULL then there was no tag
//
pwcTagVal = wcstok((PWCHAR)NULL, NETSH_ARG_DELIMITER);
if (pwcTagVal is NULL)
{
DisplayMessage(g_hModule,
ERROR_NO_TAG,
ppwcArguments[i]);
HeapFree(GetProcessHeap(),0,pwszArg);
return ERROR_INVALID_PARAMETER;
}
//
// Got the tag. Now try to match it
//
bFound = FALSE;
pdwOut[i - dwCurrentIndex] = (DWORD) -1;
for ( j = 0; j < dwNumTags; j++)
{
if (MatchToken(pwcTag, pttTagToken[j].pwszTag))
{
//
// Tag matched
//
bFound = TRUE;
pdwOut[i - dwCurrentIndex] = j;
break;
}
}
if (bFound)
{
//
// Remove tag from the argument
//
wcscpy(ppwcArguments[i], pwcTagVal);
}
else
{
DisplayError(NULL,
ERROR_INVALID_OPTION_TAG,
pwcTag);
HeapFree(GetProcessHeap(),0,pwszArg);
return ERROR_INVALID_OPTION_TAG;
}
HeapFree(GetProcessHeap(),0,pwszArg);
}
return NO_ERROR;
}
//
// Helper to IfutlParse that parses options
//
DWORD
WINAPI
IfutlParseOptions(
IN PWCHAR* ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwNumArgs,
IN TAG_TYPE* rgTags,
IN DWORD dwTagCount,
OUT LPDWORD* ppdwTagTypes)
/*++
Routine Description:
Based on an array of tag types returns which options are
included in the given command line.
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
LPDWORD pdwTagType;
DWORD i, dwErr = NO_ERROR;
// If there are no arguments, there's nothing to to
//
if ( dwNumArgs == 0 )
{
return NO_ERROR;
}
// Set up the table of present options
pdwTagType = (LPDWORD) IfutlAlloc(dwArgCount * sizeof(DWORD), TRUE);
if(pdwTagType is NULL)
{
DisplayError(NULL, ERROR_NOT_ENOUGH_MEMORY);
return ERROR_NOT_ENOUGH_MEMORY;
}
do {
//
// The argument has a tag. Assume all of them have tags
//
if(wcsstr(ppwcArguments[dwCurrentIndex], NETSH_ARG_DELIMITER))
{
dwErr = IfutlGetTagToken(
g_hModule,
ppwcArguments,
dwCurrentIndex,
dwArgCount,
rgTags,
dwTagCount,
pdwTagType);
if(dwErr isnot NO_ERROR)
{
if(dwErr is ERROR_INVALID_OPTION_TAG)
{
dwErr = ERROR_INVALID_SYNTAX;
break;
}
}
}
else
{
//
// No tags - all args must be in order
//
for(i = 0; i < dwNumArgs; i++)
{
pdwTagType[i] = i;
}
}
} while (FALSE);
// Cleanup
{
if (dwErr is NO_ERROR)
{
*ppdwTagTypes = pdwTagType;
}
else
{
IfutlFree(pdwTagType);
}
}
return dwErr;
}
//
// Generic parse
//
DWORD
IfutlParse(
IN PWCHAR* ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN BOOL* pbDone,
OUT IFMON_CMD_ARG* pIfArgs,
IN DWORD dwIfArgCount)
{
DWORD i, dwNumArgs, dwErr, dwLevel = 0;
LPDWORD pdwTagType = NULL;
TAG_TYPE* pTags = NULL;
IFMON_CMD_ARG* pArg = NULL;
if (dwIfArgCount == 0)
{
return ERROR_INVALID_PARAMETER;
}
do {
// Initialize
dwNumArgs = dwArgCount - dwCurrentIndex;
// Generate a list of the tags
//
pTags = (TAG_TYPE*)
IfutlAlloc(dwIfArgCount * sizeof(TAG_TYPE), TRUE);
if (pTags == NULL)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
for (i = 0; i < dwIfArgCount; i++)
{
CopyMemory(&pTags[i], &pIfArgs[i].rgTag, sizeof(TAG_TYPE));
}
// Get the list of present options
//
dwErr = IfutlParseOptions(
ppwcArguments,
dwCurrentIndex,
dwArgCount,
dwNumArgs,
pTags,
dwIfArgCount,
&pdwTagType);
if (dwErr isnot NO_ERROR)
{
break;
}
// Copy the tag info back
//
for (i = 0; i < dwIfArgCount; i++)
{
CopyMemory(&pIfArgs[i].rgTag, &pTags[i], sizeof(TAG_TYPE));
}
for(i = 0; i < dwNumArgs; i++)
{
// Validate the current argument
//
if (pdwTagType[i] >= dwIfArgCount)
{
i = dwNumArgs;
dwErr = ERROR_INVALID_SYNTAX;
break;
}
pArg = &pIfArgs[pdwTagType[i]];
// Get the value of the argument
//
switch (pArg->dwType)
{
case IFMON_CMD_TYPE_STRING:
pArg->Val.pszValue =
IfutlStrDup(ppwcArguments[i + dwCurrentIndex]);
break;
case IFMON_CMD_TYPE_ENUM:
dwErr = MatchEnumTag(g_hModule,
ppwcArguments[i + dwCurrentIndex],
pArg->dwEnumCount,
pArg->rgEnums,
&(pArg->Val.dwValue));
if(dwErr != NO_ERROR)
{
IfutlDispTokenErrMsg(
g_hModule,
EMSG_BAD_OPTION_VALUE,
pArg->rgTag.pwszTag,
ppwcArguments[i + dwCurrentIndex]);
i = dwNumArgs;
dwErr = ERROR_INVALID_PARAMETER;
}
break;
}
if (dwErr != NO_ERROR)
{
break;
}
// Mark the argument as present if needed
//
if (pArg->rgTag.bPresent)
{
dwErr = ERROR_TAG_ALREADY_PRESENT;
i = dwNumArgs;
break;
}
pArg->rgTag.bPresent = TRUE;
}
if(dwErr isnot NO_ERROR)
{
break;
}
// Make sure that all of the required parameters have
// been included.
//
for (i = 0; i < dwIfArgCount; i++)
{
if ((pIfArgs[i].rgTag.dwRequired & NS_REQ_PRESENT)
&& !pIfArgs[i].rgTag.bPresent)
{
DisplayMessage(g_hModule, EMSG_CANT_FIND_EOPT);
dwErr = ERROR_INVALID_SYNTAX;
break;
}
}
if(dwErr isnot NO_ERROR)
{
break;
}
} while (FALSE);
// Cleanup
{
if (pTags)
{
IfutlFree(pTags);
}
if (pdwTagType)
{
IfutlFree(pdwTagType);
}
}
return dwErr;
}
//
// Returns an allocated block of memory conditionally
// zeroed of the given size.
//
PVOID
WINAPI
IfutlAlloc(
IN DWORD dwBytes,
IN BOOL bZero
)
{
PVOID pvRet;
DWORD dwFlags = 0;
if (bZero)
{
dwFlags |= HEAP_ZERO_MEMORY;
}
return HeapAlloc(GetProcessHeap(), dwFlags, dwBytes);
}
//
// Conditionally free's a pointer if it is non-null
//
VOID
WINAPI
IfutlFree(
IN PVOID pvData
)
{
if (pvData)
{
HeapFree(GetProcessHeap(), 0, pvData);
}
}
//
// Uses IfutlAlloc to copy a string
//
PWCHAR
WINAPI
IfutlStrDup(
IN LPCWSTR pwszSrc
)
{
PWCHAR pszRet = NULL;
DWORD dwLen;
if ((pwszSrc is NULL) or
((dwLen = wcslen(pwszSrc)) == 0)
)
{
return NULL;
}
pszRet = (PWCHAR) IfutlAlloc((dwLen + 1) * sizeof(WCHAR), FALSE);
if (pszRet isnot NULL)
{
wcscpy(pszRet, pwszSrc);
}
return pszRet;
}
BOOL
IfutlIsRouterRunning(
VOID
)
/*++
Routine Description:
Gets the status of the router
Arguments:
Return Value:
--*/
{
DWORD dwErr;
//
// Check every 5th call
//
if(g_ulNumChecks isnot 0)
{
return g_bRouterRunning;
}
g_ulNumChecks++;
g_ulNumChecks %= 5;
if(MprAdminIsServiceRunning(g_pwszRouter))
{
if(g_bRouterRunning)
{
return TRUE;
}
dwErr = MprAdminServerConnect(g_pwszRouter,
&g_hMprAdmin);
if(dwErr isnot NO_ERROR)
{
DisplayError(NULL,
dwErr);
DisplayMessage(g_hModule,
EMSG_CAN_NOT_CONNECT_DIM,
dwErr);
return FALSE;
}
dwErr = MprAdminMIBServerConnect(g_pwszRouter,
&g_hMIBServer);
if(dwErr isnot NO_ERROR)
{
DisplayError(NULL,
dwErr);
DisplayMessage(g_hModule,
EMSG_CAN_NOT_CONNECT_DIM,
dwErr);
MprAdminServerDisconnect(g_hMprAdmin);
g_hMprAdmin = NULL;
return FALSE;
}
g_bRouterRunning = TRUE;
}
else
{
if(g_bRouterRunning)
{
g_bRouterRunning = FALSE;
g_hMprAdmin = NULL;
g_hMIBServer = NULL;
}
}
return g_bRouterRunning;
}
DWORD
GetIpAddress(
IN PWCHAR ppwcArg,
OUT PIPV4_ADDRESS pipAddress
)
/*++
Routine Description:
Gets the ip address from the string.
Arguments:
pwszIpAddr - Ip address string
pipAddress - IP address
Return Value:
NO_ERROR, ERROR_INVALID_PARAMETER
--*/
{
CHAR pszIpAddr[ADDR_LENGTH+1];
// Make sure all characters are legal [0-9.]
if (ppwcArg[ wcsspn(ppwcArg, L"0123456789.") ])
{
return ERROR_INVALID_PARAMETER;
}
// make sure there are 3 "." (periods)
{
DWORD i;
PWCHAR TmpPtr;
for (i=0,TmpPtr=ppwcArg; ; i++) {
TmpPtr = wcschr(TmpPtr, L'.');
if (TmpPtr)
TmpPtr++;
else
break;
}
if (i!=3)
return ERROR_INVALID_PARAMETER;
}
WideCharToMultiByte(GetConsoleOutputCP(),
0,
ppwcArg,
-1,
pszIpAddr,
ADDR_LENGTH,
NULL,
NULL);
pszIpAddr[ADDR_LENGTH] = '\0';
*pipAddress = (DWORD) inet_addr(pszIpAddr);
// if there was an error, make sure that the address
// specified was not 255.255.255.255
if (*pipAddress == INADDR_NONE
&& wcscmp(ppwcArg,L"255.255.255.255"))
{
return ERROR_INVALID_PARAMETER;
}
if ((*pipAddress&0x000000FF) == 0)
return ERROR_INVALID_PARAMETER;
return NO_ERROR;
}
// NOTE: CheckMask fails when IpAddr is 0xffffffff!
BOOL
CheckMask(
DWORD IpAddr
)
{
DWORD i,Mask;
IpAddr = htonl(IpAddr);
for (i=0,Mask=0; i<32; (Mask = ((Mask>>1) + 0x80000000)), i++ ) {
if (IpAddr == Mask)
return FALSE;
}
return TRUE;
}
DWORD
IfutlGetIfIndexFromFriendlyName(
PWCHAR IfFriendlyName,
PULONG pdwIfIndex
)
{
WCHAR wszGuid[200];
DWORD dwSize = sizeof(wszGuid);
IfutlGetInterfaceName(
IfFriendlyName,
wszGuid,
&dwSize
);
return IfutlGetIfIndexFromInterfaceName(
wszGuid,
pdwIfIndex);
}
DWORD
IfutlGetIfIndexFromInterfaceName(
IN PWCHAR pwszGuid,
OUT PDWORD pdwIfIndex
)
{
GUID guid;
DWORD dwErr, i, dwCount;
PIP_INTERFACE_NAME_INFO pTable;
BOOL bFound = FALSE;
PWCHAR TmpGuid;
*pdwIfIndex = 0;
dwErr = NhpAllocateAndGetInterfaceInfoFromStack(
&pTable,
&dwCount,
FALSE,
GetProcessHeap(),
0);
if (dwErr != NO_ERROR)
return dwErr;
for (i=0; i<dwCount; i++) {
dwErr = StringFromCLSID(&pTable[i].DeviceGuid, &TmpGuid);
if (dwErr != S_OK)
return dwErr;
if (wcscmp(TmpGuid, pwszGuid) == 0) {
bFound = TRUE;
*pdwIfIndex = pTable[i].Index;
break;
}
CoTaskMemFree(TmpGuid);
}
if (!bFound)
return ERROR_CAN_NOT_COMPLETE;
return NO_ERROR;
}
DWORD
WINAPI
InterfaceEnum(
OUT PBYTE *ppb,
OUT PDWORD pdwCount,
OUT PDWORD pdwTotal
)
{
DWORD dwRes;
PMPR_INTERFACE_0 pmi0;
/*if(!IsRouterRunning())*/
{
dwRes = MprConfigInterfaceEnum(g_hMprConfig,
0,
(LPBYTE*) &pmi0,
(DWORD) -1,
pdwCount,
pdwTotal,
NULL);
if(dwRes == NO_ERROR)
{
*ppb = (PBYTE)pmi0;
}
}
/*else
{
dwRes = MprAdminInterfaceEnum(g_hMprAdmin,
0,
(LPBYTE*) &pmi0,
(DWORD) -1,
pdwCount,
pdwTotal,
NULL);
if(dwRes == NO_ERROR)
{
*ppb = HeapAlloc(GetProcessHeap(),
0,
sizeof(MPR_INTERFACE_0) * (*pdwCount));
if(*ppb == NULL)
{
DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
return ERROR_NOT_ENOUGH_MEMORY;
}
CopyMemory(*ppb, pmi0, sizeof(MPR_INTERFACE_0) * (*pdwCount));
MprAdminBufferFree(pmi0);
}
}*/
return dwRes;
}
VOID
MakeAddressStringW(
OUT PWCHAR pwcPrefixStr,
IN IPV4_ADDRESS ipAddr
)
{
swprintf( pwcPrefixStr,
L"%d.%d.%d.%d",
PRINT_IPADDR(ipAddr) );
}
DWORD
GetGuidFromIfIndex(
IN MIB_SERVER_HANDLE hMibServer,
IN DWORD dwIfIndex,
OUT PWCHAR pwszBuffer,
IN DWORD dwBufferSize
)
{
MIB_OPAQUE_QUERY Query;
PMIB_IFROW pIfRow;
DWORD dwErr, dwOutEntrySize;
PMIB_OPAQUE_INFO pRpcInfo;
Query.dwVarId = IF_ROW;
Query.rgdwVarIndex[0] = dwIfIndex;
dwErr = MibGet( PID_IP,
IPRTRMGR_PID,
(PVOID) &Query,
sizeof(Query),
(PVOID *) &pRpcInfo,
&dwOutEntrySize );
if (dwErr isnot NO_ERROR)
{
return dwErr;
}
pIfRow = (PMIB_IFROW)(pRpcInfo->rgbyData);
wcscpy( pwszBuffer, pIfRow->wszName );
MprAdminMIBBufferFree( (PVOID) pRpcInfo );
return NO_ERROR;
}
DWORD
IfutlGetFriendlyNameFromIfIndex(
IN MIB_SERVER_HANDLE hMibServer,
IN DWORD dwIfIndex,
OUT PWCHAR pwszBuffer,
IN DWORD dwBufferSize
)
/*++
Routine Description:
Gets Friendly Interface Name from Interface Index
Arguments:
hMibServer - Handle to the MIB server
dwIfIndex - Interface index
pwszBuffer - Buffer to hold the Friendly Interface Name
dwBufferSize - Size (in Bytes) of pwszBuffer buffer
--*/
{
WCHAR wszGuid[MAX_INTERFACE_NAME_LEN + 1];
DWORD dwErr;
dwErr = GetGuidFromIfIndex(hMibServer, dwIfIndex, wszGuid, sizeof(wszGuid));
if (dwErr isnot NO_ERROR)
{
return dwErr;
}
IfutlGetInterfaceDescription(wszGuid, pwszBuffer, &dwBufferSize);
return NO_ERROR;
}
DWORD
GetMibTagToken(
IN PWCHAR *ppwcArguments,
IN DWORD dwArgCount,
IN DWORD dwNumIndices,
OUT PDWORD pdwRR,
OUT PBOOL pbIndex,
OUT PDWORD pdwIndex
)
/*++
Routine Description:
Looks for indices and refresh rate arguments in the command. If index
tag is present, it would be of the form index= index1 index2 ....
The index= is removed by this function. So is rr= if it is there in
the command. If pdwRR is 0 then, no refresh sought.
Arguments:
ppwcArguments - The argument array. Each argument has tag=value form
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is first arg.
dwArgCount - ppwcArguments[dwArgCount - 1] is last arg.
pttTagToken - Array of tag token ids that are allowed in the args
dwNumTags - Size of pttTagToken
pdwOut - Array identifying the type of each argument.
Return Value:
NO_ERROR, ERROR_INVALID_PARAMETER, ERROR_INVALID_OPTION_TAG
--*/
{
DWORD i;
BOOL bTag;
if (dwArgCount is 0)
{
*pdwRR = 0;
*pbIndex = FALSE;
return NO_ERROR;
}
if (dwArgCount < dwNumIndices)
{
//
// No index
//
*pbIndex = FALSE;
if (dwArgCount > 1)
{
*pdwRR = 0;
return ERROR_INVALID_PARAMETER;
}
//
// No Index specified. Make sure refresh rate is specified
// with tag.
//
if (_wcsnicmp(ppwcArguments[0],L"RR=",3) == 0)
{
//
// get the refresh rate
//
*pdwRR = wcstoul(&ppwcArguments[0][3], NULL, 10);
}
else
{
return ERROR_INVALID_PARAMETER;
}
}
else
{
//
// Check for index tag
//
if (_wcsnicmp(ppwcArguments[0],L"INDEX=",6) == 0)
{
*pbIndex = TRUE;
*pdwIndex = 0;
//
// remove tag and see if refresh rate is specified
//
wcscpy(ppwcArguments[0], &ppwcArguments[0][6]);
if (dwArgCount > dwNumIndices)
{
//
// Make sure that argument has RR tag
//
if (_wcsnicmp(ppwcArguments[dwNumIndices],L"RR=",3) == 0)
{
//
// get the refresh rate
//
*pdwRR = wcstoul(&ppwcArguments[dwNumIndices][3], NULL , 10);
}
else
{
return ERROR_INVALID_PARAMETER;
}
}
else
{
//
// No refresh rate specified
//
*pdwRR = 0;
return NO_ERROR;
}
}
else
{
//
// Not index tag, See if it has an RR tag
//
if (_wcsnicmp(ppwcArguments[0],L"RR=",3) == 0)
{
//
// get the refresh rate
//
*pdwRR = wcstoul(&ppwcArguments[0][3], NULL , 10);
//
// See if the index follows
//
if (dwArgCount > dwNumIndices)
{
if (dwArgCount > 1)
{
if (_wcsnicmp(ppwcArguments[1],L"INDEX=",6) == 0)
{
wcscpy(ppwcArguments[1], &ppwcArguments[1][6]);
*pbIndex = TRUE;
*pdwIndex = 1;
return NO_ERROR;
}
else
{
*pdwRR = 0;
return ERROR_INVALID_PARAMETER;
}
}
else
{
return NO_ERROR;
}
}
}
//
// No RR Tag either
//
else if (dwArgCount > dwNumIndices)
{
//
// Assume ppwcArguments[dwNumIndices] is the refresh rate
//
*pdwRR = wcstoul(ppwcArguments[dwNumIndices], NULL , 10);
if (dwNumIndices != 0)
{
*pbIndex = TRUE;
*pdwIndex = 0;
}
}
else
{
//
// only index present with no tag
//
*pbIndex = TRUE;
*pdwIndex = 0;
}
}
}
return NO_ERROR;
}
DWORD
MibGet(
DWORD dwTransportId,
DWORD dwRoutingPid,
LPVOID lpInEntry,
DWORD dwInEntrySize,
LPVOID *lplpOutEntry,
LPDWORD lpdwOutEntrySize
)
{
DWORD dwErr;
dwErr = MprAdminMIBEntryGet( g_hMIBServer,
dwTransportId,
dwRoutingPid,
lpInEntry,
dwInEntrySize,
lplpOutEntry,
lpdwOutEntrySize );
if (dwErr is RPC_S_INVALID_BINDING)
{
g_bRouterRunning = FALSE;
g_hMprAdmin = NULL;
g_hMIBServer = NULL;
}
return dwErr;
}