windows-nt/Source/XPSP1/NT/net/mmc/ipsecmon/ipsmcomp.cpp
2020-09-26 16:20:57 +08:00

1020 lines
31 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
ipsmcomp.cpp
This file contains the derived implementations from CComponent
and CComponentData for the IPSecMon snapin.
FILE HISTORY:
*/
#include "stdafx.h"
#include "root.h"
#include "server.h"
#include <atlimpl.cpp>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
DWORD gdwIpsmSnapVersion;
UINT aColumns[IPSECMON_NODETYPE_MAX][MAX_COLUMNS] =
{
{IDS_ROOT_NAME, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{IDS_SERVER_NAME, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{IDS_COL_QM_SA_SRC, IDS_COL_QM_SA_DEST, IDS_COL_QM_SA_PROT, IDS_COL_QM_SA_SRC_PORT, IDS_COL_QM_SA_DES_PORT, IDS_COL_QM_SA_POL, IDS_COL_QM_SA_AUTH, IDS_COL_QM_SA_CONF, IDS_COL_QM_SA_INTEGRITY, IDS_COL_QM_SA_MY_TNL, IDS_COL_QM_SA_PEER_TNL, 0, 0, 0}, //IPSECMON_QM_SA
{IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST, IDS_COL_FLTR_SRC_PORT, IDS_COL_FLTR_DEST_PORT, IDS_COL_FLTR_SRC_TNL, IDS_COL_FLTR_DEST_TNL, IDS_COL_FLTR_PROT, IDS_COL_FLTR_IN_FLAG, IDS_COL_FLTR_OUT_FLAG, IDS_COL_QM_POLICY, IDS_COL_IF_TYPE, 0, 0}, // IPSMSNAP_FILTER
{IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST, IDS_COL_FLTR_SRC_PORT, IDS_COL_FLTR_DEST_PORT, IDS_COL_FLTR_SRC_TNL, IDS_COL_FLTR_DEST_TNL, IDS_COL_FLTR_PROT, IDS_COL_FLTR_FLAG, IDS_COL_FLTR_DIR, IDS_COL_QM_POLICY, IDS_COL_FLTR_WEIGHT, 0, 0}, // IPSECMON_SPECIFIC_FILTER
{0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_QUICK_MODE
{0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_MAIN_MODE
{IDS_COL_MM_POL_NAME,IDS_COL_MM_POL_OFFER,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_MM_POLICY
{IDS_COL_QM_POL_NAME,IDS_COL_QM_POL_OFFER,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_QM_POLICY
{IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST, IDS_COL_MM_FLTR_POL, IDS_COL_MM_FLTR_AUTH,IDS_COL_IF_TYPE,0,0,0,0,0,0,0,0}, // IPSMSNAP_MM_FILTER
{IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST,IDS_COL_FLTR_DIR,IDS_COL_MM_FLTR_POL,IDS_COL_MM_FLTR_AUTH,IDS_COL_FLTR_WEIGHT,0,0,0,0,0,0,0}, // IPSMSNAP_MM_SP_FILTER
{IDS_COL_MM_SA_ME,IDS_COL_MM_SA_PEER,IDS_COL_MM_SA_AUTH,IDS_COL_MM_SA_ENCRYPITON,IDS_COL_MM_SA_INTEGRITY,IDS_COL_MM_SA_DH,0,0,0,0,0,0,0,0}, //IPSECMON_MM_SA
{0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
//
// CODEWORK this should be in a resource, for example code on loading data resources see
// D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
// JonN 10/11/96
//
int aColumnWidths[IPSECMON_NODETYPE_MAX][MAX_COLUMNS] =
{
{200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSMSNAP_ROOT
{200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSMSNAP_SERVER
{150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_QM_SA
{150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_FILTER
{150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_SPECIFIC_FILTER
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_QUICK_MODE
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MAIN_MODE
{150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_POLICY
{150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_QM_POLICY
{150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_FILTER
{150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_SP_FILTER
{150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_SA
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH},
};
#define HI HIDDEN
#define EN ENABLED
MMC_CONSOLE_VERB g_ConsoleVerbs[] =
{
MMC_VERB_OPEN,
MMC_VERB_COPY,
MMC_VERB_PASTE,
MMC_VERB_DELETE,
MMC_VERB_PROPERTIES,
MMC_VERB_RENAME,
MMC_VERB_REFRESH,
MMC_VERB_PRINT
};
// default states for the console verbs
MMC_BUTTON_STATE g_ConsoleVerbStates[IPSECMON_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
{
{HI, HI, HI, HI, HI, HI, HI, HI}, // IPSMSNAP_ROOT
{HI, HI, HI, EN, EN, HI, HI, HI}, // IPSMSNAP_SERVER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_SA
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_FILTER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_SPECIFIC_FILTER
{HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_QUICK_MODE,
{HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_MAIN_MODE,
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_POLICY
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_POLICY
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_FILTER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SP_FILTER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SA
{HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_QM_SA_ITEM,
{HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_FILTER_ITEM
{HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_SPECIFIC_FILTER_ITEM,
{HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_MM_POLICY_ITEM
{HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_QM_POLICY_ITEM
{HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_MM_FILTER_ITEM
{HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_MM_SP_FILTER_ITEM
{HI, HI, HI, HI, EN, HI, HI, HI} // IPSECMON_MM_SA_ITEM
};
// default states for the console verbs
MMC_BUTTON_STATE g_ConsoleVerbStatesMultiSel[IPSECMON_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
{
{HI, HI, HI, HI, HI, HI, HI, HI}, // IPSMSNAP_ROOT
{HI, HI, HI, EN, EN, HI, HI, HI}, // IPSMSNAP_SERVER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_SA
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_FILTER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_SPECIFIC_FILTER
{HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_QUICK_MODE,
{HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_MAIN_MODE,
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_POLICY
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_POLICY
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_FILTER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SP_FILTER
{HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SA
{HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_QM_SA_ITEM,
{HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_FILTER_ITEM
{HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_SPECIFIC_FILTER_ITEM,
{HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_MM_POLICY_ITEM
{HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_QM_POLICY_ITEM
{HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_MM_FILTER_ITEM
{HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_MM_SP_FILTER_ITEM
{HI, HI, HI, EN, HI, HI, HI, HI} // IPSECMON_MM_SA_ITEM
};
//TODO
// Help ID array for help on scope items
DWORD g_dwMMCHelp[IPSECMON_NODETYPE_MAX] =
{
IPSMSNAP_HELP_ROOT, // IPSMSNAP_ROOT
IPSMSNAP_HELP_SERVER, // IPSMSNAP_SERVER
IPSMSNAP_HELP_PROVIDER, // IPSECMON_QM_SA
IPSMSNAP_HELP_ROOT, // IPSECMON_FILTAER
IPSMSNAP_HELP_DEVICE, // IPSECMON_QM_SA_ITEM
};
// icon defines
UINT g_uIconMap[ICON_IDX_MAX + 1][2] =
{
{IDI_ICON01, ICON_IDX_SERVER},
{IDI_ICON02, ICON_IDX_SERVER_BUSY},
{IDI_ICON03, ICON_IDX_SERVER_CONNECTED},
{IDI_ICON04, ICON_IDX_SERVER_LOST_CONNECTION},
{IDI_ICON05, ICON_IDX_MACHINE},
{IDI_ICON06, ICON_IDX_FOLDER_CLOSED},
{IDI_ICON07, ICON_IDX_FOLDER_OPEN},
{IDI_IPSECMON_SNAPIN, ICON_IDX_PRODUCT},
{IDI_IPSM_FILTER, ICON_IDX_FILTER},
{IDI_IPSM_POLICY, ICON_IDX_POLICY},
{0, 0}
};
/*!--------------------------------------------------------------------------
GetSystemMessage
Use FormatMessage() to get a system error message
Author: EricDav
---------------------------------------------------------------------------*/
LONG
GetSystemMessage
(
UINT nId,
TCHAR * chBuffer,
int cbBuffSize
)
{
TCHAR * pszText = NULL ;
HINSTANCE hdll = NULL ;
DWORD flags = FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_MAX_WIDTH_MASK;
//
// Interpret the error. Need to special case
// the lmerr & ntstatus ranges, as well as
// dhcp server error messages.
//
if( nId >= NERR_BASE && nId <= MAX_NERR )
{
hdll = LoadLibrary( _T("netmsg.dll") );
}
else if( nId >= 0x40000000L )
{
hdll = LoadLibrary( _T("ntdll.dll") );
}
if( hdll == NULL )
{
flags |= FORMAT_MESSAGE_FROM_SYSTEM;
}
else
{
flags |= FORMAT_MESSAGE_FROM_HMODULE;
}
//
// Let FormatMessage do the dirty work.
//
DWORD dwResult = ::FormatMessage( flags,
(LPVOID) hdll,
nId,
0,
chBuffer,
cbBuffSize,
NULL ) ;
if( hdll != NULL )
{
LONG err = GetLastError();
FreeLibrary( hdll );
if ( dwResult == 0 )
{
::SetLastError( err );
}
}
return dwResult ? 0 : ::GetLastError() ;
}
/*!--------------------------------------------------------------------------
LoadMessage
Loads the error message from the correct DLL.
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
LoadMessage
(
UINT nIdPrompt,
TCHAR * chMsg,
int nMsgSize
)
{
BOOL bOk;
//
// Substitute a friendly message for "RPC server not
// available" and "No more endpoints available from
// the endpoint mapper".
//
if (nIdPrompt == RPC_S_UNKNOWN_IF)
{
nIdPrompt = IDS_ERR_SPD_DOWN;
}
else if (nIdPrompt == RPC_S_SERVER_UNAVAILABLE)
{
nIdPrompt = IDS_ERR_SPD_UNAVAILABLE;
}
//
// If it's a socket error or our error, the text is in our resource fork.
// Otherwise, use FormatMessage() and the appropriate DLL.
//
if (nIdPrompt >= IDS_ERR_BASE && nIdPrompt < IDS_MESG_MAX)
{
//
// It's in our resource fork
//
bOk = ::LoadString( AfxGetInstanceHandle(), nIdPrompt, chMsg, nMsgSize ) != 0 ;
}
else
{
//
// It's in the system somewhere.
//
bOk = GetSystemMessage( nIdPrompt, chMsg, nMsgSize ) == 0 ;
}
//
// If the error message did not compute, replace it.
//
if ( ! bOk )
{
TCHAR chBuff [STRING_LENGTH_MAX] ;
static const TCHAR * pszReplacement = _T("System Error: %ld");
const TCHAR * pszMsg = pszReplacement ;
//
// Try to load the generic (translatable) error message text
//
if ( ::LoadString( AfxGetInstanceHandle(), IDS_ERR_MESSAGE_GENERIC,
chBuff, DimensionOf(chBuff) ) != 0 )
{
pszMsg = chBuff ;
}
::wsprintf( chMsg, pszMsg, nIdPrompt ) ;
}
return bOk;
}
/*!--------------------------------------------------------------------------
IpsmMessageBox
Puts up a message box with the corresponding error text.
Author: EricDav
---------------------------------------------------------------------------*/
int
IpsmMessageBox
(
UINT nIdPrompt,
UINT nType,
const TCHAR * pszSuffixString,
UINT nHelpContext
)
{
TCHAR chMesg [4000] = {0};
BOOL bOk ;
bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(chMesg[0]));
if ( pszSuffixString )
{
::lstrcat( chMesg, _T(" ") ) ;
::lstrcat( chMesg, pszSuffixString ) ;
}
return ::AfxMessageBox( chMesg, nType, nHelpContext ) ;
}
/*!--------------------------------------------------------------------------
IpsmMessageBoxEx
Puts up a message box with the corresponding error text.
Author: EricDav
---------------------------------------------------------------------------*/
int
IpsmMessageBoxEx
(
UINT nIdPrompt,
LPCTSTR pszPrefixMessage,
UINT nType,
UINT nHelpContext
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
TCHAR chMesg[4000] = {0};
CString strMessage;
BOOL bOk;
bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(chMesg[0]));
if ( pszPrefixMessage )
{
strMessage = pszPrefixMessage;
strMessage += _T("\n");
strMessage += _T("\n");
strMessage += chMesg;
}
else
{
strMessage = chMesg;
}
return AfxMessageBox(strMessage, nType, nHelpContext);
}
/*---------------------------------------------------------------------------
Class CIpsmComponent implementation
---------------------------------------------------------------------------*/
CIpsmComponent::CIpsmComponent()
{
m_pbmpToolbar = NULL;
}
CIpsmComponent::~CIpsmComponent()
{
if (m_pbmpToolbar)
{
delete m_pbmpToolbar;
m_pbmpToolbar = NULL;
}
}
STDMETHODIMP CIpsmComponent::InitializeBitmaps(MMC_COOKIE cookie)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(m_spImageList != NULL);
HICON hIcon;
for (int i = 0; i < ICON_IDX_MAX; i++)
{
hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
if (hIcon)
{
// call mmc
VERIFY(SUCCEEDED(m_spImageList->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1])));
}
}
return S_OK;
}
/*!--------------------------------------------------------------------------
CIpsmComponent::QueryDataObject
Implementation of IComponent::QueryDataObject. We need this for
virtual listbox support. MMC calls us back normally with the cookie
we handed it... In the case of the VLB, it hands us the index of
the item. So, we need to do some extra checking...
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CIpsmComponent::QueryDataObject
(
MMC_COOKIE cookie,
DATA_OBJECT_TYPES type,
LPDATAOBJECT* ppDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
SPITFSNode spSelectedNode;
SPITFSResultHandler spResultHandler;
long lViewOptions;
LPOLESTR pViewType;
CDataObject * pDataObject;
COM_PROTECT_TRY
{
// check to see what kind of result view type the selected node has
CORg (GetSelectedNode(&spSelectedNode));
CORg (spSelectedNode->GetResultHandler(&spResultHandler));
CORg (spResultHandler->OnGetResultViewType(this, spSelectedNode->GetData(TFS_DATA_COOKIE), &pViewType, &lViewOptions));
if ( (lViewOptions & MMC_VIEW_OPTIONS_OWNERDATALIST) ||
(cookie == MMC_MULTI_SELECT_COOKIE) )
{
if (cookie == MMC_MULTI_SELECT_COOKIE)
{
// this is a special case for multiple select. We need to build a list
// of GUIDs and the code to do this is in the handler...
spResultHandler->OnCreateDataObject(this, cookie, type, ppDataObject);
}
else
{
// this node has a virtual listbox for the result pane. Gerenate
// a special data object using the selected node as the cookie
Assert(m_spComponentData != NULL);
CORg (m_spComponentData->QueryDataObject(reinterpret_cast<MMC_COOKIE>((ITFSNode *) spSelectedNode), type, ppDataObject));
}
pDataObject = reinterpret_cast<CDataObject *>(*ppDataObject);
pDataObject->SetVirtualIndex((int) cookie);
}
else
{
// just forward this to the component data
Assert(m_spComponentData != NULL);
CORg (m_spComponentData->QueryDataObject(cookie, type, ppDataObject));
}
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH
return hr;
}
/*!--------------------------------------------------------------------------
CIpsmComponent::CompareObjects
Implementation of IComponent::CompareObjects
MMC calls this to compare two objects
We override this for the virtual listbox case. With a virtual listbox,
the cookies are the same, but the index in the internal structs
indicate which item the dataobject refers to. So, we need to look
at the indicies instead of just the cookies.
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP
CIpsmComponent::CompareObjects
(
LPDATAOBJECT lpDataObjectA,
LPDATAOBJECT lpDataObjectB
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (lpDataObjectA == NULL || lpDataObjectB == NULL)
return E_POINTER;
// Make sure both data object are mine
SPINTERNAL spA;
SPINTERNAL spB;
HRESULT hr = S_FALSE;
COM_PROTECT_TRY
{
spA = ExtractInternalFormat(lpDataObjectA);
spB = ExtractInternalFormat(lpDataObjectB);
if (spA != NULL && spB != NULL)
{
if (spA->m_cookie != spB->m_cookie)
{
hr = S_FALSE;
}
else
{
if (spA->HasVirtualIndex() && spB->HasVirtualIndex())
{
hr = (spA->GetVirtualIndex() == spB->GetVirtualIndex()) ? S_OK : S_FALSE;
}
else
{
hr = S_OK;
}
}
}
}
COM_PROTECT_CATCH
return hr;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::SetControlbar
-
Author: EricDav, KennT
---------------------------------------------------------------------------*/
HRESULT
CIpsmComponent::SetControlbar
(
LPCONTROLBAR pControlbar
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
if (pControlbar)
{
}
// store the control bar away for future use
m_spControlbar.Set(pControlbar);
return hr;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::ControlbarNotify
-
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CIpsmComponent::ControlbarNotify
(
MMC_NOTIFY_TYPE event,
LPARAM arg,
LPARAM param
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
return hr;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::OnSnapinHelp
-
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CIpsmComponent::OnSnapinHelp
(
LPDATAOBJECT pDataObject,
LPARAM arg,
LPARAM param
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
//TODO add the help info here
HtmlHelpA(NULL, "ipsecconcepts.chm", HH_DISPLAY_TOPIC, 0);
return hr;
}
/*---------------------------------------------------------------------------
Class CIpsmComponentData implementation
---------------------------------------------------------------------------*/
CIpsmComponentData::CIpsmComponentData()
{
gdwIpsmSnapVersion = IPSMSNAP_VERSION;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::OnInitialize
-
Author: EricDav, KennT
---------------------------------------------------------------------------*/
STDMETHODIMP CIpsmComponentData::OnInitialize(LPIMAGELIST pScopeImage)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HICON hIcon;
for (int i = 0; i < ICON_IDX_MAX; i++)
{
hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
if (hIcon)
{
// call mmc
VERIFY(SUCCEEDED(pScopeImage->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1])));
}
}
return hrOK;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::OnDestroy
-
Author: EricDav, KennT
---------------------------------------------------------------------------*/
STDMETHODIMP CIpsmComponentData::OnDestroy()
{
m_spNodeMgr.Release();
return hrOK;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::OnInitializeNodeMgr
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CIpsmComponentData::OnInitializeNodeMgr
(
ITFSComponentData * pTFSCompData,
ITFSNodeMgr * pNodeMgr
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// For now create a new node handler for each new node,
// this is rather bogus as it can get expensive. We can
// consider creating only a single node handler for each
// node type.
CIpsmRootHandler * pHandler = NULL;
SPITFSNodeHandler spHandler;
SPITFSNode spNode;
HRESULT hr = hrOK;
try
{
pHandler = new CIpsmRootHandler(pTFSCompData);
// Do this so that it will get released correctly
spHandler = pHandler;
}
catch(...)
{
hr = E_OUTOFMEMORY;
}
CORg( hr );
// Create the root node for this sick puppy
CORg( CreateContainerTFSNode(&spNode,
&GUID_IpsmRootNodeType,
pHandler,
pHandler, /* result handler */
pNodeMgr) );
// Need to initialize the data for the root node
pHandler->InitializeNode(spNode);
CORg( pNodeMgr->SetRootNode(spNode) );
m_spRootNode.Set(spNode);
//TODO this should refer to ipsmsnap.chm
pTFSCompData->SetHTMLHelpFileName(_T("ipsecconcepts.chm"));
Error:
return hr;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::OnCreateComponent
-
Author: EricDav, KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CIpsmComponentData::OnCreateComponent
(
LPCOMPONENT *ppComponent
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(ppComponent != NULL);
HRESULT hr = hrOK;
CIpsmComponent * pComp = NULL;
try
{
pComp = new CIpsmComponent;
}
catch(...)
{
hr = E_OUTOFMEMORY;
}
if (FHrSucceeded(hr))
{
pComp->Construct(m_spNodeMgr,
static_cast<IComponentData *>(this),
m_spTFSComponentData);
*ppComponent = static_cast<IComponent *>(pComp);
}
return hr;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::GetCoClassID
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP_(const CLSID *)
CIpsmComponentData::GetCoClassID()
{
return &CLSID_IpsmSnapin;
}
/*!--------------------------------------------------------------------------
CIpsmComponentData::OnCreateDataObject
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CIpsmComponentData::OnCreateDataObject
(
MMC_COOKIE cookie,
DATA_OBJECT_TYPES type,
IDataObject ** ppDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
Assert(ppDataObject != NULL);
CDataObject * pObject = NULL;
SPIDataObject spDataObject;
pObject = new CDataObject;
spDataObject = pObject; // do this so that it gets released correctly
Assert(pObject != NULL);
// Save cookie and type for delayed rendering
pObject->SetType(type);
pObject->SetCookie(cookie);
// Store the coclass with the data object
pObject->SetClsid(*GetCoClassID());
pObject->SetTFSComponentData(m_spTFSComponentData);
return pObject->QueryInterface(IID_IDataObject,
reinterpret_cast<void**>(ppDataObject));
}
///////////////////////////////////////////////////////////////////////////////
//// IPersistStream interface members
STDMETHODIMP
CIpsmComponentData::GetClassID
(
CLSID *pClassID
)
{
ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_IpsmSnapin;
return hrOK;
}
STDMETHODIMP
CIpsmComponentData::IsDirty()
{
HRESULT hr = hrFalse;
if (m_spRootNode->GetData(TFS_DATA_DIRTY))
{
hr = hrOK;
}
return hr;
}
STDMETHODIMP
CIpsmComponentData::Load
(
IStream *pStm
)
{
HRESULT hr = hrOK;
DWORD dwSavedVersion;
CString str;
int i, j;
ASSERT(pStm);
CStringArray strArrayName;
CDWordArray dwArrayRefreshInterval;
CDWordArray dwArrayOptions;
CDWordArray dwArrayColumnInfo;
ASSERT(pStm);
CIpsmRootHandler * pRootHandler = GETHANDLER(CIpsmRootHandler, m_spRootNode);
// set the mode for this stream
XferStream xferStream(pStm, XferStream::MODE_READ);
// read the version of the file format
DWORD dwFileVersion;
CORg(xferStream.XferDWORD(IPSMSTRM_TAG_VERSION, &dwFileVersion));
if (dwFileVersion < IPSMSNAP_FILE_VERSION)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
AfxMessageBox(IDS_ERR_OLD_CONSOLE_FILE);
return hr;
}
// Read the version # of the admin tool
CORg(xferStream.XferDWORD(IPSMSTRM_TAG_VERSIONADMIN, &dwSavedVersion));
if (dwSavedVersion < gdwIpsmSnapVersion)
{
// File is an older version. Warn the user and then don't
// load anything else
Assert(FALSE);
}
// now read all of the server information
CORg(xferStream.XferCStringArray(IPSMSTRM_TAG_SERVER_NAME, &strArrayName));
CORg(xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval));
CORg(xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_OPTIONS, &dwArrayOptions));
// now load the column information
for (i = 0; i < NUM_SCOPE_ITEMS; i++)
{
CORg(xferStream.XferDWORDArray(IPSMSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
for (j = 0; j < MAX_COLUMNS; j++)
{
aColumnWidths[i][j] = dwArrayColumnInfo[j];
}
}
// now create the servers based on the information
for (i = 0; i < strArrayName.GetSize(); i++)
{
//
// now create the server object
//
pRootHandler->AddServer(NULL,
strArrayName[i],
FALSE,
dwArrayOptions[i],
dwArrayRefreshInterval[i],
FALSE,
0,
0);
}
Error:
return SUCCEEDED(hr) ? S_OK : E_FAIL;
}
STDMETHODIMP
CIpsmComponentData::Save
(
IStream *pStm,
BOOL fClearDirty
)
{
HRESULT hr = hrOK;
CStringArray strArrayName;
CDWordArray dwArrayRefreshInterval;
CDWordArray dwArrayOptions;
CDWordArray dwArrayColumnInfo;
ASSERT(pStm);
// set the mode for this stream
XferStream xferStream(pStm, XferStream::MODE_WRITE);
CString str;
// Write the version # of the file format
DWORD dwFileVersion = IPSMSNAP_FILE_VERSION;
xferStream.XferDWORD(IPSMSTRM_TAG_VERSION, &dwFileVersion);
// Write the version # of the admin tool
xferStream.XferDWORD(IPSMSTRM_TAG_VERSIONADMIN, &gdwIpsmSnapVersion);
//
// Build our array of servers
//
int nNumServers = 0, nVisibleCount = 0;
hr = m_spRootNode->GetChildCount(&nVisibleCount, &nNumServers);
strArrayName.SetSize(nNumServers);
dwArrayRefreshInterval.SetSize(nNumServers);
dwArrayOptions.SetSize(nNumServers);
dwArrayColumnInfo.SetSize(MAX_COLUMNS);
//
// loop and save off all the server's attributes
//
SPITFSNodeEnum spNodeEnum;
SPITFSNode spCurrentNode;
ULONG nNumReturned = 0;
int nCount = 0;
m_spRootNode->GetEnum(&spNodeEnum);
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
while (nNumReturned)
{
CIpsmServer * pServer = GETHANDLER(CIpsmServer, spCurrentNode);
// query the server for it's options:
// auto refresh
dwArrayRefreshInterval[nCount] = pServer->GetAutoRefreshInterval();
dwArrayOptions[nCount] = pServer->GetOptions();
// put the information in our array
strArrayName[nCount] = pServer->GetName();
// go to the next node
spCurrentNode.Release();
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
nCount++;
}
// now write out all of the server information
xferStream.XferCStringArray(IPSMSTRM_TAG_SERVER_NAME, &strArrayName);
xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval);
xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_OPTIONS, &dwArrayOptions);
// now save the column information
for (int i = 0; i < NUM_SCOPE_ITEMS; i++)
{
for (int j = 0; j < MAX_COLUMNS; j++)
{
dwArrayColumnInfo[j] = aColumnWidths[i][j];
}
xferStream.XferDWORDArray(IPSMSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo);
}
if (fClearDirty)
{
m_spRootNode->SetData(TFS_DATA_DIRTY, FALSE);
}
return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE;
}
STDMETHODIMP
CIpsmComponentData::GetSizeMax
(
ULARGE_INTEGER *pcbSize
)
{
ASSERT(pcbSize);
// Set the size of the string to be saved
ULISet32(*pcbSize, 10000);
return S_OK;
}
STDMETHODIMP
CIpsmComponentData::InitNew()
{
return hrOK;
}
HRESULT
CIpsmComponentData::FinalConstruct()
{
HRESULT hr = hrOK;
hr = CComponentData::FinalConstruct();
if (FHrSucceeded(hr))
{
m_spTFSComponentData->GetNodeMgr(&m_spNodeMgr);
}
return hr;
}
void
CIpsmComponentData::FinalRelease()
{
CComponentData::FinalRelease();
}