windows-nt/Source/XPSP1/NT/net/layer2svc/wlsnp/ccomp.cpp
2020-09-26 16:20:57 +08:00

570 lines
18 KiB
C++

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2001.
//
// File: ccomp.cpp
//
// Contents:
//
//
// History: TaroonM
// 10/30/01
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include <atlimpl.cpp>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// contruction/descruction
DEBUG_DECLARE_INSTANCE_COUNTER(CComponentImpl);
CComponentImpl::CComponentImpl()
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CComponentImpl);
Construct();
}
CComponentImpl::~CComponentImpl()
{
#if DBG==1
ASSERT(dbg_cRef == 0);
#endif
DEBUG_DECREMENT_INSTANCE_COUNTER(CComponentImpl);
// Make sure the interfaces have been released
ASSERT(m_pConsole == NULL);
ASSERT(m_pHeader == NULL);
}
void CComponentImpl::Construct()
{
#if DBG==1
dbg_cRef = 0;
#endif
m_pConsole = NULL;
m_pHeader = NULL;
m_pResultData = NULL;
m_pComponentData = NULL;
m_pConsoleVerb = NULL;
m_CustomViewID = VIEW_DEFAULT_LV;
m_dwSortOrder = 0; // default is 0, else RSI_DESCENDING
m_nSortColumn = 0;
}
/////////////////////////////////////////////////////////////////////////////
// CComponentImpl's IComponent multiple view/instance helper functions
STDMETHODIMP CComponentImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
{
OPT_TRACE( _T("CComponentImpl::QueryDataObject this-%p, cookie-%p\n"), this, cookie );
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (ppDataObject == NULL)
{
TRACE(_T("CComponentImpl::QueryDataObject called with ppDataObject==NULL \n"));
return E_UNEXPECTED;
}
if (cookie == NULL)
{
TRACE(_T("CComponentImpl::QueryDataObject called with cookie==NULL \n"));
return E_UNEXPECTED;
}
*ppDataObject = NULL;
IUnknown* pUnk = (IUnknown *) cookie;
#ifdef _DEBUG
HRESULT hr = pUnk->QueryInterface( IID_IDataObject, (void**)ppDataObject );
OPT_TRACE(_T(" QI on cookie-%p -> pDataObj-%p\n"), cookie, *ppDataObject);
return hr;
#else
return pUnk->QueryInterface( IID_IDataObject, (void**)ppDataObject );
#endif //#ifdef _DEBUG
}
void CComponentImpl::SetIComponentData(CComponentDataImpl* pData)
{
ASSERT(pData);
ASSERT(m_pComponentData == NULL);
LPUNKNOWN pUnk = pData->GetUnknown();
HRESULT hr;
// store their IComponentData for later use
hr = pUnk->QueryInterface(IID_IComponentData, reinterpret_cast<void**>(&m_pComponentData));
// store their CComponentData for later use
m_pCComponentData = pData;
}
STDMETHODIMP CComponentImpl::GetResultViewType(MMC_COOKIE cookie, LPOLESTR* ppViewType, long* pViewOptions)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT (m_CustomViewID == VIEW_DEFAULT_LV);
return S_FALSE;
}
STDMETHODIMP CComponentImpl::Initialize(LPCONSOLE lpConsole)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = E_UNEXPECTED;
ASSERT(lpConsole != NULL);
// Save the IConsole pointer
m_pConsole = lpConsole;
m_pConsole->AddRef();
// QI for IHeaderCtrl
hr = m_pConsole->QueryInterface(IID_IHeaderCtrl, reinterpret_cast<void**>(&m_pHeader));
ASSERT (hr == S_OK);
if (hr != S_OK)
{
return hr;
}
// Pass the IHeaderCtrl Interface on to the console
m_pConsole->SetHeader(m_pHeader);
// QI for IResultData
hr = m_pConsole->QueryInterface(IID_IResultData, reinterpret_cast<void**>(&m_pResultData));
ASSERT (hr == S_OK);
if (hr != S_OK)
{
return hr;
}
// m_pCComponentData->SetResultData (m_pResultData);
// get the IControlVerb interface to support enable/disable of verbs (ie CUT/PASTE etc)
hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
ASSERT(hr == S_OK);
return hr;
}
STDMETHODIMP CComponentImpl::Destroy(MMC_COOKIE cookie)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Release the interfaces that we QI'ed
if (m_pConsole != NULL)
{
// Tell the console to release the header control interface
m_pConsole->SetHeader(NULL);
SAFE_RELEASE(m_pHeader);
SAFE_RELEASE(m_pResultData);
// Release the IConsole interface last
SAFE_RELEASE(m_pConsole);
SAFE_RELEASE(m_pComponentData); // QI'ed in IComponentDataImpl::CreateComponent
SAFE_RELEASE(m_pConsoleVerb);
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// CComponentImpl's IComponent view/data helper functions
STDMETHODIMP CComponentImpl::GetDisplayInfo(LPRESULTDATAITEM pResult)
{
OPT_TRACE(_T("CComponentImpl::GetDisplayInfo this-%p pUnk-%p\n"), this, pResult->lParam);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(pResult != NULL);
if (NULL == pResult)
// gack!
return E_INVALIDARG;
ASSERT( NULL != pResult->lParam );
if (NULL == pResult->lParam)
{
TRACE(_T("CComponentImpl::GetDisplayInfo RESULTDATAITEM.lParam == NULL\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
IUnknown* pUnk = (IUnknown*)pResult->lParam;
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
if (spData == NULL)
{
TRACE(_T("CComponentImpl::GetDisplayInfo QI for IWirelessSnapInDataObject FAILED\n"));
return E_UNEXPECTED;
}
return spData->GetResultDisplayInfo( pResult );
}
/////////////////////////////////////////////////////////////////////////////
// CComponentImpl's I????? misc helper functions
// TODO: Some misc functions don't appear to ever be called?
STDMETHODIMP CComponentImpl::GetClassID(CLSID *pClassID)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT (0);
// TODO: CComponentDataImpl::GetClassID and CComponentImpl::GetClassID are identical (?)
ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_Snapin;
return E_NOTIMPL;
}
// This compares two data objects to see if they are the same object.
STDMETHODIMP CComponentImpl::CompareObjects(LPDATAOBJECT pDataObjectA, LPDATAOBJECT pDataObjectB)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (NULL == pDataObjectA || NULL == pDataObjectB)
return E_INVALIDARG;
HRESULT res = S_FALSE;
// we need to check to make sure both objects belong to us...
if (m_pCComponentData)
{
HRESULT hr;
GUID guidA;
GUID guidB;
// Obtain GUID for A
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataA(pDataObjectA);
if (spDataA == NULL)
{
TRACE(_T("CComponentImpl::CompareObjects - QI for IWirelessSnapInDataObject[A] FAILED\n"));
return E_UNEXPECTED;
}
hr = spDataA->GetGuidForCompare( &guidA );
ASSERT(hr == S_OK);
// Obtain GUID for B
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataB(pDataObjectB);
if (spDataB == NULL)
{
TRACE(_T("CComponentImpl::CompareObjects - QI for IWirelessSnapInDataObject[B] FAILED\n"));
return E_UNEXPECTED;
}
hr &= spDataB->GetGuidForCompare( &guidB );
ASSERT(hr == S_OK);
// Compare GUIDs
if (IsEqualGUID( guidA, guidB ))
{
return S_OK;
}
}
// they were not ours, or they couldn't have been ours...
return E_UNEXPECTED;
}
// This Compare is used to sort the item's in the result pane using the C runtime's
// string comparison function.
STDMETHODIMP CComponentImpl::Compare(LPARAM lUserParam, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int* pnResult)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
OPT_TRACE(_T("CComponentImpl::Compare cookieA-%p, cookieB-%p, Column-%i, userParam-%i\n"), cookieA, cookieB, *pnResult, lUserParam );
// Get pDataObject for item A
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataA((LPDATAOBJECT)cookieA);
if (spDataA == NULL)
{
TRACE(_T("CComponentImpl::Compare - QI for IWirelessSnapInDataObject[A] FAILED\n"));
return E_UNEXPECTED;
}
// Get pDataObject for item B
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataB((LPDATAOBJECT)cookieB);
if (spDataB == NULL)
{
TRACE(_T("CComponentImpl::Compare - QI for IWirelessSnapInDataObject[B] FAILED\n"));
return E_UNEXPECTED;
}
HRESULT hr = S_OK;
do
{
RESULTDATAITEM rdiA;
RESULTDATAITEM rdiB;
// Obtain item A's sort string
rdiA.mask = RDI_STR;
rdiA.nCol = *pnResult; // obtain string for this column
hr = spDataA->GetResultDisplayInfo( &rdiA );
if (hr != S_OK)
{
TRACE(_T("CComponentImpl::Compare - IWirelessSnapInDataObject[A].GetResultDisplayInfo FAILED\n"));
hr = E_UNEXPECTED;
break;
}
// Obtain item B's sort string
rdiB.mask = RDI_STR;
rdiB.nCol = *pnResult; // obtain string for this column
hr = spDataB->GetResultDisplayInfo( &rdiB );
if (hr != S_OK)
{
TRACE(_T("CComponentImpl::Compare - IWirelessSnapInDataObject[B].GetResultDisplayInfo FAILED\n"));
hr = E_UNEXPECTED;
break;
}
// Compare strings for sort
*pnResult = _tcsicmp( rdiA.str, rdiB.str );
} while (0); // simulate try block
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// Event handlers for IFrame::Notify
STDMETHODIMP CComponentImpl::Notify(LPDATAOBJECT pDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
{
OPT_TRACE(_T("CComponentImpl::Notify pDataObject-%p\n"), pDataObject);
if (pDataObject == NULL)
{
if (MMCN_PROPERTY_CHANGE == event)
{
if (param)
{
IWirelessSnapInDataObject * pData = (IWirelessSnapInDataObject *)param;
//used IComponentData's IIconsole, fix for bug 464858
//pData->Notify(event, arg, param, FALSE, m_pConsole, m_pHeader );
pData->Notify(event, arg, param, FALSE, m_pCComponentData->m_pConsole, m_pHeader );
}
}
if (MMCN_COLUMN_CLICK == event)
{
ASSERT( NULL != m_pCComponentData ); // should always have this
// MMCN_COLUMN_CLICK is specified as having a NULL pDataObject.
ASSERT( NULL != m_pResultData );
if (NULL != m_pResultData)
{
// Save sort request details
m_nSortColumn = arg;
m_dwSortOrder = param;
// Sort all result items
HRESULT hr = m_pResultData->Sort( arg, param, 0 );
return hr;
}
return E_UNEXPECTED;
}
TRACE(_T("CComponentImpl::Notify ERROR(?) called with pDataObject==NULL for event-%i\n"), event);
// If this asserts, look at "event" and determine whether it is normal for
// pDataObject to be NULL. If so add code above to handle event.
ASSERT( FALSE );
return E_UNEXPECTED;
}
if (MMCN_VIEW_CHANGE == event)
{
// Pack info for sorting result view into the hint for this event. Its safe
// to do this because all calls to IConsole::UpdateAllViews from within this
// snap-in do not use the hint.
param = MAKELONG( m_nSortColumn, m_dwSortOrder );
}
// Pass call to result item.
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pDataObject );
if (spData == NULL)
{
// If we are loaded as an extension snapin, let our static node handle this.
if (NULL != m_pCComponentData->GetStaticScopeObject()->GetExtScopeObject())
{
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject>
spExtData( m_pCComponentData->GetStaticScopeObject()->GetExtScopeObject() );
if (spExtData != NULL)
{
HRESULT hr;
hr = spExtData->Notify( event, arg, param, FALSE, m_pConsole, m_pHeader );
return hr;
}
ASSERT( FALSE );
}
TRACE(_T("CComponentImpl::Notify - QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
return spData->Notify( event, arg, param, FALSE, m_pConsole, m_pHeader );
}
/////////////////////////////////////////////////////////////////////////////
// IExtendPropertySheet Implementation
STDMETHODIMP CComponentImpl::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT pDataObject)
{
if (pDataObject == NULL)
{
TRACE(_T("CComponentImpl::CreatePropertyPages called with pDataObject == NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentImpl::CreatePropertyPages - QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
return spData->CreatePropertyPages( lpProvider, handle );
}
STDMETHODIMP CComponentImpl::QueryPagesFor(LPDATAOBJECT pDataObject)
{
if (pDataObject == NULL)
{
TRACE(_T("CComponentImpl::QueryPagesFor called with pDataObject == NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentImpl::QueryPagesFor - QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
return spData->QueryPagesFor();
}
/////////////////////////////////////////////////////////////////////////////
// IExtendContextMenus Implementation
STDMETHODIMP CComponentImpl::AddMenuItems(LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pContextMenuCallback, long *pInsertionAllowed)
{
if (pDataObject == NULL)
{
TRACE(_T("CComponentImpl::AddMenuItems called with pDataObject == NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentImpl::AddMenuItems - QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
return spData->AddMenuItems( pContextMenuCallback, pInsertionAllowed );
}
STDMETHODIMP CComponentImpl::Command(long nCommandID, LPDATAOBJECT pDataObject)
{
if (pDataObject == NULL)
{
TRACE(_T("CComponentImpl::Command called with pDataObject == NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentImpl::Command - QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
return spData->Command( nCommandID, NULL /*IConsoleNameSpace* */ );
}
/////////////////////////////////////////////////////////////////////////////
// IExtendControlbar Implementation
STDMETHODIMP CComponentImpl::SetControlbar( LPCONTROLBAR pControlbar )
{
OPT_TRACE( _T("CComponentImpl::IExtendControlbar::SetControlbar\n") );
// pControlbar was obtained by MMC (MMCNDMGR) from our CComponentImpl by doing
// a QI on IExtendControlbar. Save it so we can use it later.
// Note: Always assign pControlbar to our smart pointer. pControlbar == NULL
// when MMC wants us to release the interface we already have.
m_spControlbar = pControlbar;
return S_OK;
}
STDMETHODIMP CComponentImpl::ControlbarNotify( MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param )
{
OPT_TRACE( _T("CComponentImpl::IExtendControlbar::ControlbarNotify\n") );
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Obtain the data obj of the currently selected item.
LPDATAOBJECT pDataObject = NULL;
if (event == MMCN_BTN_CLICK)
{
pDataObject = (LPDATAOBJECT)arg;
}
else if (event == MMCN_SELECT)
{
pDataObject = (LPDATAOBJECT)param;
}
if (NULL == pDataObject)
{
// This can happen on a MMCN_BTN_CLICK if the result pane is clicked, but not
// on a result item, then a scope item toolbar button is pressed. In this case
// check for one of the known scope item toolbar commands.
if (IDM_CREATENEWSECPOL == param )
{
pDataObject = m_pCComponentData->GetStaticScopeObject();
}
else
{
TRACE(_T("CComponentImpl::ControlbarNotify - ERROR no IDataObject available\n"));
return E_UNEXPECTED;
}
}
// Let selected item handle command
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pDataObject );
if (spData == NULL)
{
TRACE(_T("CComponentImpl::ControlbarNotify - QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
HRESULT hr = spData->ControlbarNotify( m_spControlbar, (IExtendControlbar*)this,
event, arg, param );
// If the command was not handled by the selected item, pass it to our static
// scope obj.
if (E_NOTIMPL == hr || S_FALSE == hr)
{
if (m_pCComponentData->GetStaticScopeObject() != pDataObject)
{
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject>
spScopeData( m_pCComponentData->GetStaticScopeObject() );
if (spScopeData == NULL)
{
TRACE(_T("CComponentImpl::ControlbarNotify - StaticScopeObj.QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
hr = spScopeData->ControlbarNotify( m_spControlbar, (IExtendControlbar*)this,
event, arg, param );
}
}
return hr;
}