1800 lines
48 KiB
C++
1800 lines
48 KiB
C++
/*===================================================================
|
||
Microsoft IIS
|
||
|
||
Microsoft Confidential.
|
||
Copyright 1997 Microsoft Corporation. All Rights Reserved.
|
||
|
||
Component: WAMREG
|
||
|
||
File: mtsconfig.cpp
|
||
|
||
implementation of supporting functions for WAMREG, including
|
||
|
||
interface to Add/Remove Component from a MTS package,
|
||
|
||
History: LeiJin created on 9/24/1997
|
||
|
||
Note:
|
||
|
||
===================================================================*/
|
||
#include "common.h"
|
||
#include "auxfunc.h"
|
||
#include "comadmii.c"
|
||
#include "dbgutil.h"
|
||
#include "export.h"
|
||
|
||
|
||
/*===================================================================
|
||
Define the global variables and types
|
||
======================================================================*/
|
||
|
||
//
|
||
// Following is a list of all the WAMREG/MTS properties for Package creation
|
||
// Format:
|
||
// (prop-symbolic-name, property-name-string)
|
||
//
|
||
// WAMREG_MTS_PROPERTY() -> means property for NT & Win9x
|
||
// WAMREG_MTS_NTPROPERTY() -> means property for NT only
|
||
//
|
||
|
||
# define ALL_WAMREG_MTS_PROPERTY() \
|
||
WAMREG_MTS_PROPERTY( WM_ID, L"ID") \
|
||
WAMREG_MTS_PROPERTY( WM_NAME, L"Name") \
|
||
WAMREG_MTS_PROPERTY( WM_CREATED_BY, L"CreatedBy") \
|
||
WAMREG_MTS_PROPERTY( WM_RUN_FOREVER, L"RunForever") \
|
||
WAMREG_MTS_NTPROPERTY( WM_IDENTITY, L"Identity") \
|
||
WAMREG_MTS_NTPROPERTY( WM_PASSWORD, L"Password") \
|
||
WAMREG_MTS_PROPERTY( WM_ACTIVATION, L"Activation") \
|
||
WAMREG_MTS_PROPERTY( WM_CHANGEABLE, L"Changeable") \
|
||
WAMREG_MTS_PROPERTY( WM_DELETABLE, L"Deleteable") \
|
||
WAMREG_MTS_PROPERTY( WM_SECSUPP, L"AccessChecksLevel") \
|
||
|
||
|
||
//
|
||
// Let us expand the macros here for defining the symbolic-name
|
||
//
|
||
//
|
||
# define WAMREG_MTS_PROPERTY( symName, pwsz) symName,
|
||
# define WAMREG_MTS_NTPROPERTY( symName, pwsz) symName,
|
||
|
||
enum WAMREG_MTS_PROP_NAMES {
|
||
ALL_WAMREG_MTS_PROPERTY()
|
||
MAX_WAMREG_MTS_PROP_NAMES // sentinel element
|
||
};
|
||
|
||
# undef WAMREG_MTS_PROPERTY
|
||
# undef WAMREG_MTS_NTPROPERTY
|
||
|
||
|
||
struct MtsProperty {
|
||
LPCWSTR m_pszPropName;
|
||
BOOL m_fWinNTOnly;
|
||
};
|
||
|
||
//
|
||
// Let us expand the macros here for defining the property strings
|
||
//
|
||
//
|
||
# define WAMREG_MTS_PROPERTY( symName, pwsz) { pwsz, FALSE },
|
||
# define WAMREG_MTS_NTPROPERTY( symName, pwsz) { pwsz, TRUE },
|
||
|
||
static const MtsProperty g_rgWamRegMtsProperties[]= {
|
||
ALL_WAMREG_MTS_PROPERTY()
|
||
{ NULL, FALSE} // sentinel element
|
||
};
|
||
|
||
# define NUM_WAMREG_MTS_PROPERTIES \
|
||
((sizeof(g_rgWamRegMtsProperties)/sizeof(g_rgWamRegMtsProperties[0])) - 1)
|
||
|
||
# undef WAMREG_MTS_PROPERTY
|
||
# undef WAMREG_MTS_NTPROPERTY
|
||
|
||
|
||
|
||
|
||
|
||
/*===================================================================
|
||
WamRegPackageConfig
|
||
|
||
Constructor.
|
||
|
||
Parameter:
|
||
NONE;
|
||
===================================================================*/
|
||
WamRegPackageConfig::WamRegPackageConfig()
|
||
: m_pCatalog(NULL),
|
||
m_pPkgCollection(NULL),
|
||
m_pCompCollection(NULL),
|
||
m_pPackage(NULL)
|
||
{
|
||
|
||
}
|
||
|
||
/*===================================================================
|
||
~WamRegPackageConfig
|
||
|
||
Destructor.
|
||
By the time the object gets destructed, all resources should be freed.
|
||
We do most of the cleanup inside WamReqPackageConfig::Cleanup() so
|
||
that callers call that function separately to cleanup state
|
||
especially if the caller also calls CoUninitialize().
|
||
WamRegPackageConfig should be cleaned up before CoUninitialize()
|
||
|
||
Parameter:
|
||
NONE;
|
||
===================================================================*/
|
||
WamRegPackageConfig::~WamRegPackageConfig()
|
||
{
|
||
Cleanup();
|
||
|
||
// insane checks to ensure everything is happy here
|
||
DBG_ASSERT(m_pCatalog == NULL);
|
||
DBG_ASSERT(m_pPkgCollection == NULL);
|
||
DBG_ASSERT(m_pCompCollection == NULL);
|
||
DBG_ASSERT(m_pPackage == NULL);
|
||
}
|
||
|
||
VOID
|
||
WamRegPackageConfig::Cleanup(VOID)
|
||
{
|
||
if (m_pPackage != NULL ) {
|
||
RELEASE( m_pPackage);
|
||
m_pPackage = NULL;
|
||
}
|
||
|
||
if (m_pCompCollection != NULL) {
|
||
RELEASE (m_pCompCollection);
|
||
m_pCompCollection = NULL;
|
||
}
|
||
|
||
if (m_pPkgCollection != NULL ) {
|
||
RELEASE(m_pPkgCollection);
|
||
m_pPkgCollection = NULL;
|
||
}
|
||
|
||
if (m_pCatalog != NULL ) {
|
||
RELEASE(m_pCatalog);
|
||
m_pCatalog = NULL;
|
||
}
|
||
|
||
} // WamPackageConfig::Cleanup()
|
||
|
||
|
||
/*===================================================================
|
||
ReleaseAll
|
||
|
||
Release all resources.
|
||
|
||
Parameter:
|
||
NONE;
|
||
===================================================================*/
|
||
VOID WamRegPackageConfig::ReleaseAll
|
||
(
|
||
)
|
||
{
|
||
RELEASE(m_pPackage);
|
||
RELEASE(m_pCompCollection);
|
||
|
||
//
|
||
// NOTE: I am not releasing m_pCatalog, m_pPkgCollection
|
||
// These will be released by the Cleanup().
|
||
//
|
||
}
|
||
|
||
/*===================================================================
|
||
CreateCatalog
|
||
|
||
CoCreateObject of an MTS Catalog object if the Catalog object has not been
|
||
created.
|
||
|
||
Parameter:
|
||
NONE;
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::CreateCatalog
|
||
(
|
||
VOID
|
||
)
|
||
{
|
||
HRESULT hr = NOERROR;
|
||
|
||
DBG_ASSERT(m_pCatalog == NULL);
|
||
DBG_ASSERT(m_pPkgCollection == NULL);
|
||
|
||
// Create instance of the catalog object
|
||
hr = CoCreateInstance(CLSID_COMAdminCatalog
|
||
, NULL
|
||
, CLSCTX_SERVER
|
||
, IID_ICOMAdminCatalog
|
||
, (void**)&m_pCatalog);
|
||
|
||
if (FAILED(hr)) {
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"Failed to CoCreateInstance of Catalog Object.,hr = %08x\n",
|
||
hr));
|
||
}
|
||
else {
|
||
DBG_ASSERT(m_pCatalog != NULL);
|
||
|
||
BSTR bstr;
|
||
|
||
//
|
||
// Get the Packages collection
|
||
//
|
||
bstr = SysAllocString(L"Applications");
|
||
hr = m_pCatalog->GetCollection(bstr, (IDispatch**)&m_pPkgCollection);
|
||
FREEBSTR(bstr);
|
||
if (FAILED(hr)) {
|
||
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"m_pCatalog(%08x)->GetCollection() failed, hr = %08x\n",
|
||
m_pCatalog,
|
||
hr));
|
||
} else {
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
}
|
||
|
||
}
|
||
|
||
return hr;
|
||
} // WamRegPackageConfig::CreateCatalog()
|
||
|
||
|
||
|
||
/*===================================================================
|
||
SetCatalogObjectProperty
|
||
|
||
Get a SafeArray contains one ComponentCLSID
|
||
|
||
Parameter:
|
||
szComponentCLSID the CLSID need to be put in the safe array
|
||
paCLSIDs pointer to a pointer of safe array(safe array provided by caller).
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
|
||
Note:
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::GetSafeArrayOfCLSIDs
|
||
(
|
||
IN LPCWSTR szComponentCLSID,
|
||
OUT SAFEARRAY** paCLSIDs
|
||
)
|
||
{
|
||
SAFEARRAY* aCLSIDs = NULL;
|
||
SAFEARRAYBOUND rgsaBound[1];
|
||
LONG Indices[1];
|
||
VARIANT varT;
|
||
HRESULT hr = NOERROR;
|
||
|
||
DBG_ASSERT(szComponentCLSID && paCLSIDs);
|
||
DBG_ASSERT(*paCLSIDs == NULL);
|
||
|
||
// PopulateByKey is expecting a SAFEARRAY parameter input,
|
||
// Create a one element SAFEARRAY, the one element of the SAFEARRAY contains
|
||
// the packageID.
|
||
rgsaBound[0].cElements = 1;
|
||
rgsaBound[0].lLbound = 0;
|
||
aCLSIDs = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
|
||
|
||
if (aCLSIDs)
|
||
{
|
||
Indices[0] = 0;
|
||
|
||
VariantInit(&varT);
|
||
varT.vt = VT_BSTR;
|
||
varT.bstrVal = SysAllocString(szComponentCLSID);
|
||
hr = SafeArrayPutElement(aCLSIDs, Indices, &varT);
|
||
VariantClear(&varT);
|
||
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayPutElement, CLSID is %S, hr %08x\n",
|
||
szComponentCLSID,
|
||
hr));
|
||
|
||
if (aCLSIDs != NULL)
|
||
{
|
||
HRESULT hrT = SafeArrayDestroy(aCLSIDs);
|
||
if (FAILED(hrT))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
|
||
hr));
|
||
}
|
||
aCLSIDs = NULL;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayCreate, hr %08x\n",
|
||
hr));
|
||
}
|
||
|
||
*paCLSIDs = aCLSIDs;
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
/*===================================================================
|
||
SetComponentObjectProperty
|
||
|
||
Set component level property.
|
||
|
||
Parameter:
|
||
pComponent - pointer to the ICatalogObject(MTS) used to update property
|
||
szPropertyName - Name of the property
|
||
szPropertyValue- Value of the property
|
||
fPropertyValue - If szPropertyValue is NULL, use fPropertyValue
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
|
||
Note:
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::SetComponentObjectProperty
|
||
(
|
||
IN ICatalogObject * pComponent,
|
||
IN LPCWSTR szPropertyName,
|
||
IN LPCWSTR szPropertyValue,
|
||
BOOL fPropertyValue
|
||
)
|
||
{
|
||
BSTR bstr = NULL;
|
||
HRESULT hr = NOERROR;
|
||
VARIANT varT;
|
||
|
||
VariantInit(&varT);
|
||
bstr = SysAllocString(szPropertyName);
|
||
|
||
if (szPropertyValue != NULL)
|
||
{
|
||
varT.vt = VT_BSTR;
|
||
varT.bstrVal = SysAllocString(szPropertyValue);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// COM+ regcongize -1 as TRUE, and 0 as FALSE. I believe the root is from VB.
|
||
//
|
||
varT.vt = VT_BOOL;
|
||
varT.boolVal = (fPropertyValue) ? -1 : 0;
|
||
}
|
||
|
||
hr = pComponent->put_Value(bstr, varT);
|
||
|
||
FREEBSTR(bstr);
|
||
VariantClear(&varT);
|
||
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"MTS-Component(%08x)::SetProperty(%S => %S) failed;"
|
||
" hr %08x\n",
|
||
pComponent, szPropertyName, szPropertyValue, hr));
|
||
}
|
||
return hr;
|
||
}
|
||
|
||
|
||
/*===================================================================
|
||
WamRegPackageConfig::SetComponentObjectProperties()
|
||
|
||
Sets the componnet properties for newly created component that houses
|
||
the WAM unit
|
||
|
||
Parameter:
|
||
szComponentCLSID - CLSID for the component that is newly created
|
||
|
||
Return: HRESULT
|
||
|
||
Side Affect:
|
||
If there is a failure all the previously set values are not cleared.
|
||
The caller should make sure that the proper cleanup of package happens
|
||
on partial errors.
|
||
|
||
Note:
|
||
===================================================================*/
|
||
HRESULT
|
||
WamRegPackageConfig::SetComponentObjectProperties(
|
||
IN LPCWSTR szComponentCLSID
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
SAFEARRAY* aCLSIDs = NULL;
|
||
long lCompCount = 0;
|
||
ICatalogObject* pComponent = NULL;
|
||
BOOL fFound;
|
||
|
||
DBG_ASSERT( m_pCompCollection != NULL);
|
||
|
||
//
|
||
// Create the array containing the CLSIDs from the component name
|
||
// this will be used to find our object in MTS and set properties
|
||
// on the same
|
||
//
|
||
|
||
hr = GetSafeArrayOfCLSIDs(szComponentCLSID, &aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"Failed in GetSafeArrayOfCLSIDs(%S). hr=%08x\n",
|
||
szComponentCLSID, hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pCompCollection->PopulateByKey(aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Find our component in the list (should be the only one)
|
||
hr = m_pCompCollection->get_Count(&lCompCount);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"Failed in CompCollection(%08x)::get_Count(). hr = %08x\n",
|
||
m_pCompCollection, hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
|
||
//
|
||
// Load the component object so that we can set properties
|
||
//
|
||
fFound = FALSE;
|
||
if (SUCCEEDED(hr) && lCompCount == 1)
|
||
{
|
||
hr = m_pCompCollection->get_Item(0, (IDispatch**)&pComponent);
|
||
|
||
if (FAILED(hr))
|
||
{
|
||
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"Failed in CompCollection(%08x)::get component() hr=%08x\n",
|
||
m_pCompCollection, hr));
|
||
goto LErrExit;
|
||
}
|
||
else
|
||
{
|
||
|
||
// Found it
|
||
DBG_ASSERT(pComponent);
|
||
fFound = TRUE;
|
||
}
|
||
}
|
||
|
||
if (fFound)
|
||
{
|
||
|
||
//
|
||
// Component Properties InProc OutOfProc
|
||
// --------------------- -------- ----------
|
||
// Synchronization 0 same
|
||
// Transaction "Not Supported" same
|
||
// JustInTimeActivation N same
|
||
// IISIntrinsics N same
|
||
// COMTIIntrinsics N same
|
||
// ComponentAccessChecksEnabled 0 same
|
||
hr = SetComponentObjectProperty( pComponent, L"Synchronization", L"0");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = SetComponentObjectProperty( pComponent, L"ComponentAccessChecksEnabled", L"0");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = SetComponentObjectProperty( pComponent, L"Transaction", L"0");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = SetComponentObjectProperty( pComponent, L"JustInTimeActivation",NULL,FALSE);
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = SetComponentObjectProperty( pComponent, L"IISIntrinsics", NULL, FALSE);
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = SetComponentObjectProperty( pComponent, L"COMTIIntrinsics", NULL, FALSE);
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = SetComponentObjectProperty(pComponent, L"EventTrackingEnabled", L"N");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"Unable to find newly create WAM component in package\n"));
|
||
DBG_ASSERT(FALSE);
|
||
}
|
||
|
||
LErrExit:
|
||
RELEASE(pComponent);
|
||
|
||
if (aCLSIDs != NULL) {
|
||
|
||
HRESULT hrT = SafeArrayDestroy(aCLSIDs);
|
||
if (FAILED(hrT)) {
|
||
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"Failed to call SafeArrayDestroy(aCLSIDs=%08x),"
|
||
" hr = %08x\n",
|
||
aCLSIDs, hr));
|
||
}
|
||
aCLSIDs = NULL;
|
||
}
|
||
|
||
return ( hr);
|
||
} // // WamRegPackageConfig::SetComponentObjectProperties()
|
||
|
||
|
||
|
||
/*===================================================================
|
||
SetPackageObjectProperty
|
||
|
||
Set package level property.
|
||
|
||
Parameter:
|
||
szPropertyName Name of the property
|
||
szPropertyValue Value of the property
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
|
||
Note:
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::SetPackageObjectProperty
|
||
(
|
||
IN LPCWSTR szPropertyName,
|
||
IN LPCWSTR szPropertyValue
|
||
)
|
||
{
|
||
BSTR bstr = NULL;
|
||
HRESULT hr = NOERROR;
|
||
VARIANT varT;
|
||
|
||
|
||
VariantInit(&varT);
|
||
bstr = SysAllocString(szPropertyName);
|
||
varT.vt = VT_BSTR;
|
||
varT.bstrVal = SysAllocString(szPropertyValue);
|
||
DBG_ASSERT(m_pPackage != NULL);
|
||
hr = m_pPackage->put_Value(bstr, varT);
|
||
|
||
FREEBSTR(bstr);
|
||
VariantClear(&varT);
|
||
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"Set Catalog Object Property failed, "
|
||
"Component is %S, hr %08x\n",
|
||
szPropertyName,
|
||
hr));
|
||
}
|
||
return hr;
|
||
} // WamRegPackageConfig::SetPackageObjectProperty()
|
||
|
||
|
||
|
||
|
||
/*===================================================================
|
||
WamRegPackageConfig::SetPackageProperties()
|
||
|
||
Sets package properties for all WAMREG properties.
|
||
|
||
Parameter:
|
||
rgpszValues: An array containing pointers to string values to be used
|
||
for setting up the WAMREG related properites for MTS catalog.
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
If there is a failure all the previously set values are not cleared.
|
||
The caller should make sure that the proper cleanup of package happens
|
||
on partial errors.
|
||
|
||
Note:
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::SetPackageProperties
|
||
(
|
||
IN LPCWSTR * rgpszValues
|
||
)
|
||
{
|
||
HRESULT hr = NOERROR;
|
||
|
||
DBG_ASSERT( m_pPackage);
|
||
|
||
//
|
||
// Loop through all properties and set the values for these
|
||
// properties using the passed in array of strings.
|
||
// UGLY: MTS likes to have string properties which need to be
|
||
// fed in as BSTRs => very inefficient.
|
||
//
|
||
|
||
for (DWORD i = 0; i < NUM_WAMREG_MTS_PROPERTIES; i++) {
|
||
|
||
if ( (TsIsWindows95() && g_rgWamRegMtsProperties[i].m_fWinNTOnly) ||
|
||
(rgpszValues[i] == NULL)
|
||
) {
|
||
|
||
//
|
||
// This parameter is for Win95 only
|
||
// Or this parameter is required only for certain cases.
|
||
// Skip this parameter.
|
||
//
|
||
|
||
continue;
|
||
}
|
||
|
||
DBG_ASSERT( rgpszValues[i] != NULL);
|
||
|
||
IF_DEBUG( WAMREG_MTS) {
|
||
DBGPRINTF(( DBG_CONTEXT,
|
||
"In Package(%08x) setting property %S to value %S\n",
|
||
m_pPackage,
|
||
g_rgWamRegMtsProperties[i].m_pszPropName,
|
||
rgpszValues[i]
|
||
));
|
||
}
|
||
|
||
//
|
||
// Now let us set up the property in the MTS package
|
||
//
|
||
|
||
hr = SetPackageObjectProperty(g_rgWamRegMtsProperties[i].m_pszPropName,
|
||
rgpszValues[i]);
|
||
if ( FAILED (hr)) {
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to set property %S, value is %S\n",
|
||
g_rgWamRegMtsProperties[i].m_pszPropName,
|
||
rgpszValues[i]));
|
||
break;
|
||
}
|
||
} // for all properties
|
||
|
||
return (hr);
|
||
} // WamRegPackageConfig::SetPackageProperties()
|
||
|
||
|
||
BOOL WamRegPackageConfig::IsPackageInstalled
|
||
(
|
||
IN LPCWSTR szPackageID,
|
||
IN LPCWSTR szComponentCLSID
|
||
)
|
||
/*++
|
||
Routine Description:
|
||
|
||
Determine if the WAM package is installed and is valid. Currently this
|
||
is only called by setup.
|
||
|
||
Parameters
|
||
|
||
IN LPCWSTR szPackageID - Package ID
|
||
IN LPCWSTR szComponentCLSID - Component CLSID
|
||
|
||
Return Value
|
||
|
||
BOOL - True if package contains the component. False otherwise.
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr;
|
||
SAFEARRAY* aCLSIDs = NULL;
|
||
SAFEARRAY* aCLSIDsComponent = NULL;
|
||
|
||
DBG_ASSERT( m_pCatalog != NULL);
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
|
||
long lPkgCount;
|
||
BOOL fFound = FALSE;
|
||
ICatalogCollection* pCompCollection = NULL;
|
||
|
||
// Only use the trace macro here, even for error conditions.
|
||
// This routine may fail in a variety of ways, but we expect
|
||
// to be able to fix any of them, only report an error if
|
||
// the failure is likely to impair the functionality of the
|
||
// server.
|
||
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"CALL - IsPackageInstalled, Package(%S) Component(%S)\n",
|
||
szPackageID,
|
||
szComponentCLSID
|
||
));
|
||
|
||
//
|
||
// Get the package
|
||
//
|
||
|
||
hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Failed to GetSafeArrayOfCLSIDs for %S, hr = %08x\n",
|
||
szPackageID,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pPkgCollection(%p)->PopulateByKey(), hr = %08x\n",
|
||
m_pPkgCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pPkgCollection->get_Count(&lPkgCount);
|
||
if (SUCCEEDED(hr) && lPkgCount == 1)
|
||
{
|
||
//
|
||
// We found the package. Now verify that it contains our component.
|
||
//
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Successfully retrieved package (%S).\n",
|
||
szPackageID
|
||
));
|
||
|
||
VARIANT varKey;
|
||
BSTR bstrComponentCollection;
|
||
|
||
VariantInit(&varKey);
|
||
varKey.vt = VT_BSTR;
|
||
varKey.bstrVal = SysAllocString(szPackageID);
|
||
|
||
// Get the "ComponentsInPackage" collection.
|
||
bstrComponentCollection = SysAllocString(L"Components");
|
||
hr = m_pPkgCollection->GetCollection(
|
||
bstrComponentCollection,
|
||
varKey,
|
||
(IDispatch**)&pCompCollection
|
||
);
|
||
|
||
FREEBSTR(bstrComponentCollection);
|
||
VariantClear(&varKey);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pPkgCollection(%p)->GetCollection(), hr = %08x\n",
|
||
m_pPkgCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = GetSafeArrayOfCLSIDs(szComponentCLSID, &aCLSIDsComponent);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Failed to GetSafeArrayOfCLSIDs for %S, hr = %08x\n",
|
||
szComponentCLSID,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = pCompCollection->PopulateByKey( aCLSIDsComponent );
|
||
if( FAILED(hr) )
|
||
{
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Failed in pCompCollection(%p)->PopulateByKey, hr = %08x\n",
|
||
pCompCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = pCompCollection->get_Count( &lPkgCount );
|
||
if( SUCCEEDED(hr) && lPkgCount == 1 )
|
||
{
|
||
// Success! We found the package and it contains the
|
||
// correct component.
|
||
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Successfully retrieved component (%S) from package (%S).\n",
|
||
szComponentCLSID,
|
||
szPackageID
|
||
));
|
||
|
||
fFound = TRUE;
|
||
}
|
||
}
|
||
|
||
LErrExit:
|
||
if (aCLSIDs != NULL)
|
||
{
|
||
SafeArrayDestroy(aCLSIDs);
|
||
aCLSIDs = NULL;
|
||
}
|
||
|
||
if( aCLSIDsComponent != NULL )
|
||
{
|
||
SafeArrayDestroy(aCLSIDsComponent);
|
||
aCLSIDsComponent = NULL;
|
||
}
|
||
|
||
RELEASE( pCompCollection );
|
||
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"RETURN - IsPackageInstalled, hr=%08x\n",
|
||
hr
|
||
));
|
||
return fFound;
|
||
}
|
||
/*===================================================================
|
||
RemovePackage
|
||
|
||
Remove a Viper Package.
|
||
|
||
Parameter:
|
||
szPackageID: an MTS package ID.
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
|
||
Note:
|
||
Remove an IIS package from MTS. So far, only been called from RemoveIISPackage.
|
||
RemoveComponentFromPackage() also removes a IIS package sometimes.
|
||
Refer to that function header for info.
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::RemovePackage
|
||
(
|
||
IN LPCWSTR szPackageID
|
||
)
|
||
{
|
||
HRESULT hr = NOERROR;
|
||
long lPkgCount = 0;
|
||
long lChanges;
|
||
SAFEARRAY* aCLSIDs = NULL;
|
||
|
||
DBG_ASSERT(szPackageID);
|
||
|
||
DBG_ASSERT( m_pCatalog != NULL);
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
|
||
hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to get SafeArrayofCLSIDs, szPackageID is %S, hr %08x",
|
||
szPackageID,
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
//
|
||
// Populate it
|
||
//
|
||
hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pPkgCollection->get_Count(&lPkgCount);
|
||
if (FAILED(hr))
|
||
{
|
||
IF_DEBUG(ERROR)
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "pPkgCollection->Populate() failed, hr = %08x\n",
|
||
hr));
|
||
}
|
||
goto LErrExit;
|
||
}
|
||
|
||
if (SUCCEEDED(hr) && lPkgCount == 1)
|
||
{
|
||
hr = m_pPkgCollection->get_Item(0, (IDispatch**)&m_pPackage);
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Found it - remove it and call Save Changes
|
||
// First, Set Deleteable = Y property on package
|
||
hr = SetPackageObjectProperty(L"Deleteable", L"Y");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
RELEASE(m_pPackage);
|
||
|
||
// Let save the Deletable settings
|
||
hr = m_pPkgCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Save the Deletable settings failed, hr = %08x\n",
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Now we can delete
|
||
hr = m_pPkgCollection->Remove(0);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Remove the Component from package failed, hr = %08x\n",
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Aha, we should be able to delete now.
|
||
hr = m_pPkgCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Save changes failed, hr = %08x\n",
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
}
|
||
|
||
LErrExit:
|
||
if (aCLSIDs != NULL)
|
||
{
|
||
HRESULT hrT = SafeArrayDestroy(aCLSIDs);
|
||
if (FAILED(hrT))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
|
||
hr));
|
||
}
|
||
aCLSIDs = NULL;
|
||
}
|
||
|
||
ReleaseAll();
|
||
|
||
return hr;
|
||
}
|
||
|
||
/*===================================================================
|
||
CreatePackage
|
||
|
||
Create a viper package.
|
||
|
||
Parameter:
|
||
szPackageID: [in] Viper Package ID.
|
||
szPackageName: [in] the name of the package.
|
||
szIdentity: [in] Pakcage identity
|
||
szIdPassword: [in] Package idneitty password
|
||
fInProc: [in] Inproc or outproc package
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
NONE.
|
||
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::CreatePackage
|
||
(
|
||
IN LPCWSTR szPackageID,
|
||
IN LPCWSTR szPackageName,
|
||
IN LPCWSTR szIdentity,
|
||
IN LPCWSTR szIdPassword,
|
||
IN BOOL fInProc
|
||
)
|
||
{
|
||
|
||
HRESULT hr;
|
||
SAFEARRAY* aCLSIDs = NULL;
|
||
|
||
DBG_ASSERT( m_pCatalog != NULL);
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
|
||
long lPkgCount;
|
||
BOOL fFound = FALSE;
|
||
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"CALL - CreatePackage ID(%S) Name(%S)\n",
|
||
szPackageID,
|
||
szPackageName
|
||
));
|
||
|
||
//
|
||
// Try to get the package.
|
||
//
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Checking to see if package ID(%S) Name(%S) exists.\n",
|
||
szPackageID,
|
||
szPackageName
|
||
));
|
||
|
||
hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed to GetSafeArrayOfCLSIDs for %S, hr = %08x\n",
|
||
szPackageID,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pPkgCollection(%p)->PopulateByKey(), hr = %08x\n",
|
||
m_pPkgCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pPkgCollection->get_Count(&lPkgCount);
|
||
if (SUCCEEDED(hr) && lPkgCount == 1)
|
||
{
|
||
//
|
||
// Found the CLSID in PopulateByKey().
|
||
//
|
||
hr = m_pPkgCollection->get_Item(0, (IDispatch**)&m_pPackage);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pPkgCollection(%p)->get_Item(). Err=%08x\n",
|
||
m_pPkgCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
else
|
||
{
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"CreatePackage - Package already exists, ID(%S), Name(%S)\n",
|
||
szPackageID,
|
||
szPackageName
|
||
));
|
||
DBG_ASSERT(m_pPackage);
|
||
fFound = TRUE;
|
||
}
|
||
}
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
|
||
if( !fFound )
|
||
{
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"Package ID(%S) Name(%S) does not exist. Attempting to create it.\n",
|
||
szPackageID,
|
||
szPackageName
|
||
));
|
||
//
|
||
// The package does not already exist, we need to call Add() to
|
||
// add this package and then set it's properties.
|
||
//
|
||
hr = m_pPkgCollection->Add((IDispatch**)&m_pPackage);
|
||
if ( FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pPkgCollection(%p)->Add(). Err=%08x\n",
|
||
m_pPkgCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
}
|
||
|
||
DBG_ASSERT( SUCCEEDED( hr));
|
||
DBG_ASSERT( m_pPackage != NULL);
|
||
|
||
if( SUCCEEDED(hr) && m_pPackage != NULL )
|
||
{
|
||
//
|
||
// Set the Package properties
|
||
// first by initializing the array of values and then
|
||
// calling SetPackageProperties()
|
||
//
|
||
|
||
LPCWSTR rgpszValues[ MAX_WAMREG_MTS_PROP_NAMES];
|
||
|
||
ZeroMemory( rgpszValues, sizeof( rgpszValues));
|
||
|
||
if( fFound )
|
||
{
|
||
// For an existing package, we don't want to set the ID
|
||
rgpszValues[ WM_ID] = NULL;
|
||
}
|
||
else
|
||
{
|
||
rgpszValues[ WM_ID] = szPackageID;
|
||
}
|
||
|
||
rgpszValues[ WM_NAME] = szPackageName;
|
||
rgpszValues[ WM_CREATED_BY] =
|
||
L"Microsoft Internet Information Services";
|
||
|
||
rgpszValues[ WM_RUN_FOREVER] = L"Y";
|
||
|
||
rgpszValues[ WM_IDENTITY] = szIdentity;
|
||
rgpszValues[ WM_PASSWORD] = szIdPassword;
|
||
rgpszValues[ WM_ACTIVATION] =
|
||
((fInProc) ? L"InProc" : L"Local");
|
||
|
||
rgpszValues[ WM_CHANGEABLE] = L"Y";
|
||
rgpszValues[ WM_DELETABLE] = L"N";
|
||
rgpszValues[ WM_SECSUPP] = L"0";
|
||
|
||
//
|
||
// Now that we have the properties setup, let us
|
||
// now set the properties in the MTS using catalog
|
||
// object
|
||
//
|
||
hr = SetPackageProperties( rgpszValues);
|
||
if ( FAILED( hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed to set properties for package %p. Err=%08x\n",
|
||
m_pPackage,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
long lChanges;
|
||
|
||
hr = m_pPkgCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pPkgCollection(%p)->SaveChanges. error = %08x\n",
|
||
m_pPkgCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
}
|
||
}
|
||
|
||
LErrExit:
|
||
|
||
if (aCLSIDs != NULL)
|
||
{
|
||
SafeArrayDestroy(aCLSIDs);
|
||
aCLSIDs = NULL;
|
||
}
|
||
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed to Create Package. Package Name = %S, Package ID = %S, error = %08x\n",
|
||
szPackageName,
|
||
szPackageID,
|
||
hr
|
||
));
|
||
}
|
||
|
||
SETUP_TRACE_ASSERT(SUCCEEDED(hr));
|
||
|
||
ReleaseAll();
|
||
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"RETURN - CreatePackage ID(%S) Name(%S)\n",
|
||
szPackageID,
|
||
szPackageName
|
||
));
|
||
|
||
return hr;
|
||
}
|
||
|
||
/*===================================================================
|
||
AddComponentFromPackage
|
||
|
||
Add a Component (a WAM CLSID) from a Viper Package. Assume the package
|
||
is already existed.
|
||
|
||
Parameter:
|
||
szPackageID: [in] Viper Package ID.
|
||
szComponentCLSID: [in] Component CLSID.
|
||
fInProc: [in] if TRUE, we set certain property on the Component.
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
NONE.
|
||
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::AddComponentToPackage
|
||
(
|
||
IN LPCWSTR szPackageID,
|
||
IN LPCWSTR szComponentCLSID
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
BSTR bstrGUID = NULL;
|
||
BSTR bstr = NULL;
|
||
VARIANT varKey;
|
||
long lChanges;
|
||
BOOL fFound;
|
||
long lPkgCount;
|
||
BOOL fImported = FALSE;
|
||
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"CALL - AddComponentToPackage, Package(%S) Component(%S)\n",
|
||
szPackageID,
|
||
szComponentCLSID
|
||
));
|
||
|
||
DBG_ASSERT(szPackageID);
|
||
DBG_ASSERT(szComponentCLSID);
|
||
|
||
VariantInit(&varKey);
|
||
VariantClear(&varKey);
|
||
|
||
DBG_ASSERT( m_pCatalog != NULL);
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
|
||
varKey.vt = VT_BSTR;
|
||
varKey.bstrVal = SysAllocString(szPackageID);
|
||
|
||
bstr = SysAllocString(szPackageID);
|
||
bstrGUID = SysAllocString(szComponentCLSID);
|
||
|
||
hr = m_pCatalog->ImportComponent(bstr, bstrGUID);
|
||
FREEBSTR(bstr);
|
||
FREEBSTR(bstrGUID);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pCatalog(%p)->ImportComponent(). error %08x\n",
|
||
m_pCatalog,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
else
|
||
{
|
||
fImported = TRUE;
|
||
}
|
||
|
||
// Get the "ComponentsInPackage" collection.
|
||
bstr = SysAllocString(L"Components");
|
||
|
||
hr = m_pPkgCollection->GetCollection(bstr, varKey, (IDispatch**)&m_pCompCollection);
|
||
FREEBSTR(bstr);
|
||
VariantClear(&varKey);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pPkgCollection(%p)->GetCollection(). error %08x\n",
|
||
m_pPkgCollection,
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
//
|
||
// Find and Set properties on the component object
|
||
//
|
||
hr = SetComponentObjectProperties( szComponentCLSID);
|
||
if ( FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed to SetComponentObjectProperties. error %08x\n",
|
||
hr
|
||
));
|
||
goto LErrExit;
|
||
}
|
||
|
||
LErrExit:
|
||
|
||
// Save changes
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = m_pCompCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hr))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pCompCollection(%p)->SaveChanges(), error = %08x\n",
|
||
m_pCompCollection,
|
||
hr
|
||
));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// CODEWORK - This seems like a bad idea. The release should drop any
|
||
// changes we made, so this cleanup code seems to be asking for trouble.
|
||
|
||
// Need to remove component from the package
|
||
if (fImported && m_pCompCollection )
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in AddComponentToPackage, removing the component, error = %08x\n",
|
||
hr
|
||
));
|
||
|
||
HRESULT hrT;
|
||
long lCompCount;
|
||
|
||
// Find our component in the list (should be the only one)
|
||
hrT = m_pCompCollection->get_Count(&lCompCount);
|
||
if (SUCCEEDED(hrT))
|
||
{
|
||
fFound = FALSE;
|
||
if (SUCCEEDED(hrT) && lCompCount == 1)
|
||
{
|
||
// Found it
|
||
fFound = TRUE;
|
||
hrT = m_pCompCollection->Remove(0);
|
||
if (SUCCEEDED(hrT))
|
||
{
|
||
hrT = m_pCompCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hrT))
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pCompCollection->SaveChanges() during cleanup, error = %08x\n",
|
||
hrT
|
||
));
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
SETUP_TRACE_ERROR((
|
||
DBG_CONTEXT,
|
||
"Failed in m_pCompCollection->Remove() during cleanup, hr = %08x\n",
|
||
hrT
|
||
));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
FREEBSTR(bstr);
|
||
VariantClear(&varKey);
|
||
|
||
ReleaseAll();
|
||
|
||
SETUP_TRACE((
|
||
DBG_CONTEXT,
|
||
"RETURN - AddComponentToPackage, Package(%S) Component(%S), hr=%08x\n",
|
||
szPackageID,
|
||
szComponentCLSID,
|
||
hr
|
||
));
|
||
|
||
return hr;
|
||
}
|
||
|
||
/*===================================================================
|
||
RemoveComponentFromPackage
|
||
|
||
Remove a Component (a WAM CLSID) from a Viper Package.
|
||
|
||
Parameter:
|
||
szPackageID: [in] Viper Package ID.
|
||
szComponentCLSID: [in] Component CLSID.
|
||
fDeletePackage: [in] if TRUE, we delete the package always. (be very careful, with in-proc
|
||
package).
|
||
|
||
Return: HRESULT
|
||
Side Affect:
|
||
After remove the component from the package, if the component count in the
|
||
package is 0, then delete the whole package.
|
||
|
||
===================================================================*/
|
||
HRESULT WamRegPackageConfig::RemoveComponentFromPackage
|
||
(
|
||
IN LPCWSTR szPackageID,
|
||
IN LPCWSTR szComponentCLSID,
|
||
IN DWORD dwAppIsolated
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
BSTR bstr = NULL;
|
||
BSTR bstrGUID = NULL;
|
||
VARIANT varKey;
|
||
VARIANT varT;
|
||
SAFEARRAY* aCLSIDs = NULL;
|
||
LONG Indices[1];
|
||
long lPkgCount, lCompCount, lChanges;
|
||
long lPkgIndex = 0;
|
||
BOOL fFound;
|
||
|
||
VariantInit(&varKey);
|
||
VariantClear(&varKey);
|
||
VariantInit(&varT);
|
||
VariantClear(&varT);
|
||
|
||
DBG_ASSERT( m_pCatalog != NULL);
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
|
||
hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
|
||
//
|
||
// Populate it
|
||
//
|
||
hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Find our component in the list (should be the only one)
|
||
hr = m_pPkgCollection->get_Count(&lPkgCount);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call MTS Admin API. error %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
fFound = FALSE;
|
||
if (SUCCEEDED(hr) && lPkgCount == 1)
|
||
{
|
||
hr = m_pPkgCollection->get_Item(0, (IDispatch**)&m_pPackage);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call MTS Admin API. error %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pPackage->get_Key(&varKey);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
// Found it
|
||
DBG_ASSERT(m_pPackage);
|
||
fFound = TRUE;
|
||
}
|
||
}
|
||
|
||
// Get the "Components" collection.
|
||
bstr = SysAllocString(L"Components");
|
||
hr = m_pPkgCollection->GetCollection(bstr, varKey, (IDispatch**)&m_pCompCollection);
|
||
FREEBSTR(bstr);
|
||
VariantClear(&varKey);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Repopulate the collection so we can find our object and set properties on it
|
||
Indices[0] = 0;
|
||
VariantInit(&varT);
|
||
varT.vt = VT_BSTR;
|
||
varT.bstrVal = SysAllocString(szComponentCLSID);
|
||
hr = SafeArrayPutElement(aCLSIDs, Indices, &varT);
|
||
VariantClear(&varT);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
|
||
hr));
|
||
}
|
||
//
|
||
// Populate it
|
||
//
|
||
hr = m_pCompCollection->PopulateByKey(aCLSIDs);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
|
||
hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Find our component in the list (should be the only one)
|
||
hr = m_pCompCollection->get_Count(&lCompCount);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call MTS Admin API. error %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
fFound = FALSE;
|
||
if (SUCCEEDED(hr) && lCompCount == 1)
|
||
{
|
||
// Found it
|
||
fFound = TRUE;
|
||
hr = m_pCompCollection->Remove(0);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
}
|
||
|
||
DBG_ASSERT(fFound);
|
||
|
||
// Save changes
|
||
hr = m_pCompCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
|
||
//
|
||
// Need to populate again to get the Component count after remove the component from
|
||
// the package. The populatebykey only populate 1 component a time.
|
||
// However, if this package is the default package hosting all in-proc WAM components,
|
||
// we know that there is at least one component W3SVC always in this package, therefore
|
||
// we skip the GetComponentCount call here.
|
||
// The component count for the default package must be at least one,
|
||
//
|
||
|
||
// Set lCompCount = 1, so that the only case that lCompCount becomes 0 is the OutProc
|
||
// Islated package has 0 components.
|
||
lCompCount = 1;
|
||
if (dwAppIsolated == static_cast<DWORD>(eAppRunOutProcIsolated))
|
||
{
|
||
hr = m_pCompCollection->Populate();
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Find our component in the list (should be the only one)
|
||
hr = m_pCompCollection->get_Count(&lCompCount);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Component count is 0, remove the package.
|
||
if (lCompCount == 0)
|
||
{
|
||
// Found it - remove it and call Save Changes
|
||
// First, Set Deleteable = Y property on package
|
||
hr = SetPackageObjectProperty(L"Deleteable", L"Y");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
RELEASE(m_pPackage);
|
||
// Let save the Deletable settings
|
||
hr = m_pPkgCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
hr = m_pPkgCollection->Remove(0);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Set Attribute Deleteable = "Y"
|
||
hr = SetPackageObjectProperty(L"Deleteable", L"Y");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Set CreatedBy = ""
|
||
hr = SetPackageObjectProperty(L"CreatedBy", L"");
|
||
if (FAILED(hr))
|
||
{
|
||
goto LErrExit;
|
||
}
|
||
|
||
// Set Identity to Interactive User. MTS might use that package with "Interactive User"
|
||
// as the indentity.
|
||
hr = SetPackageObjectProperty(L"Identity", L"Interactive User");
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
|
||
RELEASE(m_pPackage);
|
||
}
|
||
|
||
hr = m_pPkgCollection->SaveChanges(&lChanges);
|
||
if (FAILED(hr))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
|
||
goto LErrExit;
|
||
}
|
||
}
|
||
LErrExit:
|
||
|
||
if (aCLSIDs != NULL)
|
||
{
|
||
HRESULT hrT;
|
||
hrT = SafeArrayDestroy(aCLSIDs);
|
||
|
||
if (FAILED(hrT))
|
||
{
|
||
DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
|
||
hr));
|
||
}
|
||
|
||
aCLSIDs = NULL;
|
||
}
|
||
|
||
FREEBSTR(bstr);
|
||
|
||
VariantClear(&varKey);
|
||
VariantClear(&varT);
|
||
|
||
ReleaseAll();
|
||
return hr;
|
||
|
||
}
|
||
|
||
#if 0
|
||
|
||
// OBSOLETE - This fix (335422) was implemented in script but
|
||
// some of the code is general enough that it might be worth
|
||
// keeping around for a while.
|
||
|
||
|
||
HRESULT
|
||
WamRegPackageConfig::ResetPackageActivation
|
||
(
|
||
IN LPCWSTR wszPackageID,
|
||
IN LPCWSTR wszIWamUser,
|
||
IN LPCWSTR wszIWamPass
|
||
)
|
||
/*+
|
||
Routine Description:
|
||
|
||
Retrieve the specified package and reset its activation
|
||
identity.
|
||
|
||
This is really a crummy method, but this whole class is
|
||
not really designed to provide a wrapper for the com admin
|
||
api, so it's much safer just to make this a specific method.
|
||
|
||
Arguments:
|
||
|
||
IN LPCWSTR wszPackageID - the package to reset
|
||
IN LPCWSTR wszIWamUser - IWAM_*
|
||
IN LPCWSTR wszIWamPass - password for IWAM_*
|
||
|
||
Returns:
|
||
HRESULT
|
||
-*/
|
||
{
|
||
HRESULT hr = NOERROR;
|
||
LONG nChanges = 0;
|
||
|
||
DBG_ASSERT( m_pCatalog != NULL);
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
DBG_ASSERT( m_pPackage == NULL );
|
||
|
||
hr = LoadPackage( wszPackageID );
|
||
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
DBG_ASSERT( m_pPackage != NULL );
|
||
|
||
LPCWSTR rgpszValues[ MAX_WAMREG_MTS_PROP_NAMES ];
|
||
|
||
ZeroMemory( rgpszValues, sizeof(rgpszValues) );
|
||
|
||
rgpszValues[WM_IDENTITY] = wszIWamUser;
|
||
rgpszValues[WM_PASSWORD] = wszIWamPass;
|
||
|
||
hr = SetPackageProperties( rgpszValues );
|
||
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
hr = m_pPkgCollection->SaveChanges( &nChanges );
|
||
}
|
||
}
|
||
|
||
ReleaseAll();
|
||
|
||
return hr;
|
||
}
|
||
|
||
HRESULT
|
||
WamRegPackageConfig::LoadPackage
|
||
(
|
||
IN LPCWSTR wszPackageID
|
||
)
|
||
/*+
|
||
Routine Description:
|
||
|
||
Retrieve the specified package into m_pPackage
|
||
|
||
TODO - Use this when creating as well. Need to add
|
||
the necessary debug/setuplog traces.
|
||
|
||
Arguments:
|
||
|
||
IN LPCWSTR wszPackageID - the package to load
|
||
|
||
Returns:
|
||
HRESULT
|
||
-*/
|
||
{
|
||
HRESULT hr = NOERROR;
|
||
SAFEARRAY* psaPackageClsid = NULL;
|
||
|
||
DBG_ASSERT( m_pCatalog != NULL);
|
||
DBG_ASSERT( m_pPkgCollection != NULL);
|
||
DBG_ASSERT( m_pPackage == NULL );
|
||
|
||
hr = GetSafeArrayOfCLSIDs( wszPackageID, &psaPackageClsid );
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
hr = m_pPkgCollection->PopulateByKey( psaPackageClsid );
|
||
|
||
DBG_CODE(
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
LONG nPackages;
|
||
hr = m_pPkgCollection->get_Count( &nPackages );
|
||
|
||
DBG_ASSERT( SUCCEEDED(hr) );
|
||
DBG_ASSERT( nPackages == 1 );
|
||
}
|
||
);
|
||
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
hr = m_pPkgCollection->get_Item( 0, (IDispatch **)&m_pPackage );
|
||
}
|
||
}
|
||
|
||
if( psaPackageClsid ) SafeArrayDestroy( psaPackageClsid );
|
||
|
||
return hr;
|
||
}
|
||
|
||
// OBSOLETE
|
||
#endif
|