|
|
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// CServerNode
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <Pop3RegKeys.h>
#include <AuthID.h>
// Access to Snapin
#include "pop3.h"
#include "pop3snap.h"
// Access to Nodes we use
#include "ServerNode.h"
#include "DomainNode.h"
// Access to dialogs we'll display
#include "NewDomainDlg.h"
#include "ServerProp.h"
static const GUID CServerNodeGUID_NODETYPE = { 0x4c30b06c, 0x1dc3, 0x4c0d, { 0x87, 0xb4, 0x64, 0xbf, 0xe8, 0x22, 0xf4, 0x50 } };
const GUID* CServerNode::m_NODETYPE = &CServerNodeGUID_NODETYPE; const OLECHAR* CServerNode::m_SZNODETYPE = OLESTR("4C30B06C-1DC3-4c0d-87B4-64BFE822F450"); const OLECHAR* CServerNode::m_SZDISPLAY_NAME = OLESTR(""); const CLSID* CServerNode::m_SNAPIN_CLASSID = &CLSID_POP3ServerSnap;
/////////////////////////////////////////////////////////////////////////
//
// Class implementation
//
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// CServerNode::CServerNode
//
// Constructor : Uses servername for remote Servers
CServerNode::CServerNode(BSTR strServerName, CRootNode* pParent, BOOL bLocalServer) : m_lRefCount(1), m_hrValidServer(S_OK), m_bstrAuthentication(_T("")), m_bstrMailRoot(_T("")), m_bstrPort(_T("")), m_bstrLogLevel(_T("")), m_bstrServiceStatus(_T("")) { // Initialize our Scope item
memset( &m_scopeDataItem, 0, sizeof(m_scopeDataItem) ); m_scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM; m_scopeDataItem.displayname = MMC_CALLBACK; m_scopeDataItem.nImage = 0; m_scopeDataItem.nOpenImage = 0; m_scopeDataItem.lParam = (LPARAM) this; // Initialize our Result item
memset( &m_resultDataItem, 0, sizeof(m_resultDataItem) ); m_resultDataItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; m_resultDataItem.str = MMC_CALLBACK; m_resultDataItem.nImage = 0; m_resultDataItem.lParam = (LPARAM) this;
if( bLocalServer ) { // We are the local server for now.
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1] = {0}; DWORD dwBuffer = MAX_COMPUTERNAME_LENGTH+1; if( GetComputerName(szComputerName, &dwBuffer) ) { m_bstrDisplayName = szComputerName; } else { #if DBG
m_bstrDisplayName = CComBSTR("Local Server"); #else
m_bstrDisplayName = CComBSTR(""); #endif
} }
// Get Parent Information
m_pParent = pParent;
// Open our Pop3 Admin Interface and store it
HRESULT hr = CoCreateInstance(__uuidof(P3Config), NULL, CLSCTX_ALL, __uuidof(IP3Config), (LPVOID*)&m_spConfig);
if( FAILED(hr) || !m_spConfig ) { m_hrValidServer = FAILED(hr) ? hr : E_FAIL; return; }
if( !bLocalServer ) { // Configure our remote computer setup
m_bstrDisplayName = strServerName; hr = m_spConfig->put_MachineName( strServerName ); if( FAILED(hr) ) { // Invalid Server Name!
m_hrValidServer = hr; return; } } // Do our User creation property
DWORD dwValue = 0; RegQueryCreateUser( dwValue, m_bstrDisplayName ); m_bCreateUser = dwValue; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::~CServerNode
//
// Destructor : Make sure to clean up our member-list
CServerNode::~CServerNode() { for(DOMAINLIST::iterator iter = m_lDomains.begin(); iter != m_lDomains.end(); iter++) { delete (*iter); } m_lDomains.clear(); }
/////////////////////////////////////////////////////////////////////////
// CServerNode::DeleteDomain
//
// Helper function to delete a child domain from all of POP3
HRESULT CServerNode::DeleteDomain(CDomainNode* pDomainNode) { if( !pDomainNode ) return E_INVALIDARG; if( !m_spConfig ) return E_FAIL;
// Delete from POP3 Admin Interface
CComPtr<IP3Domains> spDomains; HRESULT hr = m_spConfig->get_Domains( &spDomains );
// Update the P3Admin Interface
if( SUCCEEDED(hr) ) { hr = spDomains->Remove( pDomainNode->m_bstrDisplayName ); }
// Update our list
if( SUCCEEDED(hr) ) { m_lDomains.remove(pDomainNode); }
return hr; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::OnExpand
//
// Helper function to refresh list of domains and insert them
HRESULT CServerNode::OnExpand(BOOL bExpand, HSCOPEITEM hScopeItem, IConsole* pConsole) { if( !hScopeItem || !pConsole ) return E_INVALIDARG; if( !m_spConfig ) return E_FAIL;
HRESULT hr = S_OK; CComQIPtr<IConsoleNameSpace> spConsoleNameSpace = pConsole; if( !spConsoleNameSpace ) return E_NOINTERFACE; // If we have any children, delete them all from the namespace
HSCOPEITEM hChild = NULL; MMC_COOKIE cookie = 0; hr = spConsoleNameSpace->GetChildItem(m_scopeDataItem.ID, &hChild, &cookie); if( SUCCEEDED(hr) && hChild ) { hr = spConsoleNameSpace->DeleteItem(m_scopeDataItem.ID, FALSE); }
if( SUCCEEDED(hr) ) { // then delete all of our member-list of domains
for(DOMAINLIST::iterator iter = m_lDomains.begin(); iter != m_lDomains.end(); iter++) { delete (*iter); } m_lDomains.clear(); }
if( FAILED(hr) || !bExpand ) { // Error, or we are Contracting
return S_OK; }
// Expanding
// Fill in our list of domains
CComPtr<IP3Domains> spDomains; CComPtr<IEnumVARIANT> spDomainEnum; // Get the Domains
hr = m_spConfig->get_Domains( &spDomains );
// Get an Enumerator for the Domains
if( SUCCEEDED(hr) ) { hr = spDomains->get__NewEnum( &spDomainEnum ); }
// Loop through the domains, and add each new domain
if( SUCCEEDED(hr) ) { CComVariant var; ULONG lResult = 0;
VariantInit( &var );
while ( spDomainEnum->Next(1, &var, &lResult) == S_OK ) { if ( lResult == 1 ) { CComQIPtr<IP3Domain> spDomain; spDomain = V_DISPATCH(&var);
CDomainNode* spDomainNode = new CDomainNode(spDomain, this); if( spDomainNode ) { m_lDomains.push_back(spDomainNode); } }
VariantClear(&var); } }
if( SUCCEEDED(hr) ) { for(DOMAINLIST::iterator iter = m_lDomains.begin(); iter != m_lDomains.end(); iter++) { CDomainNode* pDomain = *iter;
pDomain->m_scopeDataItem.mask |= SDI_PARENT; pDomain->m_scopeDataItem.relativeID = m_scopeDataItem.ID; hr = spConsoleNameSpace->InsertItem( &(pDomain->m_scopeDataItem) ); if( FAILED(hr) ) return hr; } }
if( SUCCEEDED(hr) ) { CComQIPtr<IConsole2> spCons2 = pConsole; if( spCons2 ) { // Output the number of servers we added
tstring strMessage = StrLoadString(IDS_SERVER_STATUSBAR); OLECHAR pszStatus[1024] = {0}; _sntprintf( pszStatus, 1023, strMessage.c_str(), m_lDomains.size() ); spCons2->SetStatusText( pszStatus ); } }
return hr; }
/////////////////////////////////////////////////////////////////////////
//
// SnapInItemImpl
//
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// CServerNode::GetScopePaneInfo
//
// Callback used to get Scope-Pane display information by MMC
HRESULT CServerNode::GetScopePaneInfo(SCOPEDATAITEM *pScopeDataItem) { if( !pScopeDataItem ) return E_INVALIDARG;
if( pScopeDataItem->mask & SDI_STR ) pScopeDataItem->displayname = m_bstrDisplayName; if( pScopeDataItem->mask & SDI_IMAGE ) pScopeDataItem->nImage = m_scopeDataItem.nImage; if( pScopeDataItem->mask & SDI_OPENIMAGE ) pScopeDataItem->nOpenImage = m_scopeDataItem.nOpenImage; if( pScopeDataItem->mask & SDI_PARAM ) pScopeDataItem->lParam = m_scopeDataItem.lParam; if( pScopeDataItem->mask & SDI_STATE ) pScopeDataItem->nState = m_scopeDataItem.nState;
return S_OK; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::GetResultPaneInfo
//
// Callback used to get Result Pane display information by MMC
HRESULT CServerNode::GetResultPaneInfo(RESULTDATAITEM *pResultDataItem) { if( !pResultDataItem ) return E_INVALIDARG;
if( pResultDataItem->bScopeItem ) { if( pResultDataItem->mask & RDI_STR ) pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol); if( pResultDataItem->mask & RDI_IMAGE ) pResultDataItem->nImage = m_scopeDataItem.nImage; if( pResultDataItem->mask & RDI_PARAM ) pResultDataItem->lParam = m_scopeDataItem.lParam; return S_OK; }
if( pResultDataItem->mask & RDI_STR ) pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol); if( pResultDataItem->mask & RDI_IMAGE ) pResultDataItem->nImage = m_resultDataItem.nImage; if( pResultDataItem->mask & RDI_PARAM ) pResultDataItem->lParam = m_resultDataItem.lParam; if( pResultDataItem->mask & RDI_INDEX ) pResultDataItem->nIndex = m_resultDataItem.nIndex; return S_OK; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::GetResultPaneColInfo
//
// Helper function used as part of the GetResultPaneInfo. This function
// will supply the text for the different columns.
LPOLESTR CServerNode::GetResultPaneColInfo(int nCol) { if( !m_spConfig ) return L"";
switch( nCol ) { case 0: // Name
{ return m_bstrDisplayName; }
case 1: // Authentication Type
{ CComPtr<IAuthMethods> spMethods; CComPtr<IAuthMethod> spAuth; CComVariant var;
HRESULT hr = m_spConfig->get_Authentication( &spMethods );
if( SUCCEEDED(hr) ) { hr = spMethods->get_CurrentAuthMethod( &var ); }
if( SUCCEEDED(hr) ) { hr = spMethods->get_Item( var, &spAuth ); }
if( SUCCEEDED(hr) ) { hr = spAuth->get_Name( &m_bstrAuthentication ); }
if( FAILED(hr) ) { #if DBG
m_bstrAuthentication = _T("Unknown"); #else
m_bstrAuthentication = _T(""); #endif
}
return m_bstrAuthentication; }
case 2: // Root Mail Directory
{ HRESULT hr = m_spConfig->get_MailRoot( &m_bstrMailRoot ); if( FAILED(hr) ) { #if DBG
m_bstrMailRoot = _T("Unknown"); #else
m_bstrMailRoot = _T(""); #endif
} return m_bstrMailRoot; }
case 3: // Port
{ long lPort = 0; CComPtr<IP3Service> spService; HRESULT hr = m_spConfig->get_Service( &spService );
if( SUCCEEDED(hr) ) { hr = spService->get_Port( &lPort );
if( FAILED(hr) ) { lPort = 0; } }
// 1K buffer: Not likely we'll exceed that many digits
TCHAR szNum[1024] = {0}; _sntprintf( szNum, 1023, _T("%d"), lPort );
m_bstrPort = szNum; return m_bstrPort; }
case 4: // Logging Level
{ long lLevel = 0; HRESULT hr = m_spConfig->get_LoggingLevel( &lLevel );
switch( lLevel ) { case 0: { m_bstrLogLevel = StrLoadString(IDS_SERVERPROP_LOG_0).c_str(); break; } case 1: { m_bstrLogLevel = StrLoadString(IDS_SERVERPROP_LOG_1).c_str(); break; } case 2: { m_bstrLogLevel = StrLoadString(IDS_SERVERPROP_LOG_2).c_str(); break; } case 3: { m_bstrLogLevel = StrLoadString(IDS_SERVERPROP_LOG_3).c_str(); break; } default: { m_bstrLogLevel = StrLoadString(IDS_SERVERPROP_LOG_0).c_str(); break; } } return m_bstrLogLevel; }
case 5: // Service Status
{ CComPtr<IP3Service> spService = NULL; long lServiceStatus = 0;
HRESULT hr = m_spConfig->get_Service( &spService ); if( SUCCEEDED(hr) ) { hr = spService->get_POP3ServiceStatus( &lServiceStatus ); } switch( lServiceStatus ) { case SERVICE_STOPPED: { m_bstrServiceStatus = StrLoadString(IDS_STATE_STOPPED).c_str(); break; } case SERVICE_RUNNING: { m_bstrServiceStatus = StrLoadString(IDS_STATE_RUNNING).c_str(); break; }
case SERVICE_PAUSED: { m_bstrServiceStatus = StrLoadString(IDS_STATE_PAUSED).c_str(); break; }
default: { m_bstrServiceStatus = StrLoadString(IDS_STATE_PENDING).c_str(); break; } }
return m_bstrServiceStatus; }
default: { #if DBG
return L"No Information"; #else
return L""; #endif
} } }
/////////////////////////////////////////////////////////////////////////
// CServerNode::GetResultViewType
//
// Sets the Result Pane to be:
// 0 Domains : Message View
// Non-0 Domains : List View
HRESULT CServerNode::GetResultViewType( LPOLESTR* ppViewType, long* pViewOptions ) { // Get the Count of Domains
CComPtr<IP3Domains> spDomains = NULL; long lDomains = 0; // Get the Domains
HRESULT hr = m_spConfig->get_Domains( &spDomains );
if( SUCCEEDED(hr) ) { spDomains->get_Count( &lDomains ); }
if( lDomains == 0 ) { // Message View
return StringFromCLSID(CLSID_MessageView, ppViewType); }
return S_FALSE; // Default List View
}
/////////////////////////////////////////////////////////////////////////
// CServerNode::Notify
//
// Core callback functionality of this Node. MMC will use this function
// for all MMC provided functionality, such as Expanding, Renaming, and
// Context Help
HRESULT CServerNode::Notify( MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param, IComponentData* pComponentData, IComponent* pComponent, DATA_OBJECT_TYPES type) { HRESULT hr = S_FALSE;
_ASSERTE(pComponentData != NULL || pComponent != NULL);
CComPtr<IConsole> spConsole = NULL; if( pComponentData ) { spConsole = ((CPOP3ServerSnapData*)pComponentData)->m_spConsole; } else if( pComponent ) { spConsole = ((CPOP3ServerSnapComponent*)pComponent)->m_spConsole; }
if( !spConsole ) return E_INVALIDARG;
switch( event ) { case MMCN_SHOW: { tstring strHeader; CComQIPtr<IHeaderCtrl2> spHeaderCtrl = spConsole; CComQIPtr<IResultData> spResultData = spConsole; if( !spHeaderCtrl || !spResultData ) return E_NOINTERFACE;
hr = spResultData->DeleteAllRsltItems();
if( arg ) { if( m_lDomains.empty() ) { // configure the ocx message in the result pane
IMessageView* pIMessageView = NULL; LPUNKNOWN pIUnk = NULL;
hr = spConsole->QueryResultView(&pIUnk);
if( SUCCEEDED(hr) ) { hr = pIUnk->QueryInterface(_uuidof(IMessageView), reinterpret_cast<void**>(&pIMessageView)); }
if( SUCCEEDED(hr) ) { hr = pIMessageView->SetIcon(Icon_Information); } if( SUCCEEDED(hr) ) { tstring strTitle = StrLoadString( IDS_SNAPINNAME ); hr = pIMessageView->SetTitleText( strTitle.c_str() ); } if( SUCCEEDED(hr) ) { tstring strMessage = StrLoadString( IDS_ERROR_NODOMAIN ); hr = pIMessageView->SetBodyText( strMessage.c_str() ); }
if( pIMessageView ) { pIMessageView->Release(); pIMessageView = NULL; }
if( pIUnk ) { pIUnk->Release(); pIUnk = NULL; }
return hr; } else { if( SUCCEEDED(hr) ) { strHeader = StrLoadString(IDS_HEADER_DOMAIN_NAME); hr = spHeaderCtrl->InsertColumn(0, strHeader.c_str(), LVCFMT_LEFT, 100); }
if( SUCCEEDED(hr) ) { strHeader = StrLoadString(IDS_HEADER_DOMAIN_NUMBOX); hr = spHeaderCtrl->InsertColumn(1, strHeader.c_str(), LVCFMT_LEFT, 100); }
if( SUCCEEDED(hr) ) { strHeader = StrLoadString(IDS_HEADER_DOMAIN_SIZE); hr = spHeaderCtrl->InsertColumn(2, strHeader.c_str(), LVCFMT_LEFT, 100); }
if( SUCCEEDED(hr) ) { strHeader = StrLoadString(IDS_HEADER_DOMAIN_NUMMES); hr = spHeaderCtrl->InsertColumn(3, strHeader.c_str(), LVCFMT_LEFT, 100); }
if( SUCCEEDED(hr) ) { strHeader = StrLoadString(IDS_HEADER_DOMAIN_LOCKED); hr = spHeaderCtrl->InsertColumn(4, strHeader.c_str(), LVCFMT_LEFT, 100); }
if( SUCCEEDED(hr) ) { CComQIPtr<IConsole2> spCons2 = spConsole; if( spCons2 ) { // Output the number of servers we added
tstring strMessage = StrLoadString(IDS_SERVER_STATUSBAR); OLECHAR pszStatus[1024] = {0}; _sntprintf( pszStatus, 1023, strMessage.c_str(), m_lDomains.size() ); spCons2->SetStatusText( pszStatus ); } } } }
break; } case MMCN_EXPAND: { hr = OnExpand(arg, m_scopeDataItem.ID, spConsole); break; } case MMCN_ADD_IMAGES: { IImageList* pImageList = (IImageList*)arg; if( !pImageList ) return E_INVALIDARG;
hr = LoadImages(pImageList); break; }
case MMCN_REFRESH: { hr = OnExpand(TRUE, m_scopeDataItem.ID, spConsole);
if( SUCCEEDED(hr) ) { CComQIPtr<IConsole2> spCons2 = spConsole; if( spCons2 ) { // Output the number of servers we added
tstring strMessage = StrLoadString(IDS_SERVER_STATUSBAR); OLECHAR pszStatus[1024] = {0}; _sntprintf( pszStatus, 1023, strMessage.c_str(), m_lDomains.size() ); spCons2->SetStatusText( pszStatus ); } } break; }
case MMCN_SELECT: { // if selecting node
if( HIWORD(arg) ) { hr = S_OK;
// get the verb interface and enable rename
CComPtr<IConsoleVerb> spConsVerb; if( spConsole->QueryConsoleVerb(&spConsVerb) == S_OK ) { // Enable the Properties Menu
hr = spConsVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE); if( FAILED(hr) ) return hr; hr = spConsVerb->SetVerbState(MMC_VERB_PROPERTIES, HIDDEN, FALSE); if( FAILED(hr) ) return hr;
// Enable the Refresh Menu
hr = spConsVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE); if( FAILED(hr) ) return hr; hr = spConsVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, FALSE); if( FAILED(hr) ) return hr; } }
break; } case MMCN_VIEW_CHANGE: { if( (param == NAV_ADD) || (param == NAV_DELETE) ) { CComQIPtr<IConsole2> spCons2 = spConsole; if( spCons2 ) { hr = spCons2->SelectScopeItem( m_scopeDataItem.ID ); } } break; }
case MMCN_CONTEXTHELP: { hr = S_OK; TCHAR szWindowsDir[MAX_PATH+1] = {0}; tstring strHelpFile = _T(""); tstring strHelpFileName = StrLoadString(IDS_HELPFILE); tstring strHelpTopicName = StrLoadString(IDS_HELPTOPIC);
if( strHelpFileName.empty() || strHelpTopicName.empty() ) { return E_FAIL; } // Build path to d:\windows\help
UINT nSize = GetSystemWindowsDirectory( szWindowsDir, MAX_PATH ); if( nSize == 0 || nSize > MAX_PATH ) { return E_FAIL; } strHelpFile = szWindowsDir; // D:\windows
strHelpFile += _T("\\Help\\"); // \help
strHelpFile += strHelpFileName; // \filename.chm
strHelpFile += _T("::/"); // ::/
strHelpFile += strHelpTopicName; // index.htm
// Show the Help topic
CComQIPtr<IDisplayHelp> spHelp = spConsole; if( !spHelp ) return E_NOINTERFACE;
hr = spHelp->ShowTopic( (LPTSTR)strHelpFile.c_str() ); break; }
}// switch
return hr; }
/////////////////////////////////////////////////////////////////////////
//
// ContextMenuImpl
//
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// CServerNode::AddMenuItems
//
// Adds our context menus into the appropriate MMC provided menu
// locations.
HRESULT CServerNode::AddMenuItems(LPCONTEXTMENUCALLBACK piCallback, long* pInsertionAllowed, DATA_OBJECT_TYPES type ) { if( !piCallback || !pInsertionAllowed ) return E_INVALIDARG; if( !m_spConfig ) return E_FAIL;
HRESULT hr = S_OK; tstring strMenu = _T(""); tstring strDesc = _T(""); CComQIPtr<IContextMenuCallback2> spContext2 = piCallback; if( !spContext2 ) return E_NOINTERFACE;
CONTEXTMENUITEM2 singleMenuItem; ZeroMemory(&singleMenuItem, sizeof(CONTEXTMENUITEM2)); singleMenuItem.fFlags = MF_ENABLED;
// Add the Disconnect Menu to the "Top" part of the MMC Context Menu
if( *pInsertionAllowed & CCM_INSERTIONALLOWED_TOP ) { strMenu = StrLoadString(IDS_MENU_SERVER_DISCON); strDesc = StrLoadString(IDS_MENU_SERVER_DISCON_DESC); singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP; singleMenuItem.strName = (LPWSTR)strMenu.c_str(); singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str(); singleMenuItem.strLanguageIndependentName = L"SERVER_DISCONNECT"; singleMenuItem.lCommandID = IDM_SERVER_TOP_DISCONNECT;
if( !strMenu.empty() ) { hr = spContext2->AddItem( &singleMenuItem ); if( FAILED(hr) ) return hr; } }
// Add the Domain Menu to the "New" part of the MMC Context Menu
if( (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) ) { strMenu = StrLoadString(IDS_MENU_SERVER_NEWDOM); strDesc = StrLoadString(IDS_MENU_SERVER_NEWDOM_DESC); singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_NEW; singleMenuItem.strName = (LPWSTR)strMenu.c_str(); singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str(); singleMenuItem.strLanguageIndependentName = L"NEW_DOMAIN"; singleMenuItem.lCommandID = IDM_SERVER_NEW_DOMAIN;
if( !strMenu.empty() ) { hr = spContext2->AddItem( &singleMenuItem ); if( FAILED(hr) ) return hr; } }
// Add the Service Operation Menus to the "Task" part of the MMC Context Menu
if( *pInsertionAllowed & CCM_INSERTIONALLOWED_TASK ) { CComPtr<IP3Service> spService;
hr = m_spConfig->get_Service( &spService ); if( FAILED(hr) ) return hr; long lServiceStatus = 0; hr = spService->get_POP3ServiceStatus( &lServiceStatus ); if( FAILED(hr) ) return hr;
singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TASK; if( lServiceStatus == SERVICE_STOPPED ) { strMenu = StrLoadString(IDS_MENU_SERVER_START); strDesc = StrLoadString(IDS_MENU_SERVER_START_DESC);
singleMenuItem.strName = (LPWSTR)strMenu.c_str(); singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str(); singleMenuItem.strLanguageIndependentName = L"SERVER_START"; singleMenuItem.lCommandID = IDM_SERVER_TASK_START;
if( !strMenu.empty() ) { hr = spContext2->AddItem( &singleMenuItem ); if( FAILED(hr) ) return hr; } }
if( lServiceStatus == SERVICE_PAUSED ) { strMenu = StrLoadString(IDS_MENU_SERVER_RESUME); strDesc = StrLoadString(IDS_MENU_SERVER_RESUME_DESC);
singleMenuItem.strName = (LPWSTR)strMenu.c_str(); singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str(); singleMenuItem.strLanguageIndependentName = L"SERVER_RESUME"; singleMenuItem.lCommandID = IDM_SERVER_TASK_RESUME;
if( !strMenu.empty() ) { hr = spContext2->AddItem( &singleMenuItem ); if( FAILED(hr) ) return hr; } }
if( lServiceStatus == SERVICE_RUNNING ) { strMenu = StrLoadString(IDS_MENU_SERVER_PAUSE); strDesc = StrLoadString(IDS_MENU_SERVER_PAUSE_DESC);
singleMenuItem.strName = (LPWSTR)strMenu.c_str(); singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str(); singleMenuItem.strLanguageIndependentName = L"SERVER_PAUSE"; singleMenuItem.lCommandID = IDM_SERVER_TASK_PAUSE;
if( !strMenu.empty() ) { hr = spContext2->AddItem( &singleMenuItem ); if( FAILED(hr) ) return hr; } }
if( (lServiceStatus == SERVICE_RUNNING) || (lServiceStatus == SERVICE_PAUSED) ) { strMenu = StrLoadString(IDS_MENU_SERVER_STOP); strDesc = StrLoadString(IDS_MENU_SERVER_STOP_DESC);
singleMenuItem.strName = (LPWSTR)strMenu.c_str(); singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str(); singleMenuItem.strLanguageIndependentName = L"SERVER_STOP"; singleMenuItem.lCommandID = IDM_SERVER_TASK_STOP;
if( !strMenu.empty() ) { hr = spContext2->AddItem( &singleMenuItem ); if( FAILED(hr) ) return hr; } }
if( (lServiceStatus == SERVICE_RUNNING) || (lServiceStatus == SERVICE_PAUSED) ) { strMenu = StrLoadString(IDS_MENU_SERVER_RESTART); strDesc = StrLoadString(IDS_MENU_SERVER_RESTART_DESC);
singleMenuItem.strName = (LPWSTR)strMenu.c_str(); singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str(); singleMenuItem.strLanguageIndependentName = L"SERVER_RESTART"; singleMenuItem.lCommandID = IDM_SERVER_TASK_RESTART;
if( !strMenu.empty() ) { hr = spContext2->AddItem( &singleMenuItem ); if( FAILED(hr) ) return hr; } } }
return hr; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::OnNewDomain
//
// Display a NewDomain dialog, and add the new domain
HRESULT CServerNode::OnNewDomain( bool& bHandled, CSnapInObjectRootBase* pObj ) { if( !pObj ) return E_INVALIDARG; if( !m_spConfig ) return E_FAIL;
bHandled = true; HRESULT hr = S_OK; // Load a dialog that asks for a Domain Name
CNewDomainDlg dlg;
if( dlg.DoModal() == IDOK ) { HWND hWnd = NULL; CComPtr<IConsole> spConsole = NULL;
// Get a window handle
hr = GetConsole( pObj, &spConsole ); if( FAILED(hr) || !spConsole ) return E_NOINTERFACE; spConsole->GetMainWindow(&hWnd);
// Access our POP3 Domain list
CComPtr<IP3Domains> spDomains; hr = m_spConfig->get_Domains( &spDomains );
// Add our domain to the POP3 Admin domainlist
if( SUCCEEDED(hr) ) { CComBSTR bstrName = dlg.m_strName.c_str(); hr = spDomains->Add( bstrName ); }
// Check for weird pre-existance condition
if( hr == ERROR_FILE_EXISTS ) { tstring strMessage = StrLoadString( IDS_WARNING_DOMAINEXISTS ); tstring strTitle = StrLoadString(IDS_SNAPINNAME); MessageBox( hWnd, strMessage.c_str(), strTitle.c_str(), MB_OK | MB_ICONWARNING ); }
if( SUCCEEDED(hr) ) { CComVariant var; CComPtr<IP3Domain> spDomain = NULL; CDomainNode* pDomainNode = NULL; // Get a grasp of the Domain interface to pass to the node
VariantInit(&var); var = dlg.m_strName.c_str(); hr = spDomains->get_Item( var, &spDomain );
if( SUCCEEDED(hr) ) { // Add the new Domain to our list of domains
pDomainNode = new CDomainNode( spDomain, this ); if( !pDomainNode ) hr = E_OUTOFMEMORY; }
if( SUCCEEDED(hr) ) { pDomainNode->m_scopeDataItem.mask |= SDI_PARENT; pDomainNode->m_scopeDataItem.relativeID = m_scopeDataItem.ID;
m_lDomains.push_back( pDomainNode );
// Add the new domain into the namespace
// Insert it into the result tree
CComQIPtr<IConsoleNameSpace2> spNameSpace = spConsole; if( !spNameSpace ) return E_NOINTERFACE;
hr = spNameSpace->InsertItem( &(pDomainNode->m_scopeDataItem) ); }
if( SUCCEEDED(hr) ) { // Get our Data Object
CComPtr<IDataObject> spDataObject = NULL; GetDataObject(&spDataObject, CCT_SCOPE); if( !spDataObject ) return E_FAIL;
// Call the Update, but don't update return result
spConsole->UpdateAllViews( spDataObject, 0, (LONG_PTR)NAV_ADD ); } } if( FAILED(hr) ) { // Failed to add the Domain
tstring strMessage = StrLoadString(IDS_ERROR_CREATEDOMAIN); tstring strTitle = StrLoadString(IDS_SNAPINNAME); DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr ); } } return hr; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::OnDisconnect
//
// Disconnect is essentially deleting ourselves from the list of servers
HRESULT CServerNode::OnDisconnect( bool& bHandled, CSnapInObjectRootBase* pObj ) { if( !pObj ) return E_INVALIDARG; if( !m_pParent ) return E_FAIL;
bHandled = true; HRESULT hr = S_OK;
// Get the Window Handle
HWND hWnd = NULL; CComPtr<IConsole> spConsole = NULL; hr = GetConsole( pObj, &spConsole ); if( FAILED(hr) || !spConsole ) return E_NOINTERFACE; spConsole->GetMainWindow(&hWnd);
// Load the message box
tstring strDeleteWarning = StrLoadString( IDS_SERVER_CONFIRMDISCONNECT ); tstring strTitle = StrLoadString( IDS_SNAPINNAME ); tstring strPropPageOpen = StrLoadString( IDS_WARNING_PROP_PAGE_OPEN ); if(1!=m_lRefCount) { MessageBox(hWnd, strPropPageOpen.c_str(),strTitle.c_str(),MB_OK); return hr; //Not error case
}
if( MessageBox(hWnd, strDeleteWarning.c_str(), strTitle.c_str(), MB_YESNO | MB_ICONWARNING ) == IDYES ) { // Remove ourselves from the tree
CComQIPtr<IConsoleNameSpace2> spNameSpace = spConsole; if( !spNameSpace ) return E_NOINTERFACE;
hr = spNameSpace->DeleteItem( m_scopeDataItem.ID, TRUE );
// The parent needs to do the deletion
if( SUCCEEDED(hr) ) { hr = m_pParent->DeleteServer(this); }
if( SUCCEEDED(hr) ) { delete this; } }
return hr; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::OnServerService
//
// Function to handle the Start/Stop/Pause/Restart of the POP3 Service
// on this computer
HRESULT CServerNode::OnServerService( UINT nID, bool& bHandled, CSnapInObjectRootBase* pObj ) { if( !m_spConfig ) return E_FAIL;
bHandled = true; HCURSOR hOldCursor = NULL; HCURSOR hWaitCursor = ::LoadCursor(NULL, IDC_WAIT); if (hWaitCursor) { hOldCursor = ::SetCursor(hWaitCursor); }
// Get the Window Handle
HWND hWnd = NULL; CComPtr<IConsole> spConsole = NULL; tstring strTitle = StrLoadString( IDS_SNAPINNAME ); tstring strMessage = _T(""); HRESULT hr = GetConsole( pObj, &spConsole ); if( FAILED(hr) || !spConsole ) return E_NOINTERFACE; spConsole->GetMainWindow(&hWnd);
// Get the POP3 Service
CComPtr<IP3Service> spService = NULL; hr = m_spConfig->get_Service( &spService );
// Do the appropriate service operation
switch( nID ) { case IDM_SERVER_TASK_START: { if( SUCCEEDED(hr) ) { hr = spService->StartPOP3Service(); }
// Used for both Start failure, and Service retreival failure
if( FAILED(hr) ) { strMessage = StrLoadString( IDS_ERROR_STARTSERVICE ); DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr ); } break; }
case IDM_SERVER_TASK_RESUME: { if( SUCCEEDED(hr) ) { hr = spService->ResumePOP3Service(); }
// Used for both Start failure, and Service retreival failure
if( FAILED(hr) ) { strMessage = StrLoadString( IDS_ERROR_RESUMESERVICE ); DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr ); } break; }
case IDM_SERVER_TASK_STOP: { if( SUCCEEDED(hr) ) { hr = spService->StopPOP3Service(); } // Used for both Start failure, and Service retreival failure
if( FAILED(hr) ) { strMessage = StrLoadString( IDS_ERROR_STOPSERVICE ); DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr ); } break; } case IDM_SERVER_TASK_PAUSE: { if( SUCCEEDED(hr) ) { hr = spService->PausePOP3Service(); }
if( FAILED(hr) ) { strMessage = StrLoadString( IDS_ERROR_PAUSESERVICE ); DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr ); } break; }
case IDM_SERVER_TASK_RESTART: { if( SUCCEEDED(hr) ) { hr = spService->StopPOP3Service(); }
if( SUCCEEDED(hr) ) { hr = spService->StartPOP3Service(); }
// Used for both Start failure, and Service retreival failure
if( FAILED(hr) ) { strMessage = StrLoadString( IDS_ERROR_RESTARTSERVICE ); DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr ); } break; } }
::SetCursor(hOldCursor);
if( SUCCEEDED(hr) ) { CComQIPtr<IConsoleNameSpace2> spNameSpace = spConsole; if( spNameSpace ) { spNameSpace->SetItem( &m_scopeDataItem ); } }
return hr; }
/////////////////////////////////////////////////////////////////////////
//
// PropertyPageImpl
//
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// CServerNode::CreatePropertyPages
//
// Fills MMC's callback with our property pages
HRESULT CServerNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, IUnknown* pUnk, DATA_OBJECT_TYPES type) { if( !lpProvider ) return E_INVALIDARG; if( !m_spConfig ) return E_FAIL;
HRESULT hr = E_FAIL; // Load our Server's General page
HPROPSHEETPAGE hpageGen = NULL; InterlockedIncrement(&m_lRefCount); CServerGeneralPage* pGenPage = new CServerGeneralPage(m_spConfig, handle, this); if( pGenPage != NULL ) { hpageGen = pGenPage->Create(); }
// Add it to the list of pages
if( hpageGen ) { hr = lpProvider->AddPage(hpageGen); }
// Destruct correctly if failure results
if( FAILED(hr) ) { InterlockedDecrement(&m_lRefCount); if( hpageGen ) { DestroyPropertySheetPage(hpageGen); } else if (pGenPage) { delete pGenPage; pGenPage = NULL; } }
return hr; }
/////////////////////////////////////////////////////////////////////////
//
// Helper Functions
//
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// CServerNode::GetAuth
//
// pbHashPW : Return Boolean for Hash Password Authentication
// pbSAM : Return Boolean for Local SAM Authentication
HRESULT CServerNode::GetAuth(BOOL* pbHashPW, BOOL* pbSAM) { if( !m_spConfig ) return E_FAIL;
CComPtr<IAuthMethods> spMethods; CComPtr<IAuthMethod> spAuth; CComVariant var; CComBSTR bstrID; long lCurrent = 0L;
HRESULT hr = m_spConfig->get_Authentication( &spMethods );
if ( SUCCEEDED(hr) ) { hr = spMethods->get_CurrentAuthMethod( &var ); }
if ( SUCCEEDED(hr) ) { hr = spMethods->get_Item( var, &spAuth ); }
if( SUCCEEDED(hr) ) { hr = spAuth->get_ID( &bstrID ); }
if( SUCCEEDED(hr) && pbHashPW ) { *pbHashPW = (_tcsicmp(bstrID, SZ_AUTH_ID_MD5_HASH) == 0); }
if( SUCCEEDED(hr) && pbSAM ) { *pbSAM = (_tcsicmp(bstrID, SZ_AUTH_ID_LOCAL_SAM) == 0); }
return hr; }
/////////////////////////////////////////////////////////////////////////
// CServerNode::GetConfirmAddUser
//
// pbConfirm : Return Boolean for User Add Confirmation
HRESULT CServerNode::GetConfirmAddUser( BOOL *pbConfirm ) { if( !m_spConfig ) return E_POINTER;
return m_spConfig->get_ConfirmAddUser( pbConfirm ); }
/////////////////////////////////////////////////////////////////////////
// CServerNode::SetConfirmAddUser
//
// pbConfirm : New Boolean Value for User Add Confirmation
HRESULT CServerNode::SetConfirmAddUser( BOOL bConfirm ) { if( !m_spConfig ) return E_POINTER;
return m_spConfig->put_ConfirmAddUser( bConfirm ); }
void CServerNode::Release() { InterlockedDecrement(&m_lRefCount); if(m_lRefCount<1) InterlockedIncrement(&m_lRefCount); }
|