2491 lines
66 KiB
C
2491 lines
66 KiB
C
/********************************************************************/
|
||
/** Copyright(c) 1995 Microsoft Corporation. **/
|
||
/********************************************************************/
|
||
|
||
//***
|
||
//
|
||
// Filename: registry.c
|
||
//
|
||
// Description: This module contains the code for DIM parameters
|
||
// initialization and loading from the registry.
|
||
//
|
||
// History: May 11,1995 NarenG Created original version.
|
||
//
|
||
|
||
#include "dimsvcp.h"
|
||
|
||
#define DIM_KEYPATH_ROUTER_PARMS TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\Parameters")
|
||
|
||
#define DIM_KEYPATH_ROUTERMANAGERS TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\RouterManagers")
|
||
|
||
#define DIM_KEYPATH_INTERFACES TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\Interfaces")
|
||
|
||
#define DIM_KEYPATH_DDM TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\DemandDialManager")
|
||
|
||
#define DIM_VALNAME_GLOBALINFO TEXT("GlobalInfo")
|
||
#define DIM_VALNAME_GLOBALINTERFACE TEXT("GlobalInterfaceInfo")
|
||
#define DIM_VALNAME_ROUTERROLE TEXT("RouterType")
|
||
#define DIM_VALNAME_LOGGINGLEVEL TEXT("LoggingFlags")
|
||
#define DIM_VALNAME_DLLPATH TEXT("DLLPath")
|
||
#define DIM_VALNAME_TYPE TEXT("Type")
|
||
#define DIM_VALNAME_PROTOCOLID TEXT("ProtocolId")
|
||
#define DIM_VALNAME_INTERFACE TEXT("InterfaceInfo")
|
||
#define DIM_VALNAME_INTERFACE_NAME TEXT("InterfaceName")
|
||
#define DIM_VALNAME_ENABLED TEXT("Enabled")
|
||
#define DIM_VALNAME_DIALOUT_HOURS TEXT("DialOutHours")
|
||
#define DIM_VALNAME_MIN_UNREACHABILITY_INTERVAL \
|
||
TEXT("MinUnreachabilityInterval")
|
||
#define DIM_VALNAME_MAX_UNREACHABILITY_INTERVAL \
|
||
TEXT("MaxUnreachabilityInterval")
|
||
|
||
static DWORD gbldwInterfaceType;
|
||
static DWORD gbldwProtocolId;
|
||
static BOOL gblfEnabled;
|
||
static BOOL gblInterfaceReachableAfterSecondsMin;
|
||
static BOOL gblInterfaceReachableAfterSecondsMax;
|
||
|
||
typedef struct _DIM_REGISTRY_PARAMS
|
||
{
|
||
LPWSTR lpwsValueName;
|
||
DWORD * pValue;
|
||
DWORD dwDefValue;
|
||
DWORD dwMinValue;
|
||
DWORD dwMaxValue;
|
||
|
||
} DIM_REGISTRY_PARAMS, *PDIM_REGISTRY_PARAMS;
|
||
|
||
//
|
||
// DIM parameter descriptor table
|
||
//
|
||
|
||
DIM_REGISTRY_PARAMS DIMRegParams[] =
|
||
{
|
||
DIM_VALNAME_ROUTERROLE,
|
||
&(gblDIMConfigInfo.dwRouterRole),
|
||
ROUTER_ROLE_RAS | ROUTER_ROLE_LAN | ROUTER_ROLE_WAN,
|
||
0,
|
||
ROUTER_ROLE_RAS | ROUTER_ROLE_LAN | ROUTER_ROLE_WAN,
|
||
|
||
DIM_VALNAME_LOGGINGLEVEL,
|
||
&(gblDIMConfigInfo.dwLoggingLevel),
|
||
DEF_LOGGINGLEVEL,
|
||
MIN_LOGGINGLEVEL,
|
||
MAX_LOGGINGLEVEL,
|
||
|
||
NULL, NULL, 0, 0, 0
|
||
};
|
||
|
||
//
|
||
// Interface parameters descriptor table
|
||
//
|
||
|
||
typedef struct _IF_REGISTRY_PARAMS
|
||
{
|
||
LPWSTR lpwsValueName;
|
||
DWORD * pValue;
|
||
DWORD dwDefValue;
|
||
DWORD dwMinValue;
|
||
DWORD dwMaxValue;
|
||
|
||
} IF_REGISTRY_PARAMS, *PIF_REGISTRY_PARAMS;
|
||
|
||
IF_REGISTRY_PARAMS IFRegParams[] =
|
||
{
|
||
DIM_VALNAME_TYPE,
|
||
&gbldwInterfaceType,
|
||
0,
|
||
1,
|
||
6,
|
||
|
||
DIM_VALNAME_ENABLED,
|
||
&gblfEnabled,
|
||
1,
|
||
0,
|
||
1,
|
||
|
||
DIM_VALNAME_MIN_UNREACHABILITY_INTERVAL,
|
||
&gblInterfaceReachableAfterSecondsMin,
|
||
300, // 5 minutes
|
||
0,
|
||
0xFFFFFFFF,
|
||
|
||
DIM_VALNAME_MAX_UNREACHABILITY_INTERVAL,
|
||
&gblInterfaceReachableAfterSecondsMax,
|
||
21600, // 6 hours
|
||
0,
|
||
0xFFFFFFFF,
|
||
|
||
NULL, NULL, 0, 0, 0
|
||
};
|
||
|
||
//
|
||
// Router Manager Globals descriptor table
|
||
//
|
||
|
||
typedef struct _GLOBALRM_REGISTRY_PARAMS
|
||
{
|
||
LPWSTR lpwsValueName;
|
||
LPVOID pValue;
|
||
LPBYTE * ppValue;
|
||
DWORD dwType;
|
||
|
||
} GLOBALRM_REGISTRY_PARAMS, *PGLOBALRM_REGISTRY_PARAMS;
|
||
|
||
|
||
GLOBALRM_REGISTRY_PARAMS GlobalRMRegParams[] =
|
||
{
|
||
DIM_VALNAME_PROTOCOLID,
|
||
&gbldwProtocolId,
|
||
NULL,
|
||
REG_DWORD,
|
||
|
||
DIM_VALNAME_GLOBALINFO,
|
||
NULL,
|
||
NULL,
|
||
REG_BINARY,
|
||
|
||
DIM_VALNAME_DLLPATH,
|
||
NULL,
|
||
NULL,
|
||
REG_BINARY,
|
||
|
||
DIM_VALNAME_GLOBALINTERFACE,
|
||
NULL,
|
||
NULL,
|
||
REG_BINARY,
|
||
|
||
NULL, NULL, NULL, 0
|
||
};
|
||
|
||
//
|
||
// Router Manager descriptor table
|
||
//
|
||
|
||
|
||
typedef struct _RM_REGISTRY_PARAMS
|
||
{
|
||
LPWSTR lpwsValueName;
|
||
LPVOID pValue;
|
||
LPBYTE * ppValue;
|
||
DWORD dwType;
|
||
|
||
} RM_REGISTRY_PARAMS, *PRM_REGISTRY_PARAMS;
|
||
|
||
|
||
RM_REGISTRY_PARAMS RMRegParams[] =
|
||
{
|
||
DIM_VALNAME_PROTOCOLID,
|
||
&gbldwProtocolId,
|
||
NULL,
|
||
REG_DWORD,
|
||
|
||
DIM_VALNAME_INTERFACE,
|
||
NULL,
|
||
NULL,
|
||
REG_BINARY,
|
||
|
||
NULL, NULL, NULL, 0
|
||
};
|
||
|
||
//**
|
||
//
|
||
// Call: GetKeyMax
|
||
//
|
||
// Returns: NO_ERROR - success
|
||
// non-zero return code - Failure
|
||
//
|
||
// Description: Returns the nr of values in this key and the maximum
|
||
// size of the value data.
|
||
//
|
||
DWORD
|
||
GetKeyMax(
|
||
IN HKEY hKey,
|
||
OUT LPDWORD lpcbMaxValNameSize, // longest valuename
|
||
OUT LPDWORD lpcNumValues, // nr of values
|
||
OUT LPDWORD lpcbMaxValueDataSize, // max size of data
|
||
OUT LPDWORD lpcNumSubKeys
|
||
)
|
||
{
|
||
DWORD dwRetCode = RegQueryInfoKey(
|
||
hKey,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
lpcNumSubKeys,
|
||
NULL,
|
||
NULL,
|
||
lpcNumValues,
|
||
lpcbMaxValNameSize,
|
||
lpcbMaxValueDataSize,
|
||
NULL,
|
||
NULL );
|
||
|
||
(*lpcbMaxValNameSize)++;
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: RegLoadDimParameters
|
||
//
|
||
// Returns: NO_ERROR - success
|
||
// non-zero return code - Failure
|
||
//
|
||
// Description: Opens the registry, reads and sets specified router
|
||
// parameters. If fatal error reading parameters writes the
|
||
// error log.
|
||
//***
|
||
DWORD
|
||
RegLoadDimParameters(
|
||
VOID
|
||
)
|
||
{
|
||
HKEY hKey;
|
||
DWORD dwIndex;
|
||
DWORD dwRetCode;
|
||
DWORD cbValueBuf;
|
||
DWORD dwType;
|
||
WCHAR * pChar;
|
||
|
||
//
|
||
// get handle to the DIM parameters key
|
||
//
|
||
|
||
if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
DIM_KEYPATH_ROUTER_PARMS,
|
||
0,
|
||
KEY_READ,
|
||
&hKey ) )
|
||
{
|
||
pChar = DIM_KEYPATH_ROUTER_PARMS;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Run through and get all the DIM values
|
||
//
|
||
|
||
for ( dwIndex = 0; DIMRegParams[dwIndex].lpwsValueName != NULL; dwIndex++ )
|
||
{
|
||
cbValueBuf = sizeof( DWORD );
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKey,
|
||
DIMRegParams[dwIndex].lpwsValueName,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)(DIMRegParams[dwIndex].pValue),
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ((dwRetCode != NO_ERROR) && (dwRetCode != ERROR_FILE_NOT_FOUND))
|
||
{
|
||
pChar = DIMRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
if ( dwRetCode == ERROR_FILE_NOT_FOUND )
|
||
{
|
||
*(DIMRegParams[dwIndex].pValue) = DIMRegParams[dwIndex].dwDefValue;
|
||
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
else
|
||
{
|
||
if ( ( dwType != REG_DWORD )
|
||
||(*(DIMRegParams[dwIndex].pValue) >
|
||
DIMRegParams[dwIndex].dwMaxValue)
|
||
||( *(DIMRegParams[dwIndex].pValue) <
|
||
DIMRegParams[dwIndex].dwMinValue))
|
||
{
|
||
pChar = DIMRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogWarning( ROUTERLOG_REGVALUE_OVERIDDEN, 1, &pChar );
|
||
|
||
*(DIMRegParams[dwIndex].pValue) =
|
||
DIMRegParams[dwIndex].dwDefValue;
|
||
}
|
||
}
|
||
}
|
||
|
||
RegCloseKey(hKey);
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: RegLoadRouterManagers
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// non-zero erroc code - Failure
|
||
//
|
||
// Description: Will load the various router managers and exchange entry points
|
||
// with them
|
||
//
|
||
//***
|
||
DWORD
|
||
RegLoadRouterManagers(
|
||
VOID
|
||
)
|
||
{
|
||
HKEY hKey = NULL;
|
||
HKEY hKeyRouterManager = NULL;
|
||
WCHAR * pChar;
|
||
DWORD dwRetCode = NO_ERROR;
|
||
DWORD cbMaxValueDataSize;
|
||
DWORD cbMaxValNameSize;
|
||
DWORD cNumValues;
|
||
WCHAR wchSubKeyName[100];
|
||
DWORD cbSubKeyName;
|
||
DWORD cNumSubKeys;
|
||
DWORD dwKeyIndex;
|
||
DWORD cbValueBuf;
|
||
LPBYTE pInterfaceInfo = NULL;
|
||
LPBYTE pGlobalInfo = NULL;
|
||
LPBYTE pDLLPath = NULL;
|
||
WCHAR * pDllExpandedPath= NULL;
|
||
DWORD dwType;
|
||
DWORD cbSize;
|
||
DWORD dwIndex;
|
||
FILETIME LastWrite;
|
||
DWORD dwMaxFilterSize;
|
||
DWORD (*StartRouter)(
|
||
IN OUT DIM_ROUTER_INTERFACE * pDimRouterIf,
|
||
IN BOOL fLANModeOnly,
|
||
IN LPVOID pGlobalInfo );
|
||
|
||
//
|
||
// get handle to the Router Managers key
|
||
//
|
||
|
||
dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
DIM_KEYPATH_ROUTERMANAGERS,
|
||
0,
|
||
KEY_READ,
|
||
&hKey );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = DIM_KEYPATH_ROUTERMANAGERS;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
return ( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Find out the number of subkeys
|
||
//
|
||
|
||
dwRetCode = GetKeyMax( hKey,
|
||
&cbMaxValNameSize,
|
||
&cNumValues,
|
||
&cbMaxValueDataSize,
|
||
&cNumSubKeys );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
RegCloseKey( hKey );
|
||
|
||
pChar = DIM_KEYPATH_ROUTERMANAGERS;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
gblDIMConfigInfo.dwNumRouterManagers = cNumSubKeys;
|
||
|
||
gblRouterManagers = (ROUTER_MANAGER_OBJECT *)LOCAL_ALLOC( LPTR,
|
||
sizeof(ROUTER_MANAGER_OBJECT) * MAX_NUM_ROUTERMANAGERS);
|
||
|
||
if ( gblRouterManagers == (ROUTER_MANAGER_OBJECT *)NULL )
|
||
{
|
||
RegCloseKey( hKey );
|
||
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = DIM_KEYPATH_ROUTERMANAGERS;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
|
||
{
|
||
DWORD cNumSubSubKeys;
|
||
|
||
cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
|
||
|
||
dwRetCode = RegEnumKeyEx(
|
||
hKey,
|
||
dwKeyIndex,
|
||
wchSubKeyName,
|
||
&cbSubKeyName,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&LastWrite
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
|
||
{
|
||
pChar = DIM_KEYPATH_ROUTERMANAGERS;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RegOpenKeyEx( hKey,
|
||
wchSubKeyName,
|
||
0,
|
||
KEY_READ,
|
||
&hKeyRouterManager );
|
||
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Find out the size of the path value.
|
||
//
|
||
|
||
dwRetCode = GetKeyMax( hKeyRouterManager,
|
||
&cbMaxValNameSize,
|
||
&cNumValues,
|
||
&cbMaxValueDataSize,
|
||
&cNumSubSubKeys);
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
//
|
||
// Allocate space to hold data
|
||
//
|
||
|
||
pDLLPath = (LPBYTE)LOCAL_ALLOC( LPTR,
|
||
cbMaxValueDataSize+sizeof(WCHAR));
|
||
pInterfaceInfo = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize );
|
||
pGlobalInfo = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize );
|
||
|
||
if ( ( pInterfaceInfo == NULL ) ||
|
||
( pGlobalInfo == NULL ) ||
|
||
( pDLLPath == NULL ) )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
GlobalRMRegParams[1].pValue = pGlobalInfo;
|
||
GlobalRMRegParams[2].pValue = pDLLPath;
|
||
GlobalRMRegParams[3].pValue = pInterfaceInfo;
|
||
|
||
GlobalRMRegParams[1].ppValue = &pGlobalInfo;
|
||
GlobalRMRegParams[2].ppValue = &pDLLPath;
|
||
GlobalRMRegParams[3].ppValue = &pInterfaceInfo;
|
||
|
||
//
|
||
// Run through and get all the RM values
|
||
//
|
||
|
||
for ( dwIndex = 0;
|
||
GlobalRMRegParams[dwIndex].lpwsValueName != NULL;
|
||
dwIndex++ )
|
||
{
|
||
if ( GlobalRMRegParams[dwIndex].dwType == REG_DWORD )
|
||
{
|
||
cbValueBuf = sizeof( DWORD );
|
||
}
|
||
else if ( GlobalRMRegParams[dwIndex].dwType == REG_SZ )
|
||
{
|
||
cbValueBuf = cbMaxValueDataSize + sizeof( WCHAR );
|
||
}
|
||
else
|
||
{
|
||
cbValueBuf = cbMaxValueDataSize;
|
||
}
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKeyRouterManager,
|
||
GlobalRMRegParams[dwIndex].lpwsValueName,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)(GlobalRMRegParams[dwIndex].pValue),
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) &&
|
||
( dwRetCode != ERROR_FILE_NOT_FOUND ) )
|
||
{
|
||
pChar = GlobalRMRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
if ( ( dwRetCode == ERROR_FILE_NOT_FOUND ) || ( cbValueBuf == 0 ) )
|
||
{
|
||
if ( GlobalRMRegParams[dwIndex].dwType == REG_DWORD )
|
||
{
|
||
pChar = GlobalRMRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar,
|
||
dwRetCode);
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
LOCAL_FREE( GlobalRMRegParams[dwIndex].pValue );
|
||
|
||
*(GlobalRMRegParams[dwIndex].ppValue) = NULL;
|
||
GlobalRMRegParams[dwIndex].pValue = NULL;
|
||
}
|
||
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
}
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
break;
|
||
}
|
||
|
||
if ( pDLLPath == NULL )
|
||
{
|
||
pChar = DIM_VALNAME_DLLPATH;
|
||
|
||
dwRetCode = ERROR_FILE_NOT_FOUND;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Replace the %SystemRoot% with the actual path.
|
||
//
|
||
|
||
cbSize = ExpandEnvironmentStrings( (LPWSTR)pDLLPath, NULL, 0 );
|
||
|
||
if ( cbSize == 0 )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = (LPWSTR)pDLLPath;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
cbSize *= sizeof( WCHAR );
|
||
}
|
||
|
||
pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize*sizeof(WCHAR) );
|
||
|
||
if ( pDllExpandedPath == (LPWSTR)NULL )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = (LPWSTR)pDLLPath;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
cbSize = ExpandEnvironmentStrings( (LPWSTR)pDLLPath,
|
||
pDllExpandedPath,
|
||
cbSize );
|
||
if ( cbSize == 0 )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = (LPWSTR)pDLLPath;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Load the DLL
|
||
//
|
||
|
||
gblRouterManagers[dwKeyIndex].hModule = LoadLibrary( pDllExpandedPath );
|
||
|
||
if ( gblRouterManagers[dwKeyIndex].hModule == NULL )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
DIMLogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Load the StartRouter
|
||
//
|
||
|
||
StartRouter = (PVOID)GetProcAddress(
|
||
gblRouterManagers[dwKeyIndex].hModule,
|
||
"StartRouter" );
|
||
|
||
if ( StartRouter == NULL )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
LogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
gblRouterManagers[dwKeyIndex].DdmRouterIf.ConnectInterface
|
||
= DIMConnectInterface;
|
||
gblRouterManagers[dwKeyIndex].DdmRouterIf.DisconnectInterface
|
||
= DIMDisconnectInterface;
|
||
gblRouterManagers[dwKeyIndex].DdmRouterIf.SaveInterfaceInfo
|
||
= DIMSaveInterfaceInfo;
|
||
gblRouterManagers[dwKeyIndex].DdmRouterIf.RestoreInterfaceInfo
|
||
= DIMRestoreInterfaceInfo;
|
||
gblRouterManagers[dwKeyIndex].DdmRouterIf.SaveGlobalInfo
|
||
= DIMSaveGlobalInfo;
|
||
gblRouterManagers[dwKeyIndex].DdmRouterIf.RouterStopped
|
||
= DIMRouterStopped;
|
||
gblRouterManagers[dwKeyIndex].DdmRouterIf.InterfaceEnabled
|
||
= DIMInterfaceEnabled;
|
||
dwRetCode = (*StartRouter)(
|
||
&(gblRouterManagers[dwKeyIndex].DdmRouterIf),
|
||
gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN,
|
||
pGlobalInfo );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
LogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Save the global client info
|
||
//
|
||
|
||
if ( pInterfaceInfo == NULL )
|
||
{
|
||
gblRouterManagers[dwKeyIndex].pDefaultClientInterface = NULL;
|
||
gblRouterManagers[dwKeyIndex].dwDefaultClientInterfaceSize = 0;
|
||
}
|
||
else
|
||
{
|
||
gblRouterManagers[dwKeyIndex].pDefaultClientInterface =
|
||
pInterfaceInfo;
|
||
gblRouterManagers[dwKeyIndex].dwDefaultClientInterfaceSize =
|
||
cbMaxValueDataSize;
|
||
}
|
||
|
||
gblRouterManagers[dwKeyIndex].fIsRunning = TRUE;
|
||
|
||
RegCloseKey( hKeyRouterManager );
|
||
|
||
hKeyRouterManager = (HKEY)NULL;
|
||
|
||
//
|
||
// Only free up 1 thru 2 since 3 is the global interface info that we
|
||
// keep around for the life of DDM.
|
||
//
|
||
|
||
for ( dwIndex = 1; dwIndex < 3; dwIndex ++ )
|
||
{
|
||
if ( GlobalRMRegParams[dwIndex].pValue != NULL )
|
||
{
|
||
LOCAL_FREE( GlobalRMRegParams[dwIndex].pValue );
|
||
*(GlobalRMRegParams[dwIndex].ppValue) = NULL;
|
||
GlobalRMRegParams[dwIndex].pValue = NULL;
|
||
}
|
||
}
|
||
|
||
if ( pDllExpandedPath != NULL )
|
||
{
|
||
LOCAL_FREE( pDllExpandedPath );
|
||
pDllExpandedPath = NULL;
|
||
}
|
||
}
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
for ( dwIndex = 1; dwIndex < 4; dwIndex ++ )
|
||
{
|
||
if ( GlobalRMRegParams[dwIndex].pValue != NULL )
|
||
{
|
||
LOCAL_FREE( GlobalRMRegParams[dwIndex].pValue );
|
||
*(GlobalRMRegParams[dwIndex].ppValue) = NULL;
|
||
GlobalRMRegParams[dwIndex].pValue = NULL;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( pDllExpandedPath != NULL )
|
||
{
|
||
LOCAL_FREE( pDllExpandedPath );
|
||
}
|
||
|
||
if ( hKeyRouterManager != (HKEY)NULL )
|
||
{
|
||
RegCloseKey( hKeyRouterManager );
|
||
}
|
||
|
||
RegCloseKey( hKey );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: RegLoadDDM
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// Non-zero return codes - Failure
|
||
//
|
||
// Description: Will load the Demand Dial Manager DLL and obtains entry points
|
||
// into it.
|
||
//
|
||
DWORD
|
||
RegLoadDDM(
|
||
VOID
|
||
)
|
||
{
|
||
HKEY hKey;
|
||
WCHAR * pChar;
|
||
DWORD cbMaxValueDataSize;
|
||
DWORD cbMaxValNameSize;
|
||
DWORD cNumValues;
|
||
DWORD cNumSubKeys;
|
||
LPBYTE pData = NULL;
|
||
WCHAR * pDllExpandedPath = NULL;
|
||
DWORD dwRetCode = NO_ERROR;
|
||
DWORD cbSize;
|
||
DWORD dwType;
|
||
DWORD dwIndex;
|
||
|
||
//
|
||
// get handle to the DIM parameters key
|
||
//
|
||
|
||
if (dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
DIM_KEYPATH_DDM,
|
||
0,
|
||
KEY_READ,
|
||
&hKey))
|
||
{
|
||
pChar = DIM_KEYPATH_ROUTER_PARMS;
|
||
|
||
LogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
return ( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Find out the size of the path value.
|
||
//
|
||
|
||
dwRetCode = GetKeyMax( hKey,
|
||
&cbMaxValNameSize,
|
||
&cNumValues,
|
||
&cbMaxValueDataSize,
|
||
&cNumSubKeys);
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
RegCloseKey( hKey );
|
||
|
||
pChar = DIM_KEYPATH_ROUTER_PARMS;
|
||
|
||
LogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
do
|
||
{
|
||
//
|
||
// Allocate space for path and add one for NULL terminator
|
||
//
|
||
|
||
pData = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize+sizeof(WCHAR) );
|
||
|
||
if ( pData == (LPBYTE)NULL )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = DIM_VALNAME_DLLPATH;
|
||
|
||
LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Read in the path
|
||
//
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKey,
|
||
DIM_VALNAME_DLLPATH,
|
||
NULL,
|
||
&dwType,
|
||
pData,
|
||
&cbMaxValueDataSize
|
||
);
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = DIM_VALNAME_DLLPATH;
|
||
|
||
LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
if ( ( dwType != REG_EXPAND_SZ ) && ( dwType != REG_SZ ) )
|
||
{
|
||
dwRetCode = ERROR_REGISTRY_CORRUPT;
|
||
|
||
pChar = DIM_VALNAME_DLLPATH;
|
||
|
||
LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Replace the %SystemRoot% with the actual path.
|
||
//
|
||
|
||
cbSize = ExpandEnvironmentStrings( (LPWSTR)pData, NULL, 0 );
|
||
|
||
if ( cbSize == 0 )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = (LPWSTR)pData;
|
||
|
||
LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
cbSize *= sizeof( WCHAR );
|
||
}
|
||
|
||
pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize*sizeof(WCHAR) );
|
||
|
||
if ( pDllExpandedPath == (LPWSTR)NULL )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = (LPWSTR)pData;
|
||
|
||
LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
cbSize = ExpandEnvironmentStrings(
|
||
(LPWSTR)pData,
|
||
pDllExpandedPath,
|
||
cbSize );
|
||
|
||
if ( cbSize == 0 )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = (LPWSTR)pData;
|
||
|
||
LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Load the DLL
|
||
//
|
||
|
||
gblhModuleDDM = LoadLibrary( pDllExpandedPath );
|
||
|
||
if ( gblhModuleDDM == (HINSTANCE)NULL )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
DIMLogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Load the DDM entrypoints.
|
||
//
|
||
|
||
for ( dwIndex = 0;
|
||
gblDDMFunctionTable[dwIndex].lpEntryPointName != NULL;
|
||
dwIndex ++ )
|
||
{
|
||
gblDDMFunctionTable[dwIndex].pEntryPoint =
|
||
(PVOID)GetProcAddress(
|
||
gblhModuleDDM,
|
||
gblDDMFunctionTable[dwIndex].lpEntryPointName );
|
||
|
||
if ( gblDDMFunctionTable[dwIndex].pEntryPoint == NULL )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
DIMLogError( ROUTERLOG_LOAD_DLL_ERROR,
|
||
1,
|
||
&pDllExpandedPath,
|
||
dwRetCode);
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
break;
|
||
}
|
||
|
||
} while(FALSE);
|
||
|
||
if ( pData != NULL )
|
||
{
|
||
LOCAL_FREE( pData );
|
||
}
|
||
|
||
if ( pDllExpandedPath != NULL )
|
||
{
|
||
LOCAL_FREE( pDllExpandedPath );
|
||
}
|
||
|
||
RegCloseKey( hKey );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: AddInterfaceToRouterManagers
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// Non-zero returns - Failure
|
||
//
|
||
// Description: Will add the interface to each of the Router Managers.
|
||
//
|
||
DWORD
|
||
AddInterfaceToRouterManagers(
|
||
IN HKEY hKeyInterface,
|
||
IN LPWSTR lpwsInterfaceName,
|
||
IN ROUTER_INTERFACE_OBJECT * pIfObject,
|
||
IN DWORD dwTransportId
|
||
)
|
||
{
|
||
DIM_ROUTER_INTERFACE * pDdmRouterIf;
|
||
HANDLE hInterface;
|
||
FILETIME LastWrite;
|
||
HKEY hKeyRM = NULL;
|
||
DWORD dwKeyIndex;
|
||
DWORD dwIndex;
|
||
DWORD dwType;
|
||
DWORD dwTransportIndex;
|
||
WCHAR * pChar;
|
||
DWORD cbMaxValueDataSize;
|
||
DWORD cbMaxValNameSize;
|
||
DWORD cNumValues;
|
||
DWORD cNumSubKeys;
|
||
DWORD dwRetCode;
|
||
WCHAR wchSubKeyName[100];
|
||
DWORD cbSubKeyName;
|
||
DWORD cbValueBuf;
|
||
DWORD dwMaxFilterSize;
|
||
LPBYTE pInterfaceInfo = NULL;
|
||
BOOL fAddedToRouterManger = FALSE;
|
||
|
||
//
|
||
// For each of the Router Managers load the static routes and
|
||
// filter information
|
||
//
|
||
|
||
for( dwKeyIndex = 0;
|
||
dwKeyIndex < gblDIMConfigInfo.dwNumRouterManagers;
|
||
dwKeyIndex++ )
|
||
{
|
||
cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
|
||
|
||
dwRetCode = RegEnumKeyEx(
|
||
hKeyInterface,
|
||
dwKeyIndex,
|
||
wchSubKeyName,
|
||
&cbSubKeyName,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&LastWrite
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
|
||
{
|
||
if ( dwRetCode == ERROR_NO_MORE_ITEMS )
|
||
{
|
||
dwRetCode = NO_ERROR;
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
pChar = lpwsInterfaceName;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode);
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RegOpenKeyEx( hKeyInterface,
|
||
wchSubKeyName,
|
||
0,
|
||
KEY_READ,
|
||
&hKeyRM );
|
||
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Find out the maximum size of the data for this RM
|
||
//
|
||
|
||
dwRetCode = GetKeyMax( hKeyRM,
|
||
&cbMaxValNameSize,
|
||
&cNumValues,
|
||
&cbMaxValueDataSize,
|
||
&cNumSubKeys );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Allocate space to hold data
|
||
//
|
||
|
||
pInterfaceInfo = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize );
|
||
|
||
if ( ( pInterfaceInfo == NULL ) )
|
||
{
|
||
dwRetCode = GetLastError();
|
||
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
RMRegParams[1].pValue = pInterfaceInfo;
|
||
RMRegParams[1].ppValue = &pInterfaceInfo;
|
||
|
||
//
|
||
// Run through and get all the RM values
|
||
//
|
||
|
||
for ( dwIndex = 0;
|
||
RMRegParams[dwIndex].lpwsValueName != NULL;
|
||
dwIndex++ )
|
||
{
|
||
if ( RMRegParams[dwIndex].dwType == REG_DWORD )
|
||
{
|
||
cbValueBuf = sizeof( DWORD );
|
||
}
|
||
else if ( RMRegParams[dwIndex].dwType == REG_SZ )
|
||
{
|
||
cbValueBuf = cbMaxValueDataSize + sizeof( WCHAR );
|
||
}
|
||
else
|
||
{
|
||
cbValueBuf = cbMaxValueDataSize;
|
||
}
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKeyRM,
|
||
RMRegParams[dwIndex].lpwsValueName,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)(RMRegParams[dwIndex].pValue),
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) &&
|
||
( dwRetCode != ERROR_FILE_NOT_FOUND ) )
|
||
{
|
||
pChar = RMRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
if ( ( dwRetCode == ERROR_FILE_NOT_FOUND ) || ( cbValueBuf == 0 ) )
|
||
{
|
||
if ( RMRegParams[dwIndex].dwType == REG_DWORD )
|
||
{
|
||
pChar = RMRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE,1,&pChar,dwRetCode);
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
LOCAL_FREE( RMRegParams[dwIndex].pValue );
|
||
|
||
*(RMRegParams[dwIndex].ppValue) = NULL;
|
||
RMRegParams[dwIndex].pValue = NULL;
|
||
}
|
||
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
}
|
||
|
||
if ( ( dwRetCode == NO_ERROR ) &&
|
||
(( dwTransportId == 0 ) || ( dwTransportId == gbldwProtocolId )) )
|
||
{
|
||
//
|
||
// If the router manager for this protocol exists then add this interface
|
||
// with it otherwise skip it
|
||
//
|
||
|
||
if ( (dwTransportIndex = GetTransportIndex(gbldwProtocolId)) != -1)
|
||
{
|
||
pDdmRouterIf=&(gblRouterManagers[dwTransportIndex].DdmRouterIf);
|
||
|
||
if (IsInterfaceRoleAcceptable(pIfObject, gbldwProtocolId))
|
||
{
|
||
dwRetCode = pDdmRouterIf->AddInterface(
|
||
lpwsInterfaceName,
|
||
pInterfaceInfo,
|
||
pIfObject->IfType,
|
||
pIfObject->hDIMInterface,
|
||
&hInterface );
|
||
|
||
if ( dwRetCode == NO_ERROR )
|
||
{
|
||
if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) )
|
||
{
|
||
WCHAR wchFriendlyName[MAX_INTERFACE_NAME_LEN+1];
|
||
LPWSTR lpszFriendlyName = wchFriendlyName;
|
||
|
||
if ( MprConfigGetFriendlyName(
|
||
gblDIMConfigInfo.hMprConfig,
|
||
lpwsInterfaceName,
|
||
wchFriendlyName,
|
||
sizeof( wchFriendlyName ) ) != NO_ERROR )
|
||
{
|
||
wcscpy( wchFriendlyName, lpwsInterfaceName );
|
||
}
|
||
|
||
//
|
||
// Disable the interface
|
||
//
|
||
|
||
pDdmRouterIf->InterfaceNotReachable(
|
||
hInterface,
|
||
INTERFACE_DISABLED );
|
||
|
||
DIMLogInformation( ROUTERLOG_IF_UNREACHABLE_REASON3, 1,
|
||
&lpszFriendlyName );
|
||
}
|
||
|
||
pIfObject->Transport[dwTransportIndex].hInterface = hInterface;
|
||
|
||
fAddedToRouterManger = TRUE;
|
||
}
|
||
else
|
||
{
|
||
LPWSTR lpwsString[2];
|
||
WCHAR wchProtocolId[10];
|
||
|
||
lpwsString[0] = lpwsInterfaceName;
|
||
lpwsString[1] = ( gbldwProtocolId == PID_IP ) ? L"IP" : L"IPX";
|
||
|
||
DIMLogErrorString( ROUTERLOG_COULDNT_ADD_INTERFACE,
|
||
2, lpwsString, dwRetCode, 2 );
|
||
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
RegCloseKey( hKeyRM );
|
||
|
||
hKeyRM = NULL;
|
||
|
||
for ( dwIndex = 1; dwIndex < 3; dwIndex ++ )
|
||
{
|
||
if ( RMRegParams[dwIndex].pValue != NULL )
|
||
{
|
||
LOCAL_FREE( RMRegParams[dwIndex].pValue );
|
||
*(RMRegParams[dwIndex].ppValue) = NULL;
|
||
RMRegParams[dwIndex].pValue = NULL;
|
||
}
|
||
}
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
for ( dwIndex = 1; dwIndex < 2; dwIndex ++ )
|
||
{
|
||
if ( RMRegParams[dwIndex].pValue != NULL )
|
||
{
|
||
LOCAL_FREE( RMRegParams[dwIndex].pValue );
|
||
}
|
||
}
|
||
|
||
if ( hKeyRM != NULL )
|
||
{
|
||
RegCloseKey( hKeyRM );
|
||
}
|
||
|
||
//
|
||
// Remove the check below. We want to allow users to add an interface
|
||
// which doesnt have any transports over it.
|
||
// AmritanR
|
||
//
|
||
|
||
#if 0
|
||
|
||
//
|
||
// If this interface was not successfully added to any router managers
|
||
// then fail
|
||
//
|
||
|
||
if ( !fAddedToRouterManger )
|
||
{
|
||
return( ERROR_NO_SUCH_INTERFACE );
|
||
}
|
||
|
||
#endif
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: RegLoadInterfaces
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// Non-zero return code is a FATAL error
|
||
//
|
||
// Description: Will try to load the various interfaces in the registry. On
|
||
// failure in trying to add any interface an error will be logged
|
||
// but will return NO_ERROR. If the input parameter is not NULL,
|
||
// it will load a specific interface.
|
||
//
|
||
DWORD
|
||
RegLoadInterfaces(
|
||
IN LPWSTR lpwsInterfaceName,
|
||
IN BOOL fAllTransports
|
||
|
||
)
|
||
{
|
||
HKEY hKey = NULL;
|
||
HKEY hKeyInterface = NULL;
|
||
WCHAR * pChar;
|
||
DWORD cbMaxValueDataSize;
|
||
DWORD cbMaxValNameSize;
|
||
DWORD cNumValues;
|
||
DWORD cNumSubKeys;
|
||
WCHAR wchInterfaceKeyName[50];
|
||
DWORD cbSubKeyName;
|
||
DWORD dwKeyIndex;
|
||
FILETIME LastWrite;
|
||
DWORD dwRetCode;
|
||
DWORD dwSubKeyIndex;
|
||
WCHAR wchInterfaceName[MAX_INTERFACE_NAME_LEN+1];
|
||
DWORD dwType;
|
||
DWORD cbValueBuf;
|
||
|
||
//
|
||
// Get handle to the INTERFACES parameters key
|
||
//
|
||
|
||
if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
DIM_KEYPATH_INTERFACES,
|
||
0,
|
||
KEY_READ,
|
||
&hKey ))
|
||
{
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
return ( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Find out the number of Interfaces
|
||
//
|
||
|
||
dwRetCode = GetKeyMax( hKey,
|
||
&cbMaxValNameSize,
|
||
&cNumValues,
|
||
&cbMaxValueDataSize,
|
||
&cNumSubKeys );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
RegCloseKey( hKey );
|
||
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
dwRetCode = ERROR_NO_SUCH_INTERFACE;
|
||
|
||
//
|
||
// For each interface
|
||
//
|
||
|
||
for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
|
||
{
|
||
cbSubKeyName = sizeof( wchInterfaceKeyName )/sizeof(WCHAR);
|
||
|
||
dwRetCode = RegEnumKeyEx(
|
||
hKey,
|
||
dwKeyIndex,
|
||
wchInterfaceKeyName,
|
||
&cbSubKeyName,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&LastWrite
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
|
||
{
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RegOpenKeyEx( hKey,
|
||
wchInterfaceKeyName,
|
||
0,
|
||
KEY_READ,
|
||
&hKeyInterface );
|
||
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchInterfaceKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Get the interface name value
|
||
//
|
||
|
||
cbValueBuf = sizeof( wchInterfaceName );
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKeyInterface,
|
||
DIM_VALNAME_INTERFACE_NAME,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)wchInterfaceName,
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) || ( dwType != REG_SZ ) )
|
||
{
|
||
pChar = DIM_VALNAME_INTERFACE_NAME;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
if ( lpwsInterfaceName != NULL )
|
||
{
|
||
//
|
||
// We need to load a specific interface
|
||
//
|
||
|
||
if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) != 0 )
|
||
{
|
||
RegCloseKey( hKeyInterface );
|
||
|
||
hKeyInterface = NULL;
|
||
|
||
continue;
|
||
}
|
||
}
|
||
|
||
dwRetCode = RegLoadInterface( wchInterfaceName, hKeyInterface, fAllTransports );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchInterfaceName;
|
||
|
||
DIMLogErrorString(ROUTERLOG_COULDNT_LOAD_IF, 1, &pChar,dwRetCode,1);
|
||
}
|
||
|
||
//
|
||
// ERROR_NOT_SUPPORTED is returned for ipip tunnels which are not
|
||
// supported as of whistler. We reset the error code here because
|
||
// this is not a critical error and in some cases, a failing
|
||
// call to RegLoadInterfaces will cause the service to not start.
|
||
//
|
||
if ( dwRetCode == ERROR_NOT_SUPPORTED )
|
||
{
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
|
||
RegCloseKey( hKeyInterface );
|
||
|
||
hKeyInterface = NULL;
|
||
|
||
if ( lpwsInterfaceName != NULL )
|
||
{
|
||
//
|
||
// If we need to load a specific interface and this was it, then we are done.
|
||
//
|
||
|
||
if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) == 0 )
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
RegCloseKey( hKey );
|
||
|
||
//
|
||
// If we aren't looking for a specific interface
|
||
//
|
||
|
||
if ( lpwsInterfaceName == NULL )
|
||
{
|
||
//
|
||
// If there was no interface found, then we are OK
|
||
//
|
||
|
||
if ( dwRetCode == ERROR_NO_SUCH_INTERFACE )
|
||
{
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
}
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: RegLoadInterface
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// Non-zero returns - Failure
|
||
//
|
||
// Description: Will load the specific interface
|
||
//
|
||
DWORD
|
||
RegLoadInterface(
|
||
IN LPWSTR lpwsInterfaceName,
|
||
IN HKEY hKeyInterface,
|
||
IN BOOL fAllTransports
|
||
)
|
||
{
|
||
DWORD dwIndex;
|
||
WCHAR * pChar;
|
||
DWORD cbValueBuf;
|
||
DWORD dwRetCode;
|
||
DWORD dwType;
|
||
ROUTER_INTERFACE_OBJECT * pIfObject;
|
||
DWORD IfState;
|
||
LPWSTR lpwsDialoutHours = NULL;
|
||
DWORD dwInactiveReason = 0;
|
||
|
||
//
|
||
// Get Interface parameters
|
||
//
|
||
|
||
for ( dwIndex = 0; IFRegParams[dwIndex].lpwsValueName != NULL; dwIndex++ )
|
||
{
|
||
cbValueBuf = sizeof( DWORD );
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKeyInterface,
|
||
IFRegParams[dwIndex].lpwsValueName,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)(IFRegParams[dwIndex].pValue),
|
||
&cbValueBuf );
|
||
|
||
if ((dwRetCode != NO_ERROR) && (dwRetCode != ERROR_FILE_NOT_FOUND))
|
||
{
|
||
pChar = IFRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
if ( dwRetCode == ERROR_FILE_NOT_FOUND )
|
||
{
|
||
//
|
||
// dwIndex == 0 means there was no type, this is an error
|
||
//
|
||
|
||
if ( dwIndex > 0 )
|
||
{
|
||
*(IFRegParams[dwIndex].pValue)=IFRegParams[dwIndex].dwDefValue;
|
||
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( ( dwType != REG_DWORD )
|
||
||(*((LPDWORD)IFRegParams[dwIndex].pValue) >
|
||
IFRegParams[dwIndex].dwMaxValue)
|
||
||( *((LPDWORD)IFRegParams[dwIndex].pValue) <
|
||
IFRegParams[dwIndex].dwMinValue))
|
||
{
|
||
//
|
||
// dwIndex == 0 means the type was invalid, this is an error
|
||
//
|
||
|
||
if ( dwIndex > 0 )
|
||
{
|
||
pChar = IFRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogWarning(ROUTERLOG_REGVALUE_OVERIDDEN, 1, &pChar);
|
||
|
||
*(IFRegParams[dwIndex].pValue) =
|
||
IFRegParams[dwIndex].dwDefValue;
|
||
}
|
||
else
|
||
{
|
||
|
||
dwRetCode = ERROR_REGISTRY_CORRUPT;
|
||
|
||
pChar = IFRegParams[dwIndex].lpwsValueName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_QUERY_VALUE,
|
||
1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// IPIP tunnels are no longer accepted
|
||
//
|
||
if ( gbldwInterfaceType == ROUTER_IF_TYPE_TUNNEL1 )
|
||
{
|
||
return ERROR_NOT_SUPPORTED;
|
||
}
|
||
|
||
//
|
||
// Check to see if this interface is active. Do not load otherwise.
|
||
//
|
||
|
||
if ( gbldwInterfaceType == ROUTER_IF_TYPE_DEDICATED )
|
||
{
|
||
//
|
||
// Need to handle the IPX interface names ie {GUID}\Frame type
|
||
//
|
||
|
||
WCHAR wchGUIDSaveLast;
|
||
LPWSTR lpwszGUIDEnd = wcsrchr( lpwsInterfaceName, L'}' );
|
||
if (lpwszGUIDEnd==NULL)
|
||
return ERROR_INVALID_PARAMETER;
|
||
|
||
wchGUIDSaveLast = *(lpwszGUIDEnd+1);
|
||
|
||
*(lpwszGUIDEnd+1) = (WCHAR)NULL;
|
||
|
||
if ( !IfObjectIsLANDeviceActive( lpwsInterfaceName, &dwInactiveReason ))
|
||
{
|
||
if ( dwInactiveReason == INTERFACE_NO_DEVICE )
|
||
{
|
||
*(lpwszGUIDEnd+1) = wchGUIDSaveLast;
|
||
|
||
return( dwRetCode );
|
||
}
|
||
}
|
||
|
||
*(lpwszGUIDEnd+1) = wchGUIDSaveLast;
|
||
}
|
||
|
||
//
|
||
// Get the dialout hours value if there is one
|
||
//
|
||
|
||
cbValueBuf = 0;
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKeyInterface,
|
||
DIM_VALNAME_DIALOUT_HOURS,
|
||
NULL,
|
||
&dwType,
|
||
NULL,
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) || ( dwType != REG_MULTI_SZ ) )
|
||
{
|
||
if ( dwRetCode != ERROR_FILE_NOT_FOUND )
|
||
{
|
||
return( dwRetCode );
|
||
}
|
||
else
|
||
{
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
}
|
||
|
||
if ( cbValueBuf > 0 )
|
||
{
|
||
if ( (lpwsDialoutHours = LOCAL_ALLOC( LPTR, cbValueBuf)) == NULL )
|
||
{
|
||
pChar = DIM_VALNAME_DIALOUT_HOURS;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKeyInterface,
|
||
DIM_VALNAME_DIALOUT_HOURS,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)lpwsDialoutHours,
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
LOCAL_FREE( lpwsDialoutHours );
|
||
|
||
pChar = DIM_VALNAME_DIALOUT_HOURS;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
return( dwRetCode );
|
||
}
|
||
}
|
||
|
||
//
|
||
// Allocate an interface object for this interface
|
||
//
|
||
|
||
if ( ( gbldwInterfaceType == ROUTER_IF_TYPE_DEDICATED ) ||
|
||
( gbldwInterfaceType == ROUTER_IF_TYPE_LOOPBACK ) ||
|
||
( gbldwInterfaceType == ROUTER_IF_TYPE_INTERNAL ) )
|
||
{
|
||
IfState = RISTATE_CONNECTED;
|
||
}
|
||
else
|
||
{
|
||
if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN )
|
||
{
|
||
pChar = lpwsInterfaceName;
|
||
|
||
LOCAL_FREE( lpwsDialoutHours );
|
||
|
||
DIMLogWarning( ROUTERLOG_DID_NOT_LOAD_DDMIF, 1, &pChar );
|
||
|
||
dwRetCode = NO_ERROR;
|
||
|
||
return( dwRetCode );
|
||
}
|
||
else
|
||
{
|
||
IfState = RISTATE_DISCONNECTED;
|
||
}
|
||
}
|
||
|
||
pIfObject = IfObjectAllocateAndInit(
|
||
lpwsInterfaceName,
|
||
IfState,
|
||
gbldwInterfaceType,
|
||
(HCONN)0,
|
||
gblfEnabled,
|
||
gblInterfaceReachableAfterSecondsMin,
|
||
gblInterfaceReachableAfterSecondsMax,
|
||
lpwsDialoutHours );
|
||
|
||
if ( pIfObject == NULL )
|
||
{
|
||
if ( lpwsDialoutHours != NULL )
|
||
{
|
||
LOCAL_FREE( lpwsDialoutHours );
|
||
}
|
||
|
||
dwRetCode = NO_ERROR;
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Add interface into table now because a table lookup is made within
|
||
// the InterfaceEnabled call that the router managers make in the
|
||
// context of the AddInterface call.
|
||
//
|
||
|
||
if ( ( dwRetCode = IfObjectInsertInTable( pIfObject ) ) != NO_ERROR )
|
||
{
|
||
IfObjectFree( pIfObject );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
if ( fAllTransports )
|
||
{
|
||
dwRetCode = AddInterfaceToRouterManagers( hKeyInterface,
|
||
lpwsInterfaceName,
|
||
pIfObject,
|
||
0 );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
IfObjectRemove( pIfObject->hDIMInterface );
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Check to see if the device has media sense
|
||
//
|
||
|
||
if ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED )
|
||
{
|
||
if ( dwInactiveReason == INTERFACE_NO_MEDIA_SENSE )
|
||
{
|
||
pIfObject->State = RISTATE_DISCONNECTED;
|
||
|
||
pIfObject->fFlags |= IFFLAG_NO_MEDIA_SENSE;
|
||
|
||
IfObjectNotifyOfReachabilityChange( pIfObject,
|
||
FALSE,
|
||
INTERFACE_NO_MEDIA_SENSE );
|
||
}
|
||
}
|
||
|
||
if ( pIfObject->IfType == ROUTER_IF_TYPE_FULL_ROUTER )
|
||
{
|
||
if ( pIfObject->fFlags & IFFLAG_OUT_OF_RESOURCES )
|
||
{
|
||
IfObjectNotifyOfReachabilityChange( pIfObject,
|
||
FALSE,
|
||
MPR_INTERFACE_OUT_OF_RESOURCES );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: RegOpenAppropriateKey
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
//
|
||
// Description: Will open the appropriate registry key for the given router
|
||
// manager within the given interface.
|
||
//
|
||
DWORD
|
||
RegOpenAppropriateKey(
|
||
IN LPWSTR wchInterfaceName,
|
||
IN DWORD dwProtocolId,
|
||
IN OUT HKEY * phKeyRM
|
||
)
|
||
{
|
||
HKEY hKey = NULL;
|
||
HKEY hSubKey = NULL;
|
||
WCHAR wchSubKeyName[100];
|
||
DWORD cbSubKeyName;
|
||
DWORD dwType;
|
||
DWORD dwKeyIndex;
|
||
FILETIME LastWrite;
|
||
DWORD dwPId;
|
||
DWORD cbValueBuf;
|
||
WCHAR * pChar;
|
||
DWORD dwRetCode = NO_ERROR;
|
||
DWORD cbMaxValNameSize;
|
||
DWORD cNumValues;
|
||
DWORD cbMaxValueDataSize;
|
||
DWORD cNumSubKeys;
|
||
WCHAR wchIfName[MAX_INTERFACE_NAME_LEN+1];
|
||
|
||
//
|
||
// Get handle to the INTERFACES parameters key
|
||
//
|
||
|
||
if ( ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
|
||
DIM_KEYPATH_INTERFACES,
|
||
&hKey )) != NO_ERROR )
|
||
{
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Find out the number of subkeys
|
||
//
|
||
|
||
dwRetCode = GetKeyMax( hKey,
|
||
&cbMaxValNameSize,
|
||
&cNumValues,
|
||
&cbMaxValueDataSize,
|
||
&cNumSubKeys );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
RegCloseKey( hKey );
|
||
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Find the interface
|
||
//
|
||
|
||
hSubKey = NULL;
|
||
|
||
for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
|
||
{
|
||
cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
|
||
|
||
dwRetCode = RegEnumKeyEx(
|
||
hKey,
|
||
dwKeyIndex,
|
||
wchSubKeyName,
|
||
&cbSubKeyName,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&LastWrite
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
|
||
{
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Open this key
|
||
//
|
||
|
||
if ( ( dwRetCode = RegOpenKey( hKey,
|
||
wchSubKeyName,
|
||
&hSubKey )) != NO_ERROR )
|
||
{
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
hSubKey = NULL;
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Get the interface name value
|
||
//
|
||
|
||
cbValueBuf = sizeof( wchIfName );
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hSubKey,
|
||
DIM_VALNAME_INTERFACE_NAME,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)wchIfName,
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = DIM_VALNAME_INTERFACE_NAME;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Is this the interface we want ?
|
||
//
|
||
|
||
if ( _wcsicmp( wchIfName, wchInterfaceName ) == 0 )
|
||
{
|
||
dwRetCode = NO_ERROR;
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
dwRetCode = ERROR_NO_SUCH_INTERFACE;
|
||
|
||
RegCloseKey(hSubKey);
|
||
|
||
hSubKey = NULL;
|
||
}
|
||
}
|
||
|
||
RegCloseKey( hKey );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
if ( hSubKey != NULL )
|
||
{
|
||
RegCloseKey( hSubKey );
|
||
}
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Find out which router manager to restore information for.
|
||
//
|
||
|
||
for( dwKeyIndex = 0;
|
||
dwKeyIndex < gblDIMConfigInfo.dwNumRouterManagers;
|
||
dwKeyIndex++ )
|
||
{
|
||
cbSubKeyName = sizeof( wchSubKeyName );
|
||
|
||
dwRetCode = RegEnumKeyEx(
|
||
hSubKey,
|
||
dwKeyIndex,
|
||
wchSubKeyName,
|
||
&cbSubKeyName,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&LastWrite
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
|
||
{
|
||
pChar = wchInterfaceName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RegOpenKeyEx(
|
||
hSubKey,
|
||
wchSubKeyName,
|
||
0,
|
||
KEY_READ | KEY_WRITE,
|
||
phKeyRM );
|
||
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
cbValueBuf = sizeof( DWORD );
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
*phKeyRM,
|
||
DIM_VALNAME_PROTOCOLID,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)&dwPId,
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = DIM_VALNAME_PROTOCOLID;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
if ( dwPId == dwProtocolId )
|
||
{
|
||
break;
|
||
}
|
||
|
||
RegCloseKey( *phKeyRM );
|
||
|
||
*phKeyRM = NULL;
|
||
}
|
||
|
||
RegCloseKey( hSubKey );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
if ( *phKeyRM != NULL )
|
||
{
|
||
RegCloseKey( *phKeyRM );
|
||
*phKeyRM = NULL;
|
||
}
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
if ( *phKeyRM == NULL )
|
||
{
|
||
return( ERROR_NO_SUCH_INTERFACE );
|
||
}
|
||
|
||
return( NO_ERROR );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: RegOpenAppropriateRMKey
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
//
|
||
// Description: Will open the appropriate registry key for the given router
|
||
// manager.
|
||
//
|
||
DWORD
|
||
RegOpenAppropriateRMKey(
|
||
IN DWORD dwProtocolId,
|
||
IN OUT HKEY * phKeyRM
|
||
)
|
||
{
|
||
HKEY hKey = NULL;
|
||
DWORD dwRetCode = NO_ERROR;
|
||
WCHAR wchSubKeyName[100];
|
||
DWORD cbSubKeyName;
|
||
DWORD dwPId;
|
||
DWORD dwKeyIndex;
|
||
FILETIME LastWrite;
|
||
DWORD dwType;
|
||
DWORD cbValueBuf;
|
||
WCHAR * pChar;
|
||
|
||
//
|
||
// get handle to the Router Managers key
|
||
//
|
||
|
||
dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
DIM_KEYPATH_ROUTERMANAGERS,
|
||
0,
|
||
KEY_READ,
|
||
&hKey );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = DIM_KEYPATH_ROUTERMANAGERS;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
return ( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// Find out which router manager to restore information for.
|
||
//
|
||
|
||
for( dwKeyIndex = 0;
|
||
dwKeyIndex < gblDIMConfigInfo.dwNumRouterManagers;
|
||
dwKeyIndex++ )
|
||
{
|
||
cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
|
||
|
||
dwRetCode = RegEnumKeyEx(
|
||
hKey,
|
||
dwKeyIndex,
|
||
wchSubKeyName,
|
||
&cbSubKeyName,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&LastWrite
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
|
||
{
|
||
pChar = DIM_KEYPATH_ROUTERMANAGERS;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RegOpenKeyEx(
|
||
hKey,
|
||
wchSubKeyName,
|
||
0,
|
||
KEY_READ | KEY_WRITE,
|
||
phKeyRM );
|
||
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchSubKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
cbValueBuf = sizeof( DWORD );
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
*phKeyRM,
|
||
DIM_VALNAME_PROTOCOLID,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)&dwPId,
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = DIM_VALNAME_PROTOCOLID;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
if ( dwPId == dwProtocolId )
|
||
{
|
||
break;
|
||
}
|
||
|
||
RegCloseKey( *phKeyRM );
|
||
|
||
*phKeyRM = NULL;
|
||
}
|
||
|
||
RegCloseKey( hKey );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
if ( *phKeyRM != NULL )
|
||
{
|
||
RegCloseKey( *phKeyRM );
|
||
}
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
if ( *phKeyRM == NULL )
|
||
{
|
||
return( ERROR_UNKNOWN_PROTOCOL_ID );
|
||
}
|
||
|
||
return( NO_ERROR );
|
||
}
|
||
|
||
//**
|
||
//
|
||
// Call: AddInterfacesToRouterManager
|
||
//
|
||
// Returns: NO_ERROR - Success
|
||
// Non-zero returns - Failure
|
||
//
|
||
// Description: Register all existing interfaces with this router manager
|
||
//
|
||
DWORD
|
||
AddInterfacesToRouterManager(
|
||
IN LPWSTR lpwsInterfaceName,
|
||
IN DWORD dwTransportId
|
||
)
|
||
{
|
||
ROUTER_INTERFACE_OBJECT * pIfObject;
|
||
HKEY hKey = NULL;
|
||
HKEY hKeyInterface = NULL;
|
||
DWORD dwKeyIndex = 0;
|
||
DWORD cbMaxValueDataSize;
|
||
DWORD cbMaxValNameSize;
|
||
DWORD cNumValues;
|
||
DWORD cNumSubKeys;
|
||
DWORD cbSubKeyName;
|
||
FILETIME LastWrite;
|
||
DWORD dwType;
|
||
DWORD dwRetCode;
|
||
DWORD cbValueBuf;
|
||
WCHAR * pChar;
|
||
WCHAR wchInterfaceKeyName[50];
|
||
WCHAR wchInterfaceName[MAX_INTERFACE_NAME_LEN+1];
|
||
|
||
//
|
||
// Get handle to the INTERFACES parameters key
|
||
//
|
||
|
||
if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
DIM_KEYPATH_INTERFACES,
|
||
0,
|
||
KEY_READ,
|
||
&hKey ))
|
||
{
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
return( NO_ERROR );
|
||
}
|
||
|
||
//
|
||
// Find out the number of Interfaces
|
||
//
|
||
|
||
dwRetCode = GetKeyMax( hKey,
|
||
&cbMaxValNameSize,
|
||
&cNumValues,
|
||
&cbMaxValueDataSize,
|
||
&cNumSubKeys );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
RegCloseKey( hKey );
|
||
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
return( dwRetCode );
|
||
}
|
||
|
||
//
|
||
// For each interface
|
||
//
|
||
|
||
for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
|
||
{
|
||
cbSubKeyName = sizeof( wchInterfaceKeyName )/sizeof(WCHAR);
|
||
|
||
dwRetCode = RegEnumKeyEx(
|
||
hKey,
|
||
dwKeyIndex,
|
||
wchInterfaceKeyName,
|
||
&cbSubKeyName,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&LastWrite
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
|
||
{
|
||
pChar = DIM_KEYPATH_INTERFACES;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode);
|
||
|
||
break;
|
||
}
|
||
|
||
dwRetCode = RegOpenKeyEx( hKey,
|
||
wchInterfaceKeyName,
|
||
0,
|
||
KEY_READ,
|
||
&hKeyInterface );
|
||
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchInterfaceKeyName;
|
||
|
||
DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Get the interface name value
|
||
//
|
||
|
||
cbValueBuf = sizeof( wchInterfaceName );
|
||
|
||
dwRetCode = RegQueryValueEx(
|
||
hKeyInterface,
|
||
DIM_VALNAME_INTERFACE_NAME,
|
||
NULL,
|
||
&dwType,
|
||
(LPBYTE)wchInterfaceName,
|
||
&cbValueBuf
|
||
);
|
||
|
||
if ( ( dwRetCode != NO_ERROR ) || ( dwType != REG_SZ ) )
|
||
{
|
||
pChar = DIM_VALNAME_INTERFACE_NAME;
|
||
|
||
DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
|
||
|
||
pChar = wchInterfaceKeyName;
|
||
|
||
DIMLogErrorString(ROUTERLOG_COULDNT_LOAD_IF,1,
|
||
&pChar,dwRetCode,1);
|
||
|
||
RegCloseKey( hKeyInterface );
|
||
|
||
dwRetCode = NO_ERROR;
|
||
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// If we are looking for a specific interface
|
||
//
|
||
|
||
if ( lpwsInterfaceName != NULL )
|
||
{
|
||
//
|
||
// If this is not the one then we continue looking
|
||
//
|
||
|
||
if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) != 0 )
|
||
{
|
||
RegCloseKey( hKeyInterface );
|
||
|
||
continue;
|
||
}
|
||
}
|
||
|
||
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
|
||
|
||
pIfObject = IfObjectGetPointerByName( wchInterfaceName, FALSE );
|
||
|
||
if ( pIfObject == NULL )
|
||
{
|
||
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
|
||
|
||
pChar = wchInterfaceName;
|
||
|
||
DIMLogErrorString( ROUTERLOG_COULDNT_LOAD_IF, 1,
|
||
&pChar, ERROR_NO_SUCH_INTERFACE, 1 );
|
||
|
||
RegCloseKey( hKeyInterface );
|
||
|
||
continue;
|
||
}
|
||
|
||
dwRetCode = AddInterfaceToRouterManagers( hKeyInterface,
|
||
wchInterfaceName,
|
||
pIfObject,
|
||
dwTransportId );
|
||
|
||
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
pChar = wchInterfaceName;
|
||
|
||
DIMLogErrorString( ROUTERLOG_COULDNT_LOAD_IF,1, &pChar,dwRetCode,1);
|
||
|
||
dwRetCode = NO_ERROR;
|
||
}
|
||
|
||
RegCloseKey( hKeyInterface );
|
||
|
||
//
|
||
// If we are looking for a specific interface
|
||
//
|
||
|
||
if ( lpwsInterfaceName != NULL )
|
||
{
|
||
//
|
||
// If this was the one then we are done
|
||
//
|
||
|
||
if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) == 0 )
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
RegCloseKey( hKey );
|
||
|
||
return( dwRetCode );
|
||
}
|