mirror of https://github.com/tongzx/nt5src
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.
1799 lines
48 KiB
1799 lines
48 KiB
/*===================================================================
|
|
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
|