You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2574 lines
71 KiB
2574 lines
71 KiB
/********************************************************************/
|
|
/** 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);
|
|
|
|
ZeroMemory(&gblOsVersionInfo, sizeof(OSVERSIONINFOEX));
|
|
|
|
gblOsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
|
|
if (!GetVersionEx((LPOSVERSIONINFO) &gblOsVersionInfo))
|
|
{
|
|
dwRetCode = GetLastError();
|
|
}
|
|
|
|
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=0;
|
|
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 dwRmIndex = 0;
|
|
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 );
|
|
}
|
|
|
|
#if (WINVER >= 0x0501)
|
|
|
|
if ( cNumSubKeys > MAX_NUM_ROUTERMANAGERS )
|
|
{
|
|
RegCloseKey( hKey );
|
|
|
|
dwRetCode = ERROR_INVALID_PARAMETER;
|
|
|
|
pChar = DIM_KEYPATH_ROUTERMANAGERS;
|
|
|
|
DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode);
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
gblDIMConfigInfo.dwNumRouterManagers = 0;
|
|
|
|
#else
|
|
|
|
gblDIMConfigInfo.dwNumRouterManagers = cNumSubKeys;
|
|
|
|
#endif
|
|
|
|
gblRouterManagers = (ROUTER_MANAGER_OBJECT *)LOCAL_ALLOC( LPTR,
|
|
sizeof(ROUTER_MANAGER_OBJECT) * MAX_NUM_ROUTERMANAGERS);
|
|
|
|
if ( gblRouterManagers == (ROUTER_MANAGER_OBJECT *)NULL )
|
|
{
|
|
dwRetCode = E_OUTOFMEMORY;
|
|
RegCloseKey( hKey );
|
|
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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
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 (WINVER >= 0x0501)
|
|
|
|
if ( gbldwProtocolId == PID_IPX )
|
|
{
|
|
DIMTRACE(
|
|
"IPX no longer supported. Skip loading IPX Router Manager"
|
|
);
|
|
|
|
DIMLogError(
|
|
ROUTERLOG_IPX_TRANSPORT_NOT_SUPPORTED, 0, NULL,
|
|
ERROR_NOT_SUPPORTED
|
|
);
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
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[dwRmIndex].hModule = LoadLibrary( pDllExpandedPath );
|
|
|
|
if ( gblRouterManagers[dwRmIndex].hModule == NULL )
|
|
{
|
|
dwRetCode = GetLastError();
|
|
|
|
DIMLogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Load the StartRouter
|
|
//
|
|
|
|
StartRouter = (PVOID)GetProcAddress(
|
|
gblRouterManagers[dwRmIndex].hModule,
|
|
"StartRouter" );
|
|
|
|
if ( StartRouter == NULL )
|
|
{
|
|
dwRetCode = GetLastError();
|
|
|
|
LogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
|
|
|
|
break;
|
|
}
|
|
|
|
gblRouterManagers[dwRmIndex].DdmRouterIf.ConnectInterface
|
|
= DIMConnectInterface;
|
|
gblRouterManagers[dwRmIndex].DdmRouterIf.DisconnectInterface
|
|
= DIMDisconnectInterface;
|
|
gblRouterManagers[dwRmIndex].DdmRouterIf.SaveInterfaceInfo
|
|
= DIMSaveInterfaceInfo;
|
|
gblRouterManagers[dwRmIndex].DdmRouterIf.RestoreInterfaceInfo
|
|
= DIMRestoreInterfaceInfo;
|
|
gblRouterManagers[dwRmIndex].DdmRouterIf.SaveGlobalInfo
|
|
= DIMSaveGlobalInfo;
|
|
gblRouterManagers[dwRmIndex].DdmRouterIf.RouterStopped
|
|
= DIMRouterStopped;
|
|
gblRouterManagers[dwRmIndex].DdmRouterIf.InterfaceEnabled
|
|
= DIMInterfaceEnabled;
|
|
dwRetCode = (*StartRouter)(
|
|
&(gblRouterManagers[dwRmIndex].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[dwRmIndex].pDefaultClientInterface = NULL;
|
|
gblRouterManagers[dwRmIndex].dwDefaultClientInterfaceSize = 0;
|
|
}
|
|
else
|
|
{
|
|
gblRouterManagers[dwRmIndex].pDefaultClientInterface =
|
|
pInterfaceInfo;
|
|
gblRouterManagers[dwRmIndex].dwDefaultClientInterfaceSize =
|
|
cbMaxValueDataSize;
|
|
}
|
|
|
|
RegCloseKey( hKeyRouterManager );
|
|
|
|
hKeyRouterManager = (HKEY)NULL;
|
|
|
|
gblRouterManagers[dwRmIndex].fIsRunning = TRUE;
|
|
|
|
dwRmIndex++;
|
|
|
|
gblDIMConfigInfo.dwNumRouterManagers++;
|
|
|
|
//
|
|
// 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=0;
|
|
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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
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=NO_ERROR;
|
|
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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
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=0;
|
|
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;
|
|
PVOID pvContext = NULL;
|
|
|
|
//
|
|
// 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, &pvContext );
|
|
|
|
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 );
|
|
|
|
//
|
|
// Check to see if we acquired phonebook context. Free
|
|
// it if we did.
|
|
//
|
|
if(pvContext != NULL)
|
|
{
|
|
VOID
|
|
(*IfObjectFreePhonebookContext)(VOID *) =
|
|
(VOID(*)( VOID * ))
|
|
GetDDMEntryPoint("IfObjectFreePhonebookContext");
|
|
|
|
IfObjectFreePhonebookContext(pvContext);
|
|
|
|
}
|
|
|
|
//
|
|
// 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,
|
|
IN OUT PVOID * ppvContext
|
|
)
|
|
{
|
|
DWORD dwIndex;
|
|
WCHAR * pChar;
|
|
DWORD cbValueBuf;
|
|
DWORD dwRetCode=NO_ERROR;
|
|
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,
|
|
ppvContext);
|
|
|
|
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=0;
|
|
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=0;
|
|
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 );
|
|
}
|