PEGASUS_NAMESPACE_BEGIN //////////////////////////////////////////////////////////////// // // addQualifiersToCIMParameter // // Add qualifiers from a WMI class to a CIMParameter. // /////////////////////////////////////////////////////////////// void addQualifiersToCIMParameter(const CIMQualifierList& cimQualifierList, CIMParameter& cimParam, Boolean includeQualifiers) { static const CIMName idName("ID"); static const CIMName inName("in"); static const CIMName outName("out"); for (Uint32 i = 0, n = cimQualifierList.getCount(); i < n; i++) { CIMQualifier cimQual = cimQualifierList.getQualifier(i); // Add this qualifier if includeQualifiers is true or if // this is an "ID", "in", or "out" qualifier: if (includeQualifiers || cimQual.getName().equal(inName) || cimQual.getName().equal(outName) || cimQual.getName().equal(idName)) { cimParam.addQualifier(cimQualifierList.getQualifier(i)); } } }
void CIMQualifierList::resolve( DeclContext* declContext, const CIMNamespaceName & nameSpace, CIMScope scope, // Scope of the entity being resolved. Boolean isInstancePart, CIMQualifierList& inheritedQualifiers, Boolean propagateQualifiers) { _keyIndex = PEGASUS_ORDEREDSET_INDEX_UNKNOWN; PEG_METHOD_ENTER(TRC_OBJECTRESOLUTION, "CIMQualifierList::resolve()"); // For each qualifier in the qualifiers array, the following // is checked: // // 1. Whether it is declared (can be obtained from the declContext). // // 2. Whether it has the same type as the declaration. // // 3. Whether the qualifier is valid for the given scope. // // 4. Whether the qualifier can be overriden (the flavor is // ENABLEOVERRIDE on the corresponding reference qualifier). // // 5. Whether the qualifier should be propagated to the subclass. // // If the qualifier should be overriden, then it is injected into the // qualifiers array (from the inheritedQualifiers array). for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++) { CIMQualifier q = _qualifiers[i]; //---------------------------------------------------------------------- // 1. Check to see if it's declared. //---------------------------------------------------------------------- // set this back to CIMConstQualifierDecl CIMQualifierDecl qd = declContext->lookupQualifierDecl( nameSpace, q.getName()); if (qd.isUninitialized()) { PEG_METHOD_EXIT(); throw UndeclaredQualifier(q.getName().getString ()); } //---------------------------------------------------------------------- // 2. Check the type and isArray. Must be the same: //---------------------------------------------------------------------- if (!(q.getType() == qd.getType() && q.isArray() == qd.isArray())) { PEG_METHOD_EXIT(); throw BadQualifierType(q.getName().getString ()); } //---------------------------------------------------------------------- // 3. If the qualifier is the EmbeddedInstance qualifier, then check // that the class specified by the qualifier exists in the namespace. //---------------------------------------------------------------------- if (q.getName().equal(PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE)) { String className; q.getValue().get(className); CIMClass classDef = declContext->lookupClass(nameSpace, CIMName(className)); if (classDef.isUninitialized()) { String embeddedInstType("EmbeddedInstance(\""); embeddedInstType = embeddedInstType + className + "\")"; PEG_METHOD_EXIT(); throw BadQualifierType(embeddedInstType); } } //---------------------------------------------------------------------- // 4. Check the scope: Must be legal for this qualifier //---------------------------------------------------------------------- // ATTN: These lines throw a bogus exception if the qualifier has // a valid scope (such as Scope::ASSOCIATION) which is not Scope::CLASS // ks Mar 2002. Reinstalled 23 March 2002 to test. if (!(qd.getScope().hasScope (scope))) { PEG_METHOD_EXIT(); throw BadQualifierScope (qd.getName().getString (), scope.toString ()); } //---------------------------------------------------------------------- // Resolve the qualifierflavor. Since Flavors are a combination of // inheritance and input characteristics, resolve the inherited // characteristics against those provided with the creation. If // there is a superclass the flavor is resolved against that // superclass. If not, it is resolved against the declaration. If // the flavor is disableoverride and tosubclass the resolved // qualifier value must be identical to the original //---------------------------------------------------------------------- // Test for Qualifier found in SuperClass. If found and qualifier // is not overridable. // Abstract (not Overridable and restricted) can be found in subclasses // Can have nonabstracts below abstracts. That is function of // nottosubclass Association (notOverridable and tosubclass) can be // found in subclasses but cannot be changed. No non-associatons below // associations. In other words once a class becomes an association, // no subclass can override that definition apparently // Throw exception if DisableOverride and tosubclass and different // value. Gets the source from superclass if qualifier exists or from // declaraction. // If we do not throw the exception, resolve the flavor from the // inheritance point and resolve against current input. // Diableoverride is defined in the CIM Spec to mean that the value // cannot change. // The other characteristics including the flavor can change // apparently. Thus, we need only confirm that the value is the same // (2.2 pp 33). Strange since we would think that override implies // that you cannot override any of the characteristics (value, type, // flavor, etc.) This also leaves the question of NULL or no values. // The implication is that we must move the value from the superclass // or declaration. Uint32 index = inheritedQualifiers.find(q.getName()); if (index == PEG_NOT_FOUND) { // Qualifier does not exist in superclass /* If from declaration, we can override the default value. However, we need some way to get the value if we have a Null. if (!qd.getFlavor().hasFlavor(CIMFlavor::OVERRIDABLE) && qd.getFlavor().hasFlavor(CIMFlavor::TOSUBCLASS)) { //throw BadQualifierOverride(q.getName()); } */ // Do not allow change from disable override to enable override. if ((!qd.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE)) && (q.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE))) { PEG_METHOD_EXIT(); throw BadQualifierOverride(q.getName().getString ()); } Resolver::resolveQualifierFlavor( q, CIMFlavor (qd.getFlavor ()), false); } else // qualifier exists in superclass { ////// Make Const again CIMQualifier iq = inheritedQualifiers.getQualifier(index); // don't allow change override to notoverride. if (!(iq.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE)) && q.getFlavor ().hasFlavor (CIMFlavor::OVERRIDABLE)) { PEG_METHOD_EXIT(); throw BadQualifierOverride(q.getName().getString ()); } if (!(iq.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE)) && iq.getFlavor ().hasFlavor(CIMFlavor::TOSUBCLASS)) { // test if values the same. CIMValue qv = q.getValue(); CIMValue iqv = iq.getValue(); if (!(qv == iqv)) { PEG_METHOD_EXIT(); throw BadQualifierOverride(q.getName().getString()); } } Resolver::resolveQualifierFlavor( q, CIMFlavor(iq.getFlavor()), true); } } // end of this objects qualifier loop //-------------------------------------------------------------------------- // Propagate qualifiers to subclass or to instance that do not have // already have those qualifiers: //-------------------------------------------------------------------------- if (propagateQualifiers) { for (Uint32 i = 0, n = inheritedQualifiers.getCount(); i < n; i++) { CIMQualifier iq = inheritedQualifiers.getQualifier(i); if (isInstancePart) { if (!(iq.getFlavor().hasFlavor(CIMFlavor::TOINSTANCE))) continue; } else { if (!(iq.getFlavor().hasFlavor(CIMFlavor::TOSUBCLASS))) continue; } // If the qualifiers list does not already contain this qualifier, // then propagate it (and set the propagated flag to true). Else // we keep current value. Note we have already eliminated any // possibility that a nonoverridable qualifier can be in the list. if (find(iq.getName()) != PEG_NOT_FOUND) continue; CIMQualifier q = iq.clone(); q.setPropagated(true); _qualifiers.insert(0, q); } } PEG_METHOD_EXIT(); }
WMIMethod::WMIMethod(const BSTR & name, const CComPtr<IWbemClassObject>& inParameters, const CComPtr<IWbemClassObject>& outParameters, IWbemQualifierSet * pQualifierSet, Boolean includeQualifiers) { CIMQualifierList qualifierList; CComBSTR bsName = name; CComVariant vValue = NULL; CIMTYPE returnValueType; HRESULT hr; WMIQualifierSet(pQualifierSet).cloneTo(qualifierList); // Get method return value String referenceClass = String::EMPTY; CComBSTR propertyName = L"ReturnValue"; // modified to correct bug JAGaf25827 // JAGaf25827 - new code begin if (outParameters) { hr = outParameters->Get( propertyName, 0, &vValue, &returnValueType, NULL); } else { hr = WBEM_E_NOT_FOUND; } // not found. Maybe it is a 'void' return value if (hr == WBEM_E_NOT_FOUND) { vValue = NULL; returnValueType = CIM_UINT32; } else if (hr != WBEM_S_NO_ERROR) { // Error: throw? throw Exception("WMIMethod::WMIMethod Get ReturnValue Failed."); } vValue.Clear(); // the WMI 'CIMTYPE' qualifier stores a string that contains the reference // class name cimtype_qualifier ::= ["ref:" + <reference_class_name>] // NOTE: CIMMethod does not seem to store the reference class anywhere, // but it seems like it should, so this code is here in case a reference // class member is ever added to the CIMMethod class in the future: if (CIM_REFERENCE == returnValueType) { // strip "ref:" Uint32 pos = qualifierList.find(CIMName("CIMTYPE")); if (PEG_NOT_FOUND != pos) { qualifierList.getQualifier(pos).getValue().get(referenceClass); //strip off "ref:" or, if not found, erase the whole string if ((pos = referenceClass.find(qString(Q_COLON))) != PEG_NOT_FOUND) { referenceClass.remove(0, pos + 1); } } } String classOrigin = String::EMPTY; // the 'Propagated" qualifier stores a string containing the class origin // propagated qualifier ::= [<class_origin>"."]<method_name> { Uint32 pos = qualifierList.find(CIMName("Propagated")); if (PEG_NOT_FOUND != pos) { qualifierList.getQualifier(pos).getValue().get(classOrigin); // strip on the ".<method_name> portion if there... if ((pos = classOrigin.find(".")) != PEG_NOT_FOUND) { classOrigin.remove(pos); } } } // NOTE: Currently no mapping of WMI "object" types, so this could // throw if the param is of type "object" or other un-supported // WMI type: CIMType cimType; try { cimType = WMITypeToCIMType(returnValueType); } catch (TypeMismatchException tme) { // Don't want method enumeration to fail, just because // we don't handle the type, so making this type "reference" // for now and making the reference class name "UNKNOWN_TYPE": cimType = CIMTYPE_REFERENCE; referenceClass = "UNKNOWN_TYPE"; } // Build the method CIMName cimRef; CIMName cimClsOrigin; BSTR tmpBstr = (BSTR)bsName.Copy(); String s(_bstr_t(tmpBstr, FALSE)); SysFreeString(tmpBstr); bsName.Empty(); if (0 != referenceClass.size()) { cimRef = referenceClass; } if (0 != classOrigin.size()) { cimClsOrigin = classOrigin; } *this = CIMMethod( CIMName(s), cimType, cimClsOrigin, (classOrigin.size() != 0)); // Add the qualifiers if (includeQualifiers) { Uint32 i, n; for (i = 0, n = qualifierList.getCount(); i < n; i++) { addQualifier(qualifierList.getQualifier(i)); } } // Enumerate the parameters of the WMI method in and out classes here, // adding them to the CIMMethos as appropriate. // NOTE: In WMI parameters method parameters are defined as in, out, or // both, meaning that they cold show up in both the inParameters and // outParameters lists. The addWMIParametersToCIMMethod() function will // check for the existing parameters by name, and will not attempt to // re-add any existing params (there is no need, since the "in" and "out" // versions of an in/out param are simply identical copies) addWMIParametersToCIMMethod(outParameters, *this, includeQualifiers); addWMIParametersToCIMMethod(inParameters, *this, includeQualifiers); }
WMIProperty::WMIProperty(const BSTR & name, const VARIANT & value, const CIMTYPE type, IWbemQualifierSet * pQualifierSet, Boolean includeQualifiers) { CIMQualifierList qualifierList; CComBSTR bsName = name; CComVariant vValue = value; qualifierList = WMIQualifierSet(pQualifierSet); // get additional property information String referenceClass = String::EMPTY; // the WMI 'CIMTYPE' qualifier stores a string that contains the reference class name // cimtype_qualifier ::= ["ref:" + <reference_class_name>] if (CIM_REFERENCE == type) { // strip "ref:" Uint32 pos = qualifierList.find(CIMName("CIMTYPE")); if (PEG_NOT_FOUND != pos) { qualifierList.getQualifier(pos).getValue().get(referenceClass); //strip off "ref:" or, if not found, erase the whole string if ((pos = referenceClass.find(qString(Q_COLON))) != PEG_NOT_FOUND) { referenceClass.remove(0, pos + 1); } } } String classOrigin = String::EMPTY; // the 'Propagated" qualifier stores a string containing the class origin // propagated qualifier ::= [<class_origin>"."]<property_name> { Uint32 pos = qualifierList.find(CIMName("Propagated")); if (PEG_NOT_FOUND != pos) { qualifierList.getQualifier(pos).getValue().get(classOrigin); // strip on the ".<property_name> portion if there... if ((pos = classOrigin.find(".")) != PEG_NOT_FOUND) { classOrigin.remove(pos); } } } // build the property BSTR tmpBstr = (BSTR)bsName.Copy(); String s(_bstr_t(tmpBstr, FALSE)); SysFreeString(tmpBstr); // old way -- memory leak?: // String s = WMIString(bsName); CIMName cimRef; CIMName cimClsOrigin; if (0 != referenceClass.size()) { cimRef = referenceClass; } if (0 != classOrigin.size()) { cimClsOrigin = classOrigin; } *this = CIMProperty(CIMName(s), WMIValue(vValue, type), 0, cimRef, cimClsOrigin, (classOrigin.size() != 0)); vValue.Clear(); // add the qualifiers if (includeQualifiers) { Uint32 i, n; for (i = 0, n = qualifierList.getCount(); i < n; i++) { addQualifier(qualifierList.getQualifier(i)); } } }