//--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 2001 // // File: capool.cxx // // Contents: Contains methods for CIISApplicationPool object // // History: 11-09-2000 BrentMid Created. // //---------------------------------------------------------------------------- #include "iisext.hxx" #pragma hdrstop // Class CIISApplicationPool DEFINE_IPrivateDispatch_Implementation(CIISApplicationPool) DEFINE_DELEGATING_IDispatch_Implementation(CIISApplicationPool) DEFINE_CONTAINED_IADs_Implementation(CIISApplicationPool) DEFINE_IADsExtension_Implementation(CIISApplicationPool) CIISApplicationPool::CIISApplicationPool(): _pUnkOuter(NULL), _pADs(NULL), _pszServerName(NULL), _pszPoolName(NULL), _pszMetaBasePath(NULL), _pAdminBase(NULL), _pDispMgr(NULL), _fDispInitialized(FALSE) { ENLIST_TRACKING(CIISApplicationPool); } HRESULT CIISApplicationPool::CreateApplicationPool( IUnknown *pUnkOuter, REFIID riid, void **ppvObj ) { CCredentials Credentials; CIISApplicationPool FAR * pApplicationPool = NULL; HRESULT hr = S_OK; BSTR bstrAdsPath = NULL; OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer * pLexer = NULL; LPWSTR pszIISPathName = NULL; LPWSTR *pszPoolName; hr = AllocateApplicationPoolObject(pUnkOuter, Credentials, &pApplicationPool); BAIL_ON_FAILURE(hr); // // get ServerName and pszPath // hr = pApplicationPool->_pADs->get_ADsPath(&bstrAdsPath); BAIL_ON_FAILURE(hr); pLexer = new CLexer(); hr = pLexer->Initialize(bstrAdsPath); BAIL_ON_FAILURE(hr); // // Parse the pathname // memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(pLexer, pObjectInfo); BAIL_ON_FAILURE(hr); pszIISPathName = AllocADsStr(bstrAdsPath); if (!pszIISPathName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } *pszIISPathName = L'\0'; hr = BuildIISPathFromADsPath( pObjectInfo, pszIISPathName ); BAIL_ON_FAILURE(hr); pszPoolName = &(ObjectInfo.ComponentArray[ObjectInfo.NumComponents-1].szComponent); hr = pApplicationPool->InitializeApplicationPoolObject( pObjectInfo->TreeName, pszIISPathName, *pszPoolName ); BAIL_ON_FAILURE(hr); // // pass non-delegating IUnknown back to the aggregator // *ppvObj = (INonDelegatingUnknown FAR *) pApplicationPool; if (bstrAdsPath) { ADsFreeString(bstrAdsPath); } if (pLexer) { delete pLexer; } if (pszIISPathName ) { FreeADsStr( pszIISPathName ); } FreeObjectInfo( &ObjectInfo ); RRETURN(hr); error: if (bstrAdsPath) { ADsFreeString(bstrAdsPath); } if (pLexer) { delete pLexer; } if (pszIISPathName ) { FreeADsStr( pszIISPathName ); } FreeObjectInfo( &ObjectInfo ); *ppvObj = NULL; delete pApplicationPool; RRETURN(hr); } CIISApplicationPool::~CIISApplicationPool( ) { if (_pszServerName) { FreeADsStr(_pszServerName); } if (_pszMetaBasePath) { FreeADsStr(_pszMetaBasePath); } if (_pszPoolName) { FreeADsStr(_pszPoolName); } delete _pDispMgr; } STDMETHODIMP CIISApplicationPool::QueryInterface( REFIID iid, LPVOID FAR* ppv ) { HRESULT hr = S_OK; hr = _pUnkOuter->QueryInterface(iid,ppv); RRETURN(hr); } HRESULT CIISApplicationPool::AllocateApplicationPoolObject( IUnknown *pUnkOuter, CCredentials& Credentials, CIISApplicationPool ** ppApplicationPool ) { CIISApplicationPool FAR * pApplicationPool = NULL; IADs FAR * pADs = NULL; CAggregateeDispMgr FAR * pDispMgr = NULL; HRESULT hr = S_OK; pApplicationPool = new CIISApplicationPool(); if (pApplicationPool == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr); pDispMgr = new CAggregateeDispMgr; if (pDispMgr == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr); hr = pDispMgr->LoadTypeInfoEntry( LIBID_IISExt, IID_IISApplicationPool, (IISApplicationPool *)pApplicationPool, DISPID_REGULAR ); BAIL_ON_FAILURE(hr); // // Store the IADs Pointer, but again do NOT ref-count // this pointer - we keep the pointer around, but do // a release immediately. // hr = pUnkOuter->QueryInterface(IID_IADs, (void **)&pADs); pADs->Release(); pApplicationPool->_pADs = pADs; // // Store the pointer to the pUnkOuter object // AND DO NOT add ref this pointer // pApplicationPool->_pUnkOuter = pUnkOuter; pApplicationPool->_Credentials = Credentials; pApplicationPool->_pDispMgr = pDispMgr; *ppApplicationPool = pApplicationPool; RRETURN(hr); error: delete pDispMgr; delete pApplicationPool; RRETURN(hr); } HRESULT CIISApplicationPool::InitializeApplicationPoolObject( LPWSTR pszServerName, LPWSTR pszPath, LPWSTR pszPoolName ) { HRESULT hr = S_OK; if (pszServerName) { _pszServerName = AllocADsStr(pszServerName); if (!_pszServerName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } } if (pszPath) { _pszMetaBasePath = AllocADsStr(pszPath); if (!_pszMetaBasePath) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } } if (pszPoolName) { _pszPoolName = AllocADsStr(pszPoolName); if (!_pszPoolName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } } hr = InitServerInfo(pszServerName, &_pAdminBase); BAIL_ON_FAILURE(hr); error: RRETURN(hr); } STDMETHODIMP CIISApplicationPool::ADSIInitializeDispatchManager( long dwExtensionId ) { HRESULT hr = S_OK; if (_fDispInitialized) { RRETURN(E_FAIL); } hr = _pDispMgr->InitializeDispMgr(dwExtensionId); if (SUCCEEDED(hr)) { _fDispInitialized = TRUE; } RRETURN(hr); } STDMETHODIMP CIISApplicationPool::ADSIInitializeObject( THIS_ BSTR lpszUserName, BSTR lpszPassword, long lnReserved ) { CCredentials NewCredentials(lpszUserName, lpszPassword, lnReserved); _Credentials = NewCredentials; RRETURN(S_OK); } STDMETHODIMP CIISApplicationPool::ADSIReleaseObject() { delete this; RRETURN(S_OK); } STDMETHODIMP CIISApplicationPool::NonDelegatingQueryInterface( REFIID iid, LPVOID FAR* ppv ) { ASSERT(ppv); if (IsEqualIID(iid, IID_IISApplicationPool)) { *ppv = (IADsUser FAR *) this; } else if (IsEqualIID(iid, IID_IADsExtension)) { *ppv = (IADsExtension FAR *) this; } else if (IsEqualIID(iid, IID_IUnknown)) { // // probably not needed since our 3rd party extension does not stand // alone and provider does not ask for this, but to be safe // *ppv = (INonDelegatingUnknown FAR *) this; } else { *ppv = NULL; return E_NOINTERFACE; } // // Delegating AddRef to aggregator for IADsExtesnion and IISApplicationPool. // AddRef on itself for IPrivateUnknown. (both tested.) // ((IUnknown *) (*ppv)) -> AddRef(); return S_OK; } // // IADsExtension::Operate() // STDMETHODIMP CIISApplicationPool::Operate( THIS_ DWORD dwCode, VARIANT varUserName, VARIANT varPassword, VARIANT varFlags ) { RRETURN(E_NOTIMPL); } HRESULT CIISApplicationPool::SetState( METADATA_HANDLE hObjHandle, DWORD dwState ) { HRESULT hr = S_OK; DWORD dwBufferSize = sizeof(DWORD); METADATA_RECORD mdrMDData; LPBYTE pBuffer = (LPBYTE)&dwState; MD_SET_DATA_RECORD(&mdrMDData, MD_APPPOOL_COMMAND, METADATA_VOLATILE, IIS_MD_UT_SERVER, DWORD_METADATA, dwBufferSize, pBuffer); hr = _pAdminBase->SetData( hObjHandle, L"", &mdrMDData ); RRETURN(hr); } STDMETHODIMP CIISApplicationPool::Start(THIS) { HRESULT hr = S_OK; METADATA_HANDLE hObjHandle = NULL; hr = OpenAdminBaseKey( _pszServerName, _pszMetaBasePath, METADATA_PERMISSION_WRITE, &_pAdminBase, &hObjHandle ); BAIL_ON_FAILURE(hr); hr = SetState(hObjHandle, MD_APPPOOL_COMMAND_START); BAIL_ON_FAILURE(hr); error: if (hObjHandle) { CloseAdminBaseKey(_pAdminBase, hObjHandle); } RRETURN(hr); } STDMETHODIMP CIISApplicationPool::Stop(THIS) { HRESULT hr = S_OK; METADATA_HANDLE hObjHandle = NULL; hr = OpenAdminBaseKey( _pszServerName, _pszMetaBasePath, METADATA_PERMISSION_WRITE, &_pAdminBase, &hObjHandle ); BAIL_ON_FAILURE(hr); hr = SetState(hObjHandle, MD_APPPOOL_COMMAND_STOP); BAIL_ON_FAILURE(hr); error: if (hObjHandle) { CloseAdminBaseKey(_pAdminBase, hObjHandle); } RRETURN(hr); } STDMETHODIMP CIISApplicationPool::Recycle(THIS) { HRESULT hr = S_OK; COSERVERINFO csiName; COSERVERINFO *pcsiParam = &csiName; IClassFactory * pcsfFactory = NULL; IIISApplicationAdmin * pAppAdmin = NULL; memset(pcsiParam, 0, sizeof(COSERVERINFO)); // // special case to handle "localhost" to work-around ole32 bug // if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) { pcsiParam->pwszName = NULL; } else { pcsiParam->pwszName = _pszServerName; } csiName.pAuthInfo = NULL; pcsiParam = &csiName; hr = CoGetClassObject( CLSID_WamAdmin, CLSCTX_SERVER, pcsiParam, IID_IClassFactory, (void**) &pcsfFactory ); BAIL_ON_FAILURE(hr); hr = pcsfFactory->CreateInstance( NULL, IID_IIISApplicationAdmin, (void **) &pAppAdmin ); BAIL_ON_FAILURE(hr); hr = pAppAdmin->RecycleApplicationPool( _pszPoolName ); BAIL_ON_FAILURE(hr); error: if (pcsfFactory) { pcsfFactory->Release(); } if (pAppAdmin) { pAppAdmin->Release(); } RRETURN(hr); } STDMETHODIMP CIISApplicationPool::EnumApps( VARIANT FAR* pvBuffer ) { HRESULT hr = S_OK; COSERVERINFO csiName; COSERVERINFO *pcsiParam = &csiName; IClassFactory * pcsfFactory = NULL; IIISApplicationAdmin * pAppAdmin = NULL; BSTR bstr = NULL; memset(pcsiParam, 0, sizeof(COSERVERINFO)); // // special case to handle "localhost" to work-around ole32 bug // if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) { pcsiParam->pwszName = NULL; } else { pcsiParam->pwszName = _pszServerName; } csiName.pAuthInfo = NULL; pcsiParam = &csiName; hr = CoGetClassObject( CLSID_WamAdmin, CLSCTX_SERVER, pcsiParam, IID_IClassFactory, (void**) &pcsfFactory ); BAIL_ON_FAILURE(hr); hr = pcsfFactory->CreateInstance( NULL, IID_IIISApplicationAdmin, (void **) &pAppAdmin ); BAIL_ON_FAILURE(hr); hr = pAppAdmin->EnumerateApplicationsInPool( _pszPoolName, &bstr ); BAIL_ON_FAILURE(hr); hr = MakeVariantFromStringArray( (LPWSTR)bstr, pvBuffer); BAIL_ON_FAILURE(hr); error: if (pcsfFactory) { pcsfFactory->Release(); } if (pAppAdmin) { pAppAdmin->Release(); } RRETURN(hr); } HRESULT CIISApplicationPool::MakeVariantFromStringArray( LPWSTR pszList, VARIANT *pvVariant ) { HRESULT hr = S_OK; SAFEARRAY *aList = NULL; SAFEARRAYBOUND aBound; LPWSTR pszStrList; WCHAR wchPath[MAX_PATH]; if (pszList != NULL) { long nCount = 0; long i = 0; pszStrList = pszList; if (*pszStrList == L'\0') { nCount = 1; pszStrList++; } while (*pszStrList != L'\0') { while (*pszStrList != L'\0') { pszStrList++; } nCount++; pszStrList++; } aBound.lLbound = 0; aBound.cElements = nCount; aList = SafeArrayCreate( VT_VARIANT, 1, &aBound ); if ( aList == NULL ) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } pszStrList = pszList; for (i = 0; i < nCount; i++ ) { VARIANT v; VariantInit(&v); V_VT(&v) = VT_BSTR; hr = ADsAllocString( pszStrList, &(V_BSTR(&v))); BAIL_ON_FAILURE(hr); hr = SafeArrayPutElement( aList, &i, &v ); VariantClear(&v); BAIL_ON_FAILURE(hr); pszStrList += wcslen(pszStrList) + 1; } VariantInit( pvVariant ); V_VT(pvVariant) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvVariant) = aList; } else { aBound.lLbound = 0; aBound.cElements = 0; aList = SafeArrayCreate( VT_VARIANT, 1, &aBound ); if ( aList == NULL ) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } VariantInit( pvVariant ); V_VT(pvVariant) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvVariant) = aList; } return S_OK; error: if ( aList ) SafeArrayDestroy( aList ); return hr; }