/****************************************************************** CIPPersistedRTble.CPP -- WMI provider class implementation Generated by Microsoft WMI Code Generation Engine TO DO: - See individual function headers - When linking, make sure you link to framedyd.lib & msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail). Description: ******************************************************************/ #include "precomp.h" #include #include #include #include #include #include #include #include #include #include "CIPPersistedRTble.h" extern const WCHAR *RouteDestination ; extern const WCHAR *RouteInformation ; extern const WCHAR *RouteMask ; extern const WCHAR *RouteMetric1 ; extern const WCHAR *RouteNextHop ; extern const WCHAR *RouteName ; extern const WCHAR *RouteCaption ; extern const WCHAR *RouteDescription ; #define TCIP_PERSISTENT_REG L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\PersistentRoutes" #define MAX_METRIC1 9999 #define PERSITENT_ROUTE_SEP L',' CIPPersistedRouteTable MyCIPPersistedRouteTableSet ( PROVIDER_NAME_CIPPERSISTEDROUTETABLE , L"root\\cimv2" ) ; /***************************************************************************** * * FUNCTION : CIPPersistedRouteTable::CIPPersistedRouteTable * * DESCRIPTION : Constructor * * INPUTS : none * * RETURNS : nothing * * COMMENTS : Calls the Provider constructor. * *****************************************************************************/ CIPPersistedRouteTable :: CIPPersistedRouteTable ( LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider ( lpwszName , lpwszNameSpace ) { } /***************************************************************************** * * FUNCTION : CIPPersistedRouteTable::~CIPPersistedRouteTable * * DESCRIPTION : Destructor * * INPUTS : none * * RETURNS : nothing * * COMMENTS : * *****************************************************************************/ CIPPersistedRouteTable :: ~CIPPersistedRouteTable () { } /***************************************************************************** * * FUNCTION : CIPPersistedRouteTable::EnumerateInstances * * DESCRIPTION : Returns all the instances of this class. * * INPUTS : A pointer to the MethodContext for communication with WinMgmt. * A long that contains the flags described in * IWbemServices::CreateInstanceEnumAsync. Note that the following * flags are handled by (and filtered out by) WinMgmt: * WBEM_FLAG_DEEP * WBEM_FLAG_SHALLOW * WBEM_FLAG_RETURN_IMMEDIATELY * WBEM_FLAG_FORWARD_ONLY * WBEM_FLAG_BIDIRECTIONAL * * RETURNS : WBEM_S_NO_ERROR if successful * * COMMENTS : TO DO: All instances on the machine should be returned here and * all properties that this class knows how to populate must * be filled in. If there are no instances, return * WBEM_S_NO_ERROR. It is not an error to have no instances. * If you are implementing a 'method only' provider, you * should remove this method. * *****************************************************************************/ HRESULT CIPPersistedRouteTable :: EnumerateInstances ( MethodContext *pMethodContext, long lFlags ) { HRESULT hRes = WBEM_S_NO_ERROR ; CRegistry t_Reg; DWORD dwError = ERROR_SUCCESS; if ( ( dwError = t_Reg.Open( HKEY_LOCAL_MACHINE, TCIP_PERSISTENT_REG, KEY_READ) ) == ERROR_SUCCESS) { WCHAR *pValueName = NULL ; BYTE *pValueData = NULL ; try { for(DWORD i = 0 ; i < t_Reg.GetValueCount() && SUCCEEDED(hRes); i++) { DWORD dwRetCode = t_Reg.EnumerateAndGetValues(i, pValueName, pValueData) ; if(dwRetCode == ERROR_SUCCESS) { CHString t_Dest ; CHString t_Mask ; CHString t_NextHop ; long t_Metric ; if ( Parse ( pValueName , t_Dest , t_Mask , t_NextHop , t_Metric ) ) { CInstance *pInstance = CreateNewInstance ( pMethodContext ) ; if (pInstance != NULL ) { /* * Initialize the instance */ pInstance->SetCHString( RouteDestination, t_Dest ) ; pInstance->SetCHString( RouteMask, t_Mask ) ; pInstance->SetCHString( RouteNextHop, t_NextHop ) ; pInstance->SetDWORD ( RouteMetric1, t_Metric ) ; //set the inherited properties that are sensible SetInheritedProperties ( t_Dest , t_NextHop , t_Mask , t_Metric , *pInstance ) ; /* * Forward the instance onto the core wmi service */ hRes = Commit ( pInstance ) ; } } } if ( pValueName ) { delete [] pValueName ; pValueName = NULL ; } if ( pValueData ) { delete [] pValueData ; pValueData = NULL ; } } t_Reg.Close() ; } catch ( ... ) { if ( pValueName ) { delete [] pValueName ; pValueName = NULL ; } if ( pValueData ) { delete [] pValueData ; pValueData = NULL ; } throw ; } } else { if ( ERROR_ACCESS_DENIED == dwError ) { hRes = WBEM_E_ACCESS_DENIED ; } else { hRes = WBEM_E_FAILED ; } } return hRes ; } /***************************************************************************** * * FUNCTION : CIPPersistedRouteTable::GetObject * * DESCRIPTION : Find a single instance based on the key properties for the * class. * * INPUTS : A pointer to a CInstance object containing the key properties. * A long that contains the flags described in * IWbemServices::GetObjectAsync. * * RETURNS : WBEM_S_NO_ERROR if the instance can be found * WBEM_E_NOT_FOUND if the instance described by the key properties * could not be found * WBEM_E_FAILED if the instance could be found but another error * occurred. * * COMMENTS : If you are implementing a 'method only' provider, you should * remove this method. * *****************************************************************************/ HRESULT CIPPersistedRouteTable :: GetObject ( CInstance *pInstance, long lFlags ) { HRESULT hr = WBEM_E_NOT_FOUND; CHString t_Dest ; CHString t_Mask ; CHString t_NextHop ; long t_Metric1 = 1; pInstance->GetCHString ( RouteDestination , t_Dest ) ; pInstance->GetCHString ( RouteMask , t_Mask ) ; pInstance->GetCHString ( RouteNextHop , t_NextHop ) ; pInstance->GetDWORD ( RouteMetric1 , (DWORD&)t_Metric1 ) ; CRegistry t_Reg; DWORD dwError = ERROR_SUCCESS; if ( ( dwError = t_Reg.Open( HKEY_LOCAL_MACHINE, TCIP_PERSISTENT_REG, KEY_READ) ) == ERROR_SUCCESS) { WCHAR buff [ 20 ]; buff [ 0 ] = L'\0' ; _ultow( t_Metric1, buff , 10 ) ; CHString t_ValName = t_Dest + PERSITENT_ROUTE_SEP + t_Mask + PERSITENT_ROUTE_SEP + t_NextHop + PERSITENT_ROUTE_SEP + buff ; if ( RegQueryValueEx ( t_Reg.GethKey(), t_ValName , NULL , NULL , NULL , NULL ) == ERROR_SUCCESS ) { hr = S_OK ; /* * Initialize the instance */ //set the inherited properties that are sensible SetInheritedProperties ( t_Dest , t_NextHop , t_Mask , t_Metric1, *pInstance ) ; } t_Reg.Close(); } else { if ( ERROR_ACCESS_DENIED == dwError ) { hr = WBEM_E_ACCESS_DENIED ; } else { hr = WBEM_E_FAILED ; } } return hr ; } /***************************************************************************** * * FUNCTION : CIPPersistedRouteTable::PutInstance * * DESCRIPTION : PutInstance should be used in provider classes that can * write instance information back to the hardware or * software. For example: Win32_Environment will allow a * PutInstance to create or update an environment variable. * However, a class like MotherboardDevice will not allow * editing of the number of slots, since it is difficult for * a provider to affect that number. * * INPUTS : A pointer to a CInstance object containing the key properties. * A long that contains the flags described in * IWbemServices::PutInstanceAsync. * * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available * WBEM_E_FAILED if there is an error delivering the instance * WBEM_E_INVALID_PARAMETER if any of the instance properties * are incorrect. * WBEM_S_NO_ERROR if instance is properly delivered * * COMMENTS : TO DO: If you don't intend to support writing to your provider, * or are creating a 'method only' provider, remove this * method. * *****************************************************************************/ HRESULT CIPPersistedRouteTable :: PutInstance ( const CInstance &Instance, long lFlags ) { HRESULT hr = WBEM_E_FAILED ; switch ( lFlags & (WBEM_FLAG_CREATE_OR_UPDATE | WBEM_FLAG_CREATE_ONLY | WBEM_FLAG_UPDATE_ONLY) ) { case WBEM_FLAG_CREATE_OR_UPDATE: case WBEM_FLAG_CREATE_ONLY: { CHString t_ValName ; hr = CheckParameters ( Instance , t_ValName ) ; if ( SUCCEEDED ( hr ) ) { CRegistry t_Reg; DWORD dwError = ERROR_SUCCESS; if ( ( dwError = t_Reg.Open( HKEY_LOCAL_MACHINE, TCIP_PERSISTENT_REG, KEY_ALL_ACCESS) ) == ERROR_SUCCESS) { CHString t_temp; if ( ERROR_SUCCESS != t_Reg.SetCurrentKeyValue( t_ValName, t_temp ) ) { hr = S_OK ; } t_Reg.Close () ; } else { if ( ERROR_ACCESS_DENIED == dwError ) { hr = WBEM_E_ACCESS_DENIED ; } else { hr = WBEM_E_FAILED ; } } } else { hr = WBEM_E_INVALID_PARAMETER ; } } break ; default: { hr = WBEM_E_PROVIDER_NOT_CAPABLE ; } break ; } return hr ; } HRESULT CIPPersistedRouteTable :: CheckParameters ( const CInstance &a_Instance , CHString &a_ValueName ) { bool t_Exists ; VARTYPE t_Type ; long t_mask = 0 ; long t_dest = 0 ; long t_nexthop = 0 ; CHString t_RouteDestinationString ; if ( a_Instance.GetStatus ( RouteDestination , t_Exists , t_Type ) ) { if ( t_Exists && ( t_Type == VT_BSTR ) ) { if ( a_Instance.GetCHString ( RouteDestination , t_RouteDestinationString ) && ! t_RouteDestinationString.IsEmpty () ) { ProvIpAddressType t_Address ( t_RouteDestinationString ) ; if ( t_Address.IsValid () ) { t_dest = htonl ( t_Address.GetValue () ) ; if ( t_dest == -1 ) { return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_INVALID_PARAMETER ; } } else { // Zero Length string return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_FAILED ; } CHString t_RouteDestinationMaskString ; if ( a_Instance.GetStatus ( RouteMask , t_Exists , t_Type ) ) { if ( t_Exists && ( t_Type == VT_BSTR ) ) { if ( a_Instance.GetCHString ( RouteMask , t_RouteDestinationMaskString ) && ! t_RouteDestinationMaskString.IsEmpty () ) { ProvIpAddressType t_Address ( t_RouteDestinationMaskString ) ; if ( t_Address.IsValid () ) { t_mask = htonl ( t_Address.GetValue () ) ; if ( ( t_dest & t_mask ) != t_dest ) { return WBEM_E_INVALID_PARAMETER; } } else { return WBEM_E_INVALID_PARAMETER ; } } else { // Zero Length string return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_FAILED ; } CHString t_RouteNextHopString ; if ( a_Instance.GetStatus ( RouteNextHop, t_Exists , t_Type ) ) { if ( t_Exists && ( t_Type == VT_BSTR ) ) { if ( a_Instance.GetCHString ( RouteNextHop , t_RouteNextHopString ) && ! t_RouteNextHopString.IsEmpty () ) { ProvIpAddressType t_Address ( t_RouteNextHopString ) ; if ( t_Address.IsValid () ) { t_nexthop = htonl ( t_Address.GetValue () ) ; if ( t_nexthop == -1 ) { return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_INVALID_PARAMETER ; } } else { // Zero Length string return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_FAILED ; } DWORD t_Metric = 0 ; if ( a_Instance.GetStatus ( RouteMetric1 , t_Exists , t_Type ) ) { if ( t_Exists && ( t_Type == VT_I4 ) ) { if ( !a_Instance.GetDWORD ( RouteMetric1 , t_Metric ) || ( t_Metric < 1) || ( t_Metric > MAX_METRIC1) ) { return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_INVALID_PARAMETER ; } } else { return WBEM_E_FAILED ; } WCHAR buff [ 20 ] ; buff [ 0 ] = L'\0' ; _ultow ( t_Metric , buff , 10 ) ; a_ValueName = t_RouteDestinationString + PERSITENT_ROUTE_SEP + t_RouteDestinationMaskString + PERSITENT_ROUTE_SEP + t_RouteNextHopString + PERSITENT_ROUTE_SEP + buff; return S_OK ; } /***************************************************************************** * * FUNCTION : CIPPersistedRouteTable::DeleteInstance * * DESCRIPTION : DeleteInstance, like PutInstance, actually writes information * to the software or hardware. For most hardware devices, * DeleteInstance should not be implemented, but for software * configuration, DeleteInstance implementation is plausible. * * INPUTS : A pointer to a CInstance object containing the key properties. * A long that contains the flags described in * IWbemServices::DeleteInstanceAsync. * * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available. * WBEM_E_FAILED if there is an error deleting the instance. * WBEM_E_INVALID_PARAMETER if any of the instance properties * are incorrect. * WBEM_S_NO_ERROR if instance is properly deleted. * * COMMENTS : TO DO: If you don't intend to support deleting instances or are * creating a 'method only' provider, remove this method. * *****************************************************************************/ HRESULT CIPPersistedRouteTable :: DeleteInstance ( const CInstance &Instance, long lFlags ) { HRESULT hr = WBEM_E_FAILED ; CHString t_Dest ; CHString t_Mask ; CHString t_NextHop ; long t_Metric1 = 1; Instance.GetCHString ( RouteDestination , t_Dest ) ; Instance.GetCHString ( RouteMask , t_Mask ) ; Instance.GetCHString ( RouteNextHop , t_NextHop ) ; Instance.GetDWORD ( RouteMetric1 , (DWORD&)t_Metric1 ) ; CRegistry t_Reg; DWORD dwError = ERROR_SUCCESS; if ( ( dwError = t_Reg.Open( HKEY_LOCAL_MACHINE, TCIP_PERSISTENT_REG, KEY_ALL_ACCESS) ) == ERROR_SUCCESS) { WCHAR buff [ 20 ]; buff[0] = L'\0' ; _ultow( t_Metric1 , buff , 10 ) ; CHString t_ValName = t_Dest + PERSITENT_ROUTE_SEP + t_Mask + PERSITENT_ROUTE_SEP + t_NextHop + PERSITENT_ROUTE_SEP + buff ; if ( t_Reg.DeleteCurrentKeyValue(t_ValName) == ERROR_SUCCESS ) { hr = S_OK ; } t_Reg.Close(); } else { if ( ERROR_ACCESS_DENIED == dwError ) { hr = WBEM_E_ACCESS_DENIED ; } } return hr ; } /***************************************************************************** * * FUNCTION : CIPPersistedRouteTable::ExecMethod * * DESCRIPTION : Override this function to provide support for methods. * A method is an entry point for the user of your provider * to request your class perform some function above and * beyond a change of state. (A change of state should be * handled by PutInstance() ) * * INPUTS : A pointer to a CInstance containing the instance the method was executed against. * A string containing the method name * A pointer to the CInstance which contains the IN parameters. * A pointer to the CInstance to contain the OUT parameters. * A set of specialized method flags * * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not implemented for this class * WBEM_S_NO_ERROR if method executes successfully * WBEM_E_FAILED if error occurs executing method * * COMMENTS : TO DO: If you don't intend to support Methods, remove this method. * *****************************************************************************/ HRESULT CIPPersistedRouteTable :: ExecMethod ( const CInstance &Instance, const BSTR bstrMethodName, CInstance *pInParams, CInstance *pOutParams, long lFlags ) { // For non-static methods, use the CInstance Get functions (for example, // call GetCHString(L"Name", sTemp)) against Instance to see the key // values the client requested. return WBEM_E_PROVIDER_NOT_CAPABLE ; } BOOL CIPPersistedRouteTable :: Parse ( LPWSTR a_InStr , CHString &a_Dest , CHString &a_Mask , CHString &a_NextHop , long &a_Metric ) { BOOL t_RetVal = FALSE ; if ( a_InStr && ( wcslen ( a_InStr ) > 0 ) ) { LPWSTR t_Str = a_InStr ; LPWSTR t_Addr = t_Str ; a_Metric = 1 ; DWORD t_count = 0; while ( *t_Str != L'\0' ) { if ( *t_Str != PERSITENT_ROUTE_SEP ) { t_Str++ ; } else { *t_Str = L'\0'; ProvIpAddressType t_Address ( t_Addr ) ; if ( t_Address.IsValid () ) { t_count++ ; t_RetVal = TRUE ; switch ( t_count ) { case 1 : { a_Dest = t_Addr ; } break ; case 2 : { a_Mask = t_Addr ; } break ; case 3 : { a_NextHop = t_Addr ; } break ; default : { t_RetVal = FALSE ; } } if ( t_RetVal ) { *t_Str = PERSITENT_ROUTE_SEP ; t_Str++ ; t_Addr = t_Str ; } else { break ; } } else { t_RetVal = FALSE ; break ; } } } if ( ( t_count == 3 ) && t_RetVal ) { //get the metric if (t_Addr != t_Str) { a_Metric = _wtoi ( t_Addr ) ; if ( a_Metric < 1 ) { t_RetVal = FALSE ; } } } else { t_RetVal = FALSE ; } } return t_RetVal; } void CIPPersistedRouteTable :: SetInheritedProperties ( LPCWSTR a_dest , LPCWSTR a_gateway , LPCWSTR a_mask , long a_metric , CInstance &a_Instance ) { CHString t_temp( a_dest ) ; a_Instance.SetCHString ( RouteName, t_temp ) ; a_Instance.SetCHString ( RouteCaption, t_temp ) ; WCHAR t_buff [ 20 ] ; t_buff[0] = L'\0' ; _ultow( a_metric , t_buff , 10 ) ; t_temp = t_temp + PERSITENT_ROUTE_SEP + a_mask + PERSITENT_ROUTE_SEP + a_gateway + PERSITENT_ROUTE_SEP + t_buff ; a_Instance.SetCHString ( RouteDescription, t_temp ) ; }