WindowsXP/admin/wmi/wbem/sdk/framedyn/new_objpath.cpp
2025-04-27 07:49:33 -04:00

1176 lines
30 KiB
C++

// unparse singleton
// check parser return codes
/*++
Copyright (C) 1999-2001 Microsoft Corporation
Module Name:
OBJPATH.CPP
Abstract:
Object path parser.
--*/
#include <precomp.h>
#include <wbemidl.h>
#include <wmiutils.h>
#include "objpath.h"
DWORD CalcCimType(VARTYPE vt)
{
DWORD dwRet = CIM_EMPTY;
switch (vt)
{
case VT_BSTR:
{
dwRet = CIM_STRING;
break;
}
case VT_UI1:
{
dwRet = CIM_UINT8;
break;
}
case VT_I2:
{
dwRet = CIM_CHAR16;
break;
}
case VT_I4:
{
dwRet = CIM_UINT32;
break;
}
case VT_BOOL:
{
dwRet = CIM_BOOLEAN;
break;
}
}
return dwRet;
}
ParsedObjectPath::ParsedObjectPath() :
m_pServer(NULL),
m_dwNumNamespaces(0),
m_dwAllocNamespaces(0),
m_paNamespaces(NULL),
m_pClass(NULL),
m_dwNumKeys(0),
m_dwAllocKeys(0),
m_paKeys(NULL)
{
m_paNamespaces = new LPWSTR[2];
// Note: We don't HAVE to throw here. We're trying to
// pre-allocate space. However, m_dwAllocNamespaces
// will correctly show how many pre-alloocated spaces we have
// available. During the add, we will new again
if(m_paNamespaces)
{
m_dwAllocNamespaces = 2;
for (unsigned i = 0; i < m_dwAllocNamespaces; i++)
{
m_paNamespaces[i] = NULL;
}
}
m_bSingletonObj = FALSE;
m_paKeys = new KeyRef *[2];
// Note: We don't HAVE to throw here. We're trying to
// pre-allocate space. However, m_dwAllocNamespaces
// will correctly show how many pre-alloocated spaces we have
// available. During the add, we will new again
if (m_paKeys)
{
m_dwAllocKeys = 2;
for (unsigned i = 0; i < m_dwAllocKeys; i++)
{
m_paKeys[i] = NULL;
}
}
}
ParsedObjectPath::~ParsedObjectPath()
{
if (m_pServer)
{
delete [] m_pServer;
m_pServer = NULL;
}
if (m_paNamespaces)
{
for (DWORD dwIx = 0; dwIx < m_dwNumNamespaces; dwIx++)
{
delete m_paNamespaces[dwIx];
}
delete [] m_paNamespaces;
m_paNamespaces = NULL;
}
if (m_pClass)
{
delete [] m_pClass;
m_pClass = NULL;
}
if (m_paKeys)
{
for (DWORD dwIx = 0; dwIx < m_dwNumKeys; dwIx++)
{
if(m_paKeys[dwIx])
{
if(m_paKeys[dwIx]->m_pName)
{
delete m_paKeys[dwIx]->m_pName;
m_paKeys[dwIx]->m_pName = NULL;
}
::VariantClear(&m_paKeys[dwIx]->m_vValue);
delete m_paKeys[dwIx];
m_paKeys[dwIx] = NULL;
}
}
delete [] m_paKeys;
m_paKeys = NULL;
}
}
void* __cdecl ParsedObjectPath::operator new( size_t n)
{
void *ptr = ::new BYTE[n];
return ptr;
}
void __cdecl ParsedObjectPath::operator delete( void *ptr )
{
::delete ptr;
}
void* __cdecl ParsedObjectPath::operator new[]( size_t n)
{
void *ptr = ::new BYTE[n];
return ptr;
}
void __cdecl ParsedObjectPath::operator delete[]( void *ptr )
{
::delete [] ptr;
}
BOOL ParsedObjectPath::SetClassName(LPCWSTR wszClassName)
{
BOOL bRet = TRUE;
if (m_pClass)
{
delete [] m_pClass;
}
if(wszClassName == NULL)
{
m_pClass = NULL;
}
else
{
DWORD dwLen = wcslen(wszClassName) + 1;
m_pClass = new WCHAR[dwLen];
if (m_pClass)
{
memcpy(m_pClass, wszClassName, dwLen * sizeof(WCHAR));
}
else
{
bRet = FALSE;
}
}
return bRet;
}
BOOL ParsedObjectPath::SetServerName(LPCWSTR wszServerName)
{
BOOL bRet = TRUE;
if (m_pServer)
{
delete [] m_pServer;
}
if(wszServerName == NULL)
{
m_pServer = NULL;
}
else
{
DWORD dwLen = wcslen(wszServerName) + 1;
m_pServer = new WCHAR[dwLen];
if (m_pServer)
{
memcpy(m_pServer, wszServerName, dwLen * sizeof(WCHAR));
}
else
{
bRet = FALSE;
}
}
return bRet;
}
BOOL ParsedObjectPath::IsClass()
{
BOOL bRet = FALSE;
if(IsObject())
{
bRet = (m_dwNumKeys == 0 && !m_bSingletonObj);
}
return bRet;
}
BOOL ParsedObjectPath::IsInstance()
{
return IsObject() && !IsClass();
}
BOOL ParsedObjectPath::IsObject()
{
return(m_pClass != NULL);
}
BOOL ParsedObjectPath::AddNamespace(LPCWSTR wszNamespace)
{
BOOL bRet = (wszNamespace != NULL);
// See if we have filled all our existing ns slots
if(bRet)
{
if(m_dwNumNamespaces == m_dwAllocNamespaces)
{
DWORD dwNewAllocNamespaces = (m_dwAllocNamespaces + 1) * 2;
LPWSTR* paNewNamespaces = new LPWSTR[dwNewAllocNamespaces];
if(paNewNamespaces != NULL)
{
memcpy(paNewNamespaces, m_paNamespaces, sizeof(LPWSTR) * m_dwAllocNamespaces);
delete [] m_paNamespaces;
m_paNamespaces = paNewNamespaces;
m_dwAllocNamespaces = dwNewAllocNamespaces;
}
else
{
bRet = FALSE;
}
}
if (bRet)
{
DWORD dwLen = wcslen(wszNamespace) + 1;
m_paNamespaces[m_dwNumNamespaces] = new WCHAR[dwLen];
if (m_paNamespaces[m_dwNumNamespaces])
{
memcpy(m_paNamespaces[m_dwNumNamespaces++], wszNamespace, dwLen * sizeof(WCHAR));
}
else
{
bRet = FALSE;
}
}
}
return bRet;
}
BOOL ParsedObjectPath::AddKeyRefEx(LPCWSTR wszKeyName, const VARIANT* pvValue )
{
BOOL bStatus = (pvValue != NULL) ;
ULONG dwIndex = 0;
BOOL bFound = FALSE ;
BOOL bUnNamed = FALSE ;
if (bStatus)
{
if (wszKeyName && (wszKeyName[0] != L'\0'))
{
for ( dwIndex = 0 ; dwIndex < m_dwNumKeys ; dwIndex ++ )
{
if ( ( m_paKeys [ dwIndex ]->m_pName ) )
{
if (bFound)
{
//check the rest of the array for unamed just in case...
continue;
}
else
{
if ( _wcsicmp ( m_paKeys [ dwIndex ]->m_pName , wszKeyName ) == 0 )
{
bFound = TRUE ;
}
}
}
else
{
bUnNamed = TRUE ;
break;
}
}
}
else
{
bUnNamed = TRUE;
}
//check to see if we need to grow our key storage...
if (!bFound || m_dwAllocKeys == 0)
{
if(m_dwNumKeys == m_dwAllocKeys)
{
DWORD dwNewAllocKeys = (m_dwAllocKeys + 1) * 2;
KeyRef** paNewKeys = new KeyRef*[dwNewAllocKeys];
if (!paNewKeys)
{
bStatus = FALSE;
}
else
{
memcpy(paNewKeys, m_paKeys, sizeof(KeyRef*) * m_dwAllocKeys);
delete [] m_paKeys;
m_paKeys = paNewKeys;
m_dwAllocKeys = dwNewAllocKeys;
}
}
}
}
//keep the code readable start a new bStatus block...
if (bStatus)
{
if ( bUnNamed )
{
//if we have an unamed key (in our list or the addition) we only want one key
//so remove all existing keys and add our single (possibly named) key
for ( dwIndex = 0 ; dwIndex < m_dwNumKeys ; dwIndex ++ )
{
delete [] ( m_paKeys [ dwIndex ]->m_pName ) ;
m_paKeys [ dwIndex ]->m_pName = NULL ;
VariantClear ( & ( m_paKeys [ dwIndex ]->m_vValue ) ) ;
}
//reset the key count as we have none...
m_dwNumKeys = 0 ;
// alloc a KeyRef...
m_paKeys[m_dwNumKeys] = new KeyRef;
if(m_paKeys[m_dwNumKeys])
{
bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ 0 ]->m_vValue, const_cast<VARIANTARG*>(pvValue)));
if (bStatus)
{
if (wszKeyName && (wszKeyName[0] != L'\0'))
{
m_paKeys [ 0 ]->m_pName = new WCHAR [ wcslen ( wszKeyName ) + 1 ] ;
if (m_paKeys [ 0 ]->m_pName)
{
//set named key, we're done...
wcscpy ( m_paKeys [ 0 ]->m_pName , wszKeyName ) ;
m_dwNumKeys = 1 ;
}
else
{
//failed to copy the name, clear our key value and we're done...
bStatus = FALSE;
VariantClear ( & ( m_paKeys [ 0 ]->m_vValue ) ) ;
delete m_paKeys[m_dwNumKeys];
m_paKeys[m_dwNumKeys] = NULL;
}
}
else
{
//unamed key, we're done...
m_dwNumKeys = 1 ;
}
}
else
{
delete m_paKeys[m_dwNumKeys];
m_paKeys[m_dwNumKeys] = NULL;
}
}
else
{
bStatus = FALSE;
}
}
else
{
//if we have a named key we need to replace a match we have found
//or add the new key to the end
if ( bFound )
{
/*
* If key already exists then just replace the value
* If a failure occurs leave with no change or no keys
*/
VARIANT vTemp;
VariantInit ( &vTemp );
bStatus = SUCCEEDED(VariantCopy( &vTemp , &m_paKeys [ dwIndex ]->m_vValue ));
if(bStatus)
{
VariantClear(&m_paKeys [ dwIndex ]->m_vValue);
VariantInit(&m_paKeys [ dwIndex ]->m_vValue);
bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ dwIndex ]->m_vValue, const_cast<VARIANTARG*>(pvValue)));
if (!bStatus)
{
//put it back to the way it was...
if ( FAILED(VariantCopy( &m_paKeys [ dwIndex ]->m_vValue , &vTemp )) )
{
//last resort, remove them all...
for ( ULONG dwDeleteIndex = 0 ; dwDeleteIndex < m_dwNumKeys ; dwDeleteIndex ++ )
{
delete [] ( m_paKeys [ dwDeleteIndex ]->m_pName ) ;
m_paKeys [ dwDeleteIndex ]->m_pName = NULL ;
if (dwDeleteIndex != dwIndex)
{
VariantClear ( & ( m_paKeys [ dwDeleteIndex ]->m_vValue ) ) ;
}
}
m_dwNumKeys = 0 ;
}
}
VariantClear( &vTemp );
}
}
else
{
//add the named key to the end...
// alloc a KeyRef...
m_paKeys[m_dwNumKeys] = new KeyRef;
if(m_paKeys[m_dwNumKeys])
{
m_paKeys [ m_dwNumKeys ]->m_pName = new WCHAR [ wcslen ( wszKeyName ) + 1 ] ;
if (m_paKeys [ m_dwNumKeys ]->m_pName)
{
wcscpy ( m_paKeys [ m_dwNumKeys ]->m_pName , wszKeyName ) ;
bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ m_dwNumKeys ]->m_vValue, const_cast<VARIANTARG*>(pvValue)));
if (!bStatus)
{
delete [] m_paKeys [ m_dwNumKeys ]->m_pName;
m_paKeys [ m_dwNumKeys ]->m_pName = NULL;
delete m_paKeys[m_dwNumKeys];
m_paKeys[m_dwNumKeys] = NULL;
}
else
{
m_dwNumKeys++ ;
}
}
else
{
bStatus = FALSE;
}
}
else
{
bStatus = FALSE;
}
}
}
}
return bStatus;
}
void ParsedObjectPath::ClearKeys ()
{
for ( ULONG dwDeleteIndex = 0 ; dwDeleteIndex < m_dwNumKeys ;
dwDeleteIndex ++ )
{
delete m_paKeys [ dwDeleteIndex ] ;
m_paKeys [ dwDeleteIndex ] = NULL ;
}
delete [] m_paKeys ;
m_dwNumKeys = 0;
m_paKeys = new KeyRef *[2];
// Note: We don't HAVE to throw here. We're trying to
// pre-allocate space. However, m_dwAllocNamespaces
// will correctly show how many pre-alloocated spaces we have
// available. During the add, we will new again
if (m_paKeys)
{
m_dwAllocKeys = 2;
}
}
BOOL ParsedObjectPath::AddKeyRef(LPCWSTR wszKeyName, const VARIANT* pvValue)
{
return AddKeyRefEx(wszKeyName, pvValue );
}
BOOL ParsedObjectPath::AddKeyRef(KeyRef* pAcquireRef)
{
BOOL bRet = (pAcquireRef != NULL);
if (bRet)
{
//the old version did a bitwise copy so we'll do the same
//to make sure behavior is consistent i.e. destructor fires...
KeyRef temp = *pAcquireRef;
bRet = AddKeyRefEx(pAcquireRef->m_pName, &(pAcquireRef->m_vValue));
}
return bRet;
}
LPWSTR ParsedObjectPath::GetNamespacePart()
{
if (m_dwNumNamespaces == 0)
return NULL;
// Compute necessary space
// =======================
int nSpace = 0;
for(DWORD i = 0; i < m_dwNumNamespaces; i++)
{
//namspace name + '\'
nSpace += 1 + wcslen(m_paNamespaces[i]);
}
nSpace--;
// Allocate buffer
// ===============
LPWSTR wszOut = new WCHAR[nSpace + 1];
if (wszOut)
{
// Output
// ======
wcscpy(wszOut, m_paNamespaces[0]);
for(i = 1; i < m_dwNumNamespaces; i++)
{
wcscat(wszOut, L"\\");
wcscat(wszOut, m_paNamespaces[i]);
}
}
return wszOut;
}
LPWSTR ParsedObjectPath::GetParentNamespacePart()
{
if(m_dwNumNamespaces < 2)
{
return NULL;
}
// Compute necessary space
// =======================
int nSpace = 0;
for(DWORD i = 0; i < m_dwNumNamespaces - 1; i++)
{
nSpace += 1 + wcslen(m_paNamespaces[i]);
}
nSpace--;
// Allocate buffer
// ===============
LPWSTR wszOut = new wchar_t[nSpace + 1];
if(wszOut != NULL)
{
// Output
// ======
wcscpy(wszOut, m_paNamespaces[0]);
for(i = 1; i < m_dwNumNamespaces - 1; i++)
{
wcscat(wszOut, L"\\");
wcscat(wszOut, m_paNamespaces[i]);
}
}
return wszOut;
}
BOOL ParsedObjectPath::IsRelative(LPCWSTR wszMachine, LPCWSTR wszNamespace)
{
// I have no idea what this routine is for. If we are checking
// whether the parsed object is relative, why do we need params? If
// we are checking the params, why do we need the data members?
//
// On the plus side, it does the same thing as the old object parser did.
if(!IsLocal(wszMachine))
return FALSE;
if(m_dwNumNamespaces == 0)
return TRUE;
LPWSTR wszCopy = new wchar_t[wcslen(wszNamespace) + 1];
if(wszCopy == NULL)
{
return FALSE;
}
wcscpy(wszCopy, wszNamespace);
LPWSTR wszLeft = wszCopy;
BOOL bFailed = FALSE;
for(DWORD i = 0; i < m_dwNumNamespaces; i++)
{
unsigned int nLen = wcslen(m_paNamespaces[i]);
if(nLen > wcslen(wszLeft))
{
bFailed = TRUE;
break;
}
if(i == m_dwNumNamespaces - 1 && wszLeft[nLen] != 0)
{
bFailed = TRUE;
break;
}
if(i != m_dwNumNamespaces - 1 && wszLeft[nLen] != L'\\')
{
bFailed = TRUE;
break;
}
wszLeft[nLen] = 0;
if(_wcsicmp(wszLeft, m_paNamespaces[i]))
{
bFailed = TRUE;
break;
}
wszLeft += nLen+1;
}
delete [] wszCopy;
return !bFailed;
}
BOOL ParsedObjectPath::IsLocal(LPCWSTR wszMachine)
{
return (m_pServer == NULL || !wcscmp(m_pServer, L".") ||
!_wcsicmp(m_pServer, wszMachine));
}
//***************************************************************************
//
// ParsedObjectPath::GetKeyString
//
// Returns the db-engine compatible key string for the object.
// The format will likely change after the Alpha PDK Release.
//
// Return value:
// NULL on error or for pure classes. Otherwise returns a pointer to
// a newly allocated string which must be deallocated with operator
// delete.
//
//***************************************************************************
LPWSTR ParsedObjectPath::GetKeyString()
{
if (m_dwNumKeys == 0 && !m_bSingletonObj)
{
if (m_pClass == 0 || wcslen(m_pClass) == 0)
return 0;
LPWSTR pTmp = new wchar_t[wcslen(m_pClass) + 1];
if (pTmp)
wcscpy(pTmp, m_pClass);
return pTmp;
}
// Allocate enough space
// =====================
int nSpace = 10;
DWORD dwIx;
for (dwIx = 0; dwIx < m_dwNumKeys; dwIx++)
{
KeyRef* pKey = m_paKeys[dwIx];
nSpace += 2; // for the |
if(V_VT(&pKey->m_vValue) == VT_BSTR)
{
nSpace += wcslen(V_BSTR(&pKey->m_vValue))*2 + 10;
}
else if(V_VT(&pKey->m_vValue) == VT_I4)
{
nSpace += 30;
}
}
if(m_bSingletonObj)
nSpace +=20;
LPWSTR pRetVal = new wchar_t[nSpace];
wchar_t Tmp[32];
long nVal;
if (!pRetVal)
return NULL;
*pRetVal = 0;
BOOL bFirst = TRUE;
// The key are already sorted lexically.
// =====================================
WCHAR wszSeparator[2];
wszSeparator[0] = 0xFFFF;
wszSeparator[1] = 0;
for (DWORD i = 0; i < m_dwNumKeys; i++)
{
if (!bFirst)
wcscat(pRetVal, wszSeparator);
bFirst = FALSE;
KeyRef *pKeyRef = m_paKeys[i];
VARIANT *pv = &pKeyRef->m_vValue;
int nType = V_VT(pv);
switch (nType)
{
case VT_LPWSTR:
case VT_BSTR:
wcscat(pRetVal, V_BSTR(pv));
break;
case VT_I4:
nVal = V_I4(pv);
swprintf(Tmp, L"%d", nVal);
wcscat(pRetVal, Tmp);
break;
case VT_I2:
nVal = V_I2(pv);
swprintf(Tmp, L"%d", nVal);
wcscat(pRetVal, Tmp);
break;
case VT_UI1:
nVal = V_UI1(pv);
swprintf(Tmp, L"%d", nVal);
wcscat(pRetVal, Tmp);
break;
case VT_BOOL:
nVal = V_BOOL(pv);
swprintf(Tmp, L"%d", (nVal?1:0));
wcscat(pRetVal, Tmp);
break;
default:
wcscat(pRetVal, L"NULL");
}
}
if (wcslen(pRetVal) == 0)
{
if(m_bSingletonObj)
{
wcscpy(pRetVal, L"@");
}
}
return pRetVal; // This may not be NULL
}
//=================================================================================================
KeyRef::KeyRef()
{
m_pName = NULL;
VariantInit(&m_vValue);
}
KeyRef::~KeyRef()
{
delete [] m_pName;
VariantClear(&m_vValue);
}
void* __cdecl KeyRef::operator new( size_t n)
{
void *ptr = ::new BYTE[n];
return ptr;
}
void __cdecl KeyRef::operator delete( void *ptr )
{
::delete ptr;
}
void* __cdecl KeyRef::operator new[]( size_t n)
{
void *ptr = ::new BYTE[n];
return ptr;
}
void __cdecl KeyRef::operator delete[]( void *ptr )
{
::delete [] ptr;
}
//=================================================================================================
CObjectPathParser::CObjectPathParser(ObjectParserFlags eFlags)
: m_eFlags(eFlags)
{
}
CObjectPathParser::~CObjectPathParser()
{
}
void* __cdecl CObjectPathParser::operator new( size_t n)
{
void *ptr = ::new BYTE[n];
return ptr;
}
void __cdecl CObjectPathParser::operator delete( void *ptr )
{
::delete ptr;
}
void* __cdecl CObjectPathParser::operator new[]( size_t n)
{
void *ptr = ::new BYTE[n];
return ptr;
}
void __cdecl CObjectPathParser::operator delete[]( void *ptr )
{
::delete [] ptr;
}
int WINAPI CObjectPathParser::Unparse(
ParsedObjectPath* pInput,
DELETE_ME LPWSTR* pwszPath)
{
if ( (pInput == NULL) || (pInput->m_pClass == NULL) )
{
return CObjectPathParser::InvalidParameter;
}
int iRet = CObjectPathParser::NoError;
SCODE sc = S_OK;
IWbemPath *pTempParser = NULL;
sc = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
IID_IWbemPath, (LPVOID *) &pTempParser);
if (SUCCEEDED(sc))
{
sc = pTempParser->SetClassName(pInput->m_pClass);
if (SUCCEEDED(sc))
{
sc = pTempParser->SetServer(pInput->m_pServer);
for (DWORD x=0; (x < pInput->m_dwNumNamespaces) && SUCCEEDED(sc); x++)
{
sc = pTempParser->SetNamespaceAt(x, pInput->m_paNamespaces[x]);
}
if (SUCCEEDED(sc))
{
IWbemPathKeyList *pKeyList = NULL;
sc = pTempParser->GetKeyList(&pKeyList);
if (SUCCEEDED(sc))
{
for (x=0; x < (pInput->m_dwNumKeys) && SUCCEEDED(sc); x++)
{
sc = pKeyList->SetKey2(pInput->m_paKeys[x]->m_pName,
0,
CalcCimType(pInput->m_paKeys[x]->m_vValue.vt),
&pInput->m_paKeys[x]->m_vValue);
}
pKeyList->Release();
}
if (SUCCEEDED(sc))
{
DWORD dwLen = 0;
sc = pTempParser->GetText(WBEMPATH_GET_SERVER_TOO, &dwLen, NULL);
if (SUCCEEDED(sc))
{
if (dwLen > 0)
{
*pwszPath = new WCHAR[dwLen];
if (*pwszPath)
{
sc = pTempParser->GetText(WBEMPATH_GET_SERVER_TOO, &dwLen, *pwszPath);
}
else
{
iRet = CObjectPathParser::OutOfMemory;
}
}
else
{
iRet = CObjectPathParser::InvalidParameter;
}
}
}
}
}
pTempParser->Release();
}
if (FAILED(sc))
{
if (sc == WBEM_E_OUT_OF_MEMORY)
{
iRet = CObjectPathParser::OutOfMemory;
}
else
{
iRet = CObjectPathParser::InvalidParameter;
}
}
return iRet;
}
LPWSTR WINAPI CObjectPathParser::GetRelativePath(LPWSTR wszFullPath)
{
LPWSTR wsz = wcschr(wszFullPath, L':');
if(wsz)
return wsz + 1;
else
return NULL;
}
int CObjectPathParser::Parse(
LPCWSTR pRawPath,
ParsedObjectPath **pOutput
)
{
if (pOutput == 0 || pRawPath == 0 || pRawPath[0] == L'\0')
{
return CObjectPathParser::InvalidParameter;
}
// Check for leading / trailing ws.
// ================================
if (iswspace(pRawPath[wcslen(pRawPath)-1]) || iswspace(pRawPath[0]))
{
return CObjectPathParser::InvalidParameter;
}
ParsedObjectPath *pTempPath = new ParsedObjectPath;
if (!pTempPath)
return OutOfMemory;
int iRet = CObjectPathParser::NoError;
SCODE sc = S_OK;
BOOL bRet = TRUE;
IWbemPath *pTempParser = NULL;
sc = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
IID_IWbemPath, (LPVOID *) &pTempParser);
if (SUCCEEDED(sc))
{
sc = pTempParser->SetText(WBEMPATH_CREATE_ACCEPT_ALL, pRawPath);
if (SUCCEEDED(sc))
{
WCHAR wTemp[256];
DWORD dwSize;
//
dwSize = 256;
sc = pTempParser->GetClassName(&dwSize, wTemp);
if (SUCCEEDED(sc))
{
bRet = pTempPath->SetClassName(wTemp);
if (bRet)
{
//
dwSize = 256;
sc = pTempParser->GetServer(&dwSize, wTemp);
if (SUCCEEDED(sc) || (sc == WBEM_E_NOT_AVAILABLE))
{
BOOL bServer = FALSE;
if (SUCCEEDED(sc))
{
bRet = pTempPath->SetServerName(wTemp);
bServer = TRUE;
}
else
{
sc = S_OK;
}
if (bRet)
{
//
ULONG lCnt;
sc = pTempParser->GetNamespaceCount(&lCnt);
if ((!bServer && (lCnt > 0)) || (bServer && (wcscmp(wTemp, L".") != 0) && (lCnt == 0)))
{
lCnt = 0;
sc = WBEM_E_FAILED;
}
for(DWORD dwCnt = 0; (dwCnt < lCnt) && SUCCEEDED(sc) && bRet; dwCnt++)
{
dwSize = 256;
sc = pTempParser->GetNamespaceAt(dwCnt, &dwSize, wTemp);
bRet = pTempPath->AddNamespace(wTemp);
}
if (SUCCEEDED(sc) && bRet)
{
//
unsigned __int64 ull = 0;
sc = pTempParser->GetInfo(0, &ull);
if (SUCCEEDED(sc))
{
pTempPath->m_bSingletonObj = (ull & WBEMPATH_INFO_CONTAINS_SINGLETON) > 0;
if (!pTempPath->m_bSingletonObj)
{
IWbemPathKeyList *pKeyList = NULL;
sc = pTempParser->GetKeyList(&pKeyList);
if (SUCCEEDED(sc))
{
unsigned long uNumKey = 0;
sc = pKeyList->GetCount(&uNumKey);
ULONG ulType = 0;
VARIANT var;
for(DWORD uKeyIx = 0; (uKeyIx < uNumKey) && SUCCEEDED(sc) && bRet; uKeyIx++)
{
dwSize = 256;
VariantInit(&var);
sc = pKeyList->GetKey2(uKeyIx, 0, &dwSize, wTemp, &var, &ulType);
if(SUCCEEDED(sc))
{
bRet = pTempPath->AddKeyRefEx(wTemp, &var);
VariantClear(&var);
}
}
pKeyList->Release();
}
}
}
}
}
}
}
}
}
pTempParser->Release();
}
if (!bRet)
{
iRet = CObjectPathParser::OutOfMemory;
}
else if (FAILED(sc))
{
if (sc == WBEM_E_OUT_OF_MEMORY)
{
iRet = CObjectPathParser::OutOfMemory;
}
else
{
iRet = CObjectPathParser::InvalidParameter;
}
}
// Add in key refs.
// ================
*pOutput = pTempPath;
return iRet;
}
void CObjectPathParser::Free(ParsedObjectPath *pOutput)
{
delete pOutput;
}
void CObjectPathParser::Free( LPWSTR wszUnparsedPath )
{
delete wszUnparsedPath;
}