|
|
/**********************************************************************/ /** 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; }
///////////////////////////////////////////////////////////////////////////////
|