Leaked source code of windows server 2003
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

/*++
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;
}