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