1125 lines
22 KiB
C++
1125 lines
22 KiB
C++
/*++
|
|
|
|
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_pool_sheet.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
#define new DEBUG_NEW
|
|
|
|
CAppPoolsContainer::CAppPoolsContainer(
|
|
CIISMachine * pOwner,
|
|
CIISService * pService
|
|
)
|
|
: CIISMBNode(pOwner, SZ_MBN_APP_POOLS),
|
|
m_pWebService(pService)
|
|
{
|
|
VERIFY(m_bstrDisplayName.LoadString(IDS_APP_POOLS));
|
|
}
|
|
|
|
CAppPoolsContainer::~CAppPoolsContainer()
|
|
{
|
|
}
|
|
|
|
/* static */ int
|
|
CAppPoolsContainer::_rgnLabels[COL_TOTAL] =
|
|
{
|
|
IDS_RESULT_SERVICE_DESCRIPTION,
|
|
IDS_RESULT_SERVICE_STATE,
|
|
};
|
|
|
|
|
|
/* static */ int
|
|
CAppPoolsContainer::_rgnWidths[COL_TOTAL] =
|
|
{
|
|
180,
|
|
70,
|
|
};
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CAppPoolsContainer::EnumerateScopePane(HSCOPEITEM hParent)
|
|
{
|
|
CError err;
|
|
CMetaEnumerator * pme = NULL;
|
|
CString strPool;
|
|
|
|
err = CreateEnumerator(pme);
|
|
|
|
while (err.Succeeded())
|
|
{
|
|
CAppPoolNode * pPool;
|
|
|
|
err = pme->Next(strPool);
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
TRACEEOLID("Enumerating node: " << strPool);
|
|
CString key_type;
|
|
CMetabasePath path(FALSE, pme->QueryMetaPath(), strPool);
|
|
CMetaKey mk(pme, path);
|
|
mk.QueryValue(MD_KEY_TYPE, key_type);
|
|
if (mk.Succeeded() && 0 == key_type.CompareNoCase(_T("IIsApplicationPool")))
|
|
{
|
|
if (NULL == (pPool = new CAppPoolNode(m_pOwner, this, strPool)))
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
err = pPool->AddToScopePane(hParent);
|
|
}
|
|
}
|
|
}
|
|
|
|
SAFE_DELETE(pme);
|
|
|
|
if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
err.Reset();
|
|
}
|
|
|
|
if (err.Failed())
|
|
{
|
|
DisplayError(err);
|
|
}
|
|
|
|
SetInterfaceError(err);
|
|
|
|
return err;
|
|
}
|
|
|
|
HRESULT
|
|
CAppPoolsContainer::EnumerateAppPools(CPoolList * pList)
|
|
{
|
|
CError err;
|
|
CMetaEnumerator * pme = NULL;
|
|
CString strPool;
|
|
|
|
err = CreateEnumerator(pme);
|
|
|
|
while (err.Succeeded())
|
|
{
|
|
err = pme->Next(strPool);
|
|
if (err.Succeeded())
|
|
{
|
|
CString key_type;
|
|
CMetabasePath path(FALSE, pme->QueryMetaPath(), strPool);
|
|
CMetaKey mk(pme, path);
|
|
mk.QueryValue(MD_KEY_TYPE, key_type);
|
|
if (mk.Succeeded() && 0 == key_type.CompareNoCase(_T("IIsApplicationPool")))
|
|
{
|
|
CAppPoolNode * pPool;
|
|
if (NULL == (pPool = new CAppPoolNode(m_pOwner, this, strPool)))
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
pList->AddTail(pPool);
|
|
}
|
|
}
|
|
}
|
|
SAFE_DELETE(pme);
|
|
|
|
if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
err.Reset();
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
/* virtual */
|
|
void
|
|
CAppPoolsContainer::InitializeChildHeaders(
|
|
IN LPHEADERCTRL lpHeader
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build result view for immediate descendant type
|
|
|
|
Arguments:
|
|
|
|
LPHEADERCTRL lpHeader : Header control
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths);
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CAppPoolsContainer::CreatePropertyPages(
|
|
IN LPPROPERTYSHEETCALLBACK lpProvider,
|
|
IN LONG_PTR handle,
|
|
IN IUnknown * pUnk,
|
|
IN 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;
|
|
CComBSTR path;
|
|
|
|
err = BuildMetaPath(path);
|
|
if (err.Failed())
|
|
return err;
|
|
|
|
CAppPoolSheet * pSheet = new CAppPoolSheet(
|
|
QueryAuthInfo(), path, GetMainWindow(), (LPARAM)this, handle
|
|
);
|
|
|
|
if (pSheet != NULL)
|
|
{
|
|
pSheet->SetModeless();
|
|
// err = AddMMCPage(lpProvider, new CAppPoolGeneral(pSheet));
|
|
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));
|
|
}
|
|
|
|
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() && (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
|
|
{
|
|
AddMenuSeparator(lpContextMenuCallback);
|
|
AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_APP_POOL);
|
|
}
|
|
}
|
|
|
|
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:
|
|
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;
|
|
// Now we should insert and select this new site
|
|
CAppPoolNode * pPool = new CAppPoolNode(m_pOwner, this, id);
|
|
if (pPool != NULL)
|
|
{
|
|
err = pPool->RefreshData();
|
|
if (err.Succeeded())
|
|
{
|
|
// If item is not expanded we will get error and no effect
|
|
if (!IsExpanded())
|
|
{
|
|
SelectScopeItem();
|
|
IConsoleNameSpace2 * pConsole
|
|
= (IConsoleNameSpace2 *)GetConsoleNameSpace();
|
|
pConsole->Expand(QueryScopeItem());
|
|
}
|
|
err = pPool->AddToScopePaneSorted(QueryScopeItem(), FALSE);
|
|
if (err.Succeeded())
|
|
{
|
|
VERIFY(SUCCEEDED(pPool->SelectScopeItem()));
|
|
}
|
|
}
|
|
}
|
|
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_PATH,
|
|
};
|
|
|
|
|
|
/* static */ int
|
|
CAppPoolNode::_rgnWidths[COL_TOTAL] =
|
|
{
|
|
180,
|
|
200,
|
|
};
|
|
|
|
CAppPoolNode::CAppPoolNode(
|
|
CIISMachine * pOwner,
|
|
CAppPoolsContainer * pContainer,
|
|
LPCTSTR name
|
|
)
|
|
: CIISMBNode(pOwner, name),
|
|
m_pContainer(pContainer)
|
|
{
|
|
}
|
|
|
|
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 apps;
|
|
BuildMetaPath(path);
|
|
CIISMBNode * that = (CIISMBNode *)this;
|
|
CIISAppPool pool(that->QueryAuthInfo(), (LPCTSTR)path);
|
|
HRESULT hr = pool.EnumerateApplications(apps);
|
|
bRes = (SUCCEEDED(hr) && apps.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;
|
|
CComBSTR path;
|
|
BuildMetaPath(path);
|
|
CIISAppPool pool(QueryAuthInfo(), (LPCTSTR)path);
|
|
|
|
err = pool.Delete(GetNodeName());
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
err = RemoveScopeItem();
|
|
}
|
|
if (err.Win32Error() == ERROR_NOT_EMPTY)
|
|
{
|
|
CString msg;
|
|
msg.LoadString(IDS_ERR_NONEMPTY_APPPOOL);
|
|
AfxMessageBox(msg);
|
|
}
|
|
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:
|
|
return OLESTR("");
|
|
}
|
|
|
|
ASSERT_MSG("Bad column number");
|
|
|
|
return OLESTR("");
|
|
}
|
|
|
|
/* virtual */
|
|
int
|
|
CAppPoolNode::QueryImage() const
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return bitmap index for the site
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
Bitmap index
|
|
|
|
--*/
|
|
{
|
|
return iFolder;
|
|
}
|
|
|
|
/* virtual */
|
|
LPOLESTR
|
|
CAppPoolNode::QueryDisplayName()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return primary display name of this site.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
The display name
|
|
|
|
--*/
|
|
{
|
|
if (m_strDisplayName.IsEmpty())
|
|
{
|
|
CComBSTR path;
|
|
BuildMetaPath(path);
|
|
CMetaKey mk(QueryInterface(), path);
|
|
if (mk.Succeeded())
|
|
{
|
|
mk.QueryValue(MD_APPPOOL_FRIENDLY_NAME, m_strDisplayName);
|
|
}
|
|
}
|
|
return (LPTSTR)(LPCTSTR)m_strDisplayName;
|
|
}
|
|
|
|
/*virtual*/
|
|
HRESULT
|
|
CAppPoolNode::RenameItem(LPOLESTR new_name)
|
|
{
|
|
CComBSTR path;
|
|
CError err;
|
|
if (new_name != NULL && lstrlen(new_name) > 0)
|
|
{
|
|
BuildMetaPath(path);
|
|
|
|
CMetaKey mk(QueryInterface(), path, METADATA_PERMISSION_WRITE);
|
|
|
|
CError err(mk.QueryResult());
|
|
if (err.Succeeded())
|
|
{
|
|
err = mk.SetValue(MD_APPPOOL_FRIENDLY_NAME, CString(new_name));
|
|
if (err.Succeeded())
|
|
{
|
|
m_strDisplayName = new_name;
|
|
}
|
|
}
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CAppPoolNode::RefreshData()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Refresh relevant configuration data required for display.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
CError err;
|
|
// CWaitCursor wait;
|
|
CComBSTR path;
|
|
CMetaKey * pKey = NULL;
|
|
|
|
do
|
|
{
|
|
ASSERT_PTR(_lpConsoleNameSpace);
|
|
err = BuildMetaPath(path);
|
|
if (err.Failed())
|
|
{
|
|
break;
|
|
}
|
|
|
|
BOOL fContinue = TRUE;
|
|
|
|
while (fContinue)
|
|
{
|
|
fContinue = FALSE;
|
|
if (NULL == (pKey = new CMetaKey(QueryInterface(), path)))
|
|
{
|
|
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
|
|
|
|
}
|
|
while(FALSE);
|
|
|
|
SAFE_DELETE(pKey);
|
|
|
|
return err;
|
|
}
|
|
|
|
/* virtual */
|
|
int
|
|
CAppPoolNode::CompareResultPaneItem(
|
|
IN CIISObject * pObject,
|
|
IN 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(
|
|
IN LPHEADERCTRL lpHeader
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build result view for immediate descendant type
|
|
|
|
Arguments:
|
|
|
|
LPHEADERCTRL lpHeader : Header control
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths);
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CAppPoolNode::EnumerateScopePane(
|
|
IN HSCOPEITEM hParent
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerate scope child items.
|
|
|
|
Arguments:
|
|
|
|
HSCOPEITEM hParent : Parent console handle
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComBSTR path;
|
|
BuildMetaPath(path);
|
|
CIISAppPool pool(QueryAuthInfo(), path);
|
|
|
|
if (pool.Succeeded())
|
|
{
|
|
CStringListEx apps;
|
|
|
|
hr = pool.EnumerateApplications(apps);
|
|
if (SUCCEEDED(hr) && apps.GetCount() > 0)
|
|
{
|
|
POSITION pos = apps.GetHeadPosition();
|
|
while ( pos != NULL)
|
|
{
|
|
CString app = apps.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->AddToScopePane(m_hScopeItem, TRUE, TRUE, FALSE);
|
|
}
|
|
else
|
|
hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CAppPoolNode::CreatePropertyPages(
|
|
IN LPPROPERTYSHEETCALLBACK lpProvider,
|
|
IN LONG_PTR handle,
|
|
IN IUnknown * pUnk,
|
|
IN 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());
|
|
|
|
CComBSTR path;
|
|
|
|
CError err(BuildMetaPath(path));
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
CAppPoolSheet * pSheet = new CAppPoolSheet(
|
|
QueryAuthInfo(), path, GetMainWindow(), (LPARAM)this, handle
|
|
);
|
|
|
|
if (pSheet != NULL)
|
|
{
|
|
pSheet->SetModeless();
|
|
// err = AddMMCPage(lpProvider, new CAppPoolGeneral(pSheet));
|
|
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.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
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ASSERT(pInsertionAllowed != NULL);
|
|
if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
|
|
{
|
|
AddMenuSeparator(lpContextMenuCallback);
|
|
AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_APP_POOL);
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
switch (lCommandID)
|
|
{
|
|
case IDM_NEW_APP_POOL:
|
|
if ( SUCCEEDED(hr = AddAppPool(pObj, type, m_pContainer, name))
|
|
&& !name.IsEmpty()
|
|
)
|
|
{
|
|
hr = m_pContainer->InsertNewPool(name);
|
|
}
|
|
break;
|
|
|
|
//
|
|
// Pass on to base class
|
|
//
|
|
default:
|
|
hr = CIISMBNode::Command(lCommandID, pObj, type);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
LPOLESTR
|
|
CApplicationNode::QueryDisplayName()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return primary display name of this site.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
The display name
|
|
|
|
--*/
|
|
{
|
|
if (m_strDisplayName.IsEmpty())
|
|
{
|
|
CMetaKey mk(QueryInterface(), m_meta_path);
|
|
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;
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|