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.
1667 lines
41 KiB
1667 lines
41 KiB
/*++
|
|
|
|
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;
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|