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.
3038 lines
72 KiB
3038 lines
72 KiB
/******************************************************************
|
|
CIPRouteTable.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 <ntddtcp.h>
|
|
#include <ipinfo.h>
|
|
#include <tdiinfo.h>
|
|
#include <winsock2.h>
|
|
#include <provexpt.h>
|
|
#include <provtempl.h>
|
|
#include <provmt.h>
|
|
#include <typeinfo.h>
|
|
#include <provcont.h>
|
|
#include <provval.h>
|
|
#include <provtype.h>
|
|
#include <provtree.h>
|
|
#include <provdnf.h>
|
|
#include "CIPRouteTable.h"
|
|
#include "CIpRouteEvent.h"
|
|
|
|
// TO DO: Replace "NameSpace" with the appropriate namespace for your
|
|
// provider instance. For instance: "root\\default or "root\\cimv2".
|
|
//===================================================================
|
|
|
|
CIPRouteTable MyCIPRouteTableSet (
|
|
|
|
PROVIDER_NAME_CIPROUTETABLE ,
|
|
L"root\\cimv2"
|
|
) ;
|
|
|
|
// Property names
|
|
//===============
|
|
const WCHAR *RouteAge = L"Age" ;
|
|
const WCHAR *RouteDestination = L"Destination" ;
|
|
const WCHAR *RouteInterfaceIndex = L"InterfaceIndex" ;
|
|
const WCHAR *RouteInformation = L"Information" ;
|
|
const WCHAR *RouteMask = L"Mask" ;
|
|
const WCHAR *RouteMetric1 = L"Metric1" ;
|
|
const WCHAR *RouteMetric2 = L"Metric2" ;
|
|
const WCHAR *RouteMetric3 = L"Metric3" ;
|
|
const WCHAR *RouteMetric4 = L"Metric4" ;
|
|
const WCHAR *RouteMetric5 = L"Metric5" ;
|
|
const WCHAR *RouteNextHop = L"NextHop" ;
|
|
const WCHAR *RouteProtocol = L"Protocol" ;
|
|
const WCHAR *RouteType = L"Type" ;
|
|
|
|
// Inherited properties populated
|
|
//===============================
|
|
const WCHAR *RouteName = L"Name" ;
|
|
const WCHAR *RouteCaption = L"Caption" ;
|
|
const WCHAR *RouteDescription = L"Description" ;
|
|
|
|
#define SYSTEM_PROPERTY_CLASS L"__CLASS"
|
|
#define SYSTEM_PROPERTY_SUPERCLASS L"__SUPERCLASS"
|
|
#define SYSTEM_PROPERTY_DYNASTY L"__DYNASTY"
|
|
#define SYSTEM_PROPERTY_DERIVATION L"__DERIVATION"
|
|
#define SYSTEM_PROPERTY_GENUS L"__GENUS"
|
|
#define SYSTEM_PROPERTY_NAMESPACE L"__NAMESPACE"
|
|
#define SYSTEM_PROPERTY_PROPERTY_COUNT L"__PROPERTY_COUNT"
|
|
#define SYSTEM_PROPERTY_SERVER L"__SERVER"
|
|
#define SYSTEM_PROPERTY_RELPATH L"__RELPATH"
|
|
#define SYSTEM_PROPERTY_PATH L"__PATH"
|
|
|
|
#define ROUTE_DESCRIPTION_SEP L" - "
|
|
|
|
_COM_SMARTPTR_TYPEDEF(IWbemClassObject, __uuidof(IWbemClassObject));
|
|
|
|
class CDeleteString
|
|
{
|
|
private:
|
|
|
|
wchar_t * m_ptr;
|
|
CDeleteString ( const CDeleteString& p ) ;
|
|
CDeleteString & operator= ( const CDeleteString & p ) ;
|
|
|
|
public:
|
|
|
|
CDeleteString ( wchar_t *ptr = NULL ) : m_ptr( ptr )
|
|
{
|
|
}
|
|
|
|
~CDeleteString ( )
|
|
{
|
|
if ( m_ptr )
|
|
{
|
|
delete [] m_ptr ;
|
|
m_ptr = NULL ;
|
|
}
|
|
}
|
|
|
|
operator LPCWSTR ( ) const { return ( (LPCWSTR) m_ptr ) ; }
|
|
};
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::CIPRouteTable
|
|
*
|
|
* DESCRIPTION : Constructor
|
|
*
|
|
* INPUTS : none
|
|
*
|
|
* RETURNS : nothing
|
|
*
|
|
* COMMENTS : Calls the Provider constructor.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
CIPRouteTable :: CIPRouteTable (
|
|
|
|
LPCWSTR lpwszName,
|
|
LPCWSTR lpwszNameSpace
|
|
|
|
) : Provider ( lpwszName , lpwszNameSpace ), m_ClassCInst( NULL )
|
|
{
|
|
InitializeCriticalSection( &m_CS ) ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::~CIPRouteTable
|
|
*
|
|
* DESCRIPTION : Destructor
|
|
*
|
|
* INPUTS : none
|
|
*
|
|
* RETURNS : nothing
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
*****************************************************************************/
|
|
|
|
CIPRouteTable :: ~CIPRouteTable ()
|
|
{
|
|
DeleteCriticalSection( &m_CS ) ;
|
|
|
|
if ( m_ClassCInst != NULL )
|
|
{
|
|
m_ClassCInst->Release();
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::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 CIPRouteTable :: RangeQuery (
|
|
|
|
MethodContext *pMethodContext,
|
|
PartitionSet &a_PartitionSet ,
|
|
long lFlags
|
|
)
|
|
{
|
|
HRESULT hRes = WBEM_S_NO_ERROR ;
|
|
|
|
SmartCloseNtHandle t_StackHandle ;
|
|
SmartCloseNtHandle t_CompleteEventHandle ;
|
|
|
|
NTSTATUS t_NtStatus = OpenQuerySource (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
ulong t_RouteTableSize = 0 ;
|
|
IPRouteEntry *t_InformationBlock = NULL ;
|
|
|
|
t_NtStatus = QueryInformation_IpRouteInfo (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle ,
|
|
t_RouteTableSize ,
|
|
t_InformationBlock
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
try
|
|
{
|
|
ULONG t_PartitionCount = a_PartitionSet.GetPartitionCount () ;
|
|
|
|
for ( ulong t_RouteIndex = 0 ; t_RouteIndex < t_RouteTableSize ; t_RouteIndex ++ )
|
|
{
|
|
IPRouteEntry &t_Entry = t_InformationBlock [ t_RouteIndex ] ;
|
|
|
|
ProvIpAddressType t_DestinationIpAddress ( ntohl ( t_Entry.ire_dest ) ) ;
|
|
CDeleteString t_DestinationIpAddressString(t_DestinationIpAddress.GetStringValue ());
|
|
|
|
BOOL t_Create = FALSE ;
|
|
|
|
for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
|
|
{
|
|
PartitionSet *t_PropertyPartition = a_PartitionSet.GetPartition ( t_Partition ) ;
|
|
|
|
WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_PropertyPartition->GetRange () ;
|
|
|
|
if ( t_Node->InfiniteLowerBound () )
|
|
{
|
|
if ( t_Node->InfiniteUpperBound () )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
else
|
|
{
|
|
int t_Compare = wcscmp ( t_DestinationIpAddressString , t_Node->UpperBound () ) ;
|
|
if ( t_Node->ClosedUpperBound () )
|
|
{
|
|
if ( t_Compare <= 0 )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( t_Compare < 0 )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int t_Compare = wcscmp ( t_DestinationIpAddressString , t_Node->LowerBound () ) ;
|
|
if ( t_Node->ClosedLowerBound () )
|
|
{
|
|
if ( t_Compare >= 0 )
|
|
{
|
|
if ( t_Node->InfiniteUpperBound () )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
else
|
|
{
|
|
t_Compare = wcscmp ( t_DestinationIpAddressString , t_Node->UpperBound () ) ;
|
|
if ( t_Node->ClosedUpperBound () )
|
|
{
|
|
if ( t_Compare <= 0 )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( t_Compare < 0 )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( t_Compare > 0 )
|
|
{
|
|
if ( t_Node->InfiniteUpperBound () )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
else
|
|
{
|
|
t_Compare = wcscmp ( t_DestinationIpAddressString , t_Node->UpperBound () ) ;
|
|
if ( t_Node->ClosedUpperBound () )
|
|
{
|
|
if ( t_Compare <= 0 )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( t_Compare < 0 )
|
|
{
|
|
t_Create = TRUE ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( t_Create )
|
|
{
|
|
|
|
/*
|
|
* Create a new instance based on the passed-in MethodContext.
|
|
* Note that CreateNewInstance may throw, but will never return NULL.
|
|
*/
|
|
|
|
CInstance *pInstance = CreateNewInstance ( pMethodContext ) ;
|
|
|
|
/*
|
|
* Set the keys for the instance
|
|
*/
|
|
|
|
pInstance->SetCHString ( RouteDestination, t_DestinationIpAddressString ) ;
|
|
|
|
ProvIpAddressType t_NextHopIpAddress ( ntohl ( t_Entry.ire_nexthop ) ) ;
|
|
CDeleteString t_NextHopIpAddressString (t_NextHopIpAddress.GetStringValue () ) ;
|
|
pInstance->SetCHString( RouteNextHop, t_NextHopIpAddressString ) ;
|
|
|
|
/*
|
|
* Initialize the instance
|
|
*/
|
|
|
|
ProvIpAddressType t_DestinationMaskIpAddress ( ntohl ( t_Entry.ire_mask ) ) ;
|
|
CDeleteString t_DestinationMaskIpAddressString (t_DestinationMaskIpAddress.GetStringValue () ) ;
|
|
pInstance->SetCHString( RouteMask, t_DestinationMaskIpAddressString ) ;
|
|
|
|
pInstance->SetDWORD ( RouteAge, t_Entry.ire_age ) ;
|
|
pInstance->SetDWORD ( RouteInterfaceIndex, t_Entry.ire_index ) ;
|
|
pInstance->SetCHString ( RouteInformation, "0.0" ) ;
|
|
pInstance->SetDWORD ( RouteProtocol, t_Entry.ire_proto ) ;
|
|
pInstance->SetDWORD ( RouteType, t_Entry.ire_type ) ;
|
|
pInstance->SetDWORD ( RouteMetric1, t_Entry.ire_metric1 ) ;
|
|
pInstance->SetDWORD ( RouteMetric2, t_Entry.ire_metric2 ) ;
|
|
pInstance->SetDWORD ( RouteMetric3, t_Entry.ire_metric3 ) ;
|
|
pInstance->SetDWORD ( RouteMetric4, t_Entry.ire_metric4 ) ;
|
|
pInstance->SetDWORD ( RouteMetric5, t_Entry.ire_metric5 ) ;
|
|
|
|
//set the inherited properties that are sensible
|
|
SetInheritedProperties (
|
|
t_DestinationIpAddressString ,
|
|
t_NextHopIpAddressString ,
|
|
t_DestinationMaskIpAddressString ,
|
|
*pInstance
|
|
) ;
|
|
|
|
|
|
/*
|
|
* Forward the instance onto the core wmi service
|
|
*/
|
|
|
|
hRes = Commit ( pInstance ) ;
|
|
}
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
HeapFree ( GetProcessHeap () , 0, t_InformationBlock ) ;
|
|
throw ;
|
|
}
|
|
|
|
HeapFree ( GetProcessHeap () , 0, t_InformationBlock ) ;
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( STATUS_ACCESS_DENIED == t_NtStatus )
|
|
{
|
|
hRes = WBEM_E_ACCESS_DENIED ;
|
|
}
|
|
else
|
|
{
|
|
hRes = WBEM_E_FAILED ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( STATUS_ACCESS_DENIED == t_NtStatus )
|
|
{
|
|
hRes = WBEM_E_ACCESS_DENIED ;
|
|
}
|
|
else
|
|
{
|
|
hRes = WBEM_E_FAILED ;
|
|
}
|
|
}
|
|
|
|
return hRes ;
|
|
}
|
|
|
|
HRESULT CIPRouteTable :: EnumerateInstances (
|
|
|
|
MethodContext *pMethodContext,
|
|
long lFlags
|
|
)
|
|
{
|
|
HRESULT hRes = WBEM_S_NO_ERROR ;
|
|
|
|
SmartCloseNtHandle t_StackHandle ;
|
|
SmartCloseNtHandle t_CompleteEventHandle ;
|
|
|
|
NTSTATUS t_NtStatus = OpenQuerySource (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
ulong t_RouteTableSize = 0 ;
|
|
IPRouteEntry *t_InformationBlock = NULL ;
|
|
|
|
t_NtStatus = QueryInformation_IpRouteInfo (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle ,
|
|
t_RouteTableSize ,
|
|
t_InformationBlock
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
try
|
|
{
|
|
for ( ulong t_RouteIndex = 0 ; t_RouteIndex < t_RouteTableSize ; t_RouteIndex ++ )
|
|
{
|
|
IPRouteEntry &t_Entry = t_InformationBlock [ t_RouteIndex ] ;
|
|
|
|
/*
|
|
* Create a new instance based on the passed-in MethodContext.
|
|
* Note that CreateNewInstance may throw, but will never return NULL.
|
|
*/
|
|
|
|
CInstance *pInstance = CreateNewInstance ( pMethodContext ) ;
|
|
|
|
/*
|
|
* Set the keys for the instance
|
|
*/
|
|
|
|
ProvIpAddressType t_DestinationIpAddress ( ntohl ( t_Entry.ire_dest ) ) ;
|
|
CDeleteString t_DestinationIpAddressString(t_DestinationIpAddress.GetStringValue ());
|
|
pInstance->SetCHString ( RouteDestination, t_DestinationIpAddressString ) ;
|
|
|
|
ProvIpAddressType t_NextHopIpAddress ( ntohl ( t_Entry.ire_nexthop ) ) ;
|
|
CDeleteString t_NextHopIpAddressString (t_NextHopIpAddress.GetStringValue () ) ;
|
|
pInstance->SetCHString( RouteNextHop, t_NextHopIpAddressString ) ;
|
|
|
|
/*
|
|
* Initialize the instance
|
|
*/
|
|
|
|
ProvIpAddressType t_DestinationMaskIpAddress ( ntohl ( t_Entry.ire_mask ) ) ;
|
|
CDeleteString t_DestinationMaskIpAddressString (t_DestinationMaskIpAddress.GetStringValue () ) ;
|
|
pInstance->SetCHString( RouteMask, t_DestinationMaskIpAddressString ) ;
|
|
|
|
pInstance->SetDWORD ( RouteAge, t_Entry.ire_age ) ;
|
|
pInstance->SetDWORD ( RouteInterfaceIndex, t_Entry.ire_index ) ;
|
|
pInstance->SetCHString ( RouteInformation, "0.0" ) ;
|
|
pInstance->SetDWORD ( RouteProtocol, t_Entry.ire_proto ) ;
|
|
pInstance->SetDWORD ( RouteType, t_Entry.ire_type ) ;
|
|
pInstance->SetDWORD ( RouteMetric1, t_Entry.ire_metric1 ) ;
|
|
pInstance->SetDWORD ( RouteMetric2, t_Entry.ire_metric2 ) ;
|
|
pInstance->SetDWORD ( RouteMetric3, t_Entry.ire_metric3 ) ;
|
|
pInstance->SetDWORD ( RouteMetric4, t_Entry.ire_metric4 ) ;
|
|
pInstance->SetDWORD ( RouteMetric5, t_Entry.ire_metric5 ) ;
|
|
|
|
//set the inherited properties that are sensible
|
|
SetInheritedProperties (
|
|
t_DestinationIpAddressString ,
|
|
t_NextHopIpAddressString ,
|
|
t_DestinationMaskIpAddressString ,
|
|
*pInstance
|
|
) ;
|
|
|
|
/*
|
|
* Forward the instance onto the core wmi service
|
|
*/
|
|
|
|
hRes = Commit ( pInstance ) ;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
HeapFree ( GetProcessHeap () , 0, t_InformationBlock ) ;
|
|
throw ;
|
|
}
|
|
|
|
HeapFree ( GetProcessHeap () , 0, t_InformationBlock ) ;
|
|
}
|
|
else
|
|
{
|
|
if ( STATUS_ACCESS_DENIED == t_NtStatus )
|
|
{
|
|
hRes = WBEM_E_ACCESS_DENIED ;
|
|
}
|
|
else
|
|
{
|
|
hRes = WBEM_E_FAILED ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( STATUS_ACCESS_DENIED == t_NtStatus )
|
|
{
|
|
hRes = WBEM_E_ACCESS_DENIED ;
|
|
}
|
|
else
|
|
{
|
|
hRes = WBEM_E_FAILED ;
|
|
}
|
|
}
|
|
|
|
return hRes ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::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 CIPRouteTable :: GetObject (
|
|
|
|
CInstance *pInstance,
|
|
long lFlags
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CHString t_KeyDest ;
|
|
pInstance->GetCHString ( RouteDestination , t_KeyDest ) ;
|
|
ProvIpAddressType t_IpAddress ( t_KeyDest ) ;
|
|
|
|
CHString t_KeyHop ;
|
|
pInstance->GetCHString ( RouteNextHop , t_KeyHop ) ;
|
|
ProvIpAddressType t_NextHop ( t_KeyHop ) ;
|
|
|
|
if ( t_IpAddress.IsValid () && t_NextHop.IsValid () )
|
|
{
|
|
IPRouteEntry t_RouteEntry ;
|
|
|
|
hr = QueryInformation_GetRouteEntry (
|
|
|
|
t_IpAddress ,
|
|
t_NextHop ,
|
|
t_RouteEntry
|
|
) ;
|
|
|
|
if ( SUCCEEDED ( hr ) )
|
|
{
|
|
/*
|
|
* Initialize the instance
|
|
*/
|
|
|
|
ProvIpAddressType t_DestinationMaskIpAddress ( ntohl ( t_RouteEntry.ire_mask ) ) ;
|
|
CDeleteString t_DestinationMaskIpAddressString (t_DestinationMaskIpAddress.GetStringValue () ) ;
|
|
pInstance->SetCHString( RouteMask, t_DestinationMaskIpAddressString ) ;
|
|
|
|
pInstance->SetDWORD ( RouteAge, t_RouteEntry.ire_age ) ;
|
|
pInstance->SetDWORD ( RouteInterfaceIndex, t_RouteEntry.ire_index ) ;
|
|
pInstance->SetCHString ( RouteInformation, "0.0" ) ;
|
|
pInstance->SetDWORD ( RouteProtocol, t_RouteEntry.ire_proto ) ;
|
|
pInstance->SetDWORD ( RouteType, t_RouteEntry.ire_type ) ;
|
|
pInstance->SetDWORD ( RouteMetric1, t_RouteEntry.ire_metric1 ) ;
|
|
pInstance->SetDWORD ( RouteMetric2, t_RouteEntry.ire_metric2 ) ;
|
|
pInstance->SetDWORD ( RouteMetric3, t_RouteEntry.ire_metric3 ) ;
|
|
pInstance->SetDWORD ( RouteMetric4, t_RouteEntry.ire_metric4 ) ;
|
|
pInstance->SetDWORD ( RouteMetric5, t_RouteEntry.ire_metric5 ) ;
|
|
|
|
//set the inherited properties that are sensible
|
|
SetInheritedProperties (
|
|
t_KeyDest ,
|
|
t_KeyHop ,
|
|
t_DestinationMaskIpAddressString ,
|
|
*pInstance
|
|
) ;
|
|
}
|
|
}
|
|
|
|
return hr ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::ExecQuery
|
|
*
|
|
* DESCRIPTION : You are passed a method context to use in the creation of
|
|
* instances that satisfy the query, and a CFrameworkQuery
|
|
* which describes the query. Create and populate all
|
|
* instances which satisfy the query. You may return more
|
|
* instances or more properties than are requested and WinMgmt
|
|
* will post filter out any that do not apply.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A query object describing the query to satisfy.
|
|
* 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_FORWARD_ONLY
|
|
* WBEM_FLAG_BIDIRECTIONAL
|
|
* WBEM_FLAG_ENSURE_LOCATABLE
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if queries not supported for
|
|
* this class or if the query is too complex for this class
|
|
* to interpret. The framework will call the EnumerateInstances
|
|
* function instead and let Winmgmt post filter.
|
|
* WBEM_E_FAILED if the query failed
|
|
* WBEM_S_NO_ERROR if query was successful
|
|
*
|
|
* COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, WinMgmt
|
|
* will call your enumerate function to get all the instances and perform the
|
|
* filtering for you. Unless you expect SIGNIFICANT savings from implementing
|
|
* queries, you should remove this method. You should also remove this method
|
|
* if you are implementing a 'method only' provider.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
HRESULT CIPRouteTable :: ExecQuery (
|
|
|
|
MethodContext *pMethodContext,
|
|
CFrameworkQuery &Query,
|
|
long lFlags
|
|
)
|
|
{
|
|
HRESULT t_Result = S_OK ;
|
|
|
|
|
|
CHString t_QueryString ;
|
|
SQL_LEVEL_1_RPN_EXPRESSION *t_RpnExpression = NULL ;
|
|
|
|
QueryPreprocessor :: QuadState t_State = QueryPreprocessor :: QuadState :: State_False;
|
|
try
|
|
{
|
|
t_QueryString = Query.GetQuery () ;
|
|
t_State = CIPRouteTable :: Query (
|
|
|
|
t_QueryString.GetBuffer ( 0 ) ,
|
|
t_RpnExpression
|
|
) ;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( t_RpnExpression )
|
|
{
|
|
delete t_RpnExpression;
|
|
t_RpnExpression = NULL;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
if ( t_State == QueryPreprocessor :: QuadState :: State_True )
|
|
{
|
|
WmiTreeNode *t_Root = NULL ;
|
|
|
|
try
|
|
{
|
|
t_State = PreProcess (
|
|
|
|
pMethodContext ,
|
|
t_RpnExpression ,
|
|
t_Root
|
|
) ;
|
|
|
|
switch ( t_State )
|
|
{
|
|
case QueryPreprocessor :: QuadState :: State_True:
|
|
{
|
|
PartitionSet *t_Partition = NULL ;
|
|
|
|
BSTR t_PropertyContainer [ 1 ] ;
|
|
t_PropertyContainer [ 0 ] = SysAllocString ( RouteDestination ) ;
|
|
|
|
if ( NULL == t_PropertyContainer [ 0 ] )
|
|
{
|
|
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
try
|
|
{
|
|
t_State = PreProcess (
|
|
|
|
pMethodContext ,
|
|
t_RpnExpression ,
|
|
t_Root ,
|
|
1 ,
|
|
t_PropertyContainer ,
|
|
t_Partition
|
|
) ;
|
|
}
|
|
catch(...)
|
|
{
|
|
if ( t_Partition )
|
|
{
|
|
delete t_Partition;
|
|
t_Partition = NULL;
|
|
}
|
|
|
|
if ( t_PropertyContainer [ 0 ] )
|
|
{
|
|
SysFreeString ( t_PropertyContainer [ 0 ] ) ;
|
|
t_PropertyContainer [ 0 ] = NULL;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
SysFreeString ( t_PropertyContainer [ 0 ] ) ;
|
|
|
|
switch ( t_State )
|
|
{
|
|
case QueryPreprocessor :: QuadState :: State_True :
|
|
{
|
|
t_Result = EnumerateInstances ( pMethodContext , lFlags ) ;
|
|
}
|
|
break ;
|
|
|
|
case QueryPreprocessor :: QuadState :: State_False :
|
|
{
|
|
/*
|
|
* Empty set
|
|
*/
|
|
}
|
|
break ;
|
|
|
|
case QueryPreprocessor :: QuadState :: State_Undefined :
|
|
{
|
|
t_Result = RangeQuery ( pMethodContext , *t_Partition , lFlags ) ;
|
|
|
|
delete t_Partition ;
|
|
t_Partition = NULL ;
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
//couldn't understand this query
|
|
t_Result = WBEM_E_PROVIDER_NOT_CAPABLE ;
|
|
}
|
|
break ;
|
|
}
|
|
|
|
//this is allocated on PreProcess(pctx, rpn, root) success
|
|
delete t_Root ;
|
|
t_Root = NULL ;
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
//couldn't understand this query
|
|
t_Result = WBEM_E_PROVIDER_NOT_CAPABLE ;
|
|
}
|
|
break ;
|
|
}
|
|
|
|
delete t_RpnExpression ;
|
|
t_RpnExpression = NULL ;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( t_Root )
|
|
{
|
|
delete t_Root;
|
|
t_Root = NULL;
|
|
}
|
|
|
|
if ( t_RpnExpression )
|
|
{
|
|
delete t_RpnExpression;
|
|
t_RpnExpression = NULL;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//couldn't understand this query
|
|
t_Result = WBEM_E_PROVIDER_NOT_CAPABLE ;
|
|
}
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::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 CIPRouteTable :: 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_UPDATE_ONLY:
|
|
case WBEM_FLAG_CREATE_ONLY:
|
|
{
|
|
CHString t_KeyDest ;
|
|
Instance.GetCHString ( RouteDestination , t_KeyDest ) ;
|
|
ProvIpAddressType t_IpAddress ( t_KeyDest ) ;
|
|
|
|
CHString t_KeyHop ;
|
|
Instance.GetCHString ( RouteNextHop , t_KeyHop ) ;
|
|
ProvIpAddressType t_NextHop ( t_KeyHop ) ;
|
|
|
|
if ( t_IpAddress.IsValid () && t_NextHop.IsValid () )
|
|
{
|
|
IPRouteEntry t_RouteEntry ;
|
|
|
|
hr = QueryInformation_GetRouteEntry (
|
|
|
|
t_IpAddress ,
|
|
t_NextHop ,
|
|
t_RouteEntry
|
|
) ;
|
|
|
|
switch ( lFlags & (WBEM_FLAG_CREATE_OR_UPDATE | WBEM_FLAG_CREATE_ONLY | WBEM_FLAG_UPDATE_ONLY) )
|
|
{
|
|
case WBEM_FLAG_CREATE_OR_UPDATE:
|
|
{
|
|
hr = ( hr == WBEM_E_NOT_FOUND || hr == WBEM_S_NO_ERROR ) ? WBEM_S_NO_ERROR : hr ;
|
|
}
|
|
break;
|
|
|
|
case WBEM_FLAG_UPDATE_ONLY:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case WBEM_FLAG_CREATE_ONLY:
|
|
{
|
|
if ( hr == WBEM_S_NO_ERROR )
|
|
{
|
|
hr = WBEM_E_ALREADY_EXISTS ;
|
|
}
|
|
else if ( hr == WBEM_E_NOT_FOUND )
|
|
{
|
|
hr = WBEM_S_NO_ERROR ;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ( SUCCEEDED ( hr ) )
|
|
{
|
|
hr = CheckParameters (
|
|
|
|
Instance ,
|
|
t_RouteEntry
|
|
) ;
|
|
}
|
|
|
|
if ( SUCCEEDED ( hr ) )
|
|
{
|
|
//reset to an error which will be cleared on success...
|
|
hr = WBEM_E_FAILED;
|
|
|
|
SmartCloseNtHandle t_StackHandle;
|
|
SmartCloseNtHandle t_CompleteEventHandle;
|
|
|
|
NTSTATUS t_NtStatus = OpenSetSource (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
t_NtStatus = SetInformation_IpRouteInfo (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle ,
|
|
t_RouteEntry
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
hr = WBEM_S_NO_ERROR ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
hr = WBEM_E_PROVIDER_NOT_CAPABLE ;
|
|
}
|
|
break ;
|
|
}
|
|
|
|
return hr ;
|
|
}
|
|
|
|
HRESULT CIPRouteTable :: CheckParameters (
|
|
|
|
const CInstance &a_Instance ,
|
|
IPRouteEntry &a_RouteEntry
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR ;
|
|
|
|
ZeroMemory ( & a_RouteEntry , sizeof ( a_RouteEntry ) ) ;
|
|
|
|
a_RouteEntry.ire_metric2 = -1 ;
|
|
a_RouteEntry.ire_metric3 = -1 ;
|
|
a_RouteEntry.ire_metric4 = -1 ;
|
|
a_RouteEntry.ire_metric5 = -1 ;
|
|
|
|
bool t_Exists ;
|
|
VARTYPE t_Type ;
|
|
|
|
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 () )
|
|
{
|
|
a_RouteEntry.ire_dest = htonl ( t_Address.GetValue () ) ;
|
|
}
|
|
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 () )
|
|
{
|
|
a_RouteEntry.ire_mask = htonl ( t_Address.GetValue () ) ;
|
|
}
|
|
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 () )
|
|
{
|
|
a_RouteEntry.ire_nexthop = htonl ( t_Address.GetValue () ) ;
|
|
}
|
|
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 ;
|
|
}
|
|
|
|
if ( a_Instance.GetStatus ( RouteInterfaceIndex , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 ) )
|
|
{
|
|
DWORD t_InterfaceIndex = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteInterfaceIndex , t_InterfaceIndex ) )
|
|
{
|
|
a_RouteEntry.ire_index = t_InterfaceIndex ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
if ( a_Instance.GetStatus ( RouteProtocol , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 ) )
|
|
{
|
|
DWORD t_Protocol = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteProtocol , t_Protocol ) )
|
|
{
|
|
a_RouteEntry.ire_proto = t_Protocol ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
|
|
if ( a_Instance.GetStatus ( RouteType , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 ) )
|
|
{
|
|
DWORD t_Type = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteType , t_Type ) )
|
|
{
|
|
a_RouteEntry.ire_type = t_Type ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
#if 0
|
|
if ( a_Instance.GetStatus ( RouteAge , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 ) )
|
|
{
|
|
DWORD t_Age = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteAge , t_Age ) )
|
|
{
|
|
a_RouteEntry.ire_age = t_Age ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
#endif
|
|
|
|
if ( a_Instance.GetStatus ( RouteMetric1 , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 ) )
|
|
{
|
|
DWORD t_Metric = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteMetric1 , t_Metric ) )
|
|
{
|
|
a_RouteEntry.ire_metric1 = t_Metric ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
if ( a_Instance.GetStatus ( RouteMetric2 , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 || t_Type == VT_NULL ) )
|
|
{
|
|
if ( t_Type == VT_NULL )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
DWORD t_Metric = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteMetric2 , t_Metric ) )
|
|
{
|
|
a_RouteEntry.ire_metric2 = t_Metric ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
if ( a_Instance.GetStatus ( RouteMetric3 , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 || t_Type == VT_NULL ) )
|
|
{
|
|
if ( t_Type == VT_NULL )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
DWORD t_Metric = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteMetric3 , t_Metric ) )
|
|
{
|
|
a_RouteEntry.ire_metric3 = t_Metric ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
if ( a_Instance.GetStatus ( RouteMetric5 , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 || t_Type == VT_NULL ) )
|
|
{
|
|
if ( t_Type == VT_NULL )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
DWORD t_Metric = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteMetric5 , t_Metric ) )
|
|
{
|
|
a_RouteEntry.ire_metric5 = t_Metric ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
if ( a_Instance.GetStatus ( RouteMetric4 , t_Exists , t_Type ) )
|
|
{
|
|
if ( t_Exists && ( t_Type == VT_I4 || t_Type == VT_NULL ) )
|
|
{
|
|
if ( t_Type == VT_NULL )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
DWORD t_Metric = 0 ;
|
|
if ( a_Instance.GetDWORD ( RouteMetric4 , t_Metric ) )
|
|
{
|
|
a_RouteEntry.ire_metric4 = t_Metric ;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_FAILED ;
|
|
}
|
|
|
|
return hr ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::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 CIPRouteTable :: DeleteInstance (
|
|
|
|
const CInstance &Instance,
|
|
long lFlags
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED ;
|
|
|
|
CHString t_KeyDest ;
|
|
Instance.GetCHString ( RouteDestination , t_KeyDest ) ;
|
|
ProvIpAddressType t_IpAddress ( t_KeyDest ) ;
|
|
|
|
CHString t_KeyHop ;
|
|
Instance.GetCHString ( RouteNextHop , t_KeyHop ) ;
|
|
ProvIpAddressType t_NextHop ( t_KeyHop ) ;
|
|
|
|
if ( t_IpAddress.IsValid () && t_NextHop.IsValid () )
|
|
{
|
|
IPRouteEntry t_RouteEntry ;
|
|
|
|
hr = QueryInformation_GetRouteEntry (
|
|
|
|
t_IpAddress ,
|
|
t_NextHop ,
|
|
t_RouteEntry
|
|
) ;
|
|
|
|
if ( SUCCEEDED ( hr ) )
|
|
{
|
|
SmartCloseNtHandle t_StackHandle ;
|
|
SmartCloseNtHandle t_CompleteEventHandle ;
|
|
|
|
NTSTATUS t_NtStatus = OpenSetSource (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
t_NtStatus = DeleteInformation_IpRouteInfo (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle ,
|
|
t_RouteEntry
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
hr = WBEM_S_NO_ERROR ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CIPRouteTable::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 CIPRouteTable :: 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 ;
|
|
}
|
|
|
|
NTSTATUS CIPRouteTable :: OpenQuerySource (
|
|
|
|
HANDLE &a_StackHandle ,
|
|
HANDLE &a_CompleteEventHandle
|
|
)
|
|
{
|
|
UNICODE_STRING t_Stack ;
|
|
RtlInitUnicodeString ( & t_Stack , DD_TCP_DEVICE_NAME ) ;
|
|
|
|
OBJECT_ATTRIBUTES t_Attributes;
|
|
InitializeObjectAttributes (
|
|
|
|
&t_Attributes,
|
|
&t_Stack ,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
) ;
|
|
|
|
IO_STATUS_BLOCK t_IoStatusBlock ;
|
|
|
|
NTSTATUS t_NtStatus = NtOpenFile (
|
|
|
|
&a_StackHandle,
|
|
GENERIC_EXECUTE,
|
|
&t_Attributes,
|
|
&t_IoStatusBlock,
|
|
FILE_SHARE_READ,
|
|
0
|
|
);
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
t_NtStatus = NtCreateEvent (
|
|
|
|
&a_CompleteEventHandle,
|
|
EVENT_ALL_ACCESS,
|
|
NULL,
|
|
SynchronizationEvent,
|
|
FALSE
|
|
) ;
|
|
|
|
if ( ! NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
NtClose ( a_StackHandle ) ;
|
|
a_StackHandle = INVALID_HANDLE_VALUE ;
|
|
}
|
|
}
|
|
|
|
return t_NtStatus ;
|
|
}
|
|
|
|
HRESULT CIPRouteTable :: QueryInformation_GetRouteEntry (
|
|
|
|
const ProvIpAddressType &a_DestinationIpAddress ,
|
|
const ProvIpAddressType &a_NextHopIpAddress ,
|
|
IPRouteEntry &a_RouteEntry
|
|
)
|
|
{
|
|
HRESULT hRes = WBEM_E_NOT_FOUND ;
|
|
|
|
SmartCloseNtHandle t_StackHandle ;
|
|
SmartCloseNtHandle t_CompleteEventHandle ;
|
|
|
|
NTSTATUS t_NtStatus = OpenQuerySource (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
ulong t_RouteTableSize = 0 ;
|
|
IPRouteEntry *t_InformationBlock = NULL ;
|
|
|
|
t_NtStatus = QueryInformation_IpRouteInfo (
|
|
|
|
t_StackHandle ,
|
|
t_CompleteEventHandle ,
|
|
t_RouteTableSize ,
|
|
t_InformationBlock
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
try
|
|
{
|
|
for ( ulong t_RouteIndex = 0 ; t_RouteIndex < t_RouteTableSize ; t_RouteIndex ++ )
|
|
{
|
|
IPRouteEntry &t_Entry = t_InformationBlock [ t_RouteIndex ] ;
|
|
|
|
ProvIpAddressType t_DestinationIpAddress ( ntohl ( t_Entry.ire_dest ) ) ;
|
|
ProvIpAddressType t_NextHopIpAddress ( ntohl ( t_Entry.ire_nexthop ) ) ;
|
|
|
|
if ( ( t_DestinationIpAddress == a_DestinationIpAddress ) &&
|
|
( t_NextHopIpAddress == a_NextHopIpAddress ) )
|
|
{
|
|
a_RouteEntry = t_InformationBlock [ t_RouteIndex ] ;
|
|
|
|
hRes = WBEM_S_NO_ERROR ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
HeapFree ( GetProcessHeap () , 0, t_InformationBlock ) ;
|
|
throw ;
|
|
}
|
|
|
|
HeapFree ( GetProcessHeap () , 0, t_InformationBlock ) ;
|
|
}
|
|
else
|
|
{
|
|
if ( STATUS_ACCESS_DENIED == t_NtStatus )
|
|
{
|
|
hRes = WBEM_E_ACCESS_DENIED ;
|
|
}
|
|
else
|
|
{
|
|
hRes = WBEM_E_FAILED ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hRes ;
|
|
}
|
|
|
|
NTSTATUS CIPRouteTable :: QueryInformation_IpRouteInfo (
|
|
|
|
HANDLE a_StackHandle ,
|
|
HANDLE a_CompleteEventHandle ,
|
|
ulong &a_RouteTableSize ,
|
|
IPRouteEntry *&a_InformationBlock
|
|
)
|
|
{
|
|
IPSNMPInfo a_Information ;
|
|
NTSTATUS t_NtStatus = QueryInformation_IpSnmpInfo (
|
|
|
|
a_StackHandle ,
|
|
a_CompleteEventHandle ,
|
|
a_Information
|
|
) ;
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
TCP_REQUEST_QUERY_INFORMATION_EX InBuf;
|
|
ulong InBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
|
|
|
|
ulong OutBufLen = ( a_Information.ipsi_numroutes + 16 ) * sizeof ( IPRouteEntry ) ;
|
|
a_InformationBlock = ( IPRouteEntry * ) HeapAlloc ( GetProcessHeap (), 0, OutBufLen ) ;
|
|
if ( a_InformationBlock )
|
|
{
|
|
TDIObjectID *ID = & ( InBuf.ID ) ;
|
|
|
|
ID = &(InBuf.ID);
|
|
ID->toi_entity.tei_entity = CL_NL_ENTITY;
|
|
ID->toi_entity.tei_instance = 0;
|
|
ID->toi_class = INFO_CLASS_PROTOCOL;
|
|
ID->toi_type = INFO_TYPE_PROVIDER;
|
|
ID->toi_id = IP_MIB_RTTABLE_ENTRY_ID;
|
|
|
|
uchar *Context = ( uchar * ) & ( InBuf.Context [ 0 ] ) ;
|
|
|
|
ZeroMemory ( Context, CONTEXT_SIZE ) ;
|
|
|
|
IO_STATUS_BLOCK t_IoStatusBlock ;
|
|
|
|
t_NtStatus = NtDeviceIoControlFile (
|
|
|
|
a_StackHandle ,
|
|
a_CompleteEventHandle ,
|
|
NULL ,
|
|
NULL ,
|
|
&t_IoStatusBlock ,
|
|
IOCTL_TCP_QUERY_INFORMATION_EX,
|
|
( void * ) & InBuf,
|
|
InBufLen,
|
|
( void * ) ( a_InformationBlock ) ,
|
|
OutBufLen
|
|
);
|
|
|
|
if ( t_NtStatus == STATUS_PENDING )
|
|
{
|
|
t_NtStatus = NtWaitForSingleObject ( a_CompleteEventHandle , FALSE, NULL ) ;
|
|
}
|
|
|
|
if ( SUCCEEDED ( t_NtStatus ) )
|
|
{
|
|
a_RouteTableSize = ( t_IoStatusBlock.Information / sizeof ( IPRouteEntry ) ) ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
}
|
|
|
|
return t_NtStatus ;
|
|
}
|
|
|
|
NTSTATUS CIPRouteTable :: QueryInformation_IpSnmpInfo (
|
|
|
|
HANDLE a_StackHandle ,
|
|
HANDLE a_CompleteEventHandle ,
|
|
IPSNMPInfo &a_Information
|
|
)
|
|
{
|
|
TCP_REQUEST_QUERY_INFORMATION_EX InBuf;
|
|
ulong InBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
|
|
ulong OutBufLen = sizeof ( IPSNMPInfo ) ;
|
|
|
|
TDIObjectID *ID = & ( InBuf.ID ) ;
|
|
|
|
ID->toi_entity.tei_entity = CL_NL_ENTITY;
|
|
ID->toi_entity.tei_instance = 0;
|
|
ID->toi_class = INFO_CLASS_PROTOCOL;
|
|
ID->toi_type = INFO_TYPE_PROVIDER;
|
|
ID->toi_id = IP_MIB_STATS_ID;
|
|
|
|
uchar *Context = ( uchar * ) & ( InBuf.Context [ 0 ] ) ;
|
|
|
|
ZeroMemory ( Context, CONTEXT_SIZE ) ;
|
|
|
|
IO_STATUS_BLOCK t_IoStatusBlock ;
|
|
|
|
NTSTATUS t_NtStatus = NtDeviceIoControlFile (
|
|
|
|
a_StackHandle ,
|
|
a_CompleteEventHandle ,
|
|
NULL ,
|
|
NULL ,
|
|
&t_IoStatusBlock ,
|
|
IOCTL_TCP_QUERY_INFORMATION_EX,
|
|
( void * ) & InBuf,
|
|
InBufLen,
|
|
( void * ) ( & a_Information ) ,
|
|
OutBufLen
|
|
);
|
|
|
|
if ( t_NtStatus == STATUS_PENDING )
|
|
{
|
|
t_NtStatus = NtWaitForSingleObject ( a_CompleteEventHandle , FALSE, NULL ) ;
|
|
}
|
|
|
|
if ( SUCCEEDED ( t_NtStatus ) )
|
|
{
|
|
}
|
|
|
|
return t_NtStatus ;
|
|
}
|
|
|
|
NTSTATUS CIPRouteTable :: OpenSetSource (
|
|
|
|
HANDLE &a_StackHandle ,
|
|
HANDLE &a_CompleteEventHandle
|
|
)
|
|
{
|
|
UNICODE_STRING t_Stack ;
|
|
RtlInitUnicodeString ( & t_Stack , DD_TCP_DEVICE_NAME ) ;
|
|
|
|
OBJECT_ATTRIBUTES t_Attributes;
|
|
InitializeObjectAttributes (
|
|
|
|
&t_Attributes,
|
|
&t_Stack ,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
) ;
|
|
|
|
IO_STATUS_BLOCK t_IoStatusBlock ;
|
|
|
|
NTSTATUS t_NtStatus = NtOpenFile (
|
|
|
|
&a_StackHandle,
|
|
GENERIC_WRITE,
|
|
&t_Attributes,
|
|
&t_IoStatusBlock,
|
|
FILE_SHARE_READ,
|
|
0
|
|
);
|
|
|
|
if ( NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
t_NtStatus = NtCreateEvent (
|
|
|
|
&a_CompleteEventHandle,
|
|
EVENT_ALL_ACCESS,
|
|
NULL,
|
|
SynchronizationEvent,
|
|
FALSE
|
|
) ;
|
|
|
|
if ( ! NT_SUCCESS ( t_NtStatus ) )
|
|
{
|
|
NtClose ( a_StackHandle ) ;
|
|
a_StackHandle = INVALID_HANDLE_VALUE ;
|
|
}
|
|
}
|
|
|
|
return t_NtStatus ;
|
|
}
|
|
|
|
NTSTATUS CIPRouteTable :: SetInformation_IpRouteInfo (
|
|
|
|
HANDLE a_StackHandle ,
|
|
HANDLE a_CompleteEventHandle ,
|
|
IPRouteEntry &a_RouteEntry
|
|
)
|
|
{
|
|
NTSTATUS t_NtStatus = STATUS_SUCCESS ;
|
|
|
|
ulong InBufLen = sizeof ( TCP_REQUEST_SET_INFORMATION_EX ) + sizeof ( IPSNMPInfo ) - 1 ;
|
|
TCP_REQUEST_SET_INFORMATION_EX *InBuf = ( TCP_REQUEST_SET_INFORMATION_EX * ) HeapAlloc ( GetProcessHeap(), 0, InBufLen ) ;
|
|
if ( InBuf )
|
|
{
|
|
try
|
|
{
|
|
IPRouteEntry *t_Entry = ( IPRouteEntry * ) &(InBuf->Buffer[0]) ;
|
|
*t_Entry = a_RouteEntry ;
|
|
|
|
TDIObjectID *ID = &(InBuf->ID);
|
|
ID->toi_entity.tei_entity = CL_NL_ENTITY;
|
|
ID->toi_entity.tei_instance = 0;
|
|
ID->toi_class = INFO_CLASS_PROTOCOL;
|
|
ID->toi_type = INFO_TYPE_PROVIDER;
|
|
ID->toi_id = IP_MIB_RTTABLE_ENTRY_ID;
|
|
|
|
InBuf->BufferSize = sizeof ( IPRouteEntry );
|
|
|
|
IO_STATUS_BLOCK t_IoStatusBlock ;
|
|
|
|
t_NtStatus = NtDeviceIoControlFile (
|
|
|
|
a_StackHandle ,
|
|
a_CompleteEventHandle ,
|
|
NULL ,
|
|
NULL ,
|
|
&t_IoStatusBlock ,
|
|
IOCTL_TCP_SET_INFORMATION_EX ,
|
|
( void * ) InBuf,
|
|
InBufLen,
|
|
NULL ,
|
|
0
|
|
);
|
|
|
|
if ( t_NtStatus == STATUS_PENDING )
|
|
{
|
|
t_NtStatus = NtWaitForSingleObject ( a_CompleteEventHandle , FALSE, NULL ) ;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
HeapFree ( GetProcessHeap () , 0, InBuf ) ;
|
|
throw ;
|
|
}
|
|
|
|
HeapFree ( GetProcessHeap () , 0, InBuf ) ;
|
|
}
|
|
else
|
|
{
|
|
t_NtStatus = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
return t_NtStatus ;
|
|
}
|
|
|
|
NTSTATUS CIPRouteTable :: DeleteInformation_IpRouteInfo (
|
|
|
|
HANDLE a_StackHandle ,
|
|
HANDLE a_CompleteEventHandle ,
|
|
IPRouteEntry &a_RouteEntry
|
|
)
|
|
{
|
|
NTSTATUS t_NtStatus = STATUS_SUCCESS ;
|
|
|
|
ulong InBufLen = sizeof ( TCP_REQUEST_SET_INFORMATION_EX ) + sizeof ( IPSNMPInfo ) - 1 ;
|
|
TCP_REQUEST_SET_INFORMATION_EX *InBuf = ( TCP_REQUEST_SET_INFORMATION_EX * ) HeapAlloc ( GetProcessHeap(), 0, InBufLen ) ;
|
|
if ( InBuf )
|
|
{
|
|
try
|
|
{
|
|
IPRouteEntry *t_Entry = ( IPRouteEntry * ) &(InBuf->Buffer[0]) ;
|
|
*t_Entry = a_RouteEntry ;
|
|
|
|
/*
|
|
* Invalidate the route
|
|
*/
|
|
|
|
t_Entry->ire_type = 2 ;
|
|
|
|
TDIObjectID *ID = &(InBuf->ID);
|
|
ID->toi_entity.tei_entity = CL_NL_ENTITY;
|
|
ID->toi_entity.tei_instance = 0;
|
|
ID->toi_class = INFO_CLASS_PROTOCOL;
|
|
ID->toi_type = INFO_TYPE_PROVIDER;
|
|
ID->toi_id = IP_MIB_RTTABLE_ENTRY_ID;
|
|
|
|
InBuf->BufferSize = sizeof ( IPRouteEntry );
|
|
|
|
IO_STATUS_BLOCK t_IoStatusBlock ;
|
|
|
|
t_NtStatus = NtDeviceIoControlFile (
|
|
|
|
a_StackHandle ,
|
|
a_CompleteEventHandle ,
|
|
NULL ,
|
|
NULL ,
|
|
&t_IoStatusBlock ,
|
|
IOCTL_TCP_SET_INFORMATION_EX ,
|
|
( void * ) InBuf,
|
|
InBufLen,
|
|
NULL ,
|
|
0
|
|
);
|
|
|
|
if ( t_NtStatus == STATUS_PENDING )
|
|
{
|
|
t_NtStatus = NtWaitForSingleObject ( a_CompleteEventHandle , FALSE, NULL ) ;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
HeapFree ( GetProcessHeap () , 0, InBuf ) ;
|
|
throw ;
|
|
}
|
|
|
|
HeapFree ( GetProcessHeap () , 0, InBuf ) ;
|
|
}
|
|
else
|
|
{
|
|
t_NtStatus = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
return t_NtStatus ;
|
|
}
|
|
|
|
DWORD CIPRouteTable :: GetPriority ( BSTR a_PropertyName )
|
|
{
|
|
return 0xFFFFFFFF ;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState CIPRouteTable :: Compare (
|
|
|
|
LONG a_Operand1 ,
|
|
LONG a_Operand2 ,
|
|
DWORD a_Operand1Func ,
|
|
DWORD a_Operand2Func ,
|
|
WmiTreeNode &a_OperatorType
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
|
|
switch ( a_Operand1Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
|
|
switch ( a_Operand2Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
|
|
if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualNode ) )
|
|
{
|
|
t_Status = a_Operand1 == a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotEqualNode ) )
|
|
{
|
|
t_Status = a_Operand1 != a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
|
|
{
|
|
t_Status = a_Operand1 >= a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrLessNode ) )
|
|
{
|
|
t_Status = a_Operand1 <= a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLessNode ) )
|
|
{
|
|
t_Status = a_Operand1 < a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorGreaterNode ) )
|
|
{
|
|
t_Status = a_Operand1 > a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLikeNode ) )
|
|
{
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotLikeNode ) )
|
|
{
|
|
}
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState CIPRouteTable :: Compare (
|
|
|
|
wchar_t *a_Operand1 ,
|
|
wchar_t *a_Operand2 ,
|
|
DWORD a_Operand1Func ,
|
|
DWORD a_Operand2Func ,
|
|
WmiTreeNode &a_OperatorType
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
|
|
CHString a_Operand1AfterFunc ;
|
|
CHString a_Operand2AfterFunc ;
|
|
|
|
switch ( a_Operand1Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Upper:
|
|
{
|
|
a_Operand1AfterFunc = a_Operand1 ;
|
|
a_Operand1AfterFunc.MakeUpper () ;
|
|
}
|
|
break ;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Lower:
|
|
{
|
|
a_Operand1AfterFunc = a_Operand1 ;
|
|
a_Operand1AfterFunc.MakeLower () ;
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
|
|
switch ( a_Operand2Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Upper:
|
|
{
|
|
a_Operand2AfterFunc = a_Operand2 ;
|
|
a_Operand2AfterFunc.MakeUpper () ;
|
|
}
|
|
break ;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Lower:
|
|
{
|
|
a_Operand2AfterFunc = a_Operand2 ;
|
|
a_Operand2AfterFunc.MakeLower () ;
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
|
|
const wchar_t *t_Arg1 = a_Operand1AfterFunc.IsEmpty () ? a_Operand1 : (LPCWSTR)a_Operand1AfterFunc ;
|
|
const wchar_t *t_Arg2 = a_Operand2AfterFunc.IsEmpty () ? a_Operand2 : (LPCWSTR)a_Operand2AfterFunc ;
|
|
|
|
if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) == 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( t_Arg1 ) || ( t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotEqualNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) != 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( t_Arg1 ) || ( t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) >= 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( t_Arg1 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
if ( t_Arg2 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrLessNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) <= 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( t_Arg1 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( t_Arg2 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLessNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) < 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( ! t_Arg1 ) && ( ! t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( t_Arg1 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorGreaterNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) > 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( ! t_Arg1 ) && ( ! t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( t_Arg1 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLikeNode ) )
|
|
{
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotLikeNode ) )
|
|
{
|
|
}
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState CIPRouteTable :: CompareString (
|
|
|
|
IWbemClassObject *a_ClassObject ,
|
|
BSTR a_PropertyName ,
|
|
WmiTreeNode *a_Operator ,
|
|
WmiTreeNode *a_Operand
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
|
|
WmiStringNode *t_StringNode = ( WmiStringNode * ) a_Operand ;
|
|
|
|
VARIANT t_Variant ;
|
|
VariantInit ( & t_Variant ) ;
|
|
|
|
HRESULT t_Result = a_ClassObject->Get ( a_PropertyName , 0 , &t_Variant , NULL , NULL ) ;
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
t_Status = Compare (
|
|
|
|
t_StringNode->GetValue () ,
|
|
t_Variant.bstrVal ,
|
|
t_StringNode->GetPropertyFunction () ,
|
|
t_StringNode->GetConstantFunction () ,
|
|
*a_Operator
|
|
) ;
|
|
}
|
|
|
|
VariantClear ( & t_Variant ) ;
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState CIPRouteTable :: CompareInteger (
|
|
|
|
IWbemClassObject *a_ClassObject ,
|
|
BSTR a_PropertyName ,
|
|
WmiTreeNode *a_Operator ,
|
|
WmiTreeNode *a_Operand
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
|
|
WmiSignedIntegerNode *t_IntegerNode = ( WmiSignedIntegerNode * ) a_Operand ;
|
|
|
|
VARIANT t_Variant ;
|
|
VariantInit ( & t_Variant ) ;
|
|
|
|
HRESULT t_Result = a_ClassObject->Get ( a_PropertyName , 0 , &t_Variant , NULL , NULL ) ;
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
t_Status = Compare (
|
|
|
|
t_IntegerNode->GetValue () ,
|
|
t_Variant.lVal ,
|
|
t_IntegerNode->GetPropertyFunction () ,
|
|
t_IntegerNode->GetConstantFunction () ,
|
|
*a_Operator
|
|
) ;
|
|
}
|
|
|
|
VariantClear ( & t_Variant ) ;
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
WmiTreeNode *CIPRouteTable :: AllocTypeNode (
|
|
|
|
void *a_Context ,
|
|
BSTR a_PropertyName ,
|
|
VARIANT &a_Variant ,
|
|
WmiValueNode :: WmiValueFunction a_PropertyFunction ,
|
|
WmiValueNode :: WmiValueFunction a_ConstantFunction ,
|
|
WmiTreeNode *a_Parent
|
|
)
|
|
{
|
|
WmiTreeNode *t_Node = NULL ;
|
|
|
|
VARTYPE t_VarType = VT_NULL ;
|
|
|
|
if ( *a_PropertyName == L'_' )
|
|
{
|
|
// System property
|
|
|
|
if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_CLASS ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_SUPERCLASS ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_GENUS ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_I4))
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.lVal,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_SERVER ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_NAMESPACE ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_PROPERTY_COUNT ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_I4))
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.lVal ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_DYNASTY ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_RELPATH ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_PATH ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
0xFFFFFFFF ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_DERIVATION ) == 0 )
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CInstance *t_ClassObject = NULL ;
|
|
HRESULT t_Result = GetClassObject ( t_ClassObject, (MethodContext *)a_Context ) ;
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
IWbemClassObjectPtr t_pClas ( t_ClassObject->GetClassObjectInterface () , false ) ;
|
|
|
|
if ( t_pClas != NULL )
|
|
{
|
|
CIMTYPE t_VarType ;
|
|
long t_Flavour ;
|
|
VARIANT t_Variant ;
|
|
VariantInit ( & t_Variant ) ;
|
|
|
|
|
|
HRESULT t_Result = t_pClas->Get (
|
|
|
|
a_PropertyName ,
|
|
0 ,
|
|
& t_Variant ,
|
|
& t_VarType ,
|
|
& t_Flavour
|
|
);
|
|
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
if ( t_VarType & CIM_FLAG_ARRAY )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
switch ( t_VarType & ( ~ CIM_FLAG_ARRAY ) )
|
|
{
|
|
case CIM_BOOLEAN:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.lVal ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if (V_VT(&a_Variant) == VT_BOOL)
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName ,
|
|
(a_Variant.lVal == VARIANT_FALSE) ? 0 : 1,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if (V_VT(&a_Variant) == VT_NULL)
|
|
{
|
|
t_Node = new WmiNullNode (
|
|
|
|
a_PropertyName ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case CIM_SINT8:
|
|
case CIM_SINT16:
|
|
case CIM_CHAR16:
|
|
case CIM_SINT32:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.lVal ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if (V_VT(&a_Variant) == VT_NULL)
|
|
{
|
|
t_Node = new WmiNullNode (
|
|
|
|
a_PropertyName ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case CIM_UINT8:
|
|
case CIM_UINT16:
|
|
case CIM_UINT32:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
t_Node = new WmiUnsignedIntegerNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.lVal ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if (V_VT(&a_Variant) == VT_NULL)
|
|
{
|
|
t_Node = new WmiNullNode (
|
|
|
|
a_PropertyName ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_BSTR)
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
_variant_t t_uintBuff (&a_Variant);
|
|
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
(BSTR)((_bstr_t) t_uintBuff),
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if (V_VT(&a_Variant) == VT_NULL)
|
|
{
|
|
t_Node = new WmiNullNode (
|
|
|
|
a_PropertyName ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case CIM_STRING:
|
|
case CIM_DATETIME:
|
|
case CIM_REFERENCE:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_BSTR)
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName ,
|
|
a_Variant.bstrVal ,
|
|
a_PropertyFunction ,
|
|
a_ConstantFunction ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
) ;
|
|
}
|
|
else if (V_VT(&a_Variant) == VT_NULL)
|
|
{
|
|
t_Node = new WmiNullNode (
|
|
|
|
a_PropertyName ,
|
|
GetPriority ( a_PropertyName ) ,
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break ;
|
|
|
|
case CIM_REAL32:
|
|
case CIM_REAL64:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
case CIM_OBJECT:
|
|
case CIM_EMPTY:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
|
|
VariantClear ( & t_Variant ) ;
|
|
}
|
|
|
|
t_ClassObject->Release () ;
|
|
}
|
|
}
|
|
|
|
return t_Node ;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState CIPRouteTable :: InvariantEvaluate (
|
|
|
|
void *a_Context ,
|
|
WmiTreeNode *a_Operator ,
|
|
WmiTreeNode *a_Operand
|
|
)
|
|
{
|
|
/*
|
|
* If property and value are invariant i.e. will never change for all instances then return State_True.
|
|
* If property is not indexable or keyed then return State_True to define an unknown number of possible values which we cannot optimise against.
|
|
* If property and value can never occur then return State_False to imply empty set
|
|
* If property and value do not infer anything then return State_Undefined.
|
|
* If property and value are in error then return State_Error
|
|
* Never return State_ReEvaluate.
|
|
*/
|
|
|
|
QueryPreprocessor :: QuadState t_State = QueryPreprocessor :: QuadState :: State_Error ;
|
|
|
|
CInstance *t_ClassObject = NULL ;
|
|
HRESULT t_Result = GetClassObject ( t_ClassObject, (MethodContext *)a_Context ) ;
|
|
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
IWbemClassObjectPtr t_pClas(t_ClassObject->GetClassObjectInterface (), false );
|
|
|
|
if (t_pClas != NULL)
|
|
{
|
|
WmiValueNode *t_Node = ( WmiValueNode * ) a_Operand ;
|
|
BSTR t_PropertyName = t_Node->GetPropertyName () ;
|
|
|
|
if ( t_PropertyName != NULL )
|
|
{
|
|
if ( *t_PropertyName == L'_' )
|
|
{
|
|
// System property, must check values
|
|
if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_CLASS ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_CLASS ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_SUPERCLASS ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_SUPERCLASS ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_GENUS ) == 0 )
|
|
{
|
|
t_State = CompareInteger (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_GENUS ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_SERVER ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_SERVER ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_NAMESPACE ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_NAMESPACE ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_PROPERTY_COUNT ) == 0 )
|
|
{
|
|
t_State = CompareInteger (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_PROPERTY_COUNT ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_DYNASTY ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_DYNASTY ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_RELPATH ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_RELPATH ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_PATH ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
t_pClas ,
|
|
SYSTEM_PROPERTY_PATH ,
|
|
a_Operator ,
|
|
a_Operand
|
|
) ;
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_DERIVATION ) == 0 )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( typeid ( *a_Operand ) == typeid ( WmiNullNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
#if 0
|
|
else if ( typeid ( *a_Operand ) == typeid ( WmiStringNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operand ) == typeid ( WmiUnsignedIntegerNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operand ) == typeid ( WmiSignedIntegerNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
|
|
if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorNotEqualNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualOrLessNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorLessNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorGreaterNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorLikeNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorNotLikeNode ) )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
|
|
}
|
|
}
|
|
|
|
t_ClassObject->Release();
|
|
}
|
|
|
|
return t_State ;
|
|
}
|
|
|
|
WmiRangeNode *CIPRouteTable :: AllocInfiniteRangeNode (
|
|
|
|
void *a_Context ,
|
|
BSTR a_PropertyName
|
|
)
|
|
{
|
|
WmiRangeNode *t_RangeNode = NULL ;
|
|
CInstance *t_ClassObject = NULL ;
|
|
HRESULT t_Result = GetClassObject ( t_ClassObject, (MethodContext *)a_Context ) ;
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
IWbemClassObjectPtr t_pClas ( t_ClassObject->GetClassObjectInterface () , false ) ;
|
|
|
|
if ( t_pClas != NULL )
|
|
{
|
|
CIMTYPE t_VarType ;
|
|
long t_Flavour ;
|
|
VARIANT t_Variant ;
|
|
VariantInit ( & t_Variant ) ;
|
|
|
|
HRESULT t_Result = t_pClas->Get (
|
|
|
|
a_PropertyName ,
|
|
0 ,
|
|
& t_Variant ,
|
|
& t_VarType ,
|
|
& t_Flavour
|
|
);
|
|
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
if ( t_VarType & CIM_FLAG_ARRAY )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
switch ( t_VarType & ( ~ CIM_FLAG_ARRAY ) )
|
|
{
|
|
case CIM_BOOLEAN:
|
|
case CIM_SINT8:
|
|
case CIM_SINT16:
|
|
case CIM_CHAR16:
|
|
case CIM_SINT32:
|
|
{
|
|
t_RangeNode = new WmiSignedIntegerRangeNode (
|
|
|
|
a_PropertyName ,
|
|
0xFFFFFFFF ,
|
|
TRUE ,
|
|
TRUE ,
|
|
FALSE ,
|
|
FALSE ,
|
|
0 ,
|
|
0 ,
|
|
NULL ,
|
|
NULL
|
|
) ;
|
|
}
|
|
break ;
|
|
|
|
case CIM_UINT8:
|
|
case CIM_UINT16:
|
|
case CIM_UINT32:
|
|
{
|
|
t_RangeNode = new WmiUnsignedIntegerRangeNode (
|
|
|
|
a_PropertyName ,
|
|
0xFFFFFFFF ,
|
|
TRUE ,
|
|
TRUE ,
|
|
FALSE ,
|
|
FALSE ,
|
|
0 ,
|
|
0 ,
|
|
NULL ,
|
|
NULL
|
|
) ;
|
|
}
|
|
break ;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
case CIM_STRING:
|
|
case CIM_DATETIME:
|
|
case CIM_REFERENCE:
|
|
{
|
|
t_RangeNode = new WmiStringRangeNode (
|
|
|
|
a_PropertyName ,
|
|
0x0 ,
|
|
TRUE ,
|
|
TRUE ,
|
|
FALSE ,
|
|
FALSE ,
|
|
NULL ,
|
|
NULL ,
|
|
NULL ,
|
|
NULL
|
|
) ;
|
|
}
|
|
break ;
|
|
|
|
case CIM_REAL32:
|
|
case CIM_REAL64:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
case CIM_OBJECT:
|
|
case CIM_EMPTY:
|
|
{
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
|
|
VariantClear ( & t_Variant ) ;
|
|
}
|
|
|
|
t_ClassObject->Release () ;
|
|
}
|
|
|
|
return t_RangeNode ;
|
|
}
|
|
|
|
HRESULT CIPRouteTable :: GetClassObject ( CInstance *&a_ClassObject, MethodContext *a_Context )
|
|
{
|
|
HRESULT t_Result = S_OK ;
|
|
EnterCriticalSection( &m_CS ) ;
|
|
|
|
try
|
|
{
|
|
if ( m_ClassCInst == NULL )
|
|
{
|
|
t_Result = WBEM_E_FAILED ;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
LeaveCriticalSection( &m_CS );
|
|
throw;
|
|
}
|
|
|
|
LeaveCriticalSection( &m_CS );
|
|
|
|
if (t_Result == WBEM_E_FAILED)
|
|
{
|
|
CHString t_Namespace ( GetNamespace () ) ;
|
|
CHString t_ComputerName ( GetLocalComputerName () ) ;
|
|
CHString t_ClassName ( GetProviderName () ) ;
|
|
CHString t_AbsPath = L"\\\\" + t_ComputerName + L"\\" + t_Namespace + L":" + t_ClassName ;
|
|
|
|
t_Result = CWbemProviderGlue :: GetInstanceByPath ( ( LPCTSTR ) t_AbsPath.GetBuffer ( 0 ) , & a_ClassObject, a_Context ) ;
|
|
|
|
if ( SUCCEEDED (t_Result) )
|
|
{
|
|
EnterCriticalSection( &m_CS ) ;
|
|
|
|
try
|
|
{
|
|
if ( m_ClassCInst == NULL )
|
|
{
|
|
m_ClassCInst = a_ClassObject ;
|
|
m_ClassCInst->AddRef();
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
LeaveCriticalSection( &m_CS );
|
|
throw;
|
|
}
|
|
|
|
LeaveCriticalSection( &m_CS );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
a_ClassObject = m_ClassCInst;
|
|
a_ClassObject->AddRef();
|
|
}
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
void CIPRouteTable :: SetInheritedProperties (
|
|
|
|
LPCWSTR a_dest ,
|
|
LPCWSTR a_gateway ,
|
|
LPCWSTR a_mask ,
|
|
CInstance &a_Instance
|
|
)
|
|
{
|
|
CHString t_temp( a_dest ) ;
|
|
a_Instance.SetCHString ( RouteName, t_temp ) ;
|
|
a_Instance.SetCHString ( RouteCaption, t_temp ) ;
|
|
|
|
t_temp = t_temp + ROUTE_DESCRIPTION_SEP + a_mask + ROUTE_DESCRIPTION_SEP + a_gateway;
|
|
a_Instance.SetCHString ( RouteDescription, t_temp ) ;
|
|
}
|