915 lines
27 KiB
C++
915 lines
27 KiB
C++
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
iroot.cpp
|
|
|
|
Abstract:
|
|
|
|
Internal implementation for the root subfolder.
|
|
|
|
Environment:
|
|
|
|
WIN32 User Mode
|
|
|
|
Author:
|
|
|
|
Darwin Ouyang (t-darouy) 30-Sept-1997
|
|
|
|
--*/
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "inode.h" // base class
|
|
#include "iroot.h" // root folder
|
|
|
|
#include "idevices.h" // devices folder
|
|
#include "ilogging.h" // logging folder
|
|
|
|
#include "faxsnapin.h" // snapin
|
|
#include "faxdataobj.h" // dataobject
|
|
#include "faxhelper.h" // ole helper functions
|
|
#include "faxstrt.h" // string table
|
|
#include "faxsecinfo.h" // fax security info
|
|
|
|
#include "dgenprop.h" // general property sheet
|
|
#include "droutpri.h" // routing priority property sheet
|
|
#include <aclui.h> // acl editor property sheet
|
|
|
|
#pragma hdrstop
|
|
|
|
// context menu command
|
|
#define RECONNECT_SERVER 101
|
|
|
|
extern CStringTable * GlobalStringTable;
|
|
|
|
// Generated with uuidgen. Each node must have a GUID associated with it.
|
|
// This one is for the main root node.
|
|
const GUID GUID_RootNode = /* 8f39b047-3071-11d1-9067-00a0c90ab504 */
|
|
{
|
|
0x8f39b047,
|
|
0x3071,
|
|
0x11d1,
|
|
{0x90, 0x67, 0x00, 0xa0, 0xc9, 0x0a, 0xb5, 0x04}
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
// Constructor and destructor
|
|
//
|
|
//
|
|
|
|
CInternalRoot::CInternalRoot(
|
|
IN CInternalNode * pParent,
|
|
IN CFaxComponentData * pCompData )
|
|
: CInternalNode( this, pCompData )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Constructor
|
|
|
|
Arguments:
|
|
|
|
pParent - pointer to parent node, in this case unused
|
|
pCompData - pointer to IComponentData implementation for snapin global data
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
iDevices = NULL;
|
|
iLogging = NULL;
|
|
|
|
targetFaxServName = NULL;
|
|
m_pCompData->m_FaxHandle = NULL;
|
|
localNodeName = NULL;
|
|
pMyPropSheet = NULL;
|
|
pMyPropSheet2 = NULL;
|
|
m_myPropPage = NULL;
|
|
}
|
|
|
|
CInternalRoot::~CInternalRoot()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destructor
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
if(iDevices != NULL ) {
|
|
delete iDevices;
|
|
}
|
|
if(iLogging != NULL ) {
|
|
delete iLogging;
|
|
}
|
|
if(m_pCompData->m_FaxHandle != NULL ) {
|
|
FaxClose( m_pCompData->m_FaxHandle ); // close the connection
|
|
m_pCompData->m_FaxHandle = NULL;
|
|
}
|
|
if(targetFaxServName != NULL ) {
|
|
delete targetFaxServName;
|
|
}
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
// Mandatory CInternalNode implementations.
|
|
//
|
|
//
|
|
|
|
const GUID * CInternalRoot::GetNodeGUID()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the node's associated GUID.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A const pointer to a binary GUID.
|
|
|
|
--*/
|
|
{
|
|
// DebugPrint(( TEXT("Trace: CInternalRoot::GetNodeGUID") ));
|
|
return &GUID_RootNode;
|
|
}
|
|
|
|
const LPTSTR
|
|
CInternalRoot::GetNodeDisplayName()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a const TSTR pointer to the node's display name.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A const pointer to a TSTR.
|
|
|
|
--*/
|
|
{
|
|
// DebugPrint(( TEXT("Trace: CInternalRoot::GetNodeDisplayName") ));
|
|
if( localNodeName == NULL ) {
|
|
if( targetFaxServName != NULL ) {
|
|
// remote machine
|
|
localNodeName = new TCHAR[ StringSize( (::GlobalStringTable->GetString(IDS_ROOTNODENAME)) )
|
|
+ StringSize( targetFaxServName )
|
|
+ 1 ];
|
|
|
|
assert( localNodeName != NULL );
|
|
if (!localNodeName) {
|
|
return NULL;
|
|
}
|
|
|
|
_tcscpy( localNodeName, ::GlobalStringTable->GetString(IDS_ROOTNODENAME) );
|
|
_tcscat( localNodeName, targetFaxServName );
|
|
} else {
|
|
// local machine
|
|
localNodeName = new TCHAR[ StringSize( (::GlobalStringTable->GetString(IDS_ROOTNODENAME)) )
|
|
+ StringSize( ::GlobalStringTable->GetString(IDS_LOCALMACHINE) )
|
|
+ 1 ];
|
|
|
|
assert( localNodeName != NULL );
|
|
if (!localNodeName) {
|
|
return NULL;
|
|
}
|
|
|
|
_tcscpy( localNodeName, ::GlobalStringTable->GetString(IDS_ROOTNODENAME) );
|
|
_tcscat( localNodeName, ::GlobalStringTable->GetString(IDS_LOCALMACHINE) );
|
|
}
|
|
|
|
}
|
|
|
|
return localNodeName;
|
|
}
|
|
|
|
const LONG_PTR
|
|
CInternalRoot::GetCookie()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the cookie for this node.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A const long containing the cookie for the pointer,
|
|
in this case, a NULL, since the root node has no cookie.
|
|
|
|
--*/
|
|
{
|
|
DebugPrint(( TEXT("Root Node Cookie: NULL") ));
|
|
return NULL; // root node has no cookie.
|
|
}
|
|
|
|
void
|
|
CInternalRoot::SetMachine(
|
|
IN LPTSTR theName )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the machine name for the root node. This is used by all other nodes
|
|
to determine the target machine name.
|
|
|
|
Arguments:
|
|
|
|
A LPTSTR pointing to the machine name. It will be string copied to an internal store.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
if(theName != NULL ) {
|
|
targetFaxServName = new TCHAR[ MAX_COMPUTERNAME_LENGTH + 1 ];
|
|
if (!targetFaxServName) {
|
|
return;
|
|
}
|
|
ZeroMemory( (PVOID) targetFaxServName, (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( TCHAR ) );
|
|
_tcsncpy( targetFaxServName, theName, MAX_COMPUTERNAME_LENGTH );
|
|
targetFaxServName[MAX_COMPUTERNAME_LENGTH] = 0;
|
|
} else {
|
|
targetFaxServName = NULL;
|
|
}
|
|
}
|
|
|
|
const LPTSTR
|
|
CInternalRoot::GetMachine()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the machine name for the root node. This is used by all other
|
|
nodes to determine the target machine name.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A const LPTSTR pointing to the machine name. Do not free this string, it is an internal
|
|
buffer.
|
|
|
|
--*/
|
|
{
|
|
return targetFaxServName;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
// Internal Event Handlers
|
|
//
|
|
//
|
|
|
|
HRESULT
|
|
CInternalRoot::ScopeOnExpand(
|
|
IN CFaxComponentData * pCompData,
|
|
IN CFaxDataObject * pdo,
|
|
IN LPARAM arg,
|
|
IN LPARAM param )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Event handler for the MMCN_EXPAND message for the root node.
|
|
|
|
Arguments:
|
|
|
|
pCompData - a pointer to the instance of IComponentData which this root node is associated with.
|
|
pdo - a pointer to the data object associated with this node
|
|
arg, param - the arguements of the message
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand") ));
|
|
|
|
INT iResult;
|
|
HRESULT hr = S_OK;
|
|
LPCONSOLE console = pCompData->m_pConsole;
|
|
HANDLE targetFaxServHandle = NULL;
|
|
DWORD descCount = 0;
|
|
|
|
assert(console != NULL); // make sure we QI'ed for the interface
|
|
|
|
if(arg == TRUE) { // folder needs to be expanded
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - Expand folder") ));
|
|
|
|
if(!pdo) {
|
|
hr = console->MessageBox(::GlobalStringTable->GetString( IDS_CORRUPT_DATAOBJECT ),
|
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
|
MB_OK,
|
|
&iResult);
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
// Make sure that what we are placing ourselves under is the root node!
|
|
if(pdo->GetCookie() != NULL)
|
|
return S_FALSE;
|
|
|
|
assert(pdo->GetContext() == CCT_SCOPE);
|
|
|
|
//
|
|
// Open the fax server connection.
|
|
//
|
|
|
|
try {
|
|
if( FaxConnectFaxServer( targetFaxServName, &targetFaxServHandle ) == FALSE ) {
|
|
m_pCompData->NotifyRpcError( TRUE );
|
|
hr = console->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
|
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
|
MB_OK,
|
|
&iResult);
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - open connection fail") ));
|
|
hr = E_UNEXPECTED;
|
|
} else {
|
|
// sucessful connect!
|
|
m_pCompData->NotifyRpcError( FALSE );
|
|
}
|
|
} catch( ... ) {
|
|
m_pCompData->NotifyRpcError( TRUE );
|
|
console->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
|
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
|
MB_OK,
|
|
&iResult);
|
|
hr = E_UNEXPECTED;
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - open connection fail") ));
|
|
}
|
|
|
|
//
|
|
// short circuit if we failed to connect to faxsvc
|
|
//
|
|
if (FAILED(hr)) {
|
|
return(hr);
|
|
}
|
|
|
|
m_pCompData->m_FaxHandle = targetFaxServHandle;
|
|
|
|
//
|
|
// Place our folder into the scope pane
|
|
//
|
|
|
|
// create a new internal representation of the devices folder.
|
|
iDevices = new CInternalDevices( this, m_pCompData );
|
|
|
|
assert( iDevices != NULL );
|
|
if (!iDevices) {
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
|
|
// insert devices folder
|
|
hr = InsertItem( iDevices, param );
|
|
|
|
// create a new internal representation of the logging folder.
|
|
iLogging = new CInternalLogging( this, m_pCompData );
|
|
|
|
assert( iLogging != NULL );
|
|
if (!iLogging) {
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
|
|
// insert logging folder
|
|
hr = InsertItem( iLogging, param );
|
|
} else if(arg == FALSE ) {
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - Contract folder") ));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CInternalRoot::ResultOnShow(
|
|
IN CFaxComponent* pComp,
|
|
IN CFaxDataObject * lpDataObject,
|
|
IN LPARAM arg,
|
|
IN LPARAM param)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Event handler for the MMCN_SHOW message for the root node.
|
|
|
|
Arguments:
|
|
|
|
pCompData - a pointer to the instance of IComponentData which this root node is associated with.
|
|
lpDataObject - a pointer to the data object containing context information for this node.
|
|
pdo - a pointer to the data object associated with this node
|
|
arg, param - the arguements of the message
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
LPHEADERCTRL pIHeaderCtrl = pComp->m_pHeaderCtrl;
|
|
HRESULT hr = S_OK;
|
|
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ResultOnShow") ));
|
|
|
|
assert( pIHeaderCtrl != NULL );
|
|
|
|
if( arg == TRUE ) {
|
|
do {
|
|
// insert the icons into the image list
|
|
hr = pComp->InsertIconsIntoImageList();
|
|
assert( SUCCEEDED( hr ) );
|
|
if( FAILED( hr ) ) {
|
|
break;
|
|
}
|
|
|
|
hr = pIHeaderCtrl->InsertColumn( 0,
|
|
::GlobalStringTable->GetString( IDS_ROOT_NAME ),
|
|
LVCFMT_LEFT,
|
|
MMCLV_AUTO );
|
|
if( FAILED( hr ) ) {
|
|
break;
|
|
}
|
|
|
|
hr = pIHeaderCtrl->InsertColumn( 1,
|
|
::GlobalStringTable->GetString( IDS_ROOT_DESC ),
|
|
LVCFMT_LEFT,
|
|
MMCLV_AUTO );
|
|
if( FAILED( hr ) ) {
|
|
break;
|
|
}
|
|
} while( 0 );
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CInternalRoot::ResultOnSelect(
|
|
IN CFaxComponent* pComp,
|
|
IN CFaxDataObject * lpDataObject,
|
|
IN LPARAM arg,
|
|
IN LPARAM param)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Event handler for the MMCN_SELECT message for the root node.
|
|
|
|
Arguments:
|
|
|
|
pCompData - a pointer to the instance of IComponentData which this root node is associated with.
|
|
pdo - a pointer to the data object associated with this node
|
|
arg, param - the arguements of the message
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ResultOnSelect") ));
|
|
if( m_pCompData->QueryRpcError() == FALSE ) {
|
|
pComp->m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE );
|
|
pComp->m_pConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN );
|
|
} else {
|
|
pComp->m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, FALSE );
|
|
pComp->m_pConsoleVerb->SetDefaultVerb( MMC_VERB_NONE );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
// IExtendPropertySheet implementation
|
|
//
|
|
//
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CInternalRoot::ComponentDataPropertySheetCreatePropertyPages(
|
|
IN CFaxComponentData * pCompData,
|
|
IN LPPROPERTYSHEETCALLBACK lpProvider,
|
|
IN LONG_PTR handle,
|
|
IN CFaxDataObject * lpIDataObject)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Event handler for the MMCN_EXPAND message for the root node.
|
|
|
|
Arguments:
|
|
|
|
pCompData - a pointer to the instance of IComponentData which this root node is associated with.
|
|
pdo - a pointer to the data object associated with this node
|
|
arg, param - the arguements of the message
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
DebugPrint(( TEXT("Trace: CInternalDevice::ComponentPropertySheetCreatePropertyPages") ));
|
|
assert( lpIDataObject != NULL );
|
|
assert( lpProvider != NULL );
|
|
|
|
HRESULT hr;
|
|
BOOL bResult = FALSE;
|
|
PFAX_SECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
|
|
CFaxSecurityInformation * psi = NULL;
|
|
DWORD descCount = 0;
|
|
|
|
PFAX_GLOBAL_ROUTING_INFO pRoutingMethod;
|
|
DWORD iRoutingMethodCount;
|
|
DWORD i;
|
|
WCHAR DllName[MAX_PATH];
|
|
BOOL bUnknownMethod = FALSE;
|
|
|
|
if( m_pCompData->QueryRpcError() == TRUE ) {
|
|
assert( FALSE );
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
if( lpIDataObject == NULL || lpProvider == NULL ) {
|
|
assert(FALSE);
|
|
return E_POINTER;
|
|
}
|
|
|
|
pMyPropSheet = new CFaxGeneralSettingsPropSheet( ::GlobalStringTable->GetInstance(), handle, this );
|
|
if (!pMyPropSheet) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto e0;
|
|
}
|
|
|
|
hr = lpProvider->AddPage( pMyPropSheet->GetHandle() );
|
|
if (FAILED(hr)) {
|
|
goto e1;
|
|
}
|
|
|
|
try {
|
|
//
|
|
// do routing priority page
|
|
//
|
|
|
|
//
|
|
// Check if we have non "default" extensions
|
|
//
|
|
|
|
|
|
if( !FaxEnumGlobalRoutingInfo( m_pCompData->m_FaxHandle,
|
|
&pRoutingMethod,
|
|
&iRoutingMethodCount ) ) {
|
|
if (GetLastError() != ERROR_ACCESS_DENIED) {
|
|
m_pCompData->NotifyRpcError( TRUE );
|
|
assert(FALSE);
|
|
}
|
|
::GlobalStringTable->SystemErrorMsg( GetLastError() );
|
|
hr = E_UNEXPECTED;
|
|
goto e1;
|
|
} else {
|
|
|
|
// go through the routing methods ensuring that
|
|
// we know of all of them
|
|
DWORD retval;
|
|
retval = ExpandEnvironmentStrings(MSFAX_EXTENSION,DllName,MAX_PATH);
|
|
if (retval == 0 || retval > MAX_PATH) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto e1;
|
|
}
|
|
|
|
for( i=0; i<iRoutingMethodCount; i++ ) {
|
|
if(wcscmp( pRoutingMethod[i].ExtensionImageName, DllName ) != 0) {
|
|
bUnknownMethod = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FaxFreeBuffer( (PVOID)pRoutingMethod );
|
|
|
|
// if we bumped into a method we don't know
|
|
// then we put up the routing property sheet
|
|
if( bUnknownMethod == TRUE ) {
|
|
pMyPropSheet2 = new CFaxRoutePriPropSheet( ::GlobalStringTable->GetInstance(), handle, this, NULL );
|
|
if (!pMyPropSheet2) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto e1;
|
|
}
|
|
hr = lpProvider->AddPage( pMyPropSheet2->GetHandle() );
|
|
if (FAILED(hr)) {
|
|
goto e2;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if( FaxGetSecurityDescriptorCount( m_pCompData->m_FaxHandle, &descCount ) ) {
|
|
// if there is only one descriptor we might as well just stick it in
|
|
// the root node
|
|
if( descCount == 1 ) {
|
|
psi = new CComObject<CFaxSecurityInformation>;
|
|
if (!psi) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto e2;
|
|
}
|
|
|
|
psi->SetOwner( this );
|
|
if( SUCCEEDED( psi->SetSecurityDescriptor( 0 ) ) ) {
|
|
m_myPropPage = CreateSecurityPage( psi );
|
|
hr = lpProvider->AddPage( m_myPropPage );
|
|
} else {
|
|
goto e3;
|
|
}
|
|
|
|
FaxFreeBuffer( (PVOID)pSecurityDescriptor );
|
|
}
|
|
}
|
|
} catch ( ... ) {
|
|
assert( FALSE );
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataPropertySheetCreatePropertyPages - RPC connection fail") ));
|
|
m_pCompData->NotifyRpcError( TRUE );
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
|
|
return hr;
|
|
|
|
e3:
|
|
if (psi) delete(psi);
|
|
e2:
|
|
if (pMyPropSheet2) delete(pMyPropSheet2);
|
|
e1:
|
|
if (pMyPropSheet) delete(pMyPropSheet);
|
|
e0:
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CInternalRoot::ComponentDataPropertySheetQueryPagesFor(
|
|
IN CFaxComponentData * pCompData,
|
|
IN CFaxDataObject * lpDataObject)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns S_OK to indicated there are property pages for this node.
|
|
|
|
Arguments:
|
|
|
|
pCompData - a pointer to the instance of IComponentData which this root node is associated with.
|
|
lpDataObject - a pointer to the data object associated with this node
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
DebugPrint(( TEXT("Trace: CInternalDevice::ComponentPropertySheetQueryPagesFor") ));
|
|
return S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IExtendContextMenu implementation
|
|
//
|
|
//
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CInternalRoot::ComponentDataContextMenuAddMenuItems(
|
|
IN CFaxComponentData * pCompData,
|
|
IN CFaxDataObject * piDataObject,
|
|
IN LPCONTEXTMENUCALLBACK piCallback,
|
|
IN OUT long __RPC_FAR *pInsertionAllowed)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Adds the context menu items to the root node.
|
|
|
|
Arguments:
|
|
|
|
pCompData - a pointer to the instance of IComponentData which this root node is associated with.
|
|
piDataObject - a pointer to the data object associated with this node
|
|
piCallback - a pointer the the IContextMenuCallback supplied by the MMC
|
|
pInsertionAllowed - a set of flags to indicate whether context menu insertion is allows
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
DebugPrint(( TEXT("Trace: CInternalDevice::ComponentContextMenuAddMenuItems") ));
|
|
|
|
CONTEXTMENUITEM menuItem;
|
|
HRESULT hr = S_OK;
|
|
|
|
if( !( *pInsertionAllowed | CCM_INSERTIONALLOWED_TOP ) ) {
|
|
assert( FALSE );
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
if( m_pCompData->QueryRpcError() == TRUE ) {
|
|
|
|
// build the submenu items
|
|
|
|
ZeroMemory( ( void* )&menuItem, sizeof( menuItem ) );
|
|
|
|
menuItem.strName = ::GlobalStringTable->GetString( IDS_RECONNECT );
|
|
menuItem.strStatusBarText = ::GlobalStringTable->GetString( IDS_RECONNECT_DESC );
|
|
menuItem.lCommandID = RECONNECT_SERVER;
|
|
menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
|
|
menuItem.fFlags = MF_ENABLED;
|
|
menuItem.fSpecialFlags = CCM_SPECIAL_DEFAULT_ITEM;
|
|
|
|
hr = piCallback->AddItem( &menuItem );
|
|
if( FAILED(hr) ) {
|
|
assert(FALSE);
|
|
return hr;
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CInternalRoot::ComponentDataContextMenuCommand(
|
|
IN CFaxComponentData * pCompData,
|
|
IN long lCommandID,
|
|
IN CFaxDataObject * piDataObject)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handles the context menu events.
|
|
|
|
Arguments:
|
|
|
|
pCompData - a pointer to the instance of IComponentData which this root node is associated with.
|
|
lCommandID - the command ID.
|
|
piDataObject - a pointer to the data object associated with this node
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataContextMenuCommand") ));
|
|
|
|
HRESULT hr = S_OK;
|
|
HANDLE targetFaxServHandle = NULL;
|
|
int iResult;
|
|
|
|
do {
|
|
switch( lCommandID ) {
|
|
case RECONNECT_SERVER:
|
|
//
|
|
// Re-open the fax server connection.
|
|
//
|
|
|
|
try {
|
|
|
|
if( FaxConnectFaxServer( targetFaxServName, &targetFaxServHandle ) == FALSE ) {
|
|
m_pCompData->NotifyRpcError( TRUE );
|
|
hr = m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
|
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
|
MB_OK,
|
|
&iResult);
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataContextMenuCommand - RE-OPEN connection fail") ));
|
|
} else {
|
|
// sucessful connect!
|
|
m_pCompData->NotifyRpcError( FALSE );
|
|
}
|
|
|
|
} catch( ... ) {
|
|
m_pCompData->NotifyRpcError( TRUE );
|
|
m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
|
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
|
MB_OK,
|
|
&iResult);
|
|
DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataContextMenuCommand - RE-OPEN connection fail") ));
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
m_pCompData->m_FaxHandle = targetFaxServHandle;
|
|
break;
|
|
|
|
default:
|
|
assert(FALSE);
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
|
|
}
|
|
|
|
} while( 0 );
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
// Utility Function
|
|
//
|
|
//
|
|
|
|
HRESULT
|
|
CInternalRoot::InsertItem(
|
|
IN CInternalNode * iCookie,
|
|
IN LPARAM param )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wrapper that inserts an item into a scope view pane given a cookie.
|
|
|
|
Arguments:
|
|
|
|
iCookie - the cookie of the node that needs to be inserted into the view
|
|
param - the HRESULTITEM of the parent to the node being inserted
|
|
|
|
Return Value:
|
|
|
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
|
|
|
--*/
|
|
{
|
|
SCOPEDATAITEM sdi;
|
|
LPCONSOLENAMESPACE consoleNameSpace = m_pCompData->m_pConsoleNameSpace;
|
|
assert(consoleNameSpace != NULL); // make sure we QI'ed for the interface
|
|
|
|
ZeroMemory(&sdi, sizeof sdi);
|
|
sdi.mask = SDI_STR | // displayname is valid
|
|
SDI_PARAM | // lParam is valid
|
|
SDI_IMAGE | // nImage is valid
|
|
SDI_OPENIMAGE | // nOpenImage is valid
|
|
SDI_CHILDREN | // cChildren is valid
|
|
SDI_PARENT;
|
|
sdi.relativeID = (HSCOPEITEM) param;
|
|
sdi.nImage = iCookie->GetNodeDisplayImage();
|
|
sdi.nOpenImage = iCookie->GetNodeDisplayOpenImage();
|
|
sdi.displayname = MMC_CALLBACK;
|
|
sdi.cChildren = 0;
|
|
sdi.lParam = (LPARAM) iCookie; // The cookie
|
|
|
|
return consoleNameSpace->InsertItem(&sdi);
|
|
}
|
|
|