Leaked source code of windows server 2003
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

/********************************************************************/
/** 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 );
}