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.
597 lines
21 KiB
597 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Abstract:
|
|
|
|
@doc
|
|
@module COMAdmin.cxx | Simple wrapper around COM Admin classes
|
|
@end
|
|
|
|
Author:
|
|
|
|
Adi Oltean [aoltean] 08/15/1999
|
|
|
|
TBD:
|
|
|
|
Add comments.
|
|
|
|
Revision History:
|
|
|
|
Name Date Comments
|
|
aoltean 08/15/1999 Created.
|
|
aoltean 09/09/1999 dss -> vss
|
|
aoltean 09/21/1999 Fixing VSSDBG_GEN.
|
|
|
|
--*/
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Defines
|
|
|
|
// C4290: C++ Exception Specification ignored
|
|
#pragma warning(disable:4290)
|
|
|
|
// C4127: conditional expression is constant
|
|
#pragma warning( disable: 4127 )
|
|
|
|
|
|
#define STRICT
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Includes
|
|
|
|
#include <wtypes.h>
|
|
#include <stddef.h>
|
|
#include <oleauto.h>
|
|
|
|
#include "vs_assert.hxx"
|
|
|
|
#include <atlconv.h>
|
|
#include <atlbase.h>
|
|
#include <comadmin.h>
|
|
|
|
#include "vssmsg.h"
|
|
|
|
#include "vs_inc.hxx"
|
|
#include "vs_idl.hxx"
|
|
#include <vs_sec.hxx>
|
|
|
|
|
|
#include "comadmin.hxx"
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Standard foo for file name aliasing. This code block must be after
|
|
// all includes of VSS header files.
|
|
//
|
|
#ifdef VSS_FILE_ALIAS
|
|
#undef VSS_FILE_ALIAS
|
|
#endif
|
|
#define VSS_FILE_ALIAS "CADCADMC"
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Globals
|
|
|
|
|
|
// Collection attributes - TBD: Verify if Keys are OK!!
|
|
struct _VsCOMCollectionAttr g_VsCOMCollectionsArray[] =
|
|
{
|
|
{ L"", L"", L"", }, // VSS_COM_UNKNOWN = 0,
|
|
{ L"ApplicationCluster", L"Name", L"Name", }, // VSS_COM_APPLICATION_CLUSTER,
|
|
{ L"Applications", L"ID", L"Name", }, // VSS_COM_APPLICATIONS,
|
|
{ L"Components", L"CLSID", L"ProgID", }, // VSS_COM_COMPONENTS,
|
|
{ L"ComputerList", L"Name", L"Name", }, // VSS_COM_COMPUTERLIST,
|
|
{ L"DCOMProtocols", L"Name", L"Name", }, // VSS_COM_DCOM_PROTOCOLS,
|
|
{ L"ErrorInfo", L"MajorRef", L"MajorRef", }, // VSS_COM_ERRORINFO,
|
|
{ L"IMDBDataSources", L"DataSource", L"DataSource",}, // VSS_COM_IMDB_DATA_SOURCES,
|
|
{ L"IMDBDataSourceTables", L"TableName", L"TableName", }, // VSS_COM_IMDB_DATA_SOURCE_TABLES,
|
|
{ L"InprocServers", L"CLSID", L"ProgID", }, // VSS_COM_INPROC_SERVERS,
|
|
{ L"InterfacesForComponent", L"IID" L"Name" }, // VSS_COM_INTERFACES_FOR_COMPONENT,
|
|
{ L"LocalComputer", L"Name", L"Name", }, // VSS_COM_LOCAL_COMPUTER,
|
|
{ L"MethodsForInterface", L"Index", L"Name", }, // VSS_COM_METHODS_FOR_INTERFACE,
|
|
{ L"PropertyInfo", L"Name", L"Name", }, // VSS_COM_PROPERTY_INFO,
|
|
{ L"PublisherProperties", L"Name", L"Name", }, // VSS_COM_PUBLISHER_PROPERTIES,
|
|
{ L"RelatedCollectionInfo", L"Name", L"Name", }, // VSS_COM_RELATED_COLLECTION_INFO,
|
|
{ L"Roles", L"Name", L"Name", }, // VSS_COM_ROLES,
|
|
{ L"RolesForComponent", L"Name", L"Name", }, // VSS_COM_ROLES_FOR_COMPONENT,
|
|
{ L"RolesForInterface", L"Name", L"Name", }, // VSS_COM_ROLES_FOR_INTERFACE,
|
|
{ L"RolesForMethod", L"Name", L"Name", }, // VSS_COM_ROLES_FOR_METHOD,
|
|
{ L"Root", L"", L"", }, // VSS_COM_ROOT,
|
|
{ L"SubscriberProperties", L"Name", L"Name", }, // VSS_COM_SUBSCRIBER_PROPERTIES,
|
|
{ L"Subscriptions", L"ID", L"Name", }, // VSS_COM_SUBSCRIPTIONS,
|
|
{ L"TransientSubscriptions", L"ID", L"Name", }, // VSS_COM_TRANSIENT_SUBSCRIPTIONS,
|
|
{ L"UsersInRole", L"User", L"User", } // VSS_COM_USERS_IN_ROLE,
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Implementation of CVssCOMAdminCatalog
|
|
|
|
|
|
HRESULT CVssCOMAdminCatalog::Attach(
|
|
IN const WCHAR* pwszAppName
|
|
)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMAdminCatalog::Attach" );
|
|
|
|
try
|
|
{
|
|
// Testing argument
|
|
if (pwszAppName == NULL || pwszAppName[0] == L'\0') {
|
|
BS_ASSERT(false);
|
|
ft.Throw(VSSDBG_GEN, E_INVALIDARG, L"NULL or empty application name");
|
|
}
|
|
|
|
// Begin initializing
|
|
m_bInitialized = false;
|
|
m_pICatalog = NULL;
|
|
|
|
// Creating the COMAdminCatalog instance
|
|
ft.CoCreateInstanceWithLog(
|
|
VSSDBG_GEN,
|
|
__uuidof(COMAdminCatalog),
|
|
L"COMAdminCatalog",
|
|
CLSCTX_ALL,
|
|
IID_ICOMAdminCatalog2,
|
|
(IUnknown**)&m_pICatalog);
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_CREATING_COMPLUS_ADMIN_CATALOG, VSSDBG_GEN << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Error creating the COMAdminCatalog instance hr = 0x%08lx", ft.hr);
|
|
}
|
|
|
|
// Getting the application name
|
|
m_bstrAppName = pwszAppName;
|
|
if (!m_bstrAppName)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
// End initializing
|
|
m_bInitialized = true;
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT CVssCOMAdminCatalog::InstallComponent(
|
|
IN const WCHAR* pwszDllName,
|
|
IN const WCHAR* pwszTlbName,
|
|
IN const WCHAR* pwszProxyStubName
|
|
)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMAdminCatalog::InstallComponent" );
|
|
|
|
try
|
|
{
|
|
// Test if initialized
|
|
if (!m_bInitialized)
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Catalog not initialized");
|
|
|
|
// Testing arguments
|
|
if (pwszDllName == NULL || pwszDllName[0] == L'\0')
|
|
ft.Throw(VSSDBG_GEN, E_INVALIDARG, L"NULL or empty paths");
|
|
|
|
CComBSTR bstrAppName = (LPWSTR)m_bstrAppName;
|
|
if ((LPWSTR)bstrAppName == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrDllName = pwszDllName;
|
|
if ((LPWSTR)bstrDllName == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrTlbName = pwszTlbName? pwszTlbName: L"";
|
|
if ((LPWSTR)bstrTlbName == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrProxyStubName = pwszProxyStubName? pwszProxyStubName: L"";
|
|
if ((LPWSTR)bstrProxyStubName == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
|
|
// Install event class for this application
|
|
ft.hr = m_pICatalog->InstallComponent(
|
|
bstrAppName,
|
|
bstrDllName,
|
|
bstrTlbName,
|
|
bstrProxyStubName
|
|
);
|
|
if (ft.HrFailed()) {
|
|
ft.TraceComError();
|
|
ft.LogError( VSS_ERROR_INSTALL_COMPONENT, VSSDBG_GEN << bstrDllName << bstrAppName << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, ft.hr, L"Installing the component failed");
|
|
}
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
|
|
HRESULT CVssCOMAdminCatalog::CreateServiceForApplication(
|
|
IN const WCHAR* pwszServiceName
|
|
)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMAdminCatalog::CreateServiceForApplication" );
|
|
|
|
try
|
|
{
|
|
// Test if initialized
|
|
if (!m_bInitialized)
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Catalog not initialized");
|
|
|
|
CComBSTR bstrAppName = (LPWSTR)m_bstrAppName;
|
|
if ((LPWSTR)bstrAppName == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrSvcName = pwszServiceName;
|
|
if ((LPWSTR)bstrSvcName == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrStartType = L"SERVICE_DEMAND_START";
|
|
if ((LPWSTR)bstrStartType == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrErrorControl = L"SERVICE_ERROR_IGNORE";
|
|
if ((LPWSTR)bstrErrorControl == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrRunAs = L"LocalSystem";
|
|
if ((LPWSTR)bstrRunAs == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
CComBSTR bstrPassword = L"";
|
|
if ((LPWSTR)bstrRunAs == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
#ifdef _DEBUG
|
|
VARIANT_BOOL vboolDesktopOK = VARIANT_TRUE;
|
|
#else
|
|
VARIANT_BOOL vboolDesktopOK = VARIANT_FALSE;
|
|
#endif
|
|
|
|
ft.Trace(VSSDBG_GEN,
|
|
L"Calling CreateServiceForApplicationStrings(%s, %s, %s, %s, %s, %s, %s, %s)",
|
|
bstrAppName,
|
|
bstrSvcName,
|
|
bstrStartType,
|
|
bstrErrorControl,
|
|
NULL,
|
|
bstrRunAs,
|
|
bstrPassword,
|
|
vboolDesktopOK == VARIANT_TRUE? L"TRUE": L"FALSE"
|
|
);
|
|
|
|
// Install event class for this application
|
|
ft.hr = m_pICatalog->CreateServiceForApplication(
|
|
m_bstrAppName,
|
|
bstrSvcName,
|
|
bstrStartType,
|
|
bstrErrorControl,
|
|
NULL,
|
|
bstrRunAs,
|
|
bstrPassword,
|
|
vboolDesktopOK
|
|
);
|
|
if (ft.HrFailed()) {
|
|
ft.TraceComError();
|
|
ft.LogError( VSS_ERROR_CREATE_SERVICE_FOR_APPLICATION, VSSDBG_GEN << bstrSvcName << m_bstrAppName << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, ft.hr, L"Installing the component failed");
|
|
}
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Implementation of CVssCOMCatalogCollection
|
|
|
|
|
|
HRESULT CVssCOMCatalogCollection::Attach(
|
|
IN CVssCOMAdminCatalog& catalog
|
|
)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMCatalogCollection::Attach_ToCatalog" );
|
|
|
|
try
|
|
{
|
|
// Begin intializing
|
|
m_bInitialized = false;
|
|
m_pICollection = NULL;
|
|
|
|
// Check if Collection type is valid
|
|
if ((m_eType <= 0) || (m_eType >= VSS_COM_COLLECTIONS_COUNT))
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Invalid collection type");
|
|
|
|
// Converting collection name into BSTR
|
|
CComBSTR bstrCollectionName = g_VsCOMCollectionsArray[m_eType].wszName;
|
|
if (!bstrCollectionName)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
// Get the catalog interface
|
|
CComPtr<ICOMAdminCatalog2> pICatalog = catalog.GetInterface();
|
|
if (pICatalog == NULL) {
|
|
BS_ASSERT(false);
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Catalog object not initialized.");
|
|
}
|
|
|
|
// Get the collection object
|
|
CComPtr<IDispatch> pIDisp;
|
|
ft.hr = pICatalog->GetCollection(bstrCollectionName, &pIDisp);
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_GETTING_COLLECTION, VSSDBG_GEN << bstrCollectionName << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in getting the collection. hr = 0x%08lx", ft.hr);
|
|
}
|
|
BS_ASSERT(pIDisp);
|
|
|
|
// Convert to ICatalogCollection
|
|
CComPtr<ICatalogCollection> pICollection;
|
|
ft.hr = pIDisp->SafeQI(ICatalogCollection, &pICollection);
|
|
if (ft.HrFailed())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in querying ICatalogCollection. hr = 0x%08lx", ft.hr);
|
|
|
|
// Populate the collection
|
|
ft.hr = pICollection->Populate();
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_POPULATING_COLLECTION, VSSDBG_GEN << bstrCollectionName << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in populating the collection object. hr = 0x%08lx", ft.hr);
|
|
}
|
|
|
|
// End intializing
|
|
m_pICollection = pICollection;
|
|
m_bInitialized = true;
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
|
|
HRESULT CVssCOMCatalogCollection::Attach(
|
|
IN CVssCOMCatalogObject& parentObject
|
|
)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMCatalogCollection::Attach_ToParentCollection" );
|
|
|
|
try
|
|
{
|
|
// Begin intializing
|
|
m_bInitialized = false;
|
|
m_pICollection = NULL;
|
|
|
|
// Check if Collection type is valid
|
|
if ((m_eType <= 0) || (m_eType >= VSS_COM_COLLECTIONS_COUNT))
|
|
ft.Throw(VSSDBG_GEN, E_INVALIDARG, L"Invalid collection type");
|
|
|
|
// Converting collection name into BSTR
|
|
CComBSTR bstrCollectionName = g_VsCOMCollectionsArray[m_eType].wszName;
|
|
if (!bstrCollectionName)
|
|
ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
// Get the parent object interface
|
|
CComPtr<ICatalogObject> pIParentObject = parentObject.GetInterface();
|
|
if (pIParentObject == NULL) {
|
|
BS_ASSERT(false);
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Parent object not initialized yet.");
|
|
}
|
|
|
|
// Get the Key that uniquely identifies the parent object in the grand parent collection
|
|
CComVariant variant;
|
|
// Beware to not leave variant resources before get_Key call!
|
|
ft.hr = pIParentObject->get_Key(&variant);
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_GET_COLLECTION_KEY, VSSDBG_GEN << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in getting object key. hr = 0x%08lx", ft.hr);
|
|
}
|
|
|
|
// Get the grand parent collection interface
|
|
CComPtr<ICatalogCollection> pIGrandParentCollection = parentObject.GetParentInterface();
|
|
if (pIGrandParentCollection == NULL) {
|
|
BS_ASSERT(false);
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Parent object not initialized.");
|
|
}
|
|
|
|
// Get the collection object
|
|
CComPtr<IDispatch> pIDisp;
|
|
ft.hr = pIGrandParentCollection->GetCollection(bstrCollectionName, variant, &pIDisp);
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_GET_COLLECTION_FROM_PARENT, VSSDBG_GEN << bstrCollectionName << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in getting collection. hr = 0x%08lx", ft.hr);
|
|
}
|
|
BS_ASSERT(pIDisp);
|
|
|
|
// Convert to ICatalogCollection
|
|
ICatalogCollection* pICollection;
|
|
ft.hr = pIDisp->SafeQI(ICatalogCollection, &pICollection);
|
|
if (ft.HrFailed())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in querying ICatalogCollection. hr = 0x%08lx", ft.hr);
|
|
BS_ASSERT(pICollection);
|
|
m_pICollection.Attach(pICollection);
|
|
|
|
// Populate the collection
|
|
ft.hr = m_pICollection->Populate();
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_POPULATING_COLLECTION, VSSDBG_GEN << bstrCollectionName << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in populating the collection object. hr = 0x%08lx", ft.hr);
|
|
}
|
|
|
|
// End intializing
|
|
m_bInitialized = true;
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
|
|
HRESULT CVssCOMCatalogCollection::SaveChanges()
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMCatalogCollection::SaveChanges" );
|
|
|
|
try
|
|
{
|
|
// Test if initialized
|
|
if (!m_bInitialized)
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Catalog not initialized");
|
|
|
|
// Save changes
|
|
LONG lRet = 0;
|
|
ft.hr = m_pICollection->SaveChanges(&lRet);
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_SAVING_CHANGES, VSSDBG_GEN << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in saving the changes. hr = 0x%08lx", ft.hr);
|
|
}
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Implementation of CVssCOMCatalogCollection
|
|
|
|
|
|
HRESULT CVssCOMCatalogObject::InsertInto(
|
|
IN CVssCOMCatalogCollection& collection
|
|
)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMCatalogObject::InsertInto" );
|
|
|
|
try
|
|
{
|
|
// Begin initialization
|
|
m_bInitialized = false;
|
|
m_pIObject = NULL;
|
|
m_pIParentCollection = NULL;
|
|
m_lIndex = -1;
|
|
|
|
// Get the collection object
|
|
CComPtr<ICatalogCollection> pIParentCollection = collection.GetInterface();
|
|
if (pIParentCollection == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Collection object not initialized");
|
|
|
|
// Get the instance of the new object
|
|
CComPtr<IDispatch> pIDisp;
|
|
ft.hr = pIParentCollection->Add(&pIDisp);
|
|
if (ft.HrFailed()) {
|
|
ft.LogError( VSS_ERROR_INSERT_INTO, VSSDBG_GEN << ft.hr );
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in adding the catalog object. hr = 0x%08lx", ft.hr);
|
|
}
|
|
BS_ASSERT(pIDisp);
|
|
|
|
// Convert to ICatalogObject
|
|
BS_ASSERT(m_pIObject == NULL);
|
|
ft.hr = pIDisp->SafeQI(ICatalogObject, &m_pIObject);
|
|
if (ft.HrFailed())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in querying ICatalogObject. hr = 0x%08lx", ft.hr);
|
|
|
|
// End initialization
|
|
m_pIParentCollection = pIParentCollection;
|
|
m_bInitialized = true;
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
//
|
|
// Disclaimer: this method assumes that the collection is already populated
|
|
//
|
|
// S_FALSE means object not found
|
|
//
|
|
HRESULT CVssCOMCatalogObject::AttachByName(
|
|
IN CVssCOMCatalogCollection& collection,
|
|
IN const WCHAR wszName[],
|
|
IN const WCHAR wszPropertyName[] /* = NULL */
|
|
)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssCOMCatalogObject::AttachByName" );
|
|
|
|
try
|
|
{
|
|
// Begin initialization
|
|
m_bInitialized = false;
|
|
m_pIObject = NULL;
|
|
m_pIParentCollection = NULL;
|
|
m_lIndex = -1;
|
|
|
|
// Check if Object type is valid
|
|
if ((m_eType <= 0) && (m_eType >= VSS_COM_COLLECTIONS_COUNT))
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Invalid object type");
|
|
if (m_eType != collection.GetType())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Object type doesn't match with collection type");
|
|
|
|
// Get the collection object
|
|
CComPtr<ICatalogCollection> pIParentCollection = collection.GetInterface();
|
|
if (pIParentCollection == NULL)
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Collection object not initialized.");
|
|
|
|
// Get the name of the property used as a key
|
|
CComBSTR bstrPropertyName;
|
|
if (wszPropertyName == NULL)
|
|
bstrPropertyName = g_VsCOMCollectionsArray[m_eType].wszDefaultKey;
|
|
else
|
|
bstrPropertyName = wszPropertyName;
|
|
|
|
// Get the number of objects in the collection
|
|
LONG lCount = -1;
|
|
ft.hr = pIParentCollection->get_Count(&lCount);
|
|
if (ft.HrFailed())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in querying the number of elements. hr = 0x%08lx", ft.hr);
|
|
if (lCount == 0)
|
|
ft.Trace(VSSDBG_GEN, L"Empty collection");
|
|
|
|
CComVariant varObjectName = wszName;
|
|
|
|
CComVariant variant;
|
|
CComPtr<IDispatch> pIDisp;
|
|
CComPtr<ICatalogObject> pIObject;
|
|
for(LONG lIndex = 0; lIndex < lCount; lIndex++)
|
|
{
|
|
// Release previous references
|
|
pIDisp = pIObject = NULL;
|
|
|
|
// Get next item
|
|
ft.hr = pIParentCollection->get_Item(lIndex, &pIDisp);
|
|
if (ft.HrFailed())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED,
|
|
L"Failure in getting object with index %ld. hr = 0x%08lx", lIndex, ft.hr);
|
|
|
|
// Convert it to ICatalogObject
|
|
ft.hr = pIDisp->SafeQI(ICatalogObject, &pIObject);
|
|
if (ft.HrFailed())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED, L"Failure in querying ICatalogObject. hr = 0x%08lx", ft.hr);
|
|
|
|
variant.Clear(); // do not forget to release resources before get_XXX !
|
|
ft.hr = pIObject->get_Value(bstrPropertyName, &variant);
|
|
if (ft.HrFailed())
|
|
ft.Throw(VSSDBG_GEN, E_UNEXPECTED,
|
|
L"Failure in getting value for the object key with index %ld. hr = 0x%08lx", lIndex, ft.hr);
|
|
|
|
if (varObjectName == variant)
|
|
{
|
|
m_bInitialized = TRUE;
|
|
m_lIndex = lIndex;
|
|
m_pIParentCollection = pIParentCollection;
|
|
m_pIObject = pIObject;
|
|
break;
|
|
}
|
|
}
|
|
if (!m_bInitialized)
|
|
ft.hr = S_FALSE; // Object not found!
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|