2290 lines
59 KiB
C++
2290 lines
59 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
AcsHand.cpp
|
|
Root node information (the root node is not displayed
|
|
in the MMC framework but contains information such as
|
|
all of the subnodes in this snapin).
|
|
|
|
FILE HISTORY:
|
|
11/05/97 Wei Jiang Created
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include <secext.h>
|
|
#include <objsel.h>
|
|
#include "acs.h"
|
|
#include "acshand.h"
|
|
#include "util.h"
|
|
#include "statsdlg.h"
|
|
#include "modeless.h"
|
|
|
|
#include "resource.h"
|
|
#include "helper.h"
|
|
#include "proppage.h"
|
|
#include "acsadmin.h"
|
|
#include "resource.h"
|
|
#include "acscomp.h"
|
|
#include "acsdata.h"
|
|
#include "newsub.h"
|
|
#include "pggen.h"
|
|
#include "pgsrvs.h"
|
|
#include "pgsbm.h"
|
|
#include "pglog.h"
|
|
|
|
// property pages
|
|
#include "pgpolicy.h" // traffic page for ACSPolicy
|
|
|
|
#include "ncglobal.h" // network console global defines
|
|
|
|
// const TCHAR g_szDefaultHelpTopic[] = _T("\\help\\QOSConcepts.chm::/acs_usingTN.htm");
|
|
const TCHAR g_szDefaultHelpTopic[] = _T("\\help\\QOSconcepts.chm::/sag_ACStopnode.htm");
|
|
|
|
UINT g_col_strid_name[] = {IDS_NAME, 0};
|
|
int g_col_width_name[] = {200, AUTO_WIDTH};
|
|
|
|
UINT g_col_strid_name_type[] = {IDS_NAME, IDS_TYPE, 0};
|
|
int g_col_width_name_type[] = {200, 75, AUTO_WIDTH};
|
|
|
|
UINT g_col_strid_name_type_desc[] = {IDS_NAME, IDS_TYPE, IDS_DESC, 0};
|
|
int g_col_width_name_type_desc[] = {200, 75, 250, AUTO_WIDTH};
|
|
|
|
UINT g_col_strid_policy[] = {IDS_COL_POLICY_APPLIES_TO, IDS_COL_POLICY_DIRECTION, IDS_COL_POLICY_SERVICE_LEVEL, IDS_COL_POLICY_DATARATE, IDS_COL_POLICY_PEAKRATE, 0};
|
|
int g_col_width_policy[] = {150, 100, 100, 50, 50, AUTO_WIDTH};
|
|
const UINT g_col_count_policy = sizeof(g_col_strid_policy)/sizeof(UINT) - 1;
|
|
|
|
// the date rate and peak rate do not make sense any more, since they are related to service type
|
|
//UINT g_col_strid_subnet[] = {IDS_COL_SUBNET_NAME, IDS_COL_SUBNET_DESC, IDS_COL_SUBNET_DATARATE, IDS_COL_SUBNET_PEAKRATE, 0};
|
|
//int g_col_width_subnet[] = {120, 150, 50, 50, AUTO_WIDTH};
|
|
UINT g_col_strid_subnet[] = {IDS_COL_SUBNET_NAME, IDS_COL_SUBNET_DESC, 0};
|
|
int g_col_width_subnet[] = {120, 150, AUTO_WIDTH};
|
|
const UINT g_col_count_subnet = sizeof(g_col_strid_subnet)/sizeof(UINT) - 1;
|
|
|
|
|
|
// keep a public map of MMC verbs
|
|
const MMC_CONSOLE_VERB g_mmc_verbs[ACS_TOTAL_MMC_VERBS] =
|
|
{
|
|
MMC_VERB_OPEN,
|
|
MMC_VERB_COPY,
|
|
MMC_VERB_PASTE,
|
|
MMC_VERB_DELETE,
|
|
MMC_VERB_PROPERTIES,
|
|
MMC_VERB_RENAME,
|
|
MMC_VERB_REFRESH,
|
|
MMC_VERB_PRINT
|
|
};
|
|
|
|
// verb state with no new menu, no property page
|
|
MMC_BUTTON_STATE g_verbs_all_hiden[ACS_TOTAL_MMC_VERBS] =
|
|
{
|
|
HIDDEN, // MMC_VERB_OPEN,
|
|
HIDDEN, // MMC_VERB_COPY,
|
|
HIDDEN, // MMC_VERB_PASTE,
|
|
HIDDEN, // MMC_VERB_DELETE,
|
|
HIDDEN, // MMC_VERB_PROPERTIES,
|
|
HIDDEN, // MMC_VERB_RENAME,
|
|
HIDDEN, // MMC_VERB_REFRESH,
|
|
HIDDEN // MMC_VERB_PRINT
|
|
};
|
|
|
|
// verb state with property page, delete, rename enabled
|
|
MMC_BUTTON_STATE g_verbs_property_delete[ACS_TOTAL_MMC_VERBS] =
|
|
{
|
|
HIDDEN, // MMC_VERB_OPEN,
|
|
HIDDEN, // MMC_VERB_COPY,
|
|
HIDDEN, // MMC_VERB_PASTE,
|
|
ENABLED, // MMC_VERB_DELETE,
|
|
ENABLED, // MMC_VERB_PROPERTIES,
|
|
HIDDEN, // MMC_VERB_RENAME,
|
|
HIDDEN, // MMC_VERB_REFRESH,
|
|
HIDDEN // MMC_VERB_PRINT
|
|
};
|
|
|
|
|
|
// Container with no property
|
|
MMC_BUTTON_STATE g_verbs_property_refresh[ACS_TOTAL_MMC_VERBS] =
|
|
{
|
|
HIDDEN, // MMC_VERB_OPEN,
|
|
HIDDEN, // MMC_VERB_COPY,
|
|
HIDDEN, // MMC_VERB_PASTE,
|
|
HIDDEN, // MMC_VERB_DELETE,
|
|
ENABLED, // MMC_VERB_PROPERTIES,
|
|
HIDDEN, // MMC_VERB_RENAME,
|
|
ENABLED, // MMC_VERB_REFRESH,
|
|
HIDDEN // MMC_VERB_PRINT
|
|
};
|
|
|
|
// Container with property
|
|
MMC_BUTTON_STATE g_verbs_refresh[ACS_TOTAL_MMC_VERBS] =
|
|
{
|
|
HIDDEN, // MMC_VERB_OPEN,
|
|
HIDDEN, // MMC_VERB_COPY,
|
|
HIDDEN, // MMC_VERB_PASTE,
|
|
HIDDEN, // MMC_VERB_DELETE,
|
|
HIDDEN, // MMC_VERB_PROPERTIES,
|
|
HIDDEN, // MMC_VERB_RENAME,
|
|
ENABLED, // MMC_VERB_REFRESH,
|
|
HIDDEN // MMC_VERB_PRINT
|
|
};
|
|
|
|
// context menu for new
|
|
const UINT g_new_menus_newsub[] = {IDS_NEWSUBNET, 0};
|
|
const UINT g_new_menus_policy[] = {IDS_NEWPOLICY, 0};
|
|
const UINT g_menus_subnet[] = {IDS_NEWPOLICY, IDS_DELETESUBNET, 0};
|
|
// const UINT g_new_menus_profile[] = {IDS_NEWPROFILE, 0};
|
|
|
|
// static string IDs for strings
|
|
const UINT g_strid_root[]= { IDS_ACSROOT, 0};
|
|
const UINT g_strid_global[]= { IDS_GLOBAL, 0};
|
|
/*
|
|
const UINT g_strid_profiles[]= { IDS_PROFILES, 0};
|
|
const UINT g_strid_users[]= { IDS_USERS, 0};
|
|
*/
|
|
const UINT g_strid_subnets[]= { IDS_SUBNETCONFIGS, 0};
|
|
|
|
//==========================================================
|
|
// CACSUIInfo structures
|
|
//
|
|
|
|
// Root handle
|
|
CACSUIInfo g_RootUIInfo =
|
|
{
|
|
g_strid_root, // static string
|
|
1, // only name column
|
|
|
|
g_col_strid_name, //m_aColumnIds;
|
|
g_col_width_name, //m_aColumnWidths;
|
|
false, //m_bPropertyPage;
|
|
true, //m_bContainer;
|
|
NULL, //m_aNewMenuTextIds;
|
|
NULL, //m_aNewMenuIds;
|
|
NULL, //m_aTaskMenuTextIds;
|
|
NULL, //m_aTaskMenuIds;
|
|
g_verbs_all_hiden, //m_pVerbStates
|
|
&CLSID_ACSRootNode
|
|
};
|
|
|
|
// Global Configuration handle
|
|
CACSUIInfo g_GlobalUIInfo =
|
|
{
|
|
g_strid_global, // static string
|
|
1, // only name column
|
|
|
|
g_col_strid_policy, //m_aColumnIds;
|
|
g_col_width_policy, //m_aColumnWidths;
|
|
false, //m_bPropertyPage;
|
|
true, //m_bContainer;
|
|
NULL, // g_new_menus_user, //m_aNewMenuTextIds;
|
|
NULL, //m_aNewMenuIds;
|
|
g_new_menus_policy, //m_aTaskMenuTextIds;
|
|
NULL, //m_aTaskMenuIds;
|
|
g_verbs_refresh, //m_pVerbStates
|
|
&CLSID_ACSGlobalHolderNode
|
|
};
|
|
|
|
// Subnetworks Configuration handle
|
|
CACSUIInfo g_SubnetworksUIInfo =
|
|
{
|
|
g_strid_subnets, // static string
|
|
1, // only name column
|
|
|
|
g_col_strid_subnet, //m_aColumnIds;
|
|
g_col_width_subnet, //m_aColumnWidths;
|
|
false, //m_bPropertyPage;
|
|
true, //m_bContainer;
|
|
NULL, // g_new_menus_newsub, //m_aNewMenuTextIds;
|
|
NULL, //m_aNewMenuIds;
|
|
g_new_menus_newsub, //m_aTaskMenuTextIds;
|
|
NULL, //m_aTaskMenuIds;
|
|
g_verbs_refresh, //m_pVerbStates
|
|
&CLSID_ACSSubnetHolderNode
|
|
};
|
|
|
|
// Policy handle
|
|
CACSUIInfo g_PolicyUIInfo =
|
|
{
|
|
NULL, // static string id
|
|
sizeof(g_col_strid_policy) / sizeof(UINT) -1, // the last string id is 0, so decrease by 1
|
|
|
|
g_col_strid_policy, //m_aColumnIds;
|
|
g_col_width_policy, //m_aColumnWidths;
|
|
true, //m_bPropertyPage;
|
|
false, //m_bContainer;
|
|
NULL, //m_aNewMenuTextIds;
|
|
NULL, //m_aNewMenuIds;
|
|
NULL, //m_aTaskMenuTextIds;
|
|
NULL, //m_aTaskMenuIds;
|
|
g_verbs_property_delete, //m_pVerbStates
|
|
&CLSID_ACSPolicyNode
|
|
};
|
|
|
|
// Subnet handle
|
|
CACSUIInfo g_SubnetUIInfo =
|
|
{
|
|
NULL, // static string id
|
|
sizeof(g_col_strid_subnet) / sizeof(UINT) -1, // decrease by 1, since the last IDS is 0
|
|
|
|
g_col_strid_policy, //m_aColumnIds;
|
|
g_col_width_policy, //m_aColumnWidths;
|
|
true, //m_bPropertyPage;
|
|
true, //m_bContainer;
|
|
NULL, //g_new_menus_user, //m_aNewMenuTextIds;
|
|
NULL, //m_aNewMenuIds;
|
|
g_menus_subnet, //m_aTaskMenuTextIds;
|
|
NULL, //m_aTaskMenuIds;
|
|
g_verbs_property_refresh, //m_pVerbStates
|
|
&CLSID_ACSSubnetNode
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSHandle implementation
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
CACSHandle::CACSHandle(ITFSComponentData *pCompData, CDSObject* pDSObject, CACSUIInfo* pUIInfo)
|
|
: CHandler(pCompData),
|
|
m_pUIInfo(pUIInfo),
|
|
m_dwShownState(0),
|
|
m_pNode(NULL),
|
|
m_pDSObject(pDSObject)
|
|
{
|
|
if(pDSObject)
|
|
{
|
|
pDSObject->AddRef();
|
|
pDSObject->SetHandle(this);
|
|
}
|
|
|
|
ASSERT(pUIInfo);
|
|
// init the static string array
|
|
if(pUIInfo->m_aStaticStrIds)
|
|
{
|
|
const UINT* pUINT = pUIInfo->m_aStaticStrIds;
|
|
int i = 0;
|
|
while(*pUINT)
|
|
{
|
|
i++;
|
|
m_aStaticStrings.AddByRID(*pUINT++);
|
|
}
|
|
m_nFirstDynCol = i;
|
|
}
|
|
else
|
|
m_nFirstDynCol = 0;
|
|
|
|
m_ulIconIndex = IMAGE_IDX_CLOSEDFOLDER;
|
|
m_ulIconIndexOpen = IMAGE_IDX_OPENFOLDER;
|
|
m_nBranchFlag = 0;
|
|
|
|
m_bACSHandleExpanded = FALSE;
|
|
m_bCheckPropertyPageOpen = TRUE;
|
|
};
|
|
|
|
CACSHandle::~CACSHandle()
|
|
{
|
|
m_aStaticStrings.DeleteAll();
|
|
|
|
if(m_pDSObject)
|
|
m_pDSObject->Release();
|
|
};
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
MachineHandler::DestroyHandler
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CACSHandle::DestroyResultHandler(LONG_PTR cookie)
|
|
{
|
|
SPITFSNode spNode;
|
|
|
|
HRESULT hr = S_OK;
|
|
if (S_OK != m_spNodeMgr->FindNode(cookie, &spNode))
|
|
return S_FALSE;
|
|
|
|
if (S_OK == BringUpPropertyPageIfOpen(spNode, NULL))
|
|
{
|
|
AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
return S_OK;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
MachineHandler::DestroyHandler
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CACSHandle::DestroyHandler(ITFSNode *pNode)
|
|
{
|
|
if (S_OK == BringUpPropertyPageIfOpen(pNode, NULL))
|
|
{
|
|
AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
return S_OK;
|
|
}
|
|
|
|
//=============================================================================
|
|
// CACSHandle::HasPropertyPages
|
|
// Implementation of ITFSNodeHandler::HasPropertyPages
|
|
// NOTE: the root node handler has to over-ride this function to
|
|
// handle the snapin manager property page (wizard) case!!!
|
|
//
|
|
// Author: KennT, WeiJiang
|
|
//=============================================================================
|
|
STDMETHODIMP
|
|
CACSHandle::HasPropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
if (dwType & TFS_COMPDATA_CREATE)
|
|
{
|
|
// This is the case where we are asked to bring up property
|
|
// pages when the user is adding a new snapin. These calls
|
|
// are forwarded to the root node to handle.
|
|
hr = S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
hr = (m_pUIInfo->m_bPropertyPage? S_OK : S_FALSE);
|
|
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CACSHandle::OnAddMenuItems
|
|
Implementation of ITFSNodeHandler::OnAddMenuItems
|
|
Author: KennT, WeiJiang
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CACSHandle::OnAddMenuItems(
|
|
ITFSNode *pNode,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
LPDATAOBJECT lpDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType,
|
|
long *pInsertionsAllowed)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = S_OK;
|
|
BOOL bExtension = !!(dwType & TFS_COMPDATA_EXTENSION);
|
|
CString stMenuItem;
|
|
|
|
if(*pInsertionsAllowed & CCM_INSERTIONALLOWED_NEW)
|
|
// if (type == CCT_SCOPE)
|
|
{
|
|
int i = 0;
|
|
long lInsertionId;
|
|
long lMenuText;
|
|
long lMenuId;
|
|
|
|
// under new menu
|
|
while(hr == S_OK && m_pUIInfo->m_aNewMenuTextIds && m_pUIInfo->m_aNewMenuTextIds[i])
|
|
{
|
|
|
|
// lInsertionId = bExtension ? CCM_INSERTIONPOINTID_3RDPARTY_NEW :
|
|
// CCM_INSERTIONPOINTID_PRIMARY_NEW;
|
|
|
|
// BUG :: bExtension is alway true for same reason
|
|
|
|
lInsertionId = CCM_INSERTIONPOINTID_PRIMARY_NEW;
|
|
|
|
lMenuText = m_pUIInfo->m_aNewMenuTextIds[i];
|
|
|
|
if(m_pUIInfo->m_aNewMenuIds)
|
|
lMenuId = m_pUIInfo->m_aNewMenuIds[i];
|
|
else
|
|
lMenuId = lMenuText;
|
|
|
|
stMenuItem.LoadString(lMenuText);
|
|
hr = LoadAndAddMenuItem( pContextMenuCallback,
|
|
stMenuItem,
|
|
lMenuId,
|
|
lInsertionId,
|
|
0 );
|
|
i++;
|
|
}
|
|
|
|
i = 0;
|
|
// under task menu
|
|
while(hr == S_OK && m_pUIInfo->m_aTaskMenuTextIds && m_pUIInfo->m_aTaskMenuTextIds[i])
|
|
{
|
|
|
|
lInsertionId = bExtension ? CCM_INSERTIONPOINTID_3RDPARTY_TASK :
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP;
|
|
|
|
// BUG :: bExtension is alway true for same reason
|
|
|
|
lInsertionId = CCM_INSERTIONPOINTID_PRIMARY_TOP;
|
|
|
|
lMenuText = m_pUIInfo->m_aTaskMenuTextIds[i];
|
|
|
|
stMenuItem.LoadString(lMenuText);
|
|
|
|
if(m_pUIInfo->m_aTaskMenuIds)
|
|
lMenuText = m_pUIInfo->m_aTaskMenuTextIds[i];
|
|
else
|
|
lMenuId = lMenuText;
|
|
|
|
hr = LoadAndAddMenuItem( pContextMenuCallback,
|
|
stMenuItem,
|
|
lMenuId,
|
|
lInsertionId,
|
|
0 );
|
|
i++;
|
|
}
|
|
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CACSHandle::AddMenuItems(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject,
|
|
LPCONTEXTMENUCALLBACK pCallback,
|
|
long *pInsertionAllowed)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
SPITFSNode spNode;
|
|
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
|
|
// Call through to the regular OnAddMenuItems
|
|
if(*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW)
|
|
hr = OnAddMenuItems(spNode,
|
|
pCallback,
|
|
pDataObject,
|
|
CCT_RESULT,
|
|
TFS_COMPDATA_CHILD_CONTEXTMENU,
|
|
pInsertionAllowed);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
PortsNodeHandler::Command
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CACSHandle::Command(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
int nCommandID,
|
|
LPDATAOBJECT pDataObject)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
SPITFSNode spNode;
|
|
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
|
|
// Call through to the regular OnCommand
|
|
hr = OnCommand(spNode,
|
|
nCommandID,
|
|
CCT_RESULT,
|
|
pDataObject,
|
|
TFS_COMPDATA_CHILD_CONTEXTMENU);
|
|
|
|
return hr;
|
|
}
|
|
/*!--------------------------------------------------------------------------
|
|
CACSHandle::OnCommand
|
|
Implementation of ITFSNodeHandler::OnCommand
|
|
Author: KennT, WeiJiang
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CACSHandle::OnCommand(ITFSNode *pNode, long nCommandId,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType)
|
|
{
|
|
TRACE(_T("Command ID %d or %x is activated\n"), nCommandId, nCommandId);
|
|
return S_OK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CACSHandle::GetString
|
|
Implementation of ITFSNodeHandler::GetString
|
|
Author: KennT, WeiJiang
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(LPCTSTR) CACSHandle::GetString(ITFSNode *pNode, int nCol)
|
|
{
|
|
if(nCol < 0)
|
|
// should be ROOT node
|
|
nCol = 0;
|
|
|
|
if(nCol < m_aStaticStrings.GetSize())
|
|
return *m_aStaticStrings[(INT_PTR)nCol];
|
|
else
|
|
{
|
|
ASSERT(nCol >= m_nFirstDynCol);
|
|
UINT dynCol = nCol - m_nFirstDynCol;
|
|
if(m_aDynStrings.GetSize() == 0) // new, not initialized yet
|
|
UpdateStrings();
|
|
|
|
if( nCol - m_nFirstDynCol < m_aDynStrings.GetSize())
|
|
return *(m_aDynStrings.GetAt(dynCol));
|
|
else
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// should call the data object to get the latest dynamic strings
|
|
HRESULT CACSHandle::UpdateStrings()
|
|
{
|
|
CString* pStr;
|
|
UINT nCol;
|
|
HRESULT hr = S_OK;
|
|
UINT dynCol;
|
|
|
|
for( nCol = m_nFirstDynCol, dynCol = 0; nCol < m_pUIInfo->m_nTotalStrs; nCol++, dynCol++)
|
|
{
|
|
if(nCol - m_nFirstDynCol < m_aDynStrings.GetSize())
|
|
pStr = m_aDynStrings.GetAt(dynCol);
|
|
else
|
|
{
|
|
pStr = new CString();
|
|
m_aDynStrings.Add(pStr);
|
|
}
|
|
hr = m_pDSObject->GetString(*pStr, nCol);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CDhcpScopeOptions::InitializeNode
|
|
Initializes node specific data
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CACSHandle::InitializeNode
|
|
(
|
|
ITFSNode * pNode
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
ASSERT(m_pNode == NULL);
|
|
m_pNode = pNode;
|
|
if(m_pNode)
|
|
m_pNode->AddRef();
|
|
|
|
//
|
|
// Create the display name for this scope
|
|
//
|
|
// Make the node immediately visible
|
|
pNode->SetVisibilityState(TFS_VIS_SHOW);
|
|
pNode->SetData(TFS_DATA_IMAGEINDEX, m_ulIconIndex);
|
|
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, m_ulIconIndexOpen);
|
|
pNode->SetData(TFS_DATA_COOKIE, (DWORD_PTR)(ITFSNode *) pNode);
|
|
TRACE(_T("COOKIE -- %08x\n"), (DWORD_PTR)(ITFSNode *) pNode);
|
|
pNode->SetData(TFS_DATA_USER, (DWORD_PTR) this);
|
|
|
|
if(IfContainer())
|
|
{
|
|
SetColumnStringIDs(m_pUIInfo->m_aColumnIds);
|
|
SetColumnWidths(m_pUIInfo->m_aColumnWidths);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CACSHandle::CompareItems
|
|
Description
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(int)
|
|
CACSHandle::CompareItems
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookieA,
|
|
MMC_COOKIE cookieB,
|
|
int nCol
|
|
)
|
|
{
|
|
SPITFSNode spNode1, spNode2;
|
|
|
|
m_spNodeMgr->FindNode(cookieA, &spNode1);
|
|
m_spNodeMgr->FindNode(cookieB, &spNode2);
|
|
|
|
CACSHandle *pSub1 = GETHANDLER(CACSHandle, spNode1);
|
|
CACSHandle *pSub2 = GETHANDLER(CACSHandle, spNode2);
|
|
|
|
LPCTSTR str1 = pSub1->GetString(NULL, nCol);
|
|
LPCTSTR str2 = pSub2->GetString(NULL, nCol);
|
|
|
|
if(str1 && str2)
|
|
{
|
|
CString str(str1);
|
|
return str.Compare(str2);
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CACSHandle::OnResultContextHelp
|
|
Implementation of ITFSResultHandler::OnResultContextHelp
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CACSHandle::OnResultContextHelp
|
|
(
|
|
ITFSComponent * pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
SPIDisplayHelp spDisplayHelp;
|
|
SPIConsole spConsole;
|
|
|
|
pComponent->GetConsole(&spConsole);
|
|
|
|
hr = spConsole->QueryInterface (IID_IDisplayHelp, (LPVOID*) &spDisplayHelp);
|
|
ASSERT (SUCCEEDED (hr));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
LPCTSTR pszHelpFile = m_spTFSCompData->GetHTMLHelpFileName();
|
|
if (pszHelpFile == NULL)
|
|
goto Error;
|
|
|
|
CString szHelpFilePath;
|
|
UINT nLen = ::GetWindowsDirectory (szHelpFilePath.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
|
|
if (nLen == 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto Error;
|
|
}
|
|
|
|
szHelpFilePath.ReleaseBuffer();
|
|
szHelpFilePath += g_szDefaultHelpTopic;
|
|
|
|
hr = spDisplayHelp->ShowTopic (T2OLE ((LPTSTR)(LPCTSTR) szHelpFilePath));
|
|
ASSERT (SUCCEEDED (hr));
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// CACSHandle::OnResultSelect
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
HRESULT CACSHandle::OnResultSelect( ITFSComponent* pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPIConsoleVerb spConsoleVerb;
|
|
int i;
|
|
|
|
CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
|
|
|
|
// if it's ok to delete ... dynamic info
|
|
|
|
// Set the states for verbs
|
|
for(i = 0; i < ACS_TOTAL_MMC_VERBS; i++)
|
|
{
|
|
spConsoleVerb->SetVerbState(g_mmc_verbs[i], m_pUIInfo->m_pVerbStates[i], TRUE);
|
|
}
|
|
|
|
if (IsOkToDelete() == S_FALSE)
|
|
spConsoleVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, TRUE);
|
|
|
|
if (m_pUIInfo->m_pVerbStates[ ACS_MMC_VERB_PROPERTIES ] == ENABLED)
|
|
spConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
|
|
else
|
|
spConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CACSHandle::GetString
|
|
Implementation of ITFSResultHandler::GetString
|
|
Author: KennT, WeiJiang
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(LPCTSTR)
|
|
CACSHandle::GetString
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
int nCol
|
|
)
|
|
{
|
|
return GetString(NULL, nCol);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CACSHandle::HasPropertyPages
|
|
Implementation of ITFSResultHandler::HasPropertyPages
|
|
Author: KennT, WeiJiang
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CACSHandle::HasPropertyPages
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject
|
|
)
|
|
{
|
|
return (m_pUIInfo->m_bPropertyPage? S_OK : S_FALSE);
|
|
}
|
|
//=============================================================================
|
|
// CACSHandle::AddChild
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
HRESULT CACSHandle::AddChild(
|
|
ITFSNode* pNode,
|
|
CACSHandle* pHandle,
|
|
ITFSNode** ppNewNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ASSERT(ppNewNode);
|
|
ASSERT(pNode);
|
|
ASSERT(pHandle);
|
|
|
|
if(pHandle->IfContainer())
|
|
{
|
|
CHECK_HR(hr = CreateContainerTFSNode(ppNewNode,
|
|
pHandle->m_pUIInfo->m_pGUID,
|
|
pHandle,
|
|
pHandle,
|
|
m_spNodeMgr));
|
|
}
|
|
else
|
|
{
|
|
CHECK_HR(hr = CreateLeafTFSNode(ppNewNode,
|
|
pHandle->m_pUIInfo->m_pGUID,
|
|
pHandle,
|
|
pHandle,
|
|
m_spNodeMgr));
|
|
}
|
|
|
|
// Need to initialize the data for the root node
|
|
CHECK_HR(hr = pHandle->InitializeNode(*ppNewNode));
|
|
|
|
// Add the node to the root node
|
|
CHECK_HR(hr = pNode->AddChild(*ppNewNode));
|
|
L_ERR:
|
|
return hr;
|
|
}
|
|
|
|
// when data is changed on property page
|
|
HRESULT CACSHandle::NotifyDataChange(LPARAM param)
|
|
{
|
|
CACSHandle* pHandle = reinterpret_cast<CACSHandle*>(param);
|
|
ASSERT(pHandle);
|
|
ASSERT(pHandle->m_pNode);
|
|
if(!pHandle->m_pNode)
|
|
return S_FALSE; // not able to refresh the changes
|
|
else
|
|
{
|
|
pHandle->m_pDSObject->SetNoObjectState();
|
|
pHandle->UpdateStrings();
|
|
if(pHandle->m_pNode->IsContainer())
|
|
return pHandle->m_pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM);
|
|
else
|
|
return pHandle->m_pNode->ChangeNode(RESULT_PANE_CHANGE_ITEM);
|
|
}
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CACSHandle::OnCreateNodeId2
|
|
Returns a unique string for this node
|
|
Author: WeiJiang
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CACSHandle::OnCreateNodeId2(ITFSNode * pNode, CString & strId,
|
|
DWORD * dwFlags)
|
|
{
|
|
const GUID * pGuid = pNode->GetNodeType();
|
|
|
|
CString strProviderId, strGuid;
|
|
|
|
StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
|
|
strGuid.ReleaseBuffer();
|
|
|
|
// attach display name
|
|
strId += GetString(NULL, 0);
|
|
strId += strGuid;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
//=============================================================================
|
|
// CACSHandle::OnExpand
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
HRESULT CACSHandle::OnExpand(
|
|
ITFSNode *pNode,LPDATAOBJECT pDataObjecct, DWORD dwType, LPARAM arg,LPARAM param)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
SPITFSNode spNode;
|
|
|
|
std::list<CACSHandle*> children;
|
|
std::list<CACSHandle*>::iterator i;
|
|
|
|
if(arg)
|
|
{
|
|
hr = ListChildren(children);
|
|
|
|
if (S_FALSE == hr)
|
|
return S_OK;
|
|
|
|
CHECK_HR(hr);
|
|
|
|
// If this is TRUE, then we should enumerate the pane
|
|
// add all children's handles
|
|
for(i = children.begin(); i != children.end(); i++)
|
|
{
|
|
// For the root node, we will create one child node
|
|
// Create a node
|
|
spNode.Release(); // make sure the smart pointer is NULL
|
|
|
|
CHECK_HR(hr = AddChild(pNode, (*i), &spNode));
|
|
|
|
(*i)->Release(); // handle pointer,
|
|
// Set the scope item for the root node
|
|
// pNode->SetData(TFS_DATA_SCOPEID, param);
|
|
// pNode->Show();
|
|
}
|
|
}
|
|
|
|
m_bACSHandleExpanded = TRUE;
|
|
|
|
L_ERR:
|
|
pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_DATA);
|
|
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_NODEEXPAND, NULL);
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CACSHandle::SaveColumns
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CACSHandle::SaveColumns
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
DWORD dwNodeType;
|
|
int nCol = 0;
|
|
int nColWidth;
|
|
SPITFSNode spNode, spRootNode;
|
|
SPIHeaderCtrl spHeaderCtrl;
|
|
BOOL bDirty = FALSE;
|
|
|
|
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
|
|
CORg (pComponent->GetHeaderCtrl(&spHeaderCtrl));
|
|
|
|
while (m_pUIInfo->m_aColumnIds[nCol] != 0)
|
|
{
|
|
hr = spHeaderCtrl->GetColumnWidth(nCol, &nColWidth);
|
|
if (SUCCEEDED(hr) &&
|
|
m_pUIInfo->m_aColumnWidths[nCol] != nColWidth)
|
|
{
|
|
m_pUIInfo->m_aColumnWidths[nCol] = nColWidth;
|
|
bDirty = TRUE;
|
|
}
|
|
|
|
nCol++;
|
|
}
|
|
|
|
if (bDirty)
|
|
{
|
|
CORg (m_spNodeMgr->GetRootNode(&spRootNode));
|
|
CORg(spRootNode->SetData(TFS_DATA_DIRTY, TRUE));
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CACSHandle::OnResultRefresh(ITFSComponent * pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spNode;
|
|
|
|
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
|
|
|
|
CORg (spNode->DeleteAllChildren(true));
|
|
|
|
CORg (OnExpand(spNode, pDataObject, 0, arg, lParam));
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CACSHandle::OnDelete(ITFSNode *pNode, LPARAM arg, LPARAM lParam)
|
|
{
|
|
Trace0("CACSHandle::Notify(MMCN_DELETE) received\n");
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
CString strMessage, strTemp;
|
|
try{
|
|
strTemp.LoadString(IDS_DELETE_CONTAINER);
|
|
strMessage.Format(strTemp, GetString(NULL, 0));
|
|
}catch(CMemoryException&)
|
|
{
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (AfxMessageBox(strMessage, MB_YESNO) == IDYES)
|
|
{
|
|
CHECK_HR(hr = Delete(pNode, NULL, TRUE));
|
|
}
|
|
|
|
L_ERR:
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_NODEDELETE, NULL);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CACSHandle::OnRename(ITFSNode *pNode, LPARAM arg, LPARAM lParam)
|
|
{
|
|
Trace0("CACSHandle::Notify(MMCN_RENAME) received\n");
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
OLECHAR* pName = (OLECHAR*)lParam;
|
|
|
|
hr = m_pDSObject->Rename(pName);
|
|
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_NODERENAME, NULL);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CACSHandle::OnResultRename( ITFSComponent* pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
Trace0("CACSHandle::Notify(MMCN_DELETE) received\n");
|
|
OLECHAR* pName = (OLECHAR*)lParam;
|
|
|
|
return m_pDSObject->Rename(pName);
|
|
|
|
}
|
|
|
|
HRESULT CACSHandle::OnResultDelete( ITFSComponent* pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
Trace0("CACSHandle::Notify(MMCN_DELETE) received\n");
|
|
HRESULT hr = S_OK;
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
// build the list of selected nodes
|
|
CTFSNodeList listNodesToDelete;
|
|
hr = BuildSelectedItemList(pComponent, &listNodesToDelete);
|
|
|
|
//
|
|
// Confirm with the user
|
|
//
|
|
CString strMessage, strTemp;
|
|
int nNodes = listNodesToDelete.GetCount();
|
|
|
|
try{
|
|
if (nNodes > 1)
|
|
{
|
|
strTemp.LoadString(IDS_DELETE_MULTIITEMS);
|
|
strMessage.Format(strTemp, nNodes);
|
|
}
|
|
else
|
|
{
|
|
strTemp.LoadString(IDS_DELETE_ITEM);
|
|
strMessage.Format(strTemp, GetString(NULL, 0));
|
|
}
|
|
}catch(CMemoryException&){
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (AfxMessageBox(strMessage, MB_YESNO) == IDNO)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
//
|
|
// Loop through all items deleting
|
|
//
|
|
while (listNodesToDelete.GetCount() > 0)
|
|
{
|
|
SPITFSNode spOptionNode;
|
|
spOptionNode = listNodesToDelete.RemoveHead();
|
|
|
|
CACSHandle* pOptItem = GETHANDLER(CACSHandle, spOptionNode);
|
|
|
|
// call the other OnDelete Function to do the deletion
|
|
CHECK_HR(hr = pOptItem->Delete(spOptionNode, pComponent, TRUE));
|
|
if(hr != S_OK)
|
|
goto L_ERR;
|
|
|
|
spOptionNode.Release();
|
|
}
|
|
|
|
L_ERR:
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_NODEDELETE, NULL);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
// bring up the property page if it's open
|
|
HRESULT CACSHandle::BringUpPropertyPageIfOpen(ITFSNode *pNode, ITFSComponent* pTFSComponent)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(!m_bCheckPropertyPageOpen) return S_FALSE;
|
|
|
|
CComPtr<IConsole2> spConsole;
|
|
CComPtr<IDataObject> spDataObject;
|
|
CComPtr<IComponentData> spComponentData;
|
|
LONG_PTR uniqID;
|
|
LONG_PTR cookie;
|
|
|
|
hr = m_spNodeMgr->GetConsole(&spConsole);
|
|
|
|
if (!spConsole)
|
|
return S_FALSE;
|
|
|
|
if ( hr != S_OK)
|
|
return hr;
|
|
|
|
// Query IConsole for the needed interface.
|
|
CComQIPtr<IComponent, &IID_IComponent> spComponent(pTFSComponent);
|
|
|
|
// Query IConsole for the needed interface.
|
|
CComQIPtr<IPropertySheetProvider, &IID_IPropertySheetProvider> spPropertySheetProvider(spConsole );
|
|
_ASSERTE( spPropertySheetProvider != NULL );
|
|
|
|
|
|
cookie = pNode->GetData(TFS_DATA_COOKIE);
|
|
// the find function FindPropertySheet takes cookie for result pane, and sopeId for scope pane
|
|
if(pNode->IsContainer())
|
|
uniqID = pNode->GetData(TFS_DATA_SCOPEID);
|
|
else
|
|
uniqID = cookie;
|
|
|
|
CHECK_HR(hr = m_spNodeMgr->GetComponentData(&spComponentData));
|
|
|
|
CHECK_HR(hr = spComponentData->QueryDataObject(cookie, pNode->IsContainer()?CCT_SCOPE:CCT_RESULT, &spDataObject));
|
|
|
|
// This returns S_OK if a property sheet for this object already exists
|
|
// and brings that property sheet to the foreground.
|
|
// It returns S_FALSE if the property sheet wasn't found.
|
|
// If this is coming in through my IComponent object, I pass the pComponent pointer.
|
|
// If this is coming in through my IComponentData object,
|
|
// then pComponent is NULL, which is the appropriate value to pass in for
|
|
// the call to FindPropertySheet when coming in through IComponentData.
|
|
hr = spPropertySheetProvider->FindPropertySheet(
|
|
(LONG_PTR) uniqID
|
|
, spComponent
|
|
, spDataObject
|
|
);
|
|
|
|
L_ERR:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT CACSHandle::Delete(ITFSNode *pNode, ITFSComponent* pTFSComponent, BOOL bCheckPropertyPage)
|
|
{
|
|
Trace0("CACSHandle::Delete\n");
|
|
|
|
HRESULT hr = S_OK;
|
|
SPITFSNode spParent;
|
|
|
|
if(bCheckPropertyPage) // check to see if the property page is open
|
|
{
|
|
if(BringUpPropertyPageIfOpen(pNode, pTFSComponent) == S_OK)
|
|
{
|
|
AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
|
|
hr = S_FALSE;
|
|
goto L_ERR;
|
|
}
|
|
}
|
|
|
|
// delete the corresponding DS object
|
|
CHECK_HR(hr = m_pDSObject->Delete());
|
|
|
|
// remove from UI
|
|
pNode->GetParent(&spParent);
|
|
CHECK_HR(hr = spParent->RemoveChild(pNode));
|
|
|
|
L_ERR:
|
|
return hr;
|
|
}
|
|
|
|
unsigned int g_cfMachineName = RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
|
|
|
|
LPOLESTR g_RootTaskOverBitmaps[ROOT_TASK_MAX] =
|
|
{
|
|
L"/toolroll.bmp",
|
|
};
|
|
|
|
LPOLESTR g_RootTaskOffBitmaps[ROOT_TASK_MAX] =
|
|
{
|
|
L"/tool.bmp",
|
|
};
|
|
|
|
UINT g_RootTaskText[ROOT_TASK_MAX] =
|
|
{
|
|
IDS_ROOT_TASK_LAUNCH_ACS, // for the extension case
|
|
};
|
|
|
|
UINT g_RootTaskHelp[ROOT_TASK_MAX] =
|
|
{
|
|
IDS_ROOT_TASK_LAUNCH_ACS_HELP, // for the extension case
|
|
};
|
|
|
|
|
|
HRESULT
|
|
CRootTasks::Init(BOOL bExtension, BOOL bThisMachine, BOOL bNetServices)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
MMC_TASK mmcTask;
|
|
int nPos = 0;
|
|
int nFinish = ROOT_TASK_MAX - 2;
|
|
|
|
m_arrayMouseOverBitmaps.SetSize(ROOT_TASK_MAX);
|
|
m_arrayMouseOffBitmaps.SetSize(ROOT_TASK_MAX);
|
|
m_arrayTaskText.SetSize(ROOT_TASK_MAX);
|
|
m_arrayTaskHelp.SetSize(ROOT_TASK_MAX);
|
|
|
|
// setup path for reuse
|
|
OLECHAR szBuffer[MAX_PATH*2]; // that should be enough
|
|
lstrcpy (szBuffer, L"res://");
|
|
::GetModuleFileName(_Module.GetModuleInstance(), szBuffer + lstrlen(szBuffer), MAX_PATH);
|
|
OLECHAR * temp = szBuffer + lstrlen(szBuffer);
|
|
|
|
if (bExtension && bThisMachine)
|
|
{
|
|
nPos = ROOT_TASK_MAX - 2;
|
|
nFinish = ROOT_TASK_MAX - 1;
|
|
}
|
|
else
|
|
if (bExtension && bNetServices)
|
|
{
|
|
nPos = ROOT_TASK_MAX - 1;
|
|
nFinish = ROOT_TASK_MAX;
|
|
}
|
|
else
|
|
{
|
|
nPos = ROOT_TASK_MAX;
|
|
nFinish = ROOT_TASK_MAX;
|
|
}
|
|
|
|
for (nPos; nPos < nFinish; nPos++)
|
|
{
|
|
m_arrayMouseOverBitmaps[nPos] = szBuffer;
|
|
m_arrayMouseOffBitmaps[nPos] = szBuffer;
|
|
m_arrayMouseOverBitmaps[nPos] += g_RootTaskOverBitmaps[nPos];
|
|
m_arrayMouseOffBitmaps[nPos] += g_RootTaskOffBitmaps[nPos];
|
|
|
|
m_arrayTaskText[nPos].LoadString(g_RootTaskText[nPos]);
|
|
m_arrayTaskHelp[nPos].LoadString(g_RootTaskHelp[nPos]);
|
|
|
|
AddTask((LPTSTR) (LPCTSTR) m_arrayMouseOverBitmaps[nPos],
|
|
(LPTSTR) (LPCTSTR) m_arrayMouseOffBitmaps[nPos],
|
|
(LPTSTR) (LPCTSTR) m_arrayTaskText[nPos],
|
|
(LPTSTR) (LPCTSTR) m_arrayTaskHelp[nPos],
|
|
MMC_ACTION_ID,
|
|
nPos);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiRootHandler::TaskPadNotify
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CACSRootHandle::TaskPadNotify
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject,
|
|
VARIANT * arg,
|
|
VARIANT * param
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
if (arg->vt == VT_I4)
|
|
{
|
|
switch (arg->lVal)
|
|
{
|
|
|
|
case ROOT_TASK_LAUNCH_ACS:
|
|
{
|
|
TCHAR SystemPath[MAX_PATH];
|
|
CString CommandLine;
|
|
|
|
GetSystemDirectory(SystemPath, MAX_PATH);
|
|
|
|
// to construct "mmc.exe /s %windir%\system32\acssnap.msc")
|
|
CommandLine = _T("mmc.exe /s ");
|
|
CommandLine += SystemPath;
|
|
CommandLine += _T("\\acssnap.msc");
|
|
USES_CONVERSION;
|
|
WinExec(T2A((LPTSTR)(LPCTSTR)CommandLine), SW_SHOW);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Panic1("CACSRootHandle::TaskPadNotify - Unrecognized command! %d", arg->lVal);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CBaseResultHandler::EnumTasks
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CACSRootHandle::EnumTasks
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject,
|
|
LPOLESTR pszTaskGroup,
|
|
IEnumTASK ** ppEnumTask
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = hrOK;
|
|
CRootTasks * pTasks = NULL;
|
|
SPIEnumTask spEnumTasks;
|
|
SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
|
|
BOOL bExtension = FALSE;
|
|
BOOL bAddThisMachineTasks = FALSE;
|
|
BOOL bAddNetServicesTasks = FALSE;
|
|
const CLSID * pNodeClsid = &CLSID_ACSSnap;
|
|
CString strMachineGroup = NETCONS_ROOT_THIS_MACHINE;
|
|
CString strNetServicesGroup = NETCONS_ROOT_NET_SERVICES;
|
|
|
|
if ((spInternal == NULL) || (*pNodeClsid != spInternal->m_clsid))
|
|
bExtension = TRUE;
|
|
|
|
if (bExtension &&
|
|
strMachineGroup.CompareNoCase(pszTaskGroup) == 0)
|
|
{
|
|
// There are multiple taskpad groups in the network console
|
|
// we need to make sure we are extending the correct one.
|
|
bAddThisMachineTasks = TRUE;
|
|
}
|
|
|
|
if (bExtension &&
|
|
strNetServicesGroup.CompareNoCase(pszTaskGroup) == 0)
|
|
{
|
|
// There are multiple taskpad groups in the network console
|
|
// we need to make sure we are extending the correct one.
|
|
bAddNetServicesTasks = TRUE;
|
|
}
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
pTasks = new CRootTasks();
|
|
spEnumTasks = pTasks;
|
|
|
|
// if (!(bExtension && !bAddThisMachineTasks && !bAddNetServicesTasks))
|
|
CORg (pTasks->Init(bExtension, bAddThisMachineTasks, bAddNetServicesTasks));
|
|
|
|
CORg (pTasks->QueryInterface (IID_IEnumTASK, (void **)ppEnumTask));
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSRootHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
HRESULT CACSRootHandle::ListChildren(std::list<CACSHandle*>& children)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CACSHandle* pHandle = NULL;
|
|
|
|
CComObject<CACSGlobalObject>* pGlobal;
|
|
CComPtr<CACSGlobalObject> spGlobal;
|
|
|
|
CComObject<CACSSubnetsObject>* pSubnets;
|
|
CComPtr<CACSSubnetsObject> spSubnets;
|
|
|
|
// Global policy folder "cn=ACS,cn=Services,cn=Configuration"
|
|
CHECK_HR(hr = CComObject<CACSGlobalObject>::CreateInstance(&pGlobal)); // ref == 0
|
|
spGlobal = pGlobal;
|
|
|
|
// open the global folder
|
|
hr = pGlobal->Open();
|
|
|
|
// Change the title of the node to include the name of the domain
|
|
ASSERT(m_aStaticStrings[0]); // we assume root node has name
|
|
|
|
*m_aStaticStrings[(INT_PTR)0] += _T(" - ");
|
|
|
|
if(FAILED(hr) && pGlobal->m_nOpenErrorId)
|
|
{
|
|
ReportError(hr, IDS_ERR_ROOTNODE, NULL);
|
|
hr = S_OK;
|
|
goto L_ERR;
|
|
}
|
|
|
|
// if opened successfully, the get name of domain information
|
|
CHECK_HR(hr);
|
|
|
|
// Change the title of the node to include the name of the domain
|
|
ASSERT(m_aStaticStrings[0]); // we assume root node has name
|
|
*m_aStaticStrings[(INT_PTR)0] += pGlobal->m_strDomainName;
|
|
|
|
//================================
|
|
// global handle reuse the ACSROOTDS OBject
|
|
pHandle = new CACSGlobalHandle(m_spTFSCompData, pGlobal); // ref == 1
|
|
|
|
if(!pHandle)
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
|
|
children.push_back(pHandle);
|
|
|
|
//=======================================
|
|
//Subnetworks configuration folder "cn=subnets,cn=sits,cn=configuration"
|
|
CHECK_HR(hr = CComObject<CACSSubnetsObject>::CreateInstance(&pSubnets)); // ref == 0
|
|
spSubnets = pSubnets;
|
|
|
|
if FAILED(hr = spSubnets->Open())
|
|
{
|
|
|
|
CHECK_HR(hr);
|
|
}
|
|
pHandle = new CACSSubnetContainerHandle(m_spTFSCompData, pSubnets); // ref == 1
|
|
|
|
if(!pHandle)
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
|
|
children.push_back(pHandle);
|
|
|
|
L_ERR:
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSSubnetContainerHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
STDMETHODIMP CACSSubnetContainerHandle::OnCommand( ITFSNode* pNode,
|
|
long nCommandId,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType)
|
|
{
|
|
CStrArray Names;
|
|
HRESULT hr = S_OK;
|
|
CComObject<CDSObject>* pNTSubnetObj = NULL;
|
|
CComPtr<CDSObject> spNTSubnetObj;
|
|
CComObject<CACSSubnetObject>* pACSSubnetObj = NULL;
|
|
CComPtr<CACSSubnetObject> spACSSubnetObj;
|
|
CACSSubnetHandle* pHandle = NULL;
|
|
ITFSNode* pNewNode = NULL;
|
|
SPIComponentData spComponentData;
|
|
|
|
int i;
|
|
|
|
TRACE(_T("Command ID %d or %x is activated\n"), nCommandId, nCommandId);
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
switch(nCommandId)
|
|
{
|
|
case IDS_NEWSUBNET:
|
|
// get the object name -- which will be a new name within the container
|
|
CHECK_HR(hr = GetNamesForCommandNew(nCommandId, Names));
|
|
|
|
try{
|
|
// for each name, create an object in list
|
|
for(i = 0; i < Names.GetSize(); i++)
|
|
{
|
|
// create the object in DS
|
|
|
|
// need to create a subnet (NT subnet object in DS)
|
|
CHECK_HR(hr = CComObject<CDSObject>::CreateInstance(&pNTSubnetObj)); // ref == 0
|
|
spNTSubnetObj = pNTSubnetObj; // ref == 1, previous one get dereferenced
|
|
|
|
CHECK_HR(hr = spNTSubnetObj->Open( m_pDSObject,
|
|
L"subnet",
|
|
T2W((LPTSTR)(LPCTSTR)(*Names[(INT_PTR)i])),
|
|
true,
|
|
true));
|
|
|
|
m_pDSObject->AddChild(pNTSubnetObj);
|
|
|
|
|
|
// create ACS subobject within the subnet object ...
|
|
CHECK_HR(hr = CComObject<CACSSubnetObject>::CreateInstance(&pACSSubnetObj));
|
|
spACSSubnetObj = pACSSubnetObj;
|
|
|
|
CHECK_HR(hr = spACSSubnetObj->SetInfo(spNTSubnetObj, ACS_CLS_CONTAINER, ACS_NAME_ACS));
|
|
|
|
// create a handle and add to the node tree
|
|
pHandle = new CACSSubnetHandle(m_spTFSCompData, spACSSubnetObj);
|
|
|
|
// add this to snapin UI
|
|
if(!pHandle)
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
|
|
AddChild(pNode, pHandle, &pNewNode);
|
|
|
|
// pNode->Show();
|
|
pNewNode->Show();
|
|
|
|
}
|
|
}catch(CMemoryException&){
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if(Names.GetSize() == 1)
|
|
{
|
|
// display the property page
|
|
m_spNodeMgr->GetComponentData(&spComponentData);
|
|
|
|
CHECK_HR( hr = DoPropertiesOurselvesSinceMMCSucks(pNewNode, (IComponentData*)spComponentData, *Names[(INT_PTR)0]));
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
CACSHandle::OnCommand(pNode, nCommandId, type, pDataObject, dwType);
|
|
|
|
}
|
|
|
|
L_ERR:
|
|
if(pHandle) pHandle->Release();
|
|
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_COMMAND, NULL);
|
|
return hr;
|
|
}
|
|
|
|
// container handler only list the subnets defined in NT, the ACS information is stored in
|
|
// 123.123.123.0/24 --> ACS --> Config
|
|
// the ACS becomes the real ACS subnet object
|
|
HRESULT CACSSubnetContainerHandle::ListChildren(std::list<CACSHandle*>& children)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CACSHandle* pHandle = NULL;
|
|
CComPtr<CDSObject> spNTSubnetObj;
|
|
CComPtr<CACSSubnetObject> spACSSubnetObj;
|
|
CComObject<CACSSubnetObject>* pACSSubnetObj = NULL;
|
|
CACSContainerObject<CDSObject>* pSubnetCont = NULL;
|
|
|
|
std::list<CDSObject*> ObjList;
|
|
std::list<CDSObject*>::iterator i;
|
|
|
|
pSubnetCont = dynamic_cast<CACSContainerObject<CDSObject>*>(m_pDSObject);
|
|
CHECK_HR(hr = pSubnetCont->ListChildren(ObjList, L"subnet"));
|
|
|
|
for( i = ObjList.begin(); i != ObjList.end(); i++)
|
|
{
|
|
spNTSubnetObj = *i; // this make a release call to the interface previously stored
|
|
|
|
CHECK_HR(hr = CComObject<CACSSubnetObject>::CreateInstance(&pACSSubnetObj));
|
|
spACSSubnetObj = pACSSubnetObj;
|
|
|
|
CHECK_HR(hr = spACSSubnetObj->SetInfo(spNTSubnetObj, ACS_CLS_CONTAINER, ACS_NAME_ACS));
|
|
|
|
spACSSubnetObj->SetNoObjectState();
|
|
|
|
pHandle = new CACSSubnetHandle(m_spTFSCompData, spACSSubnetObj); // ref == 1
|
|
|
|
if(!pHandle)
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
|
|
children.push_back(pHandle);
|
|
|
|
}
|
|
L_ERR:
|
|
for( i = ObjList.begin(); i != ObjList.end(); i++)
|
|
{
|
|
(*i)->Release(); // release the data objects
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSSubnetContainerHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
|
|
HRESULT
|
|
CACSSubnetContainerHandle::GetNamesForCommandNew(int nCommandId, CStrArray& Names)
|
|
{
|
|
CDlgNewSubnet dlg;
|
|
CString* pStr = NULL;
|
|
|
|
dlg.SetNameList(m_pDSObject->GetChildrenNameList());
|
|
|
|
if(dlg.DoModal() == IDOK && dlg.m_strSubnetName.GetLength())
|
|
{
|
|
pStr = new CString(dlg.m_strSubnetName);
|
|
Names.Add(pStr);
|
|
return S_OK;
|
|
}
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSPolicyContainerHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
|
|
STDMETHODIMP
|
|
CACSSubnetHandle::OnCommand( ITFSNode* pNode,
|
|
long nCommandId,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CACSSubnetObject* pACSSubnetObj = (CACSSubnetObject *)m_pDSObject;
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
switch(nCommandId)
|
|
{
|
|
case IDS_DELETESUBNET:
|
|
if(S_OK == BringUpPropertyPageIfOpen(pNode, NULL))
|
|
{
|
|
AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
|
|
if (AfxMessageBox(IDS_CONFIRM_DELETE, MB_YESNO) != IDYES)
|
|
break;
|
|
|
|
// delete the corresponding DS object -- subnet object is a special version, which keeps the C++ object, but delete the DS object underneath
|
|
hr = m_pDSObject->Delete();
|
|
if(hr == ERROR_NO_SUCH_OBJECT) // no such object
|
|
hr = S_FALSE;
|
|
CHECK_HR(hr);
|
|
|
|
// remove from UI -- to get rid of the sub object within it
|
|
if(hr == S_OK)
|
|
{
|
|
CHECK_HR(hr = pNode->DeleteAllChildren(true));
|
|
UpdateStrings();
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
hr = CACSPolicyContainerHandle::OnCommand(pNode, nCommandId, type, pDataObject, dwType);
|
|
break;
|
|
|
|
}
|
|
|
|
L_ERR:
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_COMMAND, NULL);
|
|
|
|
pACSSubnetObj->SetNoObjectState();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
// only shown conflict state here
|
|
HRESULT
|
|
CACSSubnetHandle::ShowState(DWORD state)
|
|
{
|
|
DWORD dwShownState = GetShownState();
|
|
|
|
HRESULT hr;
|
|
UINT id;
|
|
|
|
CHECK_HR(hr = CACSHandle::ShowState(state));
|
|
if(m_pNode == NULL)
|
|
return S_OK;
|
|
// change state on UI
|
|
|
|
id = ((state & ACSDATA_STATE_NOOBJECT) != 0)? IMAGE_IDX_SUBNETWORK_NO_ACSPOLICY : IMAGE_IDX_SUBNETWORK;
|
|
|
|
m_pNode->SetData(TFS_DATA_IMAGEINDEX, id);
|
|
m_pNode->SetData(TFS_DATA_OPENIMAGEINDEX, id);
|
|
hr = m_pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM);
|
|
//
|
|
|
|
L_ERR:
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
STDMETHODIMP
|
|
CACSSubnetHandle::CreatePropertyPages
|
|
(
|
|
ITFSNode *pNode,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwError;
|
|
CString strServiceName;
|
|
|
|
CPgGeneral* pPgGeneral = NULL;
|
|
CPgServers* pPgServers = NULL;
|
|
CPgLogging* pPgLogging = NULL;
|
|
CPgAccounting* pPgAccounting = NULL;
|
|
CPgSBM* pPgSBM = NULL;
|
|
|
|
HPROPSHEETPAGE hPgGeneral = NULL;
|
|
HPROPSHEETPAGE hPgServers = NULL;
|
|
HPROPSHEETPAGE hPgLogging = NULL;
|
|
HPROPSHEETPAGE hPgAccounting = NULL;
|
|
HPROPSHEETPAGE hPgSBM = NULL;
|
|
BOOL bNewCreated = FALSE;
|
|
|
|
CComObject<CACSSubnetPageManager>* pPageManager;
|
|
|
|
hr = CComObject<CACSSubnetPageManager>::CreateInstance(&pPageManager);
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
CACSSubnetObject* pObj = dynamic_cast<CACSSubnetObject*>(m_pDSObject);
|
|
ASSERT(pObj); // expect this object to be this type
|
|
|
|
CComPtr<CACSSubnetConfig> spConfig;
|
|
|
|
CHECK_HR(hr = pObj->MakeSureExist(&bNewCreated)); // make sure the current DS object is active
|
|
|
|
m_pDSObject->SetNoObjectState();
|
|
// if this is new added policy, need to re-expand to make sure the new added ones can be seen
|
|
if(bNewCreated && m_bACSHandleExpanded)
|
|
{
|
|
// node already in Expanded state, need to manually expand again, since
|
|
CHECK_HR(hr = pNode->DeleteAllChildren(true));
|
|
// we re-created the data object
|
|
CHECK_HR(hr = OnExpand(pNode, pDataObject, 0, 1, 0));
|
|
}
|
|
|
|
pObj->GetConfig(&spConfig);
|
|
|
|
pPageManager->SetMMCNotify(handle, (LPARAM)this);
|
|
pPageManager->SetSubnetData(spConfig, this);
|
|
|
|
CHECK_HR(hr = spConfig->Reopen()); // make sure the current DS object is active
|
|
|
|
//===============
|
|
// general page -- traffic
|
|
{
|
|
CComPtr<CACSSubnetLimitsContainer> spLimitsCont;
|
|
pObj->GetLimitsContainer(&spLimitsCont);
|
|
CHECK_HR(hr = spLimitsCont->Reopen()); // make sure the current DS object is active
|
|
pPgGeneral = new CPgGeneral((CACSSubnetConfig*)spConfig, (CACSContainerObject<CACSSubnetServiceLimits>*) spLimitsCont );
|
|
|
|
pPageManager->AddPage(pPgGeneral);
|
|
}
|
|
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
|
|
// change callback function to delete itself when the property sheet is released
|
|
pPgGeneral->SetSelfDeleteCallback();
|
|
|
|
MMCPropPageCallback(&pPgGeneral->m_psp);
|
|
|
|
hPgGeneral = ::CreatePropertySheetPage(&pPgGeneral->m_psp);
|
|
if(hPgGeneral == NULL)
|
|
return E_UNEXPECTED;
|
|
|
|
lpProvider->AddPage(hPgGeneral);
|
|
|
|
//===============
|
|
// Servers page
|
|
pPgServers = new CPgServers((CACSSubnetConfig*)spConfig);
|
|
|
|
pPageManager->AddPage(pPgServers);
|
|
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
|
|
// change callback function to delete itself when the property sheet is released
|
|
pPgServers->SetSelfDeleteCallback();
|
|
|
|
MMCPropPageCallback(&pPgServers->m_psp);
|
|
|
|
hPgServers = ::CreatePropertySheetPage(&pPgServers->m_psp);
|
|
if(hPgServers == NULL)
|
|
return E_UNEXPECTED;
|
|
|
|
lpProvider->AddPage(hPgServers);
|
|
|
|
//===============
|
|
// logging page
|
|
pPgLogging = new CPgLogging((CACSSubnetConfig*)spConfig);
|
|
|
|
pPageManager->AddPage(pPgLogging);
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
pPgLogging->SetSelfDeleteCallback();
|
|
MMCPropPageCallback(&pPgLogging->m_psp);
|
|
|
|
hPgLogging = ::CreatePropertySheetPage(&pPgLogging->m_psp);
|
|
if(hPgLogging == NULL)
|
|
return E_UNEXPECTED;
|
|
|
|
lpProvider->AddPage(hPgLogging);
|
|
|
|
//===============
|
|
// Accouting page -- added by WeiJiang 2/16/98
|
|
|
|
pPgAccounting = new CPgAccounting((CACSSubnetConfig*)spConfig);
|
|
|
|
pPageManager->AddPage(pPgAccounting);
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
pPgAccounting->SetSelfDeleteCallback();
|
|
MMCPropPageCallback(&pPgAccounting->m_psp);
|
|
|
|
hPgAccounting = ::CreatePropertySheetPage(&pPgAccounting->m_psp);
|
|
if(hPgAccounting == NULL)
|
|
return E_UNEXPECTED;
|
|
|
|
lpProvider->AddPage(hPgAccounting);
|
|
|
|
//===============
|
|
// advanced page -- SBM
|
|
pPgSBM = new CPgSBM((CACSSubnetConfig*)spConfig);
|
|
|
|
pPageManager->AddPage(pPgSBM);
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
|
|
pPgSBM->SetSelfDeleteCallback();
|
|
MMCPropPageCallback(&pPgSBM->m_psp);
|
|
|
|
hPgSBM = ::CreatePropertySheetPage(&pPgSBM->m_psp);
|
|
if(hPgSBM == NULL)
|
|
return E_UNEXPECTED;
|
|
|
|
lpProvider->AddPage(hPgSBM);
|
|
|
|
L_ERR: //
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_PROPERTYPAGE, NULL);
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSPolicyContainerHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
|
|
STDMETHODIMP
|
|
CACSPolicyContainerHandle::OnCommand( ITFSNode* pNode,
|
|
long nCommandId,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType)
|
|
{
|
|
CStrArray Names;
|
|
HRESULT hr = S_OK;
|
|
CComObject<CACSPolicyElement>* pDSObj = NULL;
|
|
CComPtr<CACSPolicyElement> spObj;
|
|
CACSPolicyHandle* pHandle = NULL;
|
|
ITFSNode* pNewNode = NULL;
|
|
SPIComponentData spComponentData;
|
|
CACSSubnetObject* pSubnetObj;
|
|
int i, j;
|
|
TCHAR szNameCanonical[MAX_PATH * 2];
|
|
ULONG len = MAX_PATH * 2;
|
|
|
|
TRACE(_T("Command ID %d or %x is activated\n"), nCommandId, nCommandId);
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
switch(nCommandId)
|
|
{
|
|
case IDS_NEWPOLICY:
|
|
// get the object name -- which will be a new name within the container
|
|
CHECK_HR(hr = GetNamesForCommandNew(nCommandId, Names));
|
|
|
|
// for each name, create an object in list
|
|
try{
|
|
for(i = 0; i < Names.GetSize(); i++)
|
|
{
|
|
|
|
// create the object in DS
|
|
CHECK_HR(hr = CComObject<CACSPolicyElement>::CreateInstance(&pDSObj)); // ref == 0
|
|
spObj = pDSObj; // ref == 1
|
|
CString* pStr;
|
|
|
|
try{
|
|
pSubnetObj = dynamic_cast<CACSSubnetObject*>(m_pDSObject);
|
|
}
|
|
catch(...)
|
|
{
|
|
};
|
|
if(pSubnetObj) // the policy is in subnet folder, otherwise, it will be global
|
|
{
|
|
BOOL bNew;
|
|
CHECK_HR(hr = pSubnetObj->MakeSureExist(&bNew));
|
|
if(bNew)
|
|
{
|
|
CHECK_HR(hr = pNode->DeleteAllChildren(true));
|
|
CHECK_HR(hr = OnExpand(pNode, pDataObject, 0, 1, 0));
|
|
}
|
|
}
|
|
spObj->SetFlags(ATTR_FLAG_SAVE, spObj->SetDefault(), true);
|
|
CHECK_HR(hr = spObj->Open( m_pDSObject,
|
|
ACS_CLS_POLICY,
|
|
T2W((LPTSTR)(LPCTSTR)*Names[(INT_PTR)i]),
|
|
true,
|
|
true));
|
|
|
|
spObj->m_bUseName_NewPolicy = TRUE;
|
|
|
|
m_pDSObject->AddChild(pDSObj);
|
|
// create a handle and add to the node tree
|
|
pHandle = new CACSPolicyHandle(m_spTFSCompData, spObj);
|
|
|
|
CHECK_HR(hr = spObj->Close());
|
|
|
|
// add this to snapin UI
|
|
AddChild(pNode, pHandle, &pNewNode);
|
|
|
|
if(!pHandle)
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
|
|
pNode->Show();
|
|
}
|
|
|
|
// Display the property pages if there is only one new policy added
|
|
if(Names.GetSize() == 1)
|
|
{
|
|
CString newPolicyName;
|
|
newPolicyName.LoadString(IDS_NEWACSPOLICY);
|
|
// display the property page
|
|
m_spNodeMgr->GetComponentData(&spComponentData);
|
|
|
|
pHandle->SetDeleteOnCancelPropertyPage(pNewNode);
|
|
|
|
CHECK_HR( hr = DoPropertiesOurselvesSinceMMCSucks(pNewNode, (IComponentData*)spComponentData, newPolicyName));
|
|
}
|
|
|
|
}catch(CMemoryException&){
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
CACSHandle::OnCommand(pNode, nCommandId, type, pDataObject, dwType);
|
|
break;
|
|
|
|
}
|
|
|
|
L_ERR:
|
|
if(pHandle) pHandle->Release();
|
|
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_COMMAND, NULL);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CACSPolicyContainerHandle::OnExpand(
|
|
ITFSNode *pNode,LPDATAOBJECT pDataObject, DWORD dwType, LPARAM arg,LPARAM param)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
CACSPolicyContainer* pCont = NULL;
|
|
|
|
CHECK_HR(hr = CACSHandle::OnExpand(pNode, pDataObject, dwType, arg, param));
|
|
pCont = dynamic_cast<CACSPolicyContainer*>(m_pDSObject);
|
|
pCont->SetChildrenConflictState();
|
|
|
|
L_ERR:
|
|
return hr;
|
|
}
|
|
HRESULT CACSPolicyContainerHandle::ListChildren(std::list<CACSHandle*>& children)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CACSHandle* pHandle = NULL;
|
|
CComPtr<CDSObject> spObj;
|
|
CACSPolicyContainer* pCont = NULL;
|
|
|
|
std::list<CACSPolicyElement*> ObjList;
|
|
std::list<CACSPolicyElement*>::iterator i;
|
|
|
|
pCont = dynamic_cast<CACSPolicyContainer*>(m_pDSObject);
|
|
hr = pCont->ListChildren(ObjList, ACS_CLS_POLICY);
|
|
|
|
if(hr == ERROR_NO_SUCH_OBJECT) // object is not found in DS, it's fine, since, some subnet with no ACS info
|
|
{
|
|
hr = S_OK;
|
|
goto L_ERR;
|
|
}
|
|
|
|
CHECK_HR(hr);
|
|
|
|
for( i = ObjList.begin(); i != ObjList.end(); i++)
|
|
{
|
|
spObj = *i; // this make a release call to the interface previously stored
|
|
pHandle = new CACSPolicyHandle(m_spTFSCompData, spObj);
|
|
|
|
CACSPolicyElement* pPolicy = dynamic_cast<CACSPolicyElement*>((CDSObject*)spObj);
|
|
ASSERT(pPolicy);
|
|
|
|
if(!pHandle)
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
|
|
pHandle->SetBranch(m_nBranchFlag);
|
|
children.push_back(pHandle);
|
|
}
|
|
L_ERR:
|
|
for( i = ObjList.begin(); i != ObjList.end(); i++)
|
|
{
|
|
(*i)->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSPolicyContainerHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
|
|
HRESULT
|
|
CACSPolicyContainerHandle::GetNamesForCommandNew(int nCommandId, CStrArray& Names)
|
|
{
|
|
// name of a policy is not important to the consumer of the policy
|
|
// policy name is constructed as AcsPolicyYYYYMMDDMMn, AcsPolicy198808211236
|
|
|
|
ASSERT(nCommandId == IDS_NEWPOLICY);
|
|
CString* pstrName = new CString();
|
|
SYSTEMTIME sysTime;
|
|
|
|
GetSystemTime(&sysTime);
|
|
|
|
pstrName->Format(_T("AcsPolicy%04d%02d%02d%02d%02d"), sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute);
|
|
CStrArray* pExistingNames = m_pDSObject->GetChildrenNameList();
|
|
|
|
int i = 0;
|
|
while(pExistingNames && pExistingNames->Find(*pstrName) != -1) // found in existing names
|
|
{
|
|
// try next name with
|
|
pstrName->Format(_T("AcsPolicy%04d%02d%02d%02d%02d%-d"), sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, i++);
|
|
};
|
|
|
|
Names.Add(pstrName);
|
|
|
|
if (!Names.GetSize())
|
|
return S_OK;
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CACSPolicyHandle
|
|
// -
|
|
// Author: WeiJiang
|
|
//
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CACSPolicyHandle::CreatePropertyPages
|
|
Implementation of ITFSResultHandler::CreatePropertyPages
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CACSPolicyHandle::CreatePropertyPages
|
|
(
|
|
ITFSNode *pNode,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
return CreatePropertyPages((ITFSComponent*)NULL, (long) 0, lpProvider, pDataObject, handle);
|
|
}
|
|
|
|
HRESULT CACSPolicyHandle::OnResultDelete( ITFSComponent* pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
Trace0("CACSPolicyHandle::Notify(MMCN_DELETE) received\n");
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
CComPtr<CACSPolicyContainer> spCont;
|
|
|
|
// GetContainer already AddRef, so avoid AddRef twice, assign directly to .p
|
|
spCont.p = dynamic_cast<CACSPolicyContainer*>(m_pDSObject->GetContainer());
|
|
|
|
HRESULT hr = CACSHandle::OnResultDelete(pComponent, pDataObject, cookie, arg, lParam);
|
|
|
|
spCont->SetChildrenConflictState();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
// only shown conflict state here
|
|
HRESULT
|
|
CACSPolicyHandle::ShowState(DWORD state)
|
|
{
|
|
DWORD dwShownState = GetShownState();
|
|
|
|
HRESULT hr;
|
|
UINT id;
|
|
|
|
CHECK_HR(hr = CACSHandle::ShowState(state));
|
|
if(m_pNode == NULL)
|
|
return S_OK;
|
|
/*
|
|
||
|
|
(dwShownState & (ACSDATA_STATE_CONFLICT | ACSDATA_STATE_DISABLED)) == (state & (ACSDATA_STATE_CONFLICT | ACSDATA_STATE_DISABLED)))
|
|
return S_OK;
|
|
*/
|
|
// change conflict state on UI
|
|
|
|
id = ((state & ACSDATA_STATE_CONFLICT) != 0)? IMAGE_IDX_CONFLICTPOLICY : IMAGE_IDX_POLICY;
|
|
id = ((state & ACSDATA_STATE_DISABLED) != 0)? IMAGE_IDX_DISABLEDPOLICY : id;
|
|
|
|
m_pNode->SetData(TFS_DATA_IMAGEINDEX, id);
|
|
m_pNode->SetData(TFS_DATA_OPENIMAGEINDEX, id);
|
|
hr = m_pNode->ChangeNode(RESULT_PANE_CHANGE_ITEM);
|
|
//
|
|
|
|
L_ERR:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CACSPolicyHandle::CreatePropertyPages
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwError;
|
|
CString strServiceName;
|
|
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
|
|
CACSPolicyElement* pObj = dynamic_cast<CACSPolicyElement*>(m_pDSObject);
|
|
CComPtr<CACSPolicyElement> spElement;
|
|
|
|
ASSERT(pObj);
|
|
|
|
spElement = pObj;
|
|
|
|
CHECK_HR(hr = spElement->Reopen());
|
|
|
|
try{
|
|
CPgPolicyGeneral* pPgGeneral = NULL;
|
|
CPgPolicyFlow* pPgFlow = NULL;
|
|
CPgPolicyAggregate* pPgAggr = NULL;
|
|
HPROPSHEETPAGE hPgGeneral = NULL;
|
|
HPROPSHEETPAGE hPgFlow = NULL;
|
|
HPROPSHEETPAGE hPgAggr = NULL;
|
|
|
|
// create a page manager for all the pages
|
|
CComObject<CACSPolicyPageManager>* pPageManager;
|
|
CHECK_HR(hr = CComObject<CACSPolicyPageManager>::CreateInstance(&pPageManager));
|
|
pPageManager->SetPolicyData(spElement, this);
|
|
pPageManager->SetMMCNotify(handle, (LPARAM)this);
|
|
|
|
//===============
|
|
// general page
|
|
pPgGeneral = new CPgPolicyGeneral((CACSPolicyElement*)spElement);
|
|
pPageManager->AddPage(pPgGeneral); // add a page to the manager
|
|
pPageManager->SetGeneralPage(pPgGeneral);
|
|
pPageManager->SetBranchFlag(m_nBranchFlag);
|
|
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
// change callback function to delete itself when the property sheet is released
|
|
pPgGeneral->SetSelfDeleteCallback();
|
|
|
|
// if there are specil operation on Cancel, make sure the page is dirty
|
|
// even when user just click on OK, OnApply is still called.
|
|
if(m_bDeleteUponCancel)
|
|
pPgGeneral->SetModified();
|
|
|
|
|
|
MMCPropPageCallback(&pPgGeneral->m_psp);
|
|
|
|
hPgGeneral = ::CreatePropertySheetPage(&pPgGeneral->m_psp);
|
|
if(hPgGeneral == NULL)
|
|
CHECK_HR(hr = E_UNEXPECTED);
|
|
|
|
lpProvider->AddPage(hPgGeneral);
|
|
|
|
//=====================
|
|
// Flow page
|
|
pPgFlow = new CPgPolicyFlow((CACSPolicyElement*)spElement);
|
|
pPageManager->AddPage(pPgFlow); // add a page to the manager
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
// change callback function to delete itself when the property sheet is released
|
|
pPgFlow->SetSelfDeleteCallback();
|
|
|
|
MMCPropPageCallback(&pPgFlow->m_psp);
|
|
|
|
hPgFlow = ::CreatePropertySheetPage(&pPgFlow->m_psp);
|
|
if(hPgFlow == NULL)
|
|
CHECK_HR(hr = E_UNEXPECTED);
|
|
|
|
lpProvider->AddPage(hPgFlow);
|
|
|
|
// set branch info and ..
|
|
pPgFlow->m_nBranchFlag = m_nBranchFlag;
|
|
pPgFlow->m_pGeneralPage = pPgGeneral;
|
|
|
|
|
|
|
|
//=====================
|
|
// Aggr page
|
|
pPgAggr = new CPgPolicyAggregate((CACSPolicyElement*)spElement);
|
|
pPageManager->AddPage(pPgAggr); // add a page to the manager
|
|
// tell MMC to hook the proc because we are running on a separate,
|
|
// non MFC thread.
|
|
// change callback function to delete itself when the property sheet is released
|
|
pPgAggr->SetSelfDeleteCallback();
|
|
|
|
MMCPropPageCallback(&pPgAggr->m_psp);
|
|
|
|
hPgAggr = ::CreatePropertySheetPage(&pPgAggr->m_psp);
|
|
if(hPgAggr == NULL)
|
|
CHECK_HR(hr = E_UNEXPECTED);
|
|
|
|
lpProvider->AddPage(hPgAggr);
|
|
|
|
// set branch info and ..
|
|
pPgAggr->m_nBranchFlag = m_nBranchFlag;
|
|
pPgAggr->m_pGeneralPage = pPgGeneral;
|
|
|
|
|
|
}catch(CMemoryException&){
|
|
CHECK_HR(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
L_ERR:
|
|
if FAILED(hr)
|
|
ReportError(hr, IDS_ERR_PROPERTYPAGE, NULL);
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|