|
|
/*++
Copyright (c) 1994-2000 Microsoft Corporation
Module Name : app_pools.cpp
Abstract: IIS Application Pools nodes
Author: Sergei Antonov (sergeia)
Project: Internet Services Manager
Revision History: 11/03/2000 sergeia Initial creation
--*/ #include "stdafx.h"
#include "common.h"
#include "inetprop.h"
#include "InetMgrApp.h"
#include "iisobj.h"
#include "shts.h"
#include "app_sheet.h"
#include "app_pool_sheet.h"
#include "tracker.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__; #endif
#define new DEBUG_NEW
extern CPropertySheetTracker g_OpenPropertySheetTracker;
CAppPoolsContainer::CAppPoolsContainer( CIISMachine * pOwner, CIISService * pService ) : CIISMBNode(pOwner, SZ_MBN_APP_POOLS), m_pWebService(pService) { VERIFY(m_bstrDisplayName.LoadString(IDS_APP_POOLS)); }
CAppPoolsContainer::~CAppPoolsContainer() { }
/*virtual*/ HRESULT CAppPoolsContainer::RefreshData() { CError err; CComBSTR bstrPath; err = BuildMetaPath(bstrPath); err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath); if (!IsLostInterface(err)) { // reset error if an other error other than No interface
err.Reset(); } if (err.Succeeded()) { return CIISMBNode::RefreshData(); } DisplayError(err); return err; }
HRESULT CAppPoolsContainer::RefreshDataChildren(CString AppPoolToRefresh,BOOL bVerifyChildren) { IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace(); HSCOPEITEM hChildItem = NULL; LONG_PTR cookie; BOOL bMyVerifyChildren = FALSE;
HRESULT hr = pConsoleNameSpace->GetChildItem(m_hScopeItem, &hChildItem, &cookie); if (AppPoolToRefresh.IsEmpty()) { // don't verify children when they ask for *.*
bMyVerifyChildren = FALSE; } else { bMyVerifyChildren = TRUE; } if (bVerifyChildren) { bMyVerifyChildren = TRUE; } while(SUCCEEDED(hr) && hChildItem) { CAppPoolNode * pItem = (CAppPoolNode *)cookie; if (pItem) { if (pItem->IsExpanded()) { if (AppPoolToRefresh.IsEmpty()) { pItem->RefreshData(TRUE,bMyVerifyChildren); pItem->RefreshDisplay(FALSE); } else { if (0 == AppPoolToRefresh.CompareNoCase(pItem->QueryDisplayName())) { pItem->RefreshData(TRUE,bMyVerifyChildren); pItem->RefreshDisplay(FALSE); } } } } hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie); }
return hr; }
/* virtual */ HRESULT CAppPoolsContainer::EnumerateScopePane(HSCOPEITEM hParent) { CPoolList list; CError err = EnumerateAppPools(&list); if (err.Succeeded()) { POSITION pos = list.GetHeadPosition(); while (pos) { CAppPoolNode * pool = list.GetNext(pos); pool->AddRef(); err = pool->AddToScopePane(hParent); if (err.Failed()) { pool->Release(); break; } } } list.RemoveAll(); DisplayError(err); return err; }
/* virtual */ LPOLESTR CAppPoolsContainer::GetResultPaneColInfo(int nCol) { if (nCol == 0) { return QueryDisplayName(); } return OLESTR(""); }
HRESULT CAppPoolsContainer::EnumerateAppPools(CPoolList * pList) { ASSERT(pList != NULL); CString strPool; CComBSTR bstrPath; CError err; DWORD dwState; do { err = BuildMetaPath(bstrPath); err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath); BREAK_ON_ERR_FAILURE(err) CMetaKey mk(QueryInterface(), bstrPath, METADATA_PERMISSION_READ); err = mk.QueryResult(); BREAK_ON_ERR_FAILURE(err) CStringListEx list; err = mk.GetChildPaths(list); BREAK_ON_ERR_FAILURE(err) CString key_type; POSITION pos = list.GetHeadPosition(); while (err.Succeeded() && pos != NULL) { strPool = list.GetNext(pos); err = mk.QueryValue(MD_KEY_TYPE, key_type, NULL, strPool); if (err == (HRESULT)MD_ERROR_DATA_NOT_FOUND) { err.Reset(); }
err = mk.QueryValue(MD_APPPOOL_STATE, dwState, NULL, strPool); if (err == (HRESULT)MD_ERROR_DATA_NOT_FOUND) { // if not found then it's state is off..
dwState = MD_APPPOOL_STATE_STOPPED; err.Reset(); }
// Get the app pool state
if (err.Succeeded() && (key_type.CompareNoCase(_T("IIsApplicationPool")) == 0)) { CAppPoolNode * pool; if (NULL == (pool = new CAppPoolNode(m_pOwner, this, strPool, dwState))) { err = ERROR_NOT_ENOUGH_MEMORY; break; } pList->AddTail(pool); } } } while (FALSE);
return err; }
/* virtual */ void CAppPoolsContainer::InitializeChildHeaders(LPHEADERCTRL lpHeader) /*++
Routine Description: Build result view for immediate descendant type
Arguments: LPHEADERCTRL lpHeader : Header control
--*/ { CAppPoolNode::InitializeHeaders(lpHeader); }
/* virtual */ HRESULT CAppPoolsContainer::CreatePropertyPages( LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, IUnknown * pUnk, DATA_OBJECT_TYPES type ) /*++
Routine Description:
Create the property pages for the given object
Arguments:
LPPROPERTYSHEETCALLBACK lpProvider : Provider LONG_PTR handle : Handle. IUnknown * pUnk, DATA_OBJECT_TYPES type
Return Value:
HRESULT --*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CError err;
if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type))) { return S_OK; } if (ERROR_ALREADY_EXISTS == err.Win32Error()) { return S_FALSE; } if (err.Succeeded()) { CComBSTR path; err = BuildMetaPath(path); if (err.Succeeded()) { err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,path); if (err.Succeeded()) { CAppPoolSheet * pSheet = new CAppPoolSheet( QueryAuthInfo(), path, GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM)GetOwner() ); if (pSheet != NULL) { // cache handle for user in MMCPropertyChangeNotify
m_ppHandle = handle;
pSheet->SetModeless(); err = AddMMCPage(lpProvider, new CAppPoolRecycle(pSheet)); err = AddMMCPage(lpProvider, new CAppPoolPerf(pSheet)); err = AddMMCPage(lpProvider, new CAppPoolHealth(pSheet)); // err = AddMMCPage(lpProvider, new CAppPoolDebug(pSheet));
err = AddMMCPage(lpProvider, new CAppPoolIdent(pSheet)); // err = AddMMCPage(lpProvider, new CAppPoolCache(pSheet));
// err = AddMMCPage(lpProvider, new CPoolProcessOpt(pSheet));
} } } } err.MessageBoxOnFailure(); return err; }
/* virtual */ HRESULT CAppPoolsContainer::BuildMetaPath( OUT CComBSTR & bstrPath ) const /*++
Routine Description:
Recursively build up the metabase path from the current node and its parents. We cannot use CIISMBNode method because AppPools is located under w3svc, but rendered after machine.
Arguments:
CComBSTR & bstrPath : Returns metabase path
Return Value:
HRESULT
--*/ { HRESULT hr = S_OK; ASSERT(m_pWebService != NULL); hr = m_pWebService->BuildMetaPath(bstrPath);
if (SUCCEEDED(hr)) { bstrPath.Append(_cszSeparator); bstrPath.Append(QueryNodeName()); return hr; }
//
// No service node
//
ASSERT_MSG("No WebService pointer"); return E_UNEXPECTED; }
HRESULT CAppPoolsContainer::QueryDefaultPoolId(CString& id) //
// Returns pool id which is set on master node for web service
//
{ CError err; CComBSTR path; CString service;
BuildMetaPath(path); CMetabasePath::GetServicePath(path, service); CMetaKey mk(QueryAuthInfo(), service, METADATA_PERMISSION_READ); err = mk.QueryResult(); if (err.Succeeded()) { err = mk.QueryValue(MD_APP_APPPOOL_ID, id); }
return err; }
/* virtual */ HRESULT CAppPoolsContainer::AddMenuItems( IN LPCONTEXTMENUCALLBACK lpContextMenuCallback, IN OUT long * pInsertionAllowed, IN DATA_OBJECT_TYPES type ) { ASSERT_READ_PTR(lpContextMenuCallback);
//
// Add base menu items
//
HRESULT hr = CIISObject::AddMenuItems( lpContextMenuCallback, pInsertionAllowed, type );
if (SUCCEEDED(hr)) { ASSERT(pInsertionAllowed != NULL); if (IsAdministrator()) { if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0) { AddMenuSeparator(lpContextMenuCallback); AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_APP_POOL);
if (IsConfigImportExportable()) { AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_APP_POOL_FROM_FILE); } }
if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) != 0) { if (IsConfigImportExportable()) { AddMenuSeparator(lpContextMenuCallback); AddMenuItemByCommand(lpContextMenuCallback, IDM_TASK_EXPORT_CONFIG_WIZARD); } } } }
return hr; }
HRESULT CAppPoolsContainer::Command( long lCommandID, CSnapInObjectRootBase * pObj, DATA_OBJECT_TYPES type ) { HRESULT hr = S_OK; CString name;
switch (lCommandID) {
case IDM_NEW_APP_POOL: { CError err; CComBSTR bstrMetaPath;
VERIFY(SUCCEEDED(BuildMetaPath(bstrMetaPath))); err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath); if (!IsLostInterface(err)) { // reset error if an other error other than No interface
err.Reset(); } if (err.Succeeded()) { if ( SUCCEEDED(hr = AddAppPool(pObj, type, this, name)) && !name.IsEmpty() ) { hr = InsertNewPool(name); } } } break;
//
// Pass on to base class
//
default: hr = CIISMBNode::Command(lCommandID, pObj, type); }
return hr; }
HRESULT CAppPoolsContainer::InsertNewPool(CString& id) { CError err; if (!IsExpanded()) { SelectScopeItem(); IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace(); pConsoleNameSpace->Expand(QueryScopeItem()); HSCOPEITEM hChildItem = NULL; LONG_PTR cookie; HRESULT hr = pConsoleNameSpace->GetChildItem(m_hScopeItem, &hChildItem, &cookie); while(SUCCEEDED(hr) && hChildItem) { CAppPoolNode * pItem = (CAppPoolNode *)cookie; ASSERT_PTR(pItem); if (0 == id.Compare(pItem->QueryDisplayName())) { pItem->SelectScopeItem(); // set status to running when creating a new apppool
pItem->ChangeState(MD_APPPOOL_COMMAND_START); break; } hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie); } } else { // Now we should insert and select this new site
CAppPoolNode * pPool = new CAppPoolNode(m_pOwner, this, id, 0); if (pPool != NULL) { err = pPool->RefreshData(); if (err.Succeeded()) { pPool->AddRef(); err = pPool->AddToScopePaneSorted(QueryScopeItem(), FALSE); if (err.Succeeded()) { VERIFY(SUCCEEDED(pPool->SelectScopeItem())); // set status to running when creating a new apppool
pPool->ChangeState(MD_APPPOOL_COMMAND_START); } else { pPool->Release(); } } } else { err = ERROR_NOT_ENOUGH_MEMORY; } } return err; }
////////////////////////////////////////////////////////////////////////////////
// CAppPoolNode implementation
//
// App Pool Result View definition
//
/* static */ int CAppPoolNode::_rgnLabels[COL_TOTAL] = { IDS_RESULT_SERVICE_DESCRIPTION, IDS_RESULT_SERVICE_STATE, IDS_RESULT_STATUS };
/* static */ int CAppPoolNode::_rgnWidths[COL_TOTAL] = { 180, 70, 200 };
/* static */ CComBSTR CAppPoolNode::_bstrStarted; /* static */ CComBSTR CAppPoolNode::_bstrStopped; /* static */ CComBSTR CAppPoolNode::_bstrUnknown; /* static */ CComBSTR CAppPoolNode::_bstrPending; /* static */ BOOL CAppPoolNode::_fStaticsLoaded = FALSE;
CAppPoolNode::CAppPoolNode( CIISMachine * pOwner, CAppPoolsContainer * pContainer, LPCTSTR name, DWORD dwState ) : CIISMBNode(pOwner, name), m_pContainer(pContainer), m_dwWin32Error(0), m_dwState(dwState) { }
CAppPoolNode::~CAppPoolNode() { }
#if 0
// This is too expensive
BOOL CAppPoolNode::IsDeletable() const { // We could delete node if it is empty and it is not default app pool
BOOL bRes = TRUE;
CComBSTR path; CStringListEx strListOfApps; BuildMetaPath(path); CIISMBNode * that = (CIISMBNode *)this; CIISAppPool pool(that->QueryAuthInfo(), (LPCTSTR)path); HRESULT hr = pool.EnumerateApplications(strListOfApps); bRes = (SUCCEEDED(hr) && strListOfApps.GetCount() == 0); if (bRes) { CString buf; hr = m_pContainer->QueryDefaultPoolId(buf); bRes = buf.CompareNoCase(QueryNodeName()) != 0; } return bRes; } #endif
HRESULT CAppPoolNode::DeleteNode(IResultData * pResult) { CError err;
// check if they have the property sheet open on it.
if (IsMyPropertySheetOpen()) { ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET); return S_OK; }
// this could be an orphaned property sheet
// check if an orphaned property sheet is open on this item.
CIISObject * pAlreadyOpenProp = NULL; if (TRUE == g_OpenPropertySheetTracker.FindAlreadyOpenPropertySheet(this,&pAlreadyOpenProp)) { // Bring it to the foreground, and bail
HWND hHwnd = 0; if (pAlreadyOpenProp) { if (hHwnd = pAlreadyOpenProp->IsMyPropertySheetOpen()) { if (hHwnd && (hHwnd != (HWND) 1)) { // Perhapse we should cancel the already
// opened property sheet...just a thought
if (!SetForegroundWindow(hHwnd)) { // wasn't able to bring this property sheet to
// the foreground, the propertysheet must not
// exist anymore. let's just clean the hwnd
// so that the user will be able to open propertysheet
pAlreadyOpenProp->SetMyPropertySheetOpen(0); } else { ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET); return S_OK; } } } } }
CComBSTR path; BuildMetaPath(path); err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,path); if (!IsLostInterface(err)) { // reset error if an other error other than No interface
err.Reset(); } if (err.Succeeded()) { if (!NoYesMessageBox(IDS_CONFIRM_DELETE)) return err;
CIISAppPool pool(QueryAuthInfo(), (LPCTSTR)path);
err = pool.Delete(QueryNodeName());
if (err.Succeeded()) { err = RemoveScopeItem(); } if (err.Win32Error() == ERROR_NOT_EMPTY) { CString msg; msg.LoadString(IDS_ERR_NONEMPTY_APPPOOL); AfxMessageBox(msg); } else { err.MessageBoxOnFailure(); } } else { err.MessageBoxOnFailure(); }
return err; }
/* virtual */ HRESULT CAppPoolNode::BuildMetaPath(CComBSTR & bstrPath) const { HRESULT hr = S_OK; ASSERT(m_pContainer != NULL); hr = m_pContainer->BuildMetaPath(bstrPath);
if (SUCCEEDED(hr)) { bstrPath.Append(_cszSeparator); bstrPath.Append(QueryNodeName()); return hr; }
//
// No service node
//
ASSERT_MSG("No pointer to container"); return E_UNEXPECTED; }
/* virtual */ LPOLESTR CAppPoolNode::GetResultPaneColInfo( IN int nCol ) /*++
Routine Description:
Return result pane string for the given column number
Arguments:
int nCol : Column number
Return Value:
String
--*/ { switch(nCol) { case COL_DESCRIPTION: return QueryDisplayName();
case COL_STATE: switch(m_dwState) { case MD_APPPOOL_STATE_STARTED: return _bstrStarted; case MD_APPPOOL_STATE_STOPPED: return _bstrStopped; case MD_APPPOOL_STATE_STARTING: case MD_APPPOOL_STATE_STOPPING: return _bstrPending; default: return OLESTR(""); } case COL_STATUS: { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CError err(m_dwWin32Error); if (err.Succeeded()) { return OLESTR(""); } _bstrResult = err; } return _bstrResult; } ASSERT_MSG("Bad column number"); return OLESTR(""); }
/* virtual */ int CAppPoolNode::QueryImage() const { if (m_dwWin32Error != 0) { return iAppPoolErr; } else { if (m_dwState == MD_APPPOOL_STATE_STOPPED) { return iAppPoolStop; } else { return iAppPool; } } }
/* virtual */ LPOLESTR CAppPoolNode::QueryDisplayName() { if (m_strDisplayName.IsEmpty()) { RefreshData(); m_strDisplayName = QueryNodeName(); } return (LPTSTR)(LPCTSTR)m_strDisplayName; }
/* virtual */ HRESULT CAppPoolNode::RefreshData() { CError err; CComBSTR bstrPath1; CMetaKey * pKey = NULL;
do { err = BuildMetaPath(bstrPath1); if (err.Failed()) { break; }
BOOL fContinue = TRUE; while (fContinue) { fContinue = FALSE; if (NULL == (pKey = new CMetaKey(QueryInterface(), bstrPath1))) { TRACEEOLID("RefreshData: Out Of Memory"); err = ERROR_NOT_ENOUGH_MEMORY; break; }
err = pKey->QueryResult();
if (IsLostInterface(err)) { SAFE_DELETE(pKey); fContinue = OnLostInterface(err); } } if (err.Failed()) { break; }
CAppPoolProps pool(pKey, _T(""));
err = pool.LoadData(); if (err.Failed()) { break; } // Assign the data
m_dwState = pool.m_dwState; m_strDisplayName = QueryNodeName(); m_dwWin32Error = pool.m_dwWin32Error; } while(FALSE); SAFE_DELETE(pKey);
return err; }
HRESULT CAppPoolNode::RefreshData(BOOL bRefreshChildren,BOOL bMyVerifyChildren) { CError err;
// call regular refreshdata on this node...
err = RefreshData();
// -------------------------------------
// Loop thru all of our children to make
// sure they are all still jiving..
// -------------------------------------
if (bRefreshChildren) { CComBSTR bstrPath1; POSITION pos1 = NULL; CApplicationList MyMMCList; CApplicationNode * pItemFromMMC = NULL;
// create a list of what is in mmc...
MyMMCList.RemoveAll();
HSCOPEITEM hChild = NULL, hCurrent; LONG_PTR cookie = 0; IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace(); err = pConsoleNameSpace->GetChildItem(QueryScopeItem(), &hChild, &cookie); while (err.Succeeded() && hChild != NULL) { CIISMBNode * pNode = (CIISMBNode *)cookie; if (pNode) { if (IsEqualGUID(* (GUID *)pNode->GetNodeType(),cApplicationNode)) { CApplicationNode * pNode2 = (CApplicationNode *) pNode; if (pNode2) { // clean the displayname, it could have changed..
// and this could be the real reason for the refresh...
pNode2->QueryDisplayName(TRUE); MyMMCList.AddTail(pNode2); } } } hCurrent = hChild; err = pConsoleNameSpace->GetNextItem(hCurrent, &hChild, &cookie); }
// Loop thru and see if we need to add anything
CStringListEx strListOfApps; BuildMetaPath(bstrPath1); CIISAppPool pool(QueryAuthInfo(), (LPCTSTR)bstrPath1); err = pool.EnumerateApplications(strListOfApps); if (err.Succeeded() && strListOfApps.GetCount() > 0) { POSITION pos2 = NULL; DWORD iNumApp = 0; CString strAppInMetabase; CString strAppInMetabaseName; pos1 = strListOfApps.GetHeadPosition(); while ( pos1 != NULL) { BOOL bExistsInUI = FALSE; strAppInMetabase = strListOfApps.GetNext(pos1);
iNumApp = CMetabasePath::GetInstanceNumber(strAppInMetabase); if (iNumApp > 0) { CMetabasePath::CleanMetaPath(strAppInMetabase); CMetabasePath::GetLastNodeName(strAppInMetabase, strAppInMetabaseName);
// Check if this item is in the list...
// Loop through our list
// and see if we need to add anything
pos2 = MyMMCList.GetHeadPosition(); while (pos2) { pItemFromMMC = MyMMCList.GetNext(pos2); if (pItemFromMMC) { CComBSTR bstrPath2; err = pItemFromMMC->BuildMetaPath(bstrPath2); CString csAppID = bstrPath2; CMetabasePath::CleanMetaPath(csAppID);
if (0 == csAppID.CompareNoCase(strAppInMetabase)) { bExistsInUI = TRUE; break; } } }
if (!bExistsInUI) { TRACEEOL(strAppInMetabase << ", not exist but should, adding to UI..."); CApplicationNode * app_node = new CApplicationNode(GetOwner(), strAppInMetabase, strAppInMetabaseName); if (app_node != NULL) { app_node->AddRef(); app_node->AddToScopePane(m_hScopeItem, TRUE, TRUE, FALSE); } } } } }
// Loop through our list and find stuff we want to delete
BuildMetaPath(bstrPath1); pos1 = MyMMCList.GetHeadPosition(); BOOL bMarkedForDelete = FALSE; while (pos1) { pItemFromMMC = MyMMCList.GetNext(pos1); bMarkedForDelete = FALSE; // see if it exists in the metabase,
// if it doesn't then add it to the delete list...
if (pItemFromMMC) { CComBSTR bstrPath3; pItemFromMMC->BuildMetaPath(bstrPath3);
// check if path exists...
CMetaKey mk(QueryInterface(), bstrPath3); if (!mk.Succeeded()) { // delete it
bMarkedForDelete = TRUE; } else { // doesn't need to be removed...
// put perhase it does..
// check if this Application is actually being used
// by the site!
if (bMyVerifyChildren) { // Lookup that website
// and get it's App that it's using
// see if it's the same as this AppID (BuildMetaPath(bstrPath1);)
err = mk.QueryResult(); if (err.Succeeded()) { CString csAppID = bstrPath1; CString csAppIDName; CMetabasePath::CleanMetaPath(csAppID); CMetabasePath::GetLastNodeName(csAppID, csAppIDName);
CString id; err = mk.QueryValue(MD_APP_APPPOOL_ID, id); err = mk.QueryResult(); if (err.Succeeded()) { if (0 != csAppIDName.CompareNoCase(id)) { // the web site, isn't actually using it..
// delete it
bMarkedForDelete = TRUE; } } } } }
if (bMarkedForDelete) { // delete it list...
TRACEEOL(bstrPath3 << ", not exist, removing from UI..."); // remove it from the UI
pItemFromMMC->RemoveScopeItem(); // delete the object
pItemFromMMC->Release(); } } } } return err; }
/* virtual */ int CAppPoolNode::CompareResultPaneItem( CIISObject * pObject, int nCol ) /*++
Routine Description:
Compare two CIISObjects on sort item criteria
Arguments:
CIISObject * pObject : Object to compare against int nCol : Column number to sort on
Return Value:
0 if the two objects are identical <0 if this object is less than pObject >0 if this object is greater than pObject
--*/ { ASSERT_READ_PTR(pObject);
if (nCol == 0) { return CompareScopeItem(pObject); }
//
// First criteria is object type
//
int n1 = QuerySortWeight(); int n2 = pObject->QuerySortWeight();
if (n1 != n2) { return n1 - n2; }
//
// Both are CAppPoolNode objects
//
CAppPoolNode * pPool = (CAppPoolNode *)pObject;
switch(nCol) { case COL_DESCRIPTION: case COL_STATE: default: //
// Lexical sort
//
return ::lstrcmpi( GetResultPaneColInfo(nCol), pObject->GetResultPaneColInfo(nCol) ); } }
/* virtual */ void CAppPoolNode::InitializeChildHeaders(LPHEADERCTRL lpHeader) /*++
Routine Description: Build result view for immediate descendant type
Arguments: LPHEADERCTRL lpHeader : Header control
--*/ { CApplicationNode::InitializeHeaders(lpHeader); }
/* static */ void CAppPoolNode::InitializeHeaders(LPHEADERCTRL lpHeader) /*++
Routine Description: Initialize the result headers
Arguments: LPHEADERCTRL lpHeader : Header control
--*/ { CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths); if (!_fStaticsLoaded) { _fStaticsLoaded = _bstrStarted.LoadString(IDS_STARTED) && _bstrStopped.LoadString(IDS_STOPPED) && _bstrUnknown.LoadString(IDS_UNKNOWN) && _bstrPending.LoadString(IDS_PENDING); } }
/* virtual */ HRESULT CAppPoolNode::EnumerateScopePane( IN HSCOPEITEM hParent ) /*++
Routine Description:
Enumerate scope child items.
Arguments:
HSCOPEITEM hParent : Parent console handle
Return Value:
HRESULT
--*/ { CError err; do { CComBSTR path; BuildMetaPath(path); err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,path); BREAK_ON_ERR_FAILURE(err)
CIISAppPool pool(QueryAuthInfo(), path); if (pool.Succeeded()) { CStringListEx strListOfApps;
err = pool.EnumerateApplications(strListOfApps); if (err.Succeeded() && strListOfApps.GetCount() > 0) { POSITION pos = strListOfApps.GetHeadPosition(); while ( pos != NULL) { CString app = strListOfApps.GetNext(pos); DWORD i = CMetabasePath::GetInstanceNumber(app); if (i > 0) { CString name; CMetabasePath::CleanMetaPath(app); CMetabasePath::GetLastNodeName(app, name); CApplicationNode * app_node = new CApplicationNode( GetOwner(), app, name); if (app_node != NULL) { app_node->AddRef(); app_node->AddToScopePane(m_hScopeItem, TRUE, TRUE, FALSE); } else { err = ERROR_NOT_ENOUGH_MEMORY; } } } } } } while (FALSE); return err; }
/* virtual */ HRESULT CAppPoolNode::CreatePropertyPages( LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, IUnknown * pUnk, DATA_OBJECT_TYPES type ) /*++
Routine Description:
Create the property pages for the given object
Arguments:
LPPROPERTYSHEETCALLBACK lpProvider : Provider LONG_PTR handle : Handle. IUnknown * pUnk, DATA_OBJECT_TYPES type
Return Value:
HRESULT --*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CError err;
if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type))) { return S_OK; } if (ERROR_ALREADY_EXISTS == err.Win32Error()) { return S_FALSE; } if (err.Succeeded()) { CComBSTR path; err = BuildMetaPath(path); if (err.Succeeded()) { err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,path); if (err.Succeeded()) { CAppPoolSheet * pSheet = new CAppPoolSheet( QueryAuthInfo(), path, GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM) m_pContainer ); if (pSheet != NULL) { // cache handle for user in MMCPropertyChangeNotify
m_ppHandle = handle;
pSheet->SetModeless(); err = AddMMCPage(lpProvider, new CAppPoolRecycle(pSheet)); err = AddMMCPage(lpProvider, new CAppPoolPerf(pSheet)); err = AddMMCPage(lpProvider, new CAppPoolHealth(pSheet)); // err = AddMMCPage(lpProvider, new CAppPoolDebug(pSheet));
err = AddMMCPage(lpProvider, new CAppPoolIdent(pSheet)); // err = AddMMCPage(lpProvider, new CAppPoolCache(pSheet));
// err = AddMMCPage(lpProvider, new CPoolProcessOpt(pSheet));
} } } } err.MessageBoxOnFailure(); return err; }
/* virtual */ HRESULT CAppPoolNode::AddMenuItems( IN LPCONTEXTMENUCALLBACK lpContextMenuCallback, IN OUT long * pInsertionAllowed, IN DATA_OBJECT_TYPES type ) { ASSERT_READ_PTR(lpContextMenuCallback);
//
// Add base menu items
//
HRESULT hr = CIISObject::AddMenuItems( lpContextMenuCallback, pInsertionAllowed, type );
ASSERT(pInsertionAllowed != NULL); if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) != 0) { AddMenuSeparator(lpContextMenuCallback); AddMenuItemByCommand(lpContextMenuCallback, IDM_START, IsStartable() ? 0 : MF_GRAYED); AddMenuItemByCommand(lpContextMenuCallback, IDM_STOP, IsStoppable() ? 0 : MF_GRAYED); AddMenuItemByCommand(lpContextMenuCallback, IDM_RECYCLE, IsRunning() ? 0 : MF_GRAYED); } if (SUCCEEDED(hr)) { ASSERT(pInsertionAllowed != NULL); if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0) { AddMenuSeparator(lpContextMenuCallback); AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_APP_POOL);
if (IsConfigImportExportable()) { AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_APP_POOL_FROM_FILE); } }
if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) != 0) { if (IsConfigImportExportable()) { AddMenuSeparator(lpContextMenuCallback); AddMenuItemByCommand(lpContextMenuCallback, IDM_TASK_EXPORT_CONFIG_WIZARD); } } }
return hr; }
/* virtual */ HRESULT CAppPoolNode::Command( IN long lCommandID, IN CSnapInObjectRootBase * pObj, IN DATA_OBJECT_TYPES type ) /*++
Routine Description:
Handle command from context menu.
Arguments:
long lCommandID : Command ID CSnapInObjectRootBase * pObj : Base object DATA_OBJECT_TYPES type : Data object type
Return Value:
HRESULT
--*/ { HRESULT hr = S_OK; CString name; DWORD command = 0; CError err; CComBSTR bstrMetaPath; BOOL bNeedMetabase = FALSE; BOOL bHaveMetabase = FALSE;
switch (lCommandID) { case IDM_NEW_APP_POOL: case IDM_START: case IDM_STOP: case IDM_RECYCLE: bNeedMetabase = TRUE; break; default: bNeedMetabase = FALSE; }
if (bNeedMetabase) { // WARNING:bstrMetaPath will be used by switch statement below
VERIFY(SUCCEEDED(BuildMetaPath(bstrMetaPath))); err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath); if (!IsLostInterface(err)) { // reset error if an other error other than No interface
err.Reset(); } if (err.Succeeded()) { bHaveMetabase = TRUE; } }
switch (lCommandID) {
case IDM_NEW_APP_POOL: if (bHaveMetabase) { if (SUCCEEDED(hr = AddAppPool(pObj, type, m_pContainer, name)) && !name.IsEmpty()) { hr = m_pContainer->InsertNewPool(name); } } break;
case IDM_START: if (bHaveMetabase) { command = MD_APPPOOL_COMMAND_START; } break;
case IDM_STOP: if (bHaveMetabase) { command = MD_APPPOOL_COMMAND_STOP; } break;
case IDM_RECYCLE: { if (bHaveMetabase) { CIISAppPool pool(QueryAuthInfo(), (LPCTSTR)bstrMetaPath); err = pool.Recycle(QueryNodeName()); hr = err; } break; } //
// Pass on to base class
//
default: hr = CIISMBNode::Command(lCommandID, pObj, type); }
if (command != 0) { hr = ChangeState(command); }
return hr; }
HRESULT CAppPoolNode::ChangeState(DWORD dwCommand) /*++
Routine Description: Change the state of this instance (started/stopped/paused)
Arguments: DWORD dwCommand : MD_SERVER_COMMAND_START, etc.
Return Value: HRESULT
--*/ { CError err; CComBSTR bstrPath;
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); do { CWaitCursor wait;
err = BuildMetaPath(bstrPath);
CAppPoolProps prop(QueryAuthInfo(), bstrPath);
err = prop.LoadData(); BREAK_ON_ERR_FAILURE(err)
err = prop.ChangeState(dwCommand); BREAK_ON_ERR_FAILURE(err)
err = RefreshData(); if (err.Succeeded()) { err = RefreshDisplay(); } } while(FALSE);
err.MessageBoxOnFailure();
return err; }
////////////////////////////////////////////////////////////////////////
/* static */ int CApplicationNode::_rgnLabels[COL_TOTAL] = { IDS_RESULT_SERVICE_DESCRIPTION, IDS_RESULT_PATH, };
/* static */ int CApplicationNode::_rgnWidths[COL_TOTAL] = { 180, 200, };
/* static */ void CApplicationNode::InitializeHeaders(LPHEADERCTRL lpHeader) /*++
Routine Description: Initialize the result headers
Arguments: LPHEADERCTRL lpHeader : Header control
--*/ { CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths); }
LPOLESTR CApplicationNode::QueryDisplayName() /*++
Routine Description:
Return primary display name of this site. Arguments:
None
Return Value:
The display name
--*/ { return QueryDisplayName(FALSE); }
LPOLESTR CApplicationNode::QueryDisplayName(BOOL bForceQuery) { if (m_strDisplayName.IsEmpty() || bForceQuery) { CMetaKey mk(QueryInterface(), m_meta_path, METADATA_PERMISSION_READ); if (mk.Succeeded()) { mk.QueryValue(MD_APP_FRIENDLY_NAME, m_strDisplayName); if (m_strDisplayName.IsEmpty()) { m_strDisplayName = QueryNodeName(); } } } return (LPTSTR)(LPCTSTR)m_strDisplayName; }
HRESULT CApplicationNode::BuildMetaPath(CComBSTR& path) const { path = m_meta_path; return S_OK; }
LPOLESTR CApplicationNode::GetResultPaneColInfo( IN int nCol ) /*++
Routine Description:
Return result pane string for the given column number
Arguments:
int nCol : Column number
Return Value:
String
--*/ { switch(nCol) { case COL_ALIAS: return QueryDisplayName();
case COL_PATH: { CString buf; return (LPTSTR)(LPCTSTR)FriendlyAppRoot(m_meta_path, buf); } }
ASSERT_MSG("Bad column number");
return OLESTR(""); }
LPCTSTR CApplicationNode::FriendlyAppRoot( LPCTSTR lpAppRoot, CString & strFriendly ) /*++
Routine Description:
Convert the metabase app root path to a friendly display name format.
Arguments:
LPCTSTR lpAppRoot : App root CString & strFriendly : Output friendly app root format
Return Value:
Reference to the output string
Notes:
App root must have been cleaned from WAM format prior to calling this function (see first ASSERT below)
--*/ { if (lpAppRoot != NULL && *lpAppRoot != 0) { //
// Make sure we cleaned up WAM format
//
ASSERT(*lpAppRoot != _T('/')); strFriendly.Empty();
CInstanceProps prop(QueryAuthInfo(), lpAppRoot); HRESULT hr = prop.LoadData();
if (SUCCEEDED(hr)) { CString root, tail; strFriendly.Format(_T("<%s>"), prop.GetDisplayText(root)); CMetabasePath::GetRootPath(lpAppRoot, root, &tail); if (!tail.IsEmpty()) { //
// Add rest of dir path
//
strFriendly += _T("/"); strFriendly += tail; }
//
// Now change forward slashes in the path to backward slashes
//
// CvtPathToDosStyle(strFriendly);
return strFriendly; } } //
// Bogus
//
VERIFY(strFriendly.LoadString(IDS_APPROOT_UNKNOWN));
return strFriendly; } //////////////////////////////////////////////////////////////////////////
|