windows-nt/Source/XPSP1/NT/base/fs/hsm/gui/hsmadmin/evntdata.cpp

797 lines
20 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
<EFBFBD> 1998 Seagate Software, Inc. All rights reserved.
Module Name:
evntdata.cpp
Abstract:
This module is responsible for handling the notification
calls from MMC CSakData.
Author:
Rohde Wakefield [rohde] 06-Mar-1997
Revision History:
--*/
#include "stdafx.h"
#include "CSakSnap.h"
#include "CSakData.h"
UINT CSakData::m_CFMachineName =
RegisterClipboardFormat( L"MMC_SNAPIN_MACHINE_NAME" );
HRESULT
CSakData::OnFolder(
IN IDataObject* pDataObject,
IN LPARAM arg,
IN LPARAM param
)
/*++
Routine Description:
Param is the unique identifier ( an HSCOPEITEM of the
expanding or contracting item )
Arguments:
pNode - The node which is expanding.
arg -
param -
Return Value:
S_OK - Created successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::OnFolder", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param );
HRESULT hr = S_OK;
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
try {
// if the arg is TRUE, the node is being expanded.
if( arg )
{
CComPtr<ISakNode> pNode;
// Get the basehsm out of the data record.
GetBaseHsmFromDataObject ( pDataObject, &pNode );
if( !pNode ) {
// The dataobject is not one of ours - we must be extending another
// snapin.
// Get the root node from UnkRootNode ( it has already been created
// by Initialize )
WsbAffirmPointer( m_pRootNode );
// We're an extension snapin.
// Get the server focus from the data object.
//
CString hsmName;
WsbAffirmHr( GetServerFocusFromDataObject( pDataObject, hsmName ) );
if( hsmName == "" ) {
m_ManageLocal = TRUE;
m_HsmName = "";
} else {
m_ManageLocal = FALSE;
// eliminate starting \\ if there is one. Computer management
// precedes the server name with \\.
if( hsmName.Left( 2 ) == L"\\\\" ) {
int len = hsmName.GetLength( );
m_HsmName = hsmName.Right( len - 2 );
} else {
m_HsmName = hsmName;
}
}
// Set the Hsm name in SakData and HsmCom objects
WsbAffirmHr( InitializeRootNode( ) );
// Create a scope pane item and insert it
SCOPEDATAITEM sdi;
ZeroMemory( &sdi, sizeof sdi );
sdi.mask = SDI_STR |
SDI_PARAM |
SDI_IMAGE |
SDI_OPENIMAGE |
SDI_PARENT;
sdi.relativeID = ( HSCOPEITEM )( param );
sdi.displayname = MMC_CALLBACK;
WsbAffirmHr( m_pRootNode->GetScopeCloseIcon( m_State, &sdi.nImage ) );
WsbAffirmHr( m_pRootNode->GetScopeOpenIcon( m_State, &sdi.nOpenImage ) );
// This is a special token for the extension root node
sdi.lParam = EXTENSION_RS_FOLDER_PARAM;
// Insert the node into the scope pane and save the scope ID
WsbAffirmHr( m_pNameSpace->InsertItem( &sdi ) );
WsbAffirmHr( m_pRootNode->SetScopeID( ( HSCOPEITEM )( sdi.ID ) ) );
m_RootNodeInitialized = TRUE;
} else {
GUID nodeGuid;
WsbAffirmHr( pNode->GetNodeType( &nodeGuid ) );
if( IsEqualGUID( nodeGuid, cGuidHsmCom ) ) {
if( !m_RootNodeInitialized ) {
m_RootNodeInitialized = TRUE;
//
// Set the scopeitem in the node
//
WsbAffirmHr( pNode->SetScopeID( ( HSCOPEITEM )( param ) ) );
//
// Update the text and icon ( text is wrong if loaded
// from file and command line switch given for
// different machine
//
SCOPEDATAITEM sdi;
ZeroMemory( &sdi, sizeof sdi );
sdi.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
sdi.ID = ( HSCOPEITEM )( param );
sdi.displayname = MMC_CALLBACK;
WsbAffirmHr( pNode->GetScopeCloseIcon( m_State, &sdi.nImage ) );
WsbAffirmHr( pNode->GetScopeOpenIcon( m_State, &sdi.nOpenImage ) );
WsbAffirmHr( m_pNameSpace->SetItem( &sdi ) );
}
}
//
// Initialize child node list prior to graphically enumerating them
//
WsbAffirmHr( EnsureChildrenAreCreated( pNode ) );
//
// Param contains the HSCOPEITEM of the node being opened.
//
WsbAffirmHr( EnumScopePane( pNode, ( HSCOPEITEM )( param ) ) );
}
}
} WsbCatch( hr );
WsbTraceOut( L"CSakData::OnFolder", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
////////////////////////////////////////////////////////////////////////////////////
//
// Description: Get the server name from the supplied data object. The dataobject
// is implemented by the snapin we are extending
//
HRESULT CSakData::GetServerFocusFromDataObject( IDataObject *pDataObject, CString& HsmName )
{
HRESULT hr = S_OK;
try {
STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
FORMATETC formatetc = { (CLIPFORMAT)m_CFMachineName, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
// Allocate memory for the stream
// Note: we add 2 bytes because Computer Management puts \\ at the
// beginning of the computer name. - AHB 12/22/97
//
stgmedium.hGlobal = GlobalAlloc( GMEM_SHARE, sizeof( WCHAR ) * ( MAX_PATH + 1 + 2 ) );
WsbAffirmPointer( stgmedium.hGlobal )
// Attempt to get data from the object
WsbAffirmHr( pDataObject->GetDataHere( &formatetc, &stgmedium ) );
HsmName = ( OLECHAR * ) stgmedium.hGlobal;
GlobalFree( stgmedium.hGlobal );
} WsbCatch ( hr ) ;
return hr;
}
HRESULT
CSakData::OnShow(
IN IDataObject* pDataObject,
IN LPARAM arg,
IN LPARAM param
)
/*++
Routine Description:
The result view is just about to be shown.
Set the headers for the result view.
Param is the unique identifier ( an HSCOPEITEM ) of the
selected or deselected item.
Arguments:
pNode - The node which is showing.
arg -
param -
Return Value:
S_OK - Created successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::OnShow", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param );
HRESULT hr = S_OK;
try {
CComPtr<ISakNode> pNode;
// Get the basehsm out of the data record.
GetBaseHsmFromDataObject ( pDataObject, &pNode );
//
// Arg is TRUE when it is time to enumerate
//
if( arg ) {
//
// Initialize child node list prior to graphically enumerating them
//
WsbAffirmHr( EnsureChildrenAreCreated( pNode ) );
//
// Enumerate both the scope and result views. "Param" contains the
// HSCOPEITEM of the node being shown.
//
WsbAffirmHr( EnumScopePane( pNode, ( HSCOPEITEM )( param ) ) );
} else {
//
// Free data associated with the result pane items, because
// your node is no longer being displayed.
// Note: The console will remove the items from the result pane
//
}
} WsbCatch( hr );
WsbTraceOut( L"CSakData::OnShow", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
CSakData::OnSelect(
IN IDataObject* pDataObject,
IN LPARAM arg,
IN LPARAM param
)
/*++
Routine Description:
Called when a "folder" ( node ) is going to be opened ( not expanded ).
Param is the unique identifier ( an HSCOPEITEM of the
expanding or contracting item )
Arguments:
pNode - The node which is expanding.
arg -
param -
Return Value:
S_OK - Created successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::OnSelect", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param );
HRESULT hr = S_OK;
WsbTraceOut( L"CSakData::OnSelect", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
CSakData::OnMinimize(
IN IDataObject* pDataObject,
IN LPARAM arg,
IN LPARAM param
)
/*++
Routine Description:
Arguments:
pNode - The node which is expanding.
arg -
param -
Return Value:
S_OK - Created successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::OnMinimize", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param );
HRESULT hr = S_OK;
WsbTraceOut( L"CSakData::OnMinimize", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
CSakData::OnContextHelp(
IN IDataObject* pDataObject,
IN LPARAM arg,
IN LPARAM param
)
/*++
Routine Description:
Called when help is selected on a node. Shows the top level help.
Arguments:
pNode - The node which is requesting help.
arg -
param -
Return Value:
S_OK - Created successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::OnContextHelp", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param );
HRESULT hr = S_OK;
try {
//
// Get the help interface
//
CComPtr<IDisplayHelp> pDisplayHelp;
WsbAffirmHr( m_pConsole.QueryInterface( &pDisplayHelp ) );
//
// Form up the correct name
//
CWsbStringPtr helpFile;
WsbAffirmHr( helpFile.LoadFromRsc( _Module.m_hInst, IDS_HELPFILELINK ) );
WsbAffirmHr( helpFile.Append( L"::/rss_node_howto.htm" ) );
//
// And show it
//
WsbAffirmHr( pDisplayHelp->ShowTopic( helpFile ) );
} WsbCatch( hr );
WsbTraceOut( L"CSakData::OnContextHelp", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
CSakData::EnumScopePane(
IN ISakNode* pNode,
IN HSCOPEITEM pParent
)
/*++
Routine Description:
Insert the items into the scopepane under the item which is represented by
cookie and pParent.
Arguments:
pNode - The node which is expanding.
arg -
param -
Return Value:
S_OK - Created successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::EnumScopePane", L"pNode = <0x%p>, pParent = <0x%p>", pNode, pParent );
HRESULT hr = S_OK;
try {
//
// Verify params
//
WsbAffirmPointer( pNode );
WsbAffirmPointer( pParent );
//
// make sure we QI'ed for the interface
//
WsbAffirmPointer( m_pNameSpace );
//
// Avoid enumerating the same node twice. Once enumerated, a node remembers it.
//
BOOL isEnumerated;
WsbAffirmHr( pNode->GetEnumState( &isEnumerated ) );
if( !isEnumerated ) {
//
// This node has NOT been enumerated in the tree.
//
if( S_OK == pNode->IsContainer( ) ) {
CComPtr<IEnumUnknown> pEnum; // child enumerator object
CComQIPtr<ISakNode, &IID_ISakNode> pBaseHsmChild; // child pointer to BaseHsm interface
// Create an Enumeration object for the children and enumerate them
WsbAffirmHr( pNode->EnumChildren( &pEnum ) );
CComPtr<IUnknown> pUnkChild; // pointer to next child in list
while( pEnum->Next( 1, &pUnkChild, NULL ) == S_OK ) {
pBaseHsmChild = pUnkChild;
WsbAffirmPointer( pBaseHsmChild );
//
// If this is a leaf node, don't enumerate in scope pane.
//
if( pBaseHsmChild->IsContainer( ) != S_OK ) {
pBaseHsmChild.Release( );
pUnkChild.Release( );
continue;
}
//
// Set up a SCOPEDATAITEM for this child node and insert the child into the scope treeview
//
SCOPEDATAITEM childScopeItem;
memset( &childScopeItem, 0, sizeof( SCOPEDATAITEM ) );
//
// Set String to be callback
//
childScopeItem.displayname = MMC_CALLBACK;
childScopeItem.mask |= SDI_STR;
//
// Add "expandable" indicator to tree node if
// this node has children. Fake out number
// of children.
//
if( pBaseHsmChild->IsContainer( ) == S_OK ) {
childScopeItem.cChildren = 1;
childScopeItem.mask |= SDI_CHILDREN;
}
//
// Set child node's scope item parent.
//
childScopeItem.relativeID = pParent;
childScopeItem.mask |= SDI_PARENT;
//
// Set the param in the ScopeItem to the unknown pointer
// to this node, so that when this scopeitem is sent back
// to us, we can get it out and use it to look up
// node-specific info.
//
WsbAffirmHr( GetCookieFromBaseHsm( pBaseHsmChild, (MMC_COOKIE*)(&childScopeItem.lParam) ) );
childScopeItem.mask |= SDI_PARAM;
childScopeItem.mask |= SDI_STATE;
childScopeItem.nState = 0;
//
// Note - After insertion into the tree, the SCOPEITEM ID member contains the handle to
// the newly inserted item
//
WsbAffirmHr ( pBaseHsmChild->GetScopeCloseIcon( m_State, &childScopeItem.nImage ) );
childScopeItem.mask |= SDI_IMAGE;
WsbAffirmHr ( pBaseHsmChild->GetScopeOpenIcon( m_State, &childScopeItem.nOpenImage ) );
childScopeItem.mask |= SDI_OPENIMAGE;
WsbAffirmHr( m_pNameSpace->InsertItem( &childScopeItem ) );
WsbAffirm( childScopeItem.ID != NULL, E_UNEXPECTED );
//
// Set the scopeitem id in the node object
//
WsbAffirmHr( pBaseHsmChild->SetScopeID( childScopeItem.ID ) );
//
// release the test interface pointer and string for next node
//
pBaseHsmChild.Release( );
pUnkChild.Release( );
}
//
// Indicate that this node has been enumerated
//
WsbAffirmHr( pNode->SetEnumState( TRUE ) );
}
}
} WsbCatch( hr );
WsbTraceOut( L"CSakData::EnumScopePane", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
CSakData::EnsureChildrenAreCreated(
IN ISakNode * pNode
)
/*++
Routine Description:
Guarantee that the immediate children of a particular node are created
in our hierarchical list of nodes.
Arguments:
pNode - The node to check.
Return Value:
S_OK - Created successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::EnsureChildrenAreCreated", L"pNode = <0x%p>", pNode );
HRESULT hr = S_OK;
try {
//
// Create the node's children if the node's list of children is
// currently invalid ( i.e. - never created, or out-of-date )
//
if( pNode->ChildrenAreValid( ) == S_FALSE ) {
WsbAffirmHr( CreateChildNodes( pNode ) );
}
} WsbCatch( hr );
WsbTraceOut( L"CSakData::EnsureChildrenAreCreated", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
CSakData::OnRemoveChildren(
IN IDataObject* pDataObject
)
/*++
Routine Description:
Arguments:
pDataObject - The node
Return Value:
S_OK - Removed successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::OnRemoveChildren", L"pDataObject = <0x%p>", pDataObject );
HRESULT hr = S_OK;
try {
CComPtr<ISakNode> pNode;
WsbAffirmHr( GetBaseHsmFromDataObject( pDataObject, &pNode ) );
WsbAffirmHr( RemoveChildren( pNode ) );
} WsbCatch( hr );
WsbTraceOut( L"CSakData::OnRemoveChildren", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
CSakData::RemoveChildren(
IN ISakNode* pNode
)
/*++
Routine Description:
Recursively clean up the cookies for this node's children,
but not this node itself.
Arguments:
pNode - The node
Return Value:
S_OK - Removed successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::RemoveChildren", L"pNode = <0x%p>", pNode );
HRESULT hr = S_OK;
try {
CComPtr<IEnumUnknown> pEnum; // child enumerator object
CComPtr<ISakNode> pChild; // child pointer to BaseHsm interface
// Create an Enumeration object for the children and enumerate them
WsbAffirmHr( pNode->EnumChildren( &pEnum ) );
CComPtr<IUnknown> pUnkChild; // pointer to next child in list
while( pEnum->Next( 1, &pUnkChild, NULL ) == S_OK ) {
WsbAffirmHr( pUnkChild.QueryInterface( &pChild ) );
RemoveChildren( pChild ); // OK to fail and keep going
DetachFromNode( pChild );
pUnkChild.Release( );
pChild.Release( );
}
} WsbCatch( hr );
WsbTraceOut( L"CSakData::RemoveChildren", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
STDMETHODIMP
CSakData::DetachFromNode(
IN ISakNode* pNode )
/*++
Routine Description:
Called when a node is terminating in order for sakdata to remove
any cookies holding onto node.
Arguments:
pNode - The node
Return Value:
S_OK - Removed successfully.
E_xxxxxxxxxxx - Failure occurred.
--*/
{
WsbTraceIn( L"CSakData::DetachFromNode", L"" );
HRESULT hr = S_OK;
try {
WsbAffirmPointer( pNode );
RS_PRIVATE_DATA data;
WsbAffirmHr( pNode->GetPrivateData( &data ) );
CSakDataNodePrivate* pNodePriv = (CSakDataNodePrivate*)data;
if( pNodePriv && SUCCEEDED( CSakDataNodePrivate::Verify( pNodePriv ) ) ) {
delete pNodePriv;
}
} WsbCatch( hr );
WsbTraceOut( L"CSakData::DetachFromNode", L"" );
return( hr );
}