Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1812 lines
49 KiB

//Copyright (c) 1998 - 1999 Microsoft Corporation
//
// 08/13/98
// alhen
//
#include "stdafx.h"
#include "tscc.h"
#include "compdata.h"
#include "comp.h"
#include "tsprsht.h"
#include "sdlgs.h"
INT_PTR CALLBACK RenameDlgProc( HWND , UINT , WPARAM , LPARAM );
void ErrMessage( HWND hwndOwner , INT_PTR iResourceID );
extern void xxxErrMessage( HWND hwnd , INT_PTR nResMessageId , INT_PTR nResTitleId , UINT nFlags );
extern void TscAccessDeniedMsg( HWND hwnd );
extern void TscGeneralErrMsg( HWND hwnd );
BOOL IsValidConnectionName( LPTSTR szConName , PDWORD );
extern void SnodeErrorHandler( HWND hParent , INT nObjectId , DWORD dwStatus );
extern void ReportStatusError( HWND hwnd , DWORD dwStatus );
extern BOOL g_bAppSrvMode;
//extern BOOL g_bEditMode;
//--------------------------------------------------------------------------
CComp::CComp( CCompdata* pCompdata )
{
m_pConsole = NULL;
m_pCompdata = pCompdata;
m_pResultData = NULL;
m_pHeaderCtrl = NULL;
m_pConsoleVerb = NULL;
m_pImageResult = NULL;
m_pDisplayHelp = NULL;
m_nSettingCol = 0;
m_nAttribCol = 0;
m_cRef = 1; // addref at ctor
}
//--------------------------------------------------------------------------
CComp::~CComp( )
{
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::QueryInterface( REFIID riid , PVOID *ppv )
{
HRESULT hr = S_OK;
if( riid == IID_IUnknown )
{
*ppv = ( LPUNKNOWN )( LPCOMPONENT )this;
}
else if( riid == IID_IComponent )
{
*ppv = ( LPCOMPONENT )this;
}
else if( riid == IID_IExtendContextMenu )
{
*ppv = ( LPEXTENDCONTEXTMENU )this;
}
else if( riid == IID_IExtendPropertySheet )
{
*ppv = ( LPEXTENDPROPERTYSHEET )this;
}
else
{
*ppv = 0;
hr = E_NOINTERFACE;
}
AddRef( );
return hr;
}
//--------------------------------------------------------------------------
STDMETHODIMP_( ULONG ) CComp::AddRef( )
{
return InterlockedIncrement( ( LPLONG )&m_cRef );
}
//--------------------------------------------------------------------------
STDMETHODIMP_( ULONG )CComp::Release( )
{
if( InterlockedDecrement( ( LPLONG )&m_cRef ) == 0 )
{
delete this;
return 0;
}
return m_cRef;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::Initialize( LPCONSOLE lpConsole )
{
HRESULT hr;
ASSERT( lpConsole != NULL );
m_pConsole = lpConsole;
m_pConsole->AddRef( );
// VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_MAINFOLDERNAME , m_strDispName , sizeof( m_strDispName ) ) );
do
{
if( FAILED( ( hr = m_pConsole->QueryInterface( IID_IResultData , ( LPVOID *)&m_pResultData ) ) ) )
{
break;
}
if( FAILED( ( hr = m_pConsole->QueryInterface( IID_IHeaderCtrl , ( LPVOID *)&m_pHeaderCtrl ) ) ) )
{
break;
}
if( FAILED( ( hr = m_pConsole->QueryConsoleVerb( &m_pConsoleVerb ) ) ) )
{
break;
}
if( FAILED( ( hr = m_pConsole->QueryInterface( IID_IDisplayHelp , ( LPVOID * )&m_pDisplayHelp ) ) ) )
{
break;
}
hr = m_pConsole->QueryResultImageList( &m_pImageResult );
}while( 0 );
return hr;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::Notify( LPDATAOBJECT pDataObj , MMC_NOTIFY_TYPE event , LPARAM arg , LPARAM )
{
switch( event )
{
case MMCN_ACTIVATE:
ODS( L"IComponent -- MMCN_ACTIVATE\n" );
//Bug 483485 - we want to call OnRefresh so that MMC can get the current window's pointer list. The
//only reason this problem wasn't seen more often is that OnShow is called when one of the left nodes
//is clicked on which does something similar to OnRefresh, so it was masking the problem. This isn't
//sufficient when accessing the result nodes immediately after switching windows though
if (arg) //We only refresh the activated node. This is also called for deactivation with arg = false
OnRefresh(pDataObj);
break;
case MMCN_ADD_IMAGES:
ODS( L"IComponent -- MMCN_ADD_IMAGES\n" );
OnAddImages( );
break;
case MMCN_BTN_CLICK:
ODS( L"IComponent -- MMCN_BTN_CLICK\n" );
break;
case MMCN_CLICK:
ODS( L"IComponent -- MMCN_CLICK\n" );
break;
case MMCN_DBLCLICK:
ODS( L"IComponent -- MMCN_DBLCLICK\n" );
// enables navigation to inner folders.
// final item launches default verb
OnDblClk( pDataObj );
return S_FALSE;
case MMCN_DELETE:
ODS( L"IComponent -- MMCN_DELETE\n" );
OnDelete( pDataObj );
break;
case MMCN_EXPAND:
ODS( L"IComponent -- MMCN_EXPAND\n" );
break;
case MMCN_MINIMIZED:
ODS( L"IComponent -- MMCN_MINIMIZED\n" );
break;
case MMCN_PROPERTY_CHANGE:
ODS( L"IComponent -- MMCN_PROPERTY_CHANGE\n" );
break;
case MMCN_REMOVE_CHILDREN:
ODS( L"IComponent -- MMCN_REMOVE_CHILDREN\n" );
break;
case MMCN_REFRESH:
ODS( L"IComponent -- MMCN_REFRESH\n" );
OnRefresh( pDataObj );
break;
case MMCN_RENAME:
ODS( L"IComponent -- MMCN_RENAME\n" );
break;
case MMCN_SELECT:
ODS( L"IComponent -- MMCN_SELECT\n" );
OnSelect( pDataObj , ( BOOL )LOWORD( arg ) , ( BOOL )HIWORD( arg ) );
break;
case MMCN_SHOW:
ODS( L"IComponent -- MMCN_SHOW\n" );
OnShow( pDataObj , ( BOOL )arg );
break;
case MMCN_VIEW_CHANGE:
ODS( L"IComponent -- MMCN_VIEW_CHANGE\n" );
OnViewChange( );
break;
case MMCN_CONTEXTHELP:
ODS( L"IComponent -- MMCN_CONTEXTHELP\n" );
OnHelp( pDataObj );
break;
case MMCN_SNAPINHELP:
ODS( L"IComponent -- MMCN_SNAPINHELP\n" );
break;
default:
ODS( L"CComp::Notify - event not registered\n" );
}
return S_OK;
}
//--------------------------------------------------------------------------
// pDataobject represents the current selected scope folder
// this should only be our main folder in the scope pane
//--------------------------------------------------------------------------
HRESULT CComp::OnShow( LPDATAOBJECT pDataobject , BOOL bSelect )
{
TCHAR tchBuffer[ 256 ];
HRESULT hr = S_FALSE;
ASSERT( pDataobject != NULL );
if( bSelect && m_pCompdata->IsSettingsFolder( pDataobject ) )
{
// set up columns for services folder
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_SETTINGS_COLUMN1 , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) ) );
if( m_nSettingCol == 0 && m_nAttribCol == 0 )
{
SetColumnsForSettingsPane( );
}
ODS( L"TSCC:Comp@OnShow inserting columns\n" );
if( m_nSettingCol == 0 )
{
hr = m_pHeaderCtrl->InsertColumn( 0 , tchBuffer , 0 , MMCLV_AUTO );
}
else
{
hr = m_pHeaderCtrl->InsertColumn( 0 , tchBuffer , 0 , m_nSettingCol );
}
if( SUCCEEDED( hr ) )
{
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ATTRIB_COLUMN2 , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) ) );
if( m_nAttribCol == 0 )
{
hr = m_pHeaderCtrl->InsertColumn( 1 , tchBuffer , 0 , MMCLV_AUTO );
}
else
{
hr = m_pHeaderCtrl->InsertColumn( 1 , tchBuffer , 0 , m_nAttribCol );
}
}
AddSettingsinResultPane( );
}
else if( bSelect && m_pCompdata->IsConnectionFolder( pDataobject ) )
{
// set up column headers for connection folder
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_COLCONNECT , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) ) );
hr = m_pHeaderCtrl->InsertColumn( 0 , tchBuffer , 0 , MMCLV_AUTO );
if( SUCCEEDED( hr ) )
{
//SetColumnWidth( 0 );
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_COLTRANSPORT , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) ) );
hr = m_pHeaderCtrl->InsertColumn( 1 , tchBuffer , 0 , MMCLV_AUTO );
}
if( SUCCEEDED( hr ) )
{
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_COLTYPE , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) ) );
// ui master dirty trick 120 equals fudge factor
hr = m_pHeaderCtrl->InsertColumn( 2 , tchBuffer , 0 , 120/*MMCLV_AUTO*/ );
}
if( SUCCEEDED( hr ) )
{
//SetColumnWidth( 2 );
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_COLCOMMENT , tchBuffer , SIZE_OF_BUFFER( tchBuffer ) ) );
hr = m_pHeaderCtrl->InsertColumn( 3 , tchBuffer , 0 , MMCLV_AUTO );
}
// insert items
if( SUCCEEDED( hr ) )
{
hr = InsertItemsinResultPane( );
}
}
return hr;
}
//--------------------------------------------------------------------------
BOOL CComp::OnAddImages( )
{
HICON hiconConnect = LoadIcon( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDI_ICON_CON ) );
HICON hiconDiscon = LoadIcon( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDI_ICON_DISCON ) );
HICON hiconBullet = LoadIcon( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDI_ICON_BULLET ) );
m_pImageResult->ImageListSetIcon( ( PLONG_PTR )hiconConnect , 1 );
m_pImageResult->ImageListSetIcon( ( PLONG_PTR )hiconDiscon , 2 );
m_pImageResult->ImageListSetIcon( ( PLONG_PTR )hiconBullet , 3 );
return TRUE;
}
//--------------------------------------------------------------------------
// update resultitems in result pane and note scopeitems
//--------------------------------------------------------------------------
BOOL CComp::OnViewChange( )
{
RESULTDATAITEM rdi;
ZeroMemory( &rdi , sizeof( RESULTDATAITEM ) );
rdi.mask = RDI_PARAM;
m_pResultData->GetItem( &rdi );
if( rdi.bScopeItem )
{
return FALSE;
}
if( SUCCEEDED( InsertItemsinResultPane( ) ) )
{
return TRUE;
}
return FALSE;
}
BOOL CComp::OnFullRefresh(LPDATAOBJECT pdo)
{
if (m_pCompdata->IsConnectionFolder(pdo))
{
if (!SUCCEEDED(InsertAndBuildItemsinResultPane()))
return FALSE;
}
if (m_pCompdata->IsSettingsFolder(pdo))
{
if (!SUCCEEDED(AddSettingsinResultPane()))
return FALSE;
}
return TRUE;
}
BOOL CComp::OnRefresh(LPDATAOBJECT pdo)
{
if (m_pCompdata->IsConnectionFolder(pdo))
{
if (!SUCCEEDED(InsertItemsinResultPane()))
return FALSE;
}
if (m_pCompdata->IsSettingsFolder(pdo))
{
if (!SUCCEEDED(AddSettingsinResultPane()))
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::Destroy( MMC_COOKIE /* reserved */ )
{
ODS( L"IComponent releasing interfaces\n" );
if( m_pResultData != NULL )
{
m_pResultData->Release( );
}
if( m_pConsole != NULL )
{
m_pConsole->Release( );
}
if( m_pHeaderCtrl != NULL )
{
m_pHeaderCtrl->Release( );
}
if( m_pConsoleVerb != NULL )
{
m_pConsoleVerb->Release( );
}
if( m_pImageResult != NULL )
{
m_pImageResult->Release( );
}
if( m_pDisplayHelp != NULL )
{
m_pDisplayHelp->Release( );
}
return S_OK;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::GetResultViewType( MMC_COOKIE , LPOLESTR* , PLONG plView )
{
*plView = MMC_VIEW_OPTIONS_NONE;
return S_FALSE;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::QueryDataObject( MMC_COOKIE ck , DATA_OBJECT_TYPES dtype , LPDATAOBJECT* ppDataObject )
{
if( dtype == CCT_RESULT )
{
*ppDataObject = ( LPDATAOBJECT )ck;
( ( LPDATAOBJECT )*ppDataObject)->AddRef( );
}
else if( m_pCompdata != NULL )
{
return m_pCompdata->QueryDataObject( ck , dtype , ppDataObject );
}
return S_OK;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::GetDisplayInfo( LPRESULTDATAITEM pRdi )
{
ASSERT( pRdi != NULL );
if( pRdi == NULL )
{
return E_INVALIDARG;
}
if( pRdi->bScopeItem )
{
CBaseNode *pScopeNode = ( CBaseNode * )pRdi->lParam;
if( pScopeNode != NULL )
{
if( pScopeNode->GetNodeType( ) == MAIN_NODE )
{
//
if( pRdi->mask & RDI_STR )
{
if( pRdi->nCol == 0 )
{
// pRdi->str is NULL in this call
pRdi->str = ( LPOLESTR )m_pCompdata->m_tchMainFolderName; //m_strDispName;
}
}
}
else if( pScopeNode->GetNodeType( ) == SETTINGS_NODE )
{
if( pRdi->mask & RDI_STR )
{
if( pRdi->nCol == 0 )
{
// pRdi->str is NULL in this call
pRdi->str = ( LPOLESTR )m_pCompdata->m_tchSettingsFolderName; //L"Server Settings";
}
}
}
}
if( pRdi->mask & RDI_IMAGE )
{
ODS( TEXT("RDI_IMAGE -- in CComponent::GetDisplayInfo\n") );
pRdi->nImage = ( ( CBaseNode * )pRdi->lParam )->GetImageIdx( );
}
}
else
{
// populate result pane
CBaseNode *pItem = ( CBaseNode * )pRdi->lParam;
if( pItem != NULL )
{
if( pItem->GetNodeType( ) == RESULT_NODE )
{
CResultNode *pNode = ( CResultNode * )pRdi->lParam;
if( pRdi->mask & RDI_STR )
{
switch( pRdi->nCol )
{
case 0:
pRdi->str = pNode->GetConName( );
break;
case 1:
pRdi->str = pNode->GetTTName( );
break;
case 2:
pRdi->str = pNode->GetTypeName( );
break;
case 3:
pRdi->str = pNode->GetComment( );
break;
}
}
}
else if( pItem->GetNodeType( ) == RSETTINGS_NODE )
{
CSettingNode *pNode = ( CSettingNode *)pRdi->lParam;
if( pRdi->mask & RDI_STR )
{
switch( pRdi->nCol )
{
case 0:
pRdi->str = pNode->GetAttributeName( );
break;
case 1:
if( pNode->GetObjectId( ) >= CUSTOM_EXTENSION )
{
DWORD dwStatus;
pNode->SetAttributeValue( 0 , &dwStatus );
}
pRdi->str = pNode->GetCachedValue( );
break;
}
}
}
}
}
return S_OK;
}
//--------------------------------------------------------------------------
// Returns S_OK if they are similar S_FALSE otherwise
//--------------------------------------------------------------------------
STDMETHODIMP CComp::CompareObjects( LPDATAOBJECT , LPDATAOBJECT )
{
return S_OK;
}
//--------------------------------------------------------------------------
//This has been added for when the user selects the Refresh menu item. We want
//to rebuild the result node list because it can change thru an external script.
//We're safe in doing this because Refresh can only be called when the focus
//is not on a result node. If it can be, there's a danger of pointer corruption
//in MMC, so we have to call InsertItemsinResultPane which is safer but not
//as complete a refresh operation.
HRESULT CComp::InsertAndBuildItemsinResultPane( )
{
HRESULT hr;
if( m_pCompdata == NULL )
return E_UNEXPECTED;
//This removes the node information from the data in MMC
if( FAILED( hr = m_pResultData->DeleteAllRsltItems( ) ) )
return hr;
if( FAILED( m_pCompdata->UpdateAllResultNodes( ) ) )
{
ODS( L"InsertItemsinResultPane - UpdateAllResultNodes failed!!\n" ) ;
return FALSE;
}
//This puts the data for the nodes into m_pCompdata and also sends that same information to MMC
if( FAILED( hr = m_pCompdata->InsertFolderItems( m_pResultData ) ) )
return hr;
return hr;
}
HRESULT CComp::InsertItemsinResultPane( )
{
HRESULT hr;
if( m_pCompdata == NULL )
return E_UNEXPECTED;
//This removes the node information from the data in MMC
if( FAILED( hr = m_pResultData->DeleteAllRsltItems( ) ) )
return hr;
//This is no longer being called because it's dangerous to modify all the result node pointers
//during execution since there's a chance they'll get out of sync with MMC's result node
//pointer list. This wasn't happening before because this is only called during an OnRefresh
//operation, which could only be called when items in the left pane were selected. Now, however,
//OnRefresh is called when switching between windows (bug 483485 - it has to be for MMC to get
//the current window's pointer list), so it's possible for a result node to have the focus,
//in which case the pointers don't get updated correctly and everything falls apart. When a
//refresh operation is triggered by the menu item, the focus has to be in the left pane so
//another method is used that includes this call to UpdateAllResultNodes
/*if( FAILED( m_pCompdata->UpdateAllResultNodes( ) ) )
{
ODS( L"InsertItemsinResultPane - UpdateAllResultNodes failed!!\n" ) ;
return FALSE;
}*/
//This puts the data for the nodes into m_pCompdata and also sends that same information to MMC
if( FAILED( hr = m_pCompdata->InsertFolderItems( m_pResultData ) ) )
return hr;
return hr;
}
//--------------------------------------------------------------------------
HRESULT CComp::AddSettingsinResultPane( )
{
HRESULT hr;
if( m_pCompdata == NULL )
return E_UNEXPECTED;
//This removes the node information from the data in MMC
if( FAILED( hr = m_pResultData->DeleteAllRsltItems( ) ) )
return hr;
if( FAILED( hr = m_pCompdata->InsertSettingItems( m_pResultData ) ) )
return hr;
return hr;
}
//--------------------------------------------------------------------------
HRESULT CComp::OnSelect( LPDATAOBJECT pdo , BOOL bScope , BOOL bSelected )
{
CBaseNode *pNode = static_cast< CBaseNode * >( pdo );
if( pNode == NULL )
{
return S_FALSE;
}
if( m_pConsoleVerb == NULL )
{
return E_UNEXPECTED;
}
// Item is being deselected and we're not interested currently
if( !bSelected )
{
return S_OK;
}
// pNode == NULL if the folder item is being viewed in the result pane
// settings node is ignored for this release
if( bScope && pNode->GetNodeType( ) == MAIN_NODE )
{
m_pConsoleVerb->SetVerbState( MMC_VERB_REFRESH , ENABLED , TRUE );
m_pConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN );
}
else if( pNode->GetNodeType() == SETTINGS_NODE )
{
m_pConsoleVerb->SetVerbState( MMC_VERB_REFRESH , ENABLED , TRUE );
}
else if( pNode->GetNodeType() == RESULT_NODE )
{
m_pConsoleVerb->SetVerbState( MMC_VERB_DELETE , ENABLED , TRUE );
//m_pConsoleVerb->SetVerbState( MMC_VERB_REFRESH , ENABLED , TRUE );
m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES , ENABLED , TRUE );
m_pConsoleVerb->SetDefaultVerb( MMC_VERB_PROPERTIES );
}
return S_OK;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::AddMenuItems( LPDATAOBJECT pdo , LPCONTEXTMENUCALLBACK pcmc , PLONG pl )
{
// CONTEXTMENUITEM cmi;
if( pdo == NULL || pcmc == NULL )
{
return E_UNEXPECTED;
}
// do not allow scope node types
if( m_pCompdata->IsConnectionFolder( pdo ) || m_pCompdata->IsSettingsFolder( pdo ) )
{
return S_FALSE;
}
CBaseNode *pNode = NULL;
pNode = static_cast< CBaseNode * >( pdo );
if( pNode == NULL )
{
return S_FALSE;
}
// hey root node has no menu items to insert.
if( pNode->GetNodeType() == 0 )
{
return S_FALSE;
}
if( pNode->AddMenuItems( pcmc , pl ) )
{
return S_OK;
}
return E_FAIL;
}
//--------------------------------------------------------------------------
// Toggles connection
//--------------------------------------------------------------------------
STDMETHODIMP CComp::Command( LONG lCmd , LPDATAOBJECT pdo )
{
TCHAR buf[ 512 ];
TCHAR tchmsg[ 256 ];
HRESULT hr;
if( pdo == NULL )
{
return E_UNEXPECTED;
}
HWND hMain;
if( FAILED( m_pConsole->GetMainWindow( &hMain ) ) )
{
hMain = NULL;
}
CResultNode *pNode = NULL;
CSettingNode *pSetNode = NULL;
if( pdo == NULL )
{
return S_FALSE;
}
if( ( ( CBaseNode * )pdo )->GetNodeType( ) == RSETTINGS_NODE )
{
pSetNode = ( CSettingNode * )pdo;
BOOL bVal;
DWORD dwStatus = 0;
switch( lCmd )
{
case IDM_SETTINGS_PROPERTIES:
OnDblClk( pdo );
break;
case IDM_SETTINGS_DELTEMPDIRSONEXIT:
case IDM_SETTINGS_USETMPDIR:
case IDM_SETTINGS_ADP:
case IDM_SETTINGS_SS:
{
bVal = ( BOOL )pSetNode->xx_GetValue( );
HCURSOR hCursor = SetCursor( LoadCursor( NULL , MAKEINTRESOURCE( IDC_WAIT ) ) );
hr = pSetNode->SetAttributeValue( !bVal , &dwStatus );
if( FAILED( hr ) )
{
SnodeErrorHandler( hMain , pSetNode->GetObjectId( ) , dwStatus );
}
//
// We might want to move this code into OnRefresh() but for now, this is fix for
// not updating attribute value and don't want to cause other regression
//
HRESULT hr;
HRESULTITEM itemID;
hr = m_pResultData->FindItemByLParam( (LPARAM) pdo, &itemID );
if( SUCCEEDED(hr) )
{
m_pResultData->UpdateItem( itemID );
}
SetCursor( hCursor );
}
break;
default:
if( pSetNode->GetObjectId() >= CUSTOM_EXTENSION )
{
IExtendServerSettings *pEss = reinterpret_cast< IExtendServerSettings * >( pSetNode->GetInterface() );
if( pEss != NULL )
{
pEss->ExecMenuCmd( lCmd , hMain , &dwStatus );
// this forces the ui to be updated.
if( dwStatus == UPDATE_TERMSRV || dwStatus == UPDATE_TERMSRV_SESSDIR )
{
ICfgComp *pCfgcomp = NULL;
m_pCompdata->GetServer( &pCfgcomp );
if( pCfgcomp != NULL )
{
ODS( L"TSCC!ExecMenuCmd forcing termsrv update\n" );
if( dwStatus == UPDATE_TERMSRV_SESSDIR )
{
HCURSOR hCursor = SetCursor( LoadCursor( NULL ,
MAKEINTRESOURCE( IDC_WAIT ) ) );
if( FAILED( pCfgcomp->UpdateSessionDirectory( &dwStatus ) ) )
{
ReportStatusError( hMain , dwStatus );
}
HRESULTITEM itemID;
hr = m_pResultData->FindItemByLParam( (LPARAM) pdo, &itemID );
if( SUCCEEDED(hr) )
{
m_pResultData->UpdateItem( itemID );
}
SetCursor(hCursor);
}
else
{
pCfgcomp->ForceUpdate( );
}
pCfgcomp->Release();
}
}
pSetNode->SetAttributeValue( 0 , &dwStatus );
}
}
}
}
else if( ( ( CBaseNode * )pdo )->GetNodeType( ) == RESULT_NODE )
{
pNode = ( CResultNode * )pdo;
if( lCmd == IDM_ENABLE_CONNECTION )
{
if( pNode->m_bEditMode )
{
xxxErrMessage( hMain , IDS_ERR_INEDITMODE , IDS_WARN_TITLE , MB_OK | MB_ICONWARNING );
return S_FALSE;
}
ICfgComp *pCfgcomp;
if( pNode->GetServer( &pCfgcomp ) != 0 )
{
WS *pWs;
LONG lSz;
if( SUCCEEDED( pCfgcomp->GetWSInfo( pNode->GetConName( ) , &lSz , &pWs ) ) )
{
BOOL bProceed = TRUE;
pWs->fEnableWinstation = !pNode->GetConnectionState( );
if( pWs->fEnableWinstation == 0 )
{
LONG lCount;
// check to see if anyone is connected
pCfgcomp->QueryLoggedOnCount( pNode->GetConName( ) , &lCount );
if( lCount > 0 )
{
LoadString( _Module.GetResourceInstance( ) , IDS_DISABLELIVECONNECTION , tchmsg , SIZE_OF_BUFFER( tchmsg ) );
}
else
{
LoadString( _Module.GetResourceInstance( ) , IDS_DISABLECONNECTION , tchmsg , SIZE_OF_BUFFER( tchmsg ) );
}
wsprintf( buf , tchmsg , pNode->GetConName( ) );
LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchmsg , SIZE_OF_BUFFER( tchmsg ) );
if( MessageBox( hMain , buf , tchmsg , MB_ICONWARNING | MB_YESNO ) == IDNO )
{
bProceed = FALSE;
}
}
if( bProceed )
{
/*pNode->EnableConnection( pWs->fEnableWinstation );
pNode->SetImageIdx( ( pWs->fEnableWinstation ? 1 : 2 ) );
pCfgcomp->UpDateWS( pWs , UPDATE_ENABLEWINSTATION );
m_pConsole->UpdateAllViews( ( LPDATAOBJECT )pNode , 0 , 0 );
*/
DWORD dwStatus;
if( FAILED( hr = pCfgcomp->UpDateWS( pWs , UPDATE_ENABLEWINSTATION , &dwStatus, TRUE ) ) )
{
if( hr == E_ACCESSDENIED )
{
TscAccessDeniedMsg( hMain );
}
else
{
TscGeneralErrMsg( hMain );
}
}
else
{
pNode->EnableConnection( pWs->fEnableWinstation );
pNode->SetImageIdx( ( pWs->fEnableWinstation ? 1 : 2 ) );
m_pConsole->UpdateAllViews( ( LPDATAOBJECT )pNode , 0 , 0 );
}
}
if(pWs->fEnableWinstation && pWs->PdClass == SdAsync)
{
ASYNCCONFIGW AsyncConfig;
HRESULT hResult = pCfgcomp->GetAsyncConfig( pWs->Name , WsName , &AsyncConfig );
if( SUCCEEDED( hResult ) )
{
if( AsyncConfig.ModemName[0] )
{
LoadString( _Module.GetResourceInstance( ) , IDS_REBOOT_REQD , buf , SIZE_OF_BUFFER( buf ) );
LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchmsg , SIZE_OF_BUFFER( tchmsg ) );
MessageBox( hMain , buf , tchmsg , MB_ICONWARNING | MB_OK );
}
}
}
CoTaskMemFree( pWs );
}
pCfgcomp->Release( );
}
}
else if( lCmd == IDM_RENAME_CONNECTION )
{
if( pNode->m_bEditMode )
{
xxxErrMessage( hMain , IDS_ERR_INEDITMODE , IDS_WARN_TITLE , MB_OK | MB_ICONWARNING );
return S_FALSE;
}
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_RENAME ) , hMain , RenameDlgProc , ( LPARAM )pNode );
}
}
return S_OK;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::CreatePropertyPages( LPPROPERTYSHEETCALLBACK psc , LONG_PTR Handle , LPDATAOBJECT pdo )
{
HRESULT hr = E_OUTOFMEMORY;
if( psc == NULL )
{
return E_UNEXPECTED;
}
CPropsheet *pPropsheet = new CPropsheet( );
if( pPropsheet != NULL )
{
HWND hMain;
if( FAILED( m_pConsole->GetMainWindow( &hMain ) ) )
{
hMain = NULL;
}
if( FAILED( ( hr = pPropsheet->InitDialogs( hMain , psc , dynamic_cast< CResultNode *>( pdo ) , Handle ) ) ) )
{
delete pPropsheet;
}
}
return hr;
}
//--------------------------------------------------------------------------
STDMETHODIMP CComp::QueryPagesFor( LPDATAOBJECT pdo )
{
if( dynamic_cast< CResultNode *>( pdo ) == NULL )
{
return E_INVALIDARG;
}
return S_OK;
}
//--------------------------------------------------------------------------
BOOL CComp::OnDelete( LPDATAOBJECT pDo )
{
CResultNode *pNode = dynamic_cast< CResultNode *>( pDo );
if( pNode == NULL )
{
ODS( L"TSCC: OnDelete, node == NULL\n");
return FALSE;
}
if( pNode->m_bEditMode )
{
HWND hMain;
if( FAILED( m_pConsole->GetMainWindow( &hMain ) ) )
{
hMain = NULL;
}
xxxErrMessage( hMain , IDS_ERR_INEDITMODE , IDS_WARN_TITLE , MB_OK | MB_ICONWARNING );
return FALSE;
}
return m_pCompdata->OnDeleteItem( pDo );
}
//--------------------------------------------------------------------------
// CResultNode passed in on init
//--------------------------------------------------------------------------
INT_PTR CALLBACK RenameDlgProc( HWND hDlg , UINT msg , WPARAM wp , LPARAM lp )
{
CResultNode *pNode;
TCHAR tchNewName[ 60 ];
// HWND h;
switch( msg )
{
case WM_INITDIALOG :
pNode = ( CResultNode *)lp;
ASSERT( pNode != NULL );
// ok to store null -- it's initializing DWLP_USER area
SetWindowLongPtr( hDlg , DWLP_USER , ( LONG_PTR )pNode );
// Insert name
ICfgComp *pCfgcomp;
if( pNode == NULL )
{
break;
}
if( pNode->GetServer( &pCfgcomp ) == 0 )
{
ASSERT( 0 );
break;
}
SetWindowText( GetDlgItem( hDlg , IDC_STATIC_CURRENT_NAME ) , pNode->GetConName( ) );
pCfgcomp->Release( );
SetFocus( GetDlgItem( hDlg , IDC_EDIT_NEWNAME ) );
SendMessage( GetDlgItem( hDlg , IDC_EDIT_NEWNAME ) , EM_SETLIMITTEXT , ( WPARAM )( WINSTATIONNAME_LENGTH - WINSTATION_NAME_TRUNCATE_BY ) , 0 );
break;
case WM_COMMAND:
if( LOWORD( wp ) == IDOK )
{
pNode = ( CResultNode *)GetWindowLongPtr( hDlg , DWLP_USER );
if( pNode == NULL )
{
break;
}
DWORD dwErr = 0;
if( GetWindowText( GetDlgItem( hDlg , IDC_EDIT_NEWNAME ) , tchNewName , SIZE_OF_BUFFER( tchNewName ) ) == 0 ||
!IsValidConnectionName( tchNewName , &dwErr ) )
{
if( dwErr == ERROR_INVALID_FIRSTCHARACTER )
{
ErrMessage( hDlg , IDS_ERR_INVALIDFIRSTCHAR );
}
else
{
ErrMessage( hDlg , IDS_ERR_INVALIDCHARS );
}
SetFocus( GetDlgItem( hDlg , IDC_EDIT_NEWNAME ) );
SendMessage( GetDlgItem( hDlg , IDC_EDIT_NEWNAME ) , EM_SETSEL , ( WPARAM )0 , ( LPARAM )-1 );
return 0;
}
// verify the name is unique
ICfgComp *pCfgcomp;
if( pNode->GetServer( &pCfgcomp ) == 0 )
{
ODS( L"GetServer failed in RenameDlgProc\n" );
break;
}
do
{
BOOL bUnique = FALSE;
if( FAILED( pCfgcomp->IsWSNameUnique( ( PWINSTATIONNAMEW )tchNewName , &bUnique ) ) )
{
break;
}
if( !bUnique )
{
ErrMessage( hDlg , IDS_ERR_WINNAME );
pCfgcomp->Release( );
SetFocus( GetDlgItem( hDlg , IDC_EDIT_NEWNAME ) );
SendMessage( GetDlgItem( hDlg , IDC_EDIT_NEWNAME ) , EM_SETSEL , ( WPARAM )0 , ( LPARAM )-1 );
return 0;
}
HRESULT hr;
LONG lCount;
TCHAR tchWrnBuf[ 256 ];
TCHAR tchOutput[ 512 ];
// check to see if anyone is connected
pCfgcomp->QueryLoggedOnCount( pNode->GetConName( ) , &lCount );
if( lCount > 0 )
{
if( lCount == 1 )
{
LoadString( _Module.GetResourceInstance() , IDS_RENAME_WRN_SINGLE , tchWrnBuf , SIZE_OF_BUFFER( tchWrnBuf ) );
}
else
{
LoadString( _Module.GetResourceInstance() , IDS_RENAME_WRN_PL , tchWrnBuf , SIZE_OF_BUFFER( tchWrnBuf ) );
}
wsprintf( tchOutput , tchWrnBuf , pNode->GetConName( ) );
LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchWrnBuf , SIZE_OF_BUFFER( tchWrnBuf ) );
if( MessageBox( hDlg , tchOutput , tchWrnBuf , MB_ICONWARNING | MB_YESNO ) == IDNO )
{
break;
}
}
if( FAILED( hr = pCfgcomp->RenameWinstation( ( PWINSTATIONNAMEW )pNode->GetConName( ) , ( PWINSTATIONNAMEW )tchNewName ) ) )
{
ODS( L"TSCC: RenameWinstation failed\n" );
if( hr == E_ACCESSDENIED )
{
TscAccessDeniedMsg( hDlg );
}
else
{
TscGeneralErrMsg( hDlg );
}
break;
}
/*
LONG lCount;
TCHAR tchWrnBuf[ 256 ];
TCHAR tchOutput[ 512 ];
// check to see if anyone is connected
pCfgcomp->QueryLoggedOnCount( pNode->GetConName( ) , &lCount );
if( lCount > 0 )
{
if( lCount == 1 )
{
LoadString( _Module.GetResourceInstance() , IDS_RENAME_WRN_SINGLE , tchWrnBuf , SIZE_OF_BUFFER( tchWrnBuf ) );
}
else
{
LoadString( _Module.GetResourceInstance() , IDS_RENAME_WRN_PL , tchWrnBuf , SIZE_OF_BUFFER( tchWrnBuf ) );
}
wsprintf( tchOutput , tchWrnBuf , pNode->GetConName( ) );
LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchWrnBuf , SIZE_OF_BUFFER( tchWrnBuf ) );
MessageBox( hDlg , tchOutput , tchWrnBuf , MB_OK | MB_ICONWARNING );
}
*/
WS *pWs;
LONG lSz;
if( SUCCEEDED( pCfgcomp->GetWSInfo(tchNewName , &lSz , &pWs ) ) )
{
if(pWs->fEnableWinstation && pWs->PdClass == SdAsync)
{
ASYNCCONFIGW AsyncConfig;
HRESULT hResult = pCfgcomp->GetAsyncConfig( pWs->Name , WsName , &AsyncConfig );
if( SUCCEEDED( hResult ) )
{
if( AsyncConfig.ModemName[0] )
{
LoadString( _Module.GetResourceInstance( ) , IDS_REBOOT_REQD , tchOutput , SIZE_OF_BUFFER( tchOutput ) );
LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchWrnBuf , SIZE_OF_BUFFER( tchWrnBuf ) );
MessageBox( hDlg , tchOutput , tchWrnBuf , MB_ICONWARNING | MB_OK );
}
}
}
CoTaskMemFree( pWs );
}
pNode->SetConName( tchNewName , SIZE_OF_BUFFER( tchNewName ) );
}while( 0 );
pCfgcomp->Release( );
EndDialog( hDlg , 0 );
}
else if( LOWORD( wp ) == IDCANCEL )
{
EndDialog( hDlg , 0 );
}
break;
}
return 0;
}
//--------------------------------------------------------------------------
BOOL IsValidConnectionName( LPTSTR szConName , PDWORD pdwErr )
{
TCHAR tchInvalidChars[ 80 ];
tchInvalidChars[0] = 0;
if( szConName == NULL || pdwErr == NULL )
{
return FALSE;
}
if( _istdigit( szConName[ 0 ] ) )
{
*pdwErr = ERROR_INVALID_FIRSTCHARACTER;
return FALSE;
}
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance() , IDS_INVALID_CHARS , tchInvalidChars , SIZE_OF_BUFFER( tchInvalidChars ) ) );
int nLen = lstrlen( tchInvalidChars );
while( *szConName )
{
for( int idx = 0 ; idx < nLen ; idx++ )
{
if( *szConName == tchInvalidChars[ idx ] )
{
*pdwErr = ERROR_ILLEGAL_CHARACTER;
return FALSE;
}
}
szConName++;
}
*pdwErr = ERROR_SUCCESS;
return TRUE;
}
//----------------------------------------------------------------------
BOOL CComp::OnHelp( LPDATAOBJECT pDo )
{
TCHAR tchTopic[ 80 ];
HRESULT hr = E_FAIL;
if( pDo == NULL || m_pDisplayHelp == NULL )
{
return hr;
}
INT_PTR nNodeType = ( ( CBaseNode * )pDo )->GetNodeType();
if( nNodeType == RESULT_NODE || nNodeType == MAIN_NODE || nNodeType == 0 )
{
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance() , IDS_TSCCHELPTOPIC , tchTopic , SIZE_OF_BUFFER( tchTopic ) ) );
hr = m_pDisplayHelp->ShowTopic( tchTopic );
}
else if( nNodeType == SETTINGS_NODE || nNodeType == RSETTINGS_NODE )
{
if( nNodeType == SETTINGS_NODE )
{
IExtendServerSettings *pEss = NULL;
INT iRet = -1;
CSettingNode *pNode = dynamic_cast< CSettingNode *>( pDo );
if( pNode != NULL )
{
if( pNode->GetObjectId( ) >= CUSTOM_EXTENSION )
{
pEss = reinterpret_cast< IExtendServerSettings * >( pNode->GetInterface( ) );
if( pEss != NULL )
{
pEss->OnHelp( &iRet );
if( iRet == 0 )
{
return TRUE;
}
}
}
}
}
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance() , IDS_SETTINGSHELP , tchTopic , SIZE_OF_BUFFER( tchTopic ) ) );
hr = m_pDisplayHelp->ShowTopic( tchTopic );
}
return ( SUCCEEDED( hr ) ? TRUE : FALSE );
}
//----------------------------------------------------------------------
BOOL CComp::OnDblClk( LPDATAOBJECT pDo )
{
CSettingNode *pNode = dynamic_cast< CSettingNode *>( pDo );
if( pNode == NULL )
{
// we're only concerned about Setting nodes
return FALSE;
}
HWND hMain;
if( FAILED( m_pConsole->GetMainWindow( &hMain ) ) )
{
hMain = NULL;
}
INT nObjectId = pNode->GetObjectId( );
switch( nObjectId )
{
/*
case 0:
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_CACHED_SESSIONS ) , hMain , CachedSessionsDlgProc , ( LPARAM )pNode );
break;*/
case DELETED_DIRS_ONEXIT:
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_YESNODIALOG ) , hMain , DeleteTempDirsDlgProc , ( LPARAM )pNode );
break;
case PERSESSION_TEMPDIR:
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_DIALOG_PERSESSION ) , hMain , UsePerSessionTempDirsDlgProc , ( LPARAM )pNode );
break;
/*
case DEF_CONSECURITY:
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_DEFCONSEC ) , hMain , DefConSecurityDlgProc , ( LPARAM )pNode );
break;
*/
case LICENSING:
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_LICENSING ) , hMain , LicensingDlgProc , ( LPARAM )pNode );
break;
case ACTIVE_DESK:
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_ADP_DIALOG ) , hMain , ConfigActiveDesktop , ( LPARAM )pNode );
break;
case USERSECURITY:
// error if we're trying to modify property in remote admin mode
if( !g_bAppSrvMode )
{
xxxErrMessage( hMain , IDS_REMOTEADMIN_ONLY , IDS_WARN_TITLE , MB_OK | MB_ICONINFORMATION );
break;
}
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_PROPPAGE_TERMINAL_SERVER_PERM ) , hMain , UserPermCompat , ( LPARAM )pNode );
break;
case SINGLE_SESSION:
::DialogBoxParam( _Module.GetModuleInstance( ) , MAKEINTRESOURCE( IDD_SINGLE_SESSION) , hMain , ConfigSingleSession , ( LPARAM )pNode );
break;
default:
if( nObjectId >= CUSTOM_EXTENSION )
{
IExtendServerSettings *pEss = reinterpret_cast< IExtendServerSettings * >( pNode->GetInterface() );
if( pEss != NULL )
{
DWORD dwStatus;
pEss->InvokeUI( hMain , &dwStatus );
if( dwStatus == UPDATE_TERMSRV || dwStatus == UPDATE_TERMSRV_SESSDIR )
{
ICfgComp *pCfgcomp = NULL;
m_pCompdata->GetServer( &pCfgcomp );
if( pCfgcomp != NULL )
{
ODS( L"TSCC!Comp OnDblClk forcing termsrv update\n" );
if( dwStatus == UPDATE_TERMSRV_SESSDIR )
{
HCURSOR hCursor = SetCursor( LoadCursor( NULL ,
MAKEINTRESOURCE( IDC_WAIT ) ) );
if( FAILED( pCfgcomp->UpdateSessionDirectory( &dwStatus ) ) )
{
ReportStatusError( hMain , dwStatus );
}
SetCursor(hCursor);
}
else
{
pCfgcomp->ForceUpdate( );
}
pCfgcomp->Release();
}
}
}
}
}
return TRUE;
}
/*
//----------------------------------------------------------------------
HRESULT CComp::SetColumnWidth( int nCol )
{
HWND hMain;
int nCurColLen;
CResultNode *pNode;
do
{
if( FAILED( m_pHeaderCtrl->GetColumnWidth( nCol , &nCurColLen ) ) )
{
break;
}
if( FAILED( m_pConsole->GetMainWindow( &hMain ) ) )
{
break;
}
HDC hdc = GetDC( hMain );
SIZE sz;
int idx = 0;
TCHAR *psz;
while( ( pNode = *m_pCompdata->GetResultNode( idx ) ) != NULL )
{
switch( nCol )
{
case 0:
psz = pNode->GetConName( );
break;
case 1:
psz = pNode->GetTTName( );
break;
case 2:
psz = pNode->GetTypeName( );
break;
// comment is too big allow user to adjust size
}
GetTextExtentPoint32( hdc , psz , lstrlen( psz ) , &sz );
if( sz.cx > nCurColLen )
{
nCurColLen = sz.cx;
}
idx++;
}
m_pHeaderCtrl->SetColumnWidth( nCol , nCurColLen );
ReleaseDC( hMain , hdc );
} while( 0 );
return S_OK;
}
*/
//----------------------------------------------------------------------
HRESULT CComp::SetColumnsForSettingsPane( )
{
HWND hParent;
SIZE sz = { 0 , 0 };
TCHAR tchBuffer[ 256 ];
INT nMaxLen;
if( FAILED( m_pConsole->GetMainWindow( &hParent ) ) )
{
hParent = NULL;
}
HDC hdc = GetDC( hParent );
if( hdc != NULL )
{
m_pCompdata->GetMaxTextLengthSetting( tchBuffer , &nMaxLen );
VERIFY_S( TRUE , GetTextExtentPoint32( hdc , tchBuffer , nMaxLen , &sz ) );
m_nSettingCol = sz.cx - 16 ; // remove icon width from column width
m_pCompdata->GetMaxTextLengthAttribute( tchBuffer , &nMaxLen );
VERIFY_S( TRUE , GetTextExtentPoint32( hdc , tchBuffer , nMaxLen , &sz ) );
m_nAttribCol = sz.cx;
ReleaseDC( hParent , hdc );
}
return S_OK;
}