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

547 lines
17 KiB
C++

//////////////////////////////////////////////////////////////////////////////
/*++
Copyright (C) Microsoft Corporation, 1997 - 1999
Module Name:
LocalFileLoggingNode.cpp
Abstract:
Implementation file for the CClient class.
Author:
Michael A. Maguire 12/15/97
Revision History:
mmaguire 12/15/97 - created
--*/
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// BEGIN INCLUDES
//
// standard includes:
//
#include "Precompiled.h"
//
// where we can find declaration for main class in this file:
//
#include "logcomp.h"
#include "LocalFileLoggingNode.h"
#include "LogCompD.h"
#include "SnapinNode.cpp" // Template class implementation
//
//
// where we can find declarations needed in this file:
//
#include "LoggingMethodsNode.h"
#include "LocalFileLoggingPage1.h"
#include "LocalFileLoggingPage2.h"
#include "LogMacNd.h"
// Need to include this at least once to get in build:
#include "sdohelperfuncs.cpp"
//
// END INCLUDES
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::CLocalFileLoggingNode
Constructor
--*/
//////////////////////////////////////////////////////////////////////////////
CLocalFileLoggingNode::CLocalFileLoggingNode( CSnapInItem * pParentNode )
:CSnapinNode<CLocalFileLoggingNode, CLoggingComponentData, CLoggingComponent>(pParentNode)
{
ATLTRACE(_T("# +++ CLocalFileLoggingNode::CLocalFileLoggingNode\n"));
// Check for preconditions:
// None.
// for help files
m_helpIndex = (((CLoggingMethodsNode *)m_pParentNode)->m_ExtendRas)? RAS_HELP_INDEX:0;
// Set the display name for this object
TCHAR lpszName[IAS_MAX_STRING];
int nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_NODE__NAME, lpszName, IAS_MAX_STRING );
_ASSERT( nLoadStringResult > 0 );
m_bstrDisplayName = lpszName;
m_resultDataItem.nImage = IDBI_NODE_LOCAL_FILE_LOGGING;
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::InitSdoPointers
Call as soon as you have constructed this class and pass in it's SDO pointer.
--*/
//////////////////////////////////////////////////////////////////////////////
HRESULT CLocalFileLoggingNode::InitSdoPointers( ISdo *pSdoMachine )
{
ATLTRACE(_T("# CLocalFileLoggingNode::InitSdoPointers\n"));
// Check for preconditions:
_ASSERTE( pSdoMachine != NULL );
HRESULT hr = S_OK;
hr = pSdoMachine->QueryInterface( IID_ISdoServiceControl, (void **) &m_spSdoServiceControl );
if( FAILED(hr) || ! m_spSdoServiceControl )
{
ShowErrorDialog( NULL, IDS_ERROR__CANT_READ_DATA_FROM_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return 0;
}
// Get the SDO accounting object.
hr = ::SDOGetSdoFromCollection( pSdoMachine
, PROPERTY_IAS_REQUESTHANDLERS_COLLECTION
, PROPERTY_COMPONENT_ID
, IAS_PROVIDER_MICROSOFT_ACCOUNTING
, &m_spSdoAccounting
);
if( m_spSdoAccounting == NULL )
{
ShowErrorDialog( NULL, IDS_ERROR__CANT_READ_DATA_FROM_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return 0;
}
return hr;
}
// refresh date
HRESULT CLocalFileLoggingNode::DataRefresh(ISdo* pSdoMachine)
{
// Check for preconditions:
_ASSERTE( pSdoMachine != NULL );
HRESULT hr = S_OK;
m_spSdoServiceControl.Release();
hr = pSdoMachine->QueryInterface( IID_ISdoServiceControl, (void **) &m_spSdoServiceControl );
if( FAILED(hr) || ! m_spSdoServiceControl )
{
ShowErrorDialog( NULL, IDS_ERROR__CANT_READ_DATA_FROM_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return 0;
}
// Get the SDO accounting object.
m_spSdoAccounting.Release();
hr = ::SDOGetSdoFromCollection( pSdoMachine
, PROPERTY_IAS_REQUESTHANDLERS_COLLECTION
, PROPERTY_COMPONENT_ID
, IAS_PROVIDER_MICROSOFT_ACCOUNTING
, &m_spSdoAccounting
);
if( m_spSdoAccounting == NULL )
{
ShowErrorDialog( NULL, IDS_ERROR__CANT_READ_DATA_FROM_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return 0;
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::LoadCachedInfoFromSdo
For quick screen updates, we cache some information like client name,
address, protocol and NAS type. Call this to load this information
from the SDO's into the caches.
--*/
//////////////////////////////////////////////////////////////////////////////
HRESULT CLocalFileLoggingNode::LoadCachedInfoFromSdo( void )
{
ATLTRACE(_T("# CLocalFileLoggingNode::LoadCachedInfoFromSdo\n"));
// Check for preconditions:
if( m_spSdoAccounting == NULL )
{
return E_FAIL;
}
HRESULT hr;
CComVariant spVariant;
// Load the log file directory.
hr = m_spSdoAccounting->GetProperty( PROPERTY_ACCOUNTING_LOG_FILE_DIRECTORY, &spVariant );
if( SUCCEEDED( hr ) )
{
_ASSERTE( spVariant.vt == VT_BSTR );
m_bstrDescription = spVariant.bstrVal;
}
spVariant.Clear();
return hr;
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::~CLocalFileLoggingNode
Destructor
--*/
//////////////////////////////////////////////////////////////////////////////
CLocalFileLoggingNode::~CLocalFileLoggingNode()
{
ATLTRACE(_T("# --- CLocalFileLoggingNode::~CLocalFileLoggingNode\n"));
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::CreatePropertyPages
See CSnapinNode::CreatePropertyPages (which this method overrides) for detailed info.
--*/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CLocalFileLoggingNode::CreatePropertyPages (
LPPROPERTYSHEETCALLBACK pPropertySheetCallback
, LONG_PTR hNotificationHandle
, IUnknown* pUnknown
, DATA_OBJECT_TYPES type
)
{
ATLTRACE(_T("# CLocalFileLoggingNode::CreatePropertyPages\n"));
// Check for preconditions:
_ASSERTE( pPropertySheetCallback != NULL );
HRESULT hr;
CLoggingMachineNode * pServerNode = GetServerRoot();
_ASSERTE( pServerNode != NULL );
hr = pServerNode->CheckConnectionToServer();
if( FAILED( hr ) )
{
return hr;
}
TCHAR lpszTab1Name[IAS_MAX_STRING];
TCHAR lpszTab2Name[IAS_MAX_STRING];
int nLoadStringResult;
// Load property page tab name from resource.
nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_PAGE1__TAB_NAME, lpszTab1Name, IAS_MAX_STRING );
_ASSERT( nLoadStringResult > 0 );
// This page will take care of deleting itself when it
// receives the PSPCB_RELEASE message.
// We specify TRUE for the bOwnsNotificationHandle parameter so that this page's destructor will be
// responsible for freeing the notification handle. Only one page per sheet should do this.
CLocalFileLoggingPage1 * pLocalFileLoggingPage1 = new CLocalFileLoggingPage1( hNotificationHandle, this, lpszTab1Name, TRUE );
if( NULL == pLocalFileLoggingPage1 )
{
ATLTRACE(_T("# ***FAILED***: CLocalFileLoggingNode::CreatePropertyPages -- Couldn't create property pages\n"));
return E_OUTOFMEMORY;
}
// Load property page tab name from resource.
nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_PAGE2__TAB_NAME, lpszTab2Name, IAS_MAX_STRING );
_ASSERT( nLoadStringResult > 0 );
// This page will take care of deleting itself when it
// receives the PSPCB_RELEASE message.
CLocalFileLoggingPage2 * pLocalFileLoggingPage2 = new CLocalFileLoggingPage2( hNotificationHandle, this, lpszTab2Name );
if( NULL == pLocalFileLoggingPage2 )
{
ATLTRACE(_T("# ***FAILED***: CLocalFileLoggingNode::CreatePropertyPages -- Couldn't create property pages\n"));
// Clean up the first page we created.
delete pLocalFileLoggingPage1;
return E_OUTOFMEMORY;
}
// Marshall the ISdo pointer so that the property page, which
// runs in another thread, can unmarshall it and use it properly.
hr = CoMarshalInterThreadInterfaceInStream(
IID_ISdo //Reference to the identifier of the interface
, m_spSdoAccounting //Pointer to the interface to be marshaled
, &( pLocalFileLoggingPage1->m_pStreamSdoAccountingMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface
);
if( FAILED( hr ) )
{
delete pLocalFileLoggingPage1;
delete pLocalFileLoggingPage2;
ShowErrorDialog( NULL, IDS_ERROR__NO_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return E_FAIL;
}
// Marshall the ISdo pointer so that the property page, which
// runs in another thread, can unmarshall it and use it properly.
hr = CoMarshalInterThreadInterfaceInStream(
IID_ISdo //Reference to the identifier of the interface
, m_spSdoAccounting //Pointer to the interface to be marshaled
, &( pLocalFileLoggingPage2->m_pStreamSdoAccountingMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface
);
if( FAILED( hr ) )
{
delete pLocalFileLoggingPage1;
delete pLocalFileLoggingPage2;
ShowErrorDialog( NULL, IDS_ERROR__NO_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return E_FAIL;
}
// Marshall the ISdo pointer so that the property page, which
// runs in another thread, can unmarshall it and use it properly.
hr = CoMarshalInterThreadInterfaceInStream(
IID_ISdoServiceControl //Reference to the identifier of the interface
, m_spSdoServiceControl //Pointer to the interface to be marshaled
, &( pLocalFileLoggingPage1->m_pStreamSdoServiceControlMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface
);
if( FAILED( hr ) )
{
delete pLocalFileLoggingPage1;
delete pLocalFileLoggingPage2;
ShowErrorDialog( NULL, IDS_ERROR__NO_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return E_FAIL;
}
// Marshall the ISdo pointer so that the property page, which
// runs in another thread, can unmarshall it and use it properly.
hr = CoMarshalInterThreadInterfaceInStream(
IID_ISdoServiceControl //Reference to the identifier of the interface
, m_spSdoServiceControl //Pointer to the interface to be marshaled
, &( pLocalFileLoggingPage2->m_pStreamSdoServiceControlMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface
);
if( FAILED( hr ) )
{
delete pLocalFileLoggingPage1;
delete pLocalFileLoggingPage2;
ShowErrorDialog( NULL, IDS_ERROR__NO_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE, GetComponentData()->m_spConsole );
return E_FAIL;
}
// Add the pages to the MMC property sheet.
hr = pPropertySheetCallback->AddPage( pLocalFileLoggingPage1->Create() );
_ASSERT( SUCCEEDED( hr ) );
hr = pPropertySheetCallback->AddPage( pLocalFileLoggingPage2->Create() );
_ASSERT( SUCCEEDED( hr ) );
// Add a synchronization object which makes sure we only commit data
// when all pages are OK with their data.
CSynchronizer * pSynchronizer = new CSynchronizer();
_ASSERTE( pSynchronizer != NULL );
// Hand the sycnchronizer off to the pages.
pLocalFileLoggingPage1->m_pSynchronizer = pSynchronizer;
pSynchronizer->AddRef();
pLocalFileLoggingPage2->m_pSynchronizer = pSynchronizer;
pSynchronizer->AddRef();
return hr;
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::QueryPagesFor
See CSnapinNode::QueryPagesFor (which this method overrides) for detailed info.
--*/
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CLocalFileLoggingNode::QueryPagesFor ( DATA_OBJECT_TYPES type )
{
ATLTRACE(_T("# CLocalFileLoggingNode::QueryPagesFor\n"));
// S_OK means we have pages to display
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::GetResultPaneColInfo
See CSnapinNode::GetResultPaneColInfo (which this method overrides) for detailed info.
--*/
//////////////////////////////////////////////////////////////////////////////
OLECHAR* CLocalFileLoggingNode::GetResultPaneColInfo(int nCol)
{
ATLTRACE(_T("# CLocalFileLoggingNode::GetResultPaneColInfo\n"));
// Check for preconditions:
// None.
switch( nCol )
{
case 0:
return m_bstrDisplayName;
break;
case 1:
return m_bstrDescription;
break;
default:
// ISSUE: error -- should we assert here?
return NULL;
break;
}
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::SetVerbs
See CSnapinNode::SetVerbs (which this method overrides) for detailed info.
--*/
//////////////////////////////////////////////////////////////////////////////
HRESULT CLocalFileLoggingNode::SetVerbs( IConsoleVerb * pConsoleVerb )
{
ATLTRACE(_T("# CLocalFileLoggingNode::SetVerbs\n"));
// Check for preconditions:
_ASSERTE( pConsoleVerb != NULL );
HRESULT hr = S_OK;
// We want the user to be able to choose Properties on this node
hr = pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE );
// We want Properties to be the default
hr = pConsoleVerb->SetDefaultVerb( MMC_VERB_PROPERTIES );
return hr;
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::GetComponentData
This method returns our unique CComponentData object representing the scope
pane of this snapin.
It relies upon the fact that each node has a pointer to its parent,
except for the root node, which instead has a member variable pointing
to CComponentData.
This would be a useful function to use if, for example, you need a reference
to some IConsole but you weren't passed one. You can use GetComponentData
and then use the IConsole pointer which is a member variable of our
CComponentData object.
--*/
//////////////////////////////////////////////////////////////////////////////
CLoggingComponentData * CLocalFileLoggingNode::GetComponentData( void )
{
ATLTRACE(_T("# CLocalFileLoggingNode::GetComponentData\n"));
// Check for preconditions:
_ASSERTE( m_pParentNode != NULL );
return ((CLoggingMethodsNode *) m_pParentNode)->GetComponentData();
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::GetServerRoot
This method returns the Server node under which this node can be found.
It relies upon the fact that each node has a pointer to its parent,
all the way up to the server node.
This would be a useful function to use if, for example, you need a reference
to some data specific to a server.
--*/
//////////////////////////////////////////////////////////////////////////////
CLoggingMachineNode * CLocalFileLoggingNode::GetServerRoot( void )
{
ATLTRACE(_T("# CLocalFileLoggingNode::GetServerRoot\n"));
// Check for preconditions:
_ASSERTE( m_pParentNode != NULL );
return ((CLoggingMethodsNode *) m_pParentNode)->GetServerRoot();
}
//////////////////////////////////////////////////////////////////////////////
/*++
CLocalFileLoggingNode::OnPropertyChange
This is our own custom response to the MMCN_PROPERTY_CHANGE notification.
MMC never actually sends this notification to our snapin with a specific lpDataObject,
so it would never normally get routed to a particular node but we have arranged it
so that our property pages can pass the appropriate CSnapInItem pointer as the param
argument. In our CComponent::Notify override, we map the notification message to
the appropriate node using the param argument.
--*/
//////////////////////////////////////////////////////////////////////////////
HRESULT CLocalFileLoggingNode::OnPropertyChange(
LPARAM arg
, LPARAM param
, IComponentData * pComponentData
, IComponent * pComponent
, DATA_OBJECT_TYPES type
)
{
ATLTRACE(_T("# CLocalFileLoggingNode::OnPropertyChange\n"));
// Check for preconditions:
// None.
return LoadCachedInfoFromSdo();
}