1041 lines
23 KiB
C++
1041 lines
23 KiB
C++
// unparse singleton
|
|
|
|
// check parser return codes
|
|
|
|
|
|
|
|
/*++
|
|
|
|
|
|
|
|
Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
|
|
|
|
Module Name:
|
|
|
|
OBJPATH.CPP
|
|
|
|
Abstract:
|
|
|
|
Object path parser.
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <wmiutils.h>
|
|
#include <wbemcli.h>
|
|
#include "npath.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;
|
|
}
|
|
|
|
if (m_paNamespaces)
|
|
{
|
|
for (DWORD dwIx = 0; dwIx < m_dwNumNamespaces; dwIx++)
|
|
{
|
|
delete m_paNamespaces[dwIx];
|
|
}
|
|
delete [] m_paNamespaces;
|
|
}
|
|
|
|
if (m_pClass)
|
|
{
|
|
delete [] m_pClass;
|
|
}
|
|
|
|
if (m_paKeys)
|
|
{
|
|
for (DWORD dwIx = 0; dwIx < m_dwNumKeys; dwIx++)
|
|
{
|
|
delete m_paKeys[dwIx];
|
|
}
|
|
delete [] m_paKeys;
|
|
}
|
|
}
|
|
|
|
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 (wszServerName)
|
|
{
|
|
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 = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = (m_dwNumKeys == 0 && !m_bSingletonObj);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL ParsedObjectPath::IsInstance()
|
|
{
|
|
return IsObject() && !IsClass();
|
|
}
|
|
|
|
BOOL ParsedObjectPath::IsObject()
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
// It's not a valid object unless we have a class name
|
|
if(m_pClass != NULL)
|
|
{
|
|
// If we have a server name, we must have namespaces. If no
|
|
// server name, then we must have zero namespaces.
|
|
if(m_pServer)
|
|
{
|
|
bRet = (m_dwNumNamespaces > 0);
|
|
}
|
|
else
|
|
{
|
|
bRet = (m_dwNumNamespaces == 0);
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL ParsedObjectPath::AddNamespace(LPCWSTR wszNamespace)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
|
|
// See if we have filled all our existing ns slots
|
|
if(m_dwNumNamespaces == m_dwAllocNamespaces)
|
|
{
|
|
DWORD dwNewAllocNamespaces = m_dwAllocNamespaces * 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, VARIANT* pvValue )
|
|
{
|
|
BOOL bStatus = TRUE ;
|
|
BOOL bFound = FALSE ;
|
|
BOOL bUnNamed = FALSE ;
|
|
|
|
for ( ULONG dwIndex = 0 ; dwIndex < m_dwNumKeys ; dwIndex ++ )
|
|
{
|
|
if ( ( m_paKeys [ dwIndex ]->m_pName ) && wszKeyName )
|
|
{
|
|
if ( _wcsicmp ( m_paKeys [ dwIndex ]->m_pName , wszKeyName )
|
|
== 0 )
|
|
{
|
|
bFound = TRUE ;
|
|
break ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( ( ( m_paKeys [ dwIndex ]->m_pName ) == 0 ) )
|
|
{
|
|
bUnNamed = TRUE ;
|
|
if ( ( wszKeyName == 0 ) )
|
|
{
|
|
bFound = TRUE ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ! wszKeyName )
|
|
{
|
|
/* Remove all existing keys */
|
|
|
|
for ( ULONG dwDeleteIndex = 0 ; dwDeleteIndex < m_dwNumKeys ;
|
|
dwDeleteIndex ++ )
|
|
{
|
|
delete [] ( m_paKeys [ dwDeleteIndex ]->m_pName ) ;
|
|
m_paKeys [ dwDeleteIndex ]->m_pName = NULL ;
|
|
VariantClear ( & ( m_paKeys [ dwDeleteIndex ]->m_vValue ) ) ;
|
|
}
|
|
|
|
bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ 0 ]->m_vValue, pvValue));
|
|
|
|
m_dwNumKeys = 1 ;
|
|
}
|
|
else
|
|
{
|
|
if ( bFound )
|
|
{
|
|
/*
|
|
* If key already exists then just replace the value
|
|
*/
|
|
|
|
if ( wszKeyName )
|
|
{
|
|
m_paKeys [ dwIndex ]->m_pName = new WCHAR [ wcslen ( wszKeyName ) + 1 ] ;
|
|
|
|
if (m_paKeys [ dwIndex ]->m_pName)
|
|
{
|
|
wcscpy ( m_paKeys [ dwIndex ]->m_pName , wszKeyName ) ;
|
|
}
|
|
else
|
|
{
|
|
bStatus = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bStatus)
|
|
{
|
|
bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ dwIndex ]->m_vValue, pvValue));
|
|
|
|
if (!bStatus)
|
|
{
|
|
delete [] m_paKeys [ dwIndex ]->m_pName;
|
|
m_paKeys [ dwIndex ]->m_pName = NULL;
|
|
|
|
VariantClear(&m_paKeys [ dwIndex ]->m_vValue);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( bUnNamed )
|
|
{
|
|
/* Add an un named key */
|
|
|
|
for ( ULONG dwDeleteIndex = 0 ; dwDeleteIndex < m_dwNumKeys ;
|
|
dwDeleteIndex ++ )
|
|
{
|
|
delete [] ( m_paKeys [ dwDeleteIndex ]->m_pName ) ;
|
|
m_paKeys [ dwDeleteIndex ]->m_pName = NULL ;
|
|
VariantClear (& ( m_paKeys [ dwDeleteIndex ]->m_vValue ) );
|
|
}
|
|
|
|
m_paKeys [ 0 ]->m_pName = new WCHAR [ wcslen ( wszKeyName ) + 1 ] ;
|
|
|
|
if (m_paKeys [ 0 ]->m_pName)
|
|
{
|
|
wcscpy ( m_paKeys [ 0 ]->m_pName , wszKeyName ) ;
|
|
}
|
|
else
|
|
{
|
|
bStatus = FALSE;
|
|
}
|
|
|
|
if (bStatus)
|
|
{
|
|
bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ 0 ]->m_vValue, pvValue));
|
|
|
|
m_dwNumKeys = 1 ;
|
|
}
|
|
|
|
if (!bStatus)
|
|
{
|
|
delete [] m_paKeys [ 0 ]->m_pName;
|
|
m_paKeys [ 0 ]->m_pName = NULL;
|
|
|
|
VariantClear(&m_paKeys [ 0 ]->m_vValue);
|
|
|
|
m_dwNumKeys = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Add a Named Key */
|
|
|
|
AddKeyRef(wszKeyName, pvValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
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, VARIANT* pvValue)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
|
|
if(m_dwNumKeys == m_dwAllocKeys)
|
|
{
|
|
DWORD dwNewAllocKeys = m_dwAllocKeys * 2;
|
|
KeyRef** paNewKeys = new KeyRef*[dwNewAllocKeys];
|
|
if (paNewKeys)
|
|
{
|
|
memcpy(paNewKeys, m_paKeys, sizeof(KeyRef*) * m_dwAllocKeys);
|
|
delete [] m_paKeys;
|
|
m_paKeys = paNewKeys;
|
|
m_dwAllocKeys = dwNewAllocKeys;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
m_paKeys[m_dwNumKeys] = new KeyRef;
|
|
if (m_paKeys[m_dwNumKeys])
|
|
{
|
|
DWORD dwLen = wcslen(wszKeyName) + 1;
|
|
|
|
m_paKeys[m_dwNumKeys]->m_pName = new WCHAR[dwLen];
|
|
|
|
if (m_paKeys[m_dwNumKeys]->m_pName)
|
|
{
|
|
memcpy(m_paKeys[m_dwNumKeys]->m_pName, wszKeyName, dwLen * sizeof(WCHAR));
|
|
|
|
bRet = SUCCEEDED(VariantCopy(&m_paKeys[m_dwNumKeys]->m_vValue, pvValue));
|
|
if (bRet)
|
|
{
|
|
m_dwNumKeys++;
|
|
}
|
|
else
|
|
{
|
|
delete [] m_paKeys[m_dwNumKeys]->m_pName;
|
|
m_paKeys[m_dwNumKeys]->m_pName = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL ParsedObjectPath::AddKeyRef(KeyRef* pAcquireRef)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
|
|
if(m_dwNumKeys == m_dwAllocKeys)
|
|
{
|
|
DWORD dwNewAllocKeys = m_dwAllocKeys * 2;
|
|
|
|
KeyRef** paNewKeys = new KeyRef*[dwNewAllocKeys];
|
|
if(paNewKeys != NULL)
|
|
{
|
|
memcpy(paNewKeys, m_paKeys, sizeof(KeyRef*) * m_dwAllocKeys);
|
|
delete [] m_paKeys;
|
|
m_paKeys = paNewKeys;
|
|
m_dwAllocKeys = dwNewAllocKeys;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
m_paKeys[m_dwNumKeys] = pAcquireRef;
|
|
m_dwNumKeys++;
|
|
}
|
|
|
|
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++)
|
|
{
|
|
nSpace += 1 + wcslen(m_paNamespaces[i]);
|
|
}
|
|
nSpace--;
|
|
|
|
// Allocate buffer
|
|
// ===============
|
|
|
|
LPWSTR wszOut = new WCHAR[nSpace + 1];
|
|
|
|
if (wszOut)
|
|
{
|
|
*wszOut = L'\0';
|
|
|
|
// Output
|
|
// ======
|
|
|
|
for(i = 0; i < m_dwNumNamespaces; i++)
|
|
{
|
|
if(i != 0)
|
|
{
|
|
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)
|
|
{
|
|
*wszOut = 0;
|
|
|
|
// Output
|
|
// ======
|
|
|
|
for(i = 0; i < m_dwNumNamespaces - 1; i++)
|
|
{
|
|
if(i != 0)
|
|
{
|
|
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));
|
|
}
|
|
|
|
|
|
//=================================================================================================
|
|
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))
|
|
{
|
|
*pwszPath = new WCHAR[dwLen];
|
|
|
|
if (*pwszPath)
|
|
{
|
|
sc = pTempParser->GetText(WBEMPATH_GET_SERVER_TOO, &dwLen, *pwszPath);
|
|
}
|
|
else
|
|
{
|
|
iRet = CObjectPathParser::OutOfMemory;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 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))
|
|
{
|
|
bRet = pTempPath->SetServerName(wTemp);
|
|
|
|
if (bRet)
|
|
{
|
|
//
|
|
ULONG lCnt;
|
|
sc = pTempParser->GetNamespaceCount(&lCnt);
|
|
|
|
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;
|
|
sc = pTempParser->GetInfo(0, &ull);
|
|
|
|
if (SUCCEEDED(sc))
|
|
{
|
|
pTempPath->m_bSingletonObj = (ull & WBEMPATH_INFO_CONTAINS_SINGLETON) > 0;
|
|
|
|
//
|
|
IWbemPathKeyList *pKeyList = NULL;
|
|
sc = pTempParser->GetKeyList(&pKeyList);
|
|
|
|
if (SUCCEEDED(sc))
|
|
{
|
|
unsigned long uNumKey;
|
|
sc = pKeyList->GetCount(&uNumKey);
|
|
|
|
ULONG ulType;
|
|
|
|
VARIANT var;
|
|
|
|
for(DWORD uKeyIx = 0;
|
|
(uKeyIx < uNumKey) && SUCCEEDED(sc) && bRet;
|
|
uKeyIx++)
|
|
{
|
|
dwSize = 256;
|
|
|
|
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;
|
|
}
|