//%2006//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation, The Open Group. // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; Symantec Corporation; The Open Group. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //============================================================================== //s // Author: Chip Vincent (cvincent@us.ibm.com) // // Modified By: Barbara Packard (barbara_packard@hp.com) // change Reference to ObjectPath - (bp 5/23/02) // Jair Santos, Hewlett-Packard Company (jair.santos@hp.com) // //%///////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "WMIObjectPath.h" #include "WMIString.h" #include "WMIType.h" #include #include #include using std::wstring; using std::cout; PEGASUS_NAMESPACE_BEGIN WMIObjectPath::WMIObjectPath(const CIMObjectPath & cimObjectPath) : CIMObjectPath(cimObjectPath) { } WMIObjectPath::WMIObjectPath(const BSTR bstr) { String str = WMIString(bstr); // autofit string str.remove(::wcslen((unsigned short *)str.getChar16Data())); /* // attempt to detect if the string has WMI 'slash-doubled' formatted. if the path is fully qualified, a WMI formatted // string will begin with 4, rather 2 slahes. if the path is relative to the namespace path (and the path has multiple // segments, like root\cimv2, it will have have 2, rather than 1 slash. if the path is relative to the model class, // ignore for now. if((str.subString(0, 4) == String("\\\\\\\\")) || ((str.find('=') < str.find('\\')) && (str.find('\\') < str.find('\"')))) { // remove all extra slahes for(Uint32 i = str.find('\\'); i != PEG_NOT_FOUND; i += str.subString(i).find('\\')) { str.remove(i++, 1); } } */ // ::= \\\:. // ::= \:. // ::= . // ::= Uint32 pos = 0; Uint32 len = 0; const Char16 * p = str.getChar16Data(); // get namespace host (optional) if((p[pos] == '\\') && (p[pos + 1] == '\\')) { pos += 2; // skip "\\\\" // seek to '\\' for(len = 0; (p[pos] != Char16(0)) && (p[pos] != '\\'); len++, pos++); setHost(String(&p[pos - len], len)); } // get namespace path (optional) if(p[pos] == '\\') { pos++; // skip '\\' // seek to ':' for(len = 0; (p[pos] != Char16(0)) && (p[pos] != ':'); len++, pos++); // change slashes String temp(String(&p[pos - len], len)); for(Uint32 i = 0; i < temp.size(); i++) { if(temp[i] == '\\') { temp[i] = '/'; } } setNameSpace(temp); } p[pos] == ':' ? pos++ : 0; // skip ':' // get class name (required) // seek to '.' for(len = 0; (p[pos] != Char16(0)) && (p[pos] != '.'); len++, pos++); setClassName(String(&p[pos - len], len)); p[pos] == '.' ? pos++ : 0; // skip '.' // get model key (optional) // ::= "=" ["," "=" ](0..n) // // ::= alphabetic_character(1..n) // ::= | | // ::= """ alphabetic_character | numeric_character | symbol_character (1..n) """ // ::= numeric_character(1..n) // ::= "true" | "false" while(p[pos] != Char16(0)) { // get keys CIMKeyBinding key; // seek to '=' for(len = 0; (p[pos] != Char16(0)) && (p[pos] != '='); len++, pos++); key.setName(String(&p[pos - len], len)); p[pos] == '=' ? pos++ : 0; // skip '=' if(p[pos] == '\"') { // parse string value // check for embedded quotes. for example, class1.property1A="class2.property2A="2A",property2B="2B"",property2A="foo" // or class1.property1A=",",property2A="." bool quote = false; // seek to '\"' or eos for(len = 0; (p[pos] != Char16(0)) && !((p[pos] == ',') && (!quote)); len++, pos++) { quote = (p[pos] == '\"') ? !quote : quote; // By Jair - check if it is not an 'internal' quote. // If it is, must be discarded in this case. if (!quote && len) quote = (p[pos - 1] == '\\'); } // strip outer quotes String temp(&p[pos - len], len); if((temp.size() != 0) && (temp[0] == '\"') && (temp[temp.size() - 1] == '\"')) { temp.remove(temp.size() - 1, 1); temp.remove(0, 1); } // remove escape sequences (the parent class will put them back later). for(Uint32 i = 0; i < temp.size(); i++) { //if((temp[i] == '\\') && ((temp[i + 1] == '"') || (temp[i + 1] == '\n') || (temp[i + 1] == '\r') || (temp[i + 1] == '\t'))) if((temp[i] == '\\') && ((temp[i + 1] == '\\') || (temp[i + 1] == '"') || (temp[i + 1] == '\n') || (temp[i + 1] == '\r') || (temp[i + 1] == '\t'))) { temp.remove(i, 1); } } key.setValue(temp); key.setType(CIMKeyBinding::STRING); } else if((p[pos] == 't') || (p[pos] == 'T') || (p[pos] == 'f') || (p[pos] == 'F')) { // parse boolean value // seek to ',' or eos for(len = 0; (p[pos] != Char16(0)) && (p[pos] != ','); len++, pos++); key.setValue(String(&p[pos - len], len)); key.setType(CIMKeyBinding::BOOLEAN); } else if(std::isdigit(p[pos], std::locale())) { // parse numeric value // seek to ',' or eos for(len = 0; (p[pos] != Char16(0)) && (p[pos] != ','); len++, pos++); key.setValue(String(&p[pos - len], len)); key.setType(CIMKeyBinding::NUMERIC); } else { throw(std::invalid_argument("unrecognized key type")); } // update key list Array keySet = getKeyBindings(); keySet.append(key); setKeyBindings(keySet); p[pos] == ',' ? pos++ : 0; // skip ',' } } WMIObjectPath::WMIObjectPath(IWbemClassObject * pObject) { // save pointer in local variable so that in the event an exception is thrown, the object is released _com_ptr_t<_com_IIID > object; try { object = pObject; } catch(_com_error *) { throw(std::invalid_argument("invalid IWbemClassObject pointer.")); } _variant_t vt; // get host (optional) vt.Clear(); pObject->Get(_bstr_t(L"__SERVER"), 0, &vt, 0, 0); try { setHost(WMIString(vt)); } catch(...) { } // get namespace (optional) vt.Clear(); pObject->Get(_bstr_t(L"__NAMESPACE"), 0, &vt, 0, 0); try { // convert slashes String temp = WMIString(vt); for(Uint32 i = 0; i < temp.size(); i++) { if(temp[i] == Char16('\\')) { temp[i] = Char16('/'); } } setNameSpace(temp); } catch(...) { } // get class (required) vt.Clear(); pObject->Get(_bstr_t(L"__CLASS"), 0, &vt, 0, 0); try { setClassName(WMIString(vt)); } catch(...) { throw(InvalidNameException(WMIString(vt))); } SAFEARRAY * pKeyArray = 0; // get keys (optional) vt.Clear(); pObject->GetNames(0, WBEM_FLAG_KEYS_ONLY, 0, &pKeyArray); long lbound = 0; long ubound = 0; ::SafeArrayGetLBound(pKeyArray, 1, &lbound); ::SafeArrayGetUBound(pKeyArray, 1, &ubound); Array KeyList; for(long i = lbound; i <= ubound; ++i) { BSTR Property = 0; ::SafeArrayGetElement(pKeyArray, &i, &Property); KeyList.append(CIMKeyBinding(WMIString(_bstr_t(Property, false)), String(), CIMKeyBinding::STRING)); } ::SafeArrayDestroy(pKeyArray); for(Uint32 j = 0; j < KeyList.size(); ++j) { CIMTYPE type; vt.Clear(); pObject->Get(_bstr_t(WMIString(KeyList[j].getName().getString())), 0, &vt, &type, 0); KeyList[j].setValue(WMIString(vt)); switch(type) { case CIM_SINT8: case CIM_UINT8: case CIM_SINT16: case CIM_UINT16: case CIM_SINT32: case CIM_UINT32: case CIM_SINT64: case CIM_UINT64: case CIM_REAL32: case CIM_REAL64: KeyList[j].setType(CIMKeyBinding::NUMERIC); break; case CIM_STRING: KeyList[j].setType(CIMKeyBinding::STRING); break; case CIM_BOOLEAN: KeyList[j].setType(CIMKeyBinding::BOOLEAN); break; default: break; } } setKeyBindings(KeyList); } WMIObjectPath::operator const BSTR(void) const { _bstr_t bstr; if(!(getNameSpace().isNull())) { bstr += _bstr_t(WMIString(getNameSpace().getString())); bstr += L":"; } bstr += _bstr_t(WMIString(getClassName().getString())); Array KeyList = getKeyBindings(); if(KeyList.size() != 0) { bstr += L"."; } for(Uint32 i = 0; i < KeyList.size(); ++i) { bstr += _bstr_t(WMIString(KeyList[i].getName().getString())); bstr += L"="; bstr += L"\""; String value(KeyList[i].getValue()); for(Uint32 j = 0; j < value.size(); j++) { if((value[j] == '\\') || (value[j] == '\"')) { bstr += L"\\"; } bstr += _bstr_t(WMIString(value.subString(j, 1))); } bstr += L"\""; if(i != (KeyList.size() - 1)) { bstr += L","; } } return(bstr); } PEGASUS_NAMESPACE_END