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.
1009 lines
33 KiB
1009 lines
33 KiB
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CDomainNode
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "pop3.h"
|
|
#include "pop3snap.h"
|
|
|
|
#include "DomainNode.h"
|
|
#include "ServerNode.h"
|
|
|
|
#include "NewUserDlg.h"
|
|
|
|
static const GUID CDomainNodeGUID_NODETYPE =
|
|
{ 0xa30bd5b4, 0xf3f1, 0x4b42, { 0xba, 0x27, 0x62, 0x23, 0x9a, 0xd, 0xc1, 0x43 } };
|
|
|
|
const GUID* CDomainNode::m_NODETYPE = &CDomainNodeGUID_NODETYPE;
|
|
const OLECHAR* CDomainNode::m_SZNODETYPE = OLESTR("A30BD5B4-F3F1-4b42-BA27-62239A0DC143");
|
|
const OLECHAR* CDomainNode::m_SZDISPLAY_NAME = OLESTR("");
|
|
const CLSID* CDomainNode::m_SNAPIN_CLASSID = &CLSID_POP3ServerSnap;
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class implementation
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::CDomainNode
|
|
//
|
|
// Constructor : Uses Domain interface for initialization
|
|
|
|
CDomainNode::CDomainNode(IP3Domain* pDomain, CServerNode* pParent)
|
|
{
|
|
// Initialize our domain
|
|
m_spDomain = pDomain;
|
|
m_pParent = pParent;
|
|
|
|
BOOL bLocked = FALSE;
|
|
HRESULT hr = E_FAIL;
|
|
if( m_spDomain )
|
|
{
|
|
// Get our initial lock state for icon display
|
|
m_spDomain->get_Lock( &bLocked );
|
|
|
|
// Get our name
|
|
hr = m_spDomain->get_Name( &m_bstrDisplayName );
|
|
}
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
m_bstrDisplayName = _T("");
|
|
}
|
|
|
|
// Initialize our column information
|
|
m_bstrNumBoxes = _T("");
|
|
m_bstrSize = _T("");
|
|
m_bstrNumMessages = _T("");
|
|
m_bstrState = _T("");
|
|
|
|
// Initialize our Scope item
|
|
memset(&m_scopeDataItem, 0, sizeof(SCOPEDATAITEM));
|
|
m_scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
|
|
m_scopeDataItem.cChildren = 0;
|
|
m_scopeDataItem.displayname = MMC_CALLBACK;
|
|
m_scopeDataItem.nImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
m_scopeDataItem.nOpenImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
m_scopeDataItem.lParam = (LPARAM) this;
|
|
|
|
// Initialize our Result item
|
|
memset(&m_resultDataItem, 0, sizeof(RESULTDATAITEM));
|
|
m_resultDataItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
|
|
m_resultDataItem.str = MMC_CALLBACK;
|
|
m_resultDataItem.nImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
m_resultDataItem.lParam = (LPARAM) this;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::~CDomainNode
|
|
//
|
|
// Destructor : Clean up our member-list of Users
|
|
|
|
CDomainNode::~CDomainNode()
|
|
{
|
|
for(USERLIST::iterator iter = m_lUsers.begin(); iter != m_lUsers.end(); iter++)
|
|
{
|
|
delete (*iter);
|
|
}
|
|
m_lUsers.clear();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::DeleteUser
|
|
//
|
|
// Helper function to delete a user from all of POP3
|
|
|
|
HRESULT CDomainNode::DeleteUser(CUserNode* pUser, BOOL bDeleteAccount)
|
|
{
|
|
if( !pUser ) return E_INVALIDARG;
|
|
if( !m_spDomain ) return E_FAIL;
|
|
|
|
// Delete from POP3 Admin Interface
|
|
|
|
// Get the User Container object
|
|
CComPtr<IP3Users> spUsers;
|
|
HRESULT hr = m_spDomain->get_Users( &spUsers );
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Delete the User from the container
|
|
if( bDeleteAccount )
|
|
{
|
|
hr = spUsers->RemoveEx( pUser->m_bstrDisplayName );
|
|
}
|
|
else
|
|
{
|
|
hr = spUsers->Remove( pUser->m_bstrDisplayName );
|
|
}
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Update our list
|
|
m_lUsers.remove(pUser);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::IsLocked
|
|
//
|
|
// Helper function to Allow children to not show their locks if the
|
|
// domain is locked
|
|
|
|
BOOL CDomainNode::IsLocked()
|
|
{
|
|
if( !m_spDomain ) return TRUE;
|
|
|
|
BOOL bLocked = TRUE;
|
|
m_spDomain->get_Lock( &bLocked );
|
|
|
|
return bLocked;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::BuildUsers
|
|
//
|
|
// Helper function to refresh list of users and insert them
|
|
|
|
HRESULT CDomainNode::BuildUsers()
|
|
{
|
|
if( !m_spDomain ) return E_FAIL;
|
|
|
|
HRESULT hr = S_OK;
|
|
HWND hWnd = NULL;
|
|
|
|
// Delete our Users
|
|
for(USERLIST::iterator iter = m_lUsers.begin(); iter != m_lUsers.end(); iter++)
|
|
{
|
|
delete (*iter);
|
|
}
|
|
m_lUsers.clear();
|
|
|
|
// Fill in all of our users
|
|
CComPtr<IP3Users> spUsers;
|
|
CComPtr<IEnumVARIANT> spUserEnum;
|
|
|
|
// Get the User Container object
|
|
hr = m_spDomain->get_Users( &spUsers );
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Get the enumeration of the users
|
|
hr = spUsers->get__NewEnum( &spUserEnum );
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Loop through all users, and add them to our vector
|
|
CComVariant var;
|
|
ULONG lResult = 0;
|
|
|
|
VariantInit( &var );
|
|
|
|
while ( spUserEnum->Next(1, &var, &lResult) == S_OK )
|
|
{
|
|
if ( lResult == 1 )
|
|
{
|
|
CComQIPtr<IP3User> spUser;
|
|
spUser = V_DISPATCH(&var);
|
|
if( !spUser ) continue;
|
|
|
|
CUserNode* spUserNode = new CUserNode(spUser, this);
|
|
if( !spUserNode ) continue;
|
|
|
|
m_lUsers.push_back(spUserNode);
|
|
}
|
|
|
|
VariantClear(&var);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SnapInItemImpl
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::GetScopePaneInfo
|
|
//
|
|
// Callback used to get Scope-Pane display information by MMC
|
|
|
|
HRESULT CDomainNode::GetScopePaneInfo(SCOPEDATAITEM *pScopeDataItem)
|
|
{
|
|
if( !pScopeDataItem ) return E_INVALIDARG;
|
|
if( !m_spDomain ) return E_FAIL;
|
|
|
|
BOOL bLocked = FALSE;
|
|
m_spDomain->get_Lock( &bLocked );
|
|
|
|
if( pScopeDataItem->mask & SDI_STR )
|
|
pScopeDataItem->displayname = m_bstrDisplayName;
|
|
if( pScopeDataItem->mask & SDI_IMAGE )
|
|
pScopeDataItem->nImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
if( pScopeDataItem->mask & SDI_OPENIMAGE )
|
|
pScopeDataItem->nOpenImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
if( pScopeDataItem->mask & SDI_PARAM )
|
|
pScopeDataItem->lParam = m_scopeDataItem.lParam;
|
|
if( pScopeDataItem->mask & SDI_STATE )
|
|
pScopeDataItem->nState = m_scopeDataItem.nState;
|
|
if( pScopeDataItem->mask & SDI_CHILDREN )
|
|
pScopeDataItem->cChildren = 0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CServerNode::GetResultPaneInfo
|
|
//
|
|
// Callback used to get Result Pane display information by MMC
|
|
|
|
HRESULT CDomainNode::GetResultPaneInfo(RESULTDATAITEM *pResultDataItem)
|
|
{
|
|
if( !pResultDataItem ) return E_INVALIDARG;
|
|
if( !m_spDomain ) return E_FAIL;
|
|
|
|
BOOL bLocked = FALSE;
|
|
m_spDomain->get_Lock( &bLocked );
|
|
|
|
if( pResultDataItem->bScopeItem )
|
|
{
|
|
if( pResultDataItem->mask & RDI_STR )
|
|
pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
|
|
if( pResultDataItem->mask & RDI_IMAGE )
|
|
pResultDataItem->nImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
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 = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
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 CDomainNode::GetResultPaneColInfo(int nCol)
|
|
{
|
|
if( !m_spDomain ) return L"";
|
|
|
|
switch( nCol )
|
|
{
|
|
case 0: // Name
|
|
{
|
|
return m_bstrDisplayName;
|
|
}
|
|
|
|
case 1: // Number of Mailboxes
|
|
{
|
|
long lCount = 0L;
|
|
|
|
// Get the Users container object for this domain
|
|
CComPtr<IP3Users> spUsers;
|
|
HRESULT hr = m_spDomain->get_Users( &spUsers );
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Get the number of mailboxes
|
|
hr = spUsers->get_Count( &lCount );
|
|
}
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
lCount = 0; // Make sure we put in a valid error value.
|
|
}
|
|
|
|
// 1K buffer: Not likely we'll exceed that many digits
|
|
TCHAR szNum[1024] = {0};
|
|
_sntprintf( szNum, 1023, _T("%d"), lCount );
|
|
|
|
m_bstrNumBoxes = szNum;
|
|
return m_bstrNumBoxes;
|
|
}
|
|
|
|
case 2: // Domain Size (MB)
|
|
{
|
|
// We want our result in Megabytes
|
|
long lFactor = 0;
|
|
long lUsage = 0;
|
|
HRESULT hr = m_spDomain->get_MessageDiskUsage( &lFactor, &lUsage );
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
lUsage = 0; // Make sure we have a valid error value
|
|
}
|
|
|
|
// Convert to KiloBytes
|
|
__int64 i64Usage = lFactor * lUsage;
|
|
i64Usage /= 1024;
|
|
|
|
// 1K buffer: Not likely we'll exceed that many digits
|
|
tstring strKiloByte = StrLoadString( IDS_KILOBYTE_EXTENSION );
|
|
TCHAR szNum[1024] = {0};
|
|
_sntprintf( szNum, 1023, strKiloByte.c_str(), i64Usage );
|
|
|
|
m_bstrSize = szNum;
|
|
return m_bstrSize;
|
|
}
|
|
|
|
case 3: // Number of Messages
|
|
{
|
|
long lCount = 0;
|
|
HRESULT hr = m_spDomain->get_MessageCount( &lCount );
|
|
|
|
// 1K buffer: Not likely we'll exceed that many digits
|
|
TCHAR szNum[1024] = {0};
|
|
_sntprintf( szNum, 1023, _T("%d"), lCount );
|
|
|
|
m_bstrNumMessages = szNum;
|
|
return m_bstrNumMessages;
|
|
}
|
|
|
|
case 4: // State of Domain
|
|
{
|
|
BOOL bLocked = FALSE;
|
|
m_spDomain->get_Lock( &bLocked );
|
|
|
|
m_bstrState.LoadString( bLocked ? IDS_STATE_LOCKED : IDS_STATE_UNLOCKED );
|
|
|
|
return m_bstrState;
|
|
}
|
|
|
|
default:
|
|
{
|
|
return L"";
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// 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 CDomainNode::Notify( MMC_NOTIFY_TYPE event,
|
|
LPARAM arg,
|
|
LPARAM param,
|
|
IComponentData* pComponentData,
|
|
IComponent* pComponent,
|
|
DATA_OBJECT_TYPES type)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
_ASSERT(pComponentData != NULL || pComponent != NULL);
|
|
|
|
// Get a pointer to the console
|
|
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:
|
|
{
|
|
hr = S_OK;
|
|
|
|
CComQIPtr<IHeaderCtrl2> spHeaderCtrl = spConsole;
|
|
if( !spHeaderCtrl ) return E_NOINTERFACE;
|
|
|
|
tstring strHeader = _T("");
|
|
|
|
strHeader = StrLoadString(IDS_HEADER_USER_NAME);
|
|
spHeaderCtrl->InsertColumn(0, strHeader.c_str(), LVCFMT_LEFT, 100);
|
|
|
|
strHeader = StrLoadString(IDS_HEADER_USER_SIZE);
|
|
spHeaderCtrl->InsertColumn(1, strHeader.c_str(), LVCFMT_LEFT, 100);
|
|
|
|
strHeader = StrLoadString(IDS_HEADER_USER_NUMMES);
|
|
spHeaderCtrl->InsertColumn(2, strHeader.c_str(), LVCFMT_LEFT, 100);
|
|
|
|
strHeader = StrLoadString(IDS_HEADER_USER_LOCKED);
|
|
spHeaderCtrl->InsertColumn(3, strHeader.c_str(), LVCFMT_LEFT, 100);
|
|
|
|
CComQIPtr<IResultData> spResultData = spConsole;
|
|
if( !spResultData ) return E_NOINTERFACE;
|
|
|
|
// Showing the list
|
|
if( arg )
|
|
{
|
|
// Empty? Then build the list.
|
|
if( m_lUsers.empty() )
|
|
{
|
|
hr = BuildUsers();
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Display our users
|
|
for(USERLIST::iterator iter = m_lUsers.begin(); iter != m_lUsers.end(); iter++)
|
|
{
|
|
CUserNode* pUser = *iter;
|
|
hr = spResultData->InsertItem(&(pUser->m_resultDataItem));
|
|
if( FAILED(hr) ) break;
|
|
}
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
CComQIPtr<IConsole2> spCons2 = spConsole;
|
|
if( spCons2 )
|
|
{
|
|
// Output the number of servers we added
|
|
tstring strMessage = StrLoadString(IDS_DOMAIN_STATUSBAR);
|
|
OLECHAR pszStatus[1024] = {0};
|
|
_sntprintf( pszStatus, 1023, strMessage.c_str(), m_lUsers.size() );
|
|
spCons2->SetStatusText( pszStatus );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// We should delete our items
|
|
hr = spResultData->DeleteAllRsltItems();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case MMCN_ADD_IMAGES:
|
|
{
|
|
IImageList* pImageList = (IImageList*)arg;
|
|
if( !pImageList ) return E_INVALIDARG;
|
|
|
|
hr = LoadImages(pImageList);
|
|
break;
|
|
}
|
|
case MMCN_VIEW_CHANGE:
|
|
{
|
|
CComQIPtr<IResultData> spResultData = spConsole;
|
|
if( !spResultData ) return E_NOINTERFACE;
|
|
|
|
if( param == NAV_REFRESH )
|
|
{
|
|
// The "arg" controls clearing, for refresh
|
|
if( arg )
|
|
{
|
|
// Clear out the list
|
|
hr = spResultData->DeleteAllRsltItems();
|
|
}
|
|
else
|
|
{
|
|
// Re-Add to our list
|
|
for(USERLIST::iterator iter = m_lUsers.begin(); iter != m_lUsers.end(); iter++)
|
|
{
|
|
CUserNode* pUser = *iter;
|
|
hr = spResultData->InsertItem(&(pUser->m_resultDataItem));
|
|
if( FAILED(hr) ) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( param == NAV_ADD )
|
|
{
|
|
CUserNode* pUser = (CUserNode*)arg;
|
|
if( !pUser ) return E_INVALIDARG;
|
|
|
|
hr = spResultData->InsertItem(&(pUser->m_resultDataItem));
|
|
}
|
|
|
|
if( param == NAV_DELETE )
|
|
{
|
|
HRESULTITEM hrItem;
|
|
hr = spResultData->FindItemByLParam( arg, &hrItem );
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = spResultData->DeleteItem( hrItem, 0 );
|
|
}
|
|
}
|
|
|
|
if( param == NAV_REFRESHCHILD )
|
|
{
|
|
CUserNode* pUser = (CUserNode*)arg;
|
|
if( !pUser ) return E_INVALIDARG;
|
|
|
|
RESULTDATAITEM rdi;
|
|
ZeroMemory( &rdi, sizeof(rdi) );
|
|
rdi.mask = RDI_IMAGE;
|
|
hr = pUser->GetResultPaneInfo( &rdi );
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = spResultData->FindItemByLParam( arg, &(rdi.itemID) );
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = spResultData->UpdateItem( rdi.itemID );
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// In order to actually update the icon, we have to do a set item
|
|
hr = spResultData->SetItem( &rdi );
|
|
}
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
CComQIPtr<IConsole2> spCons2 = spConsole;
|
|
if( spCons2 )
|
|
{
|
|
// Output the number of servers we added
|
|
tstring strMessage = StrLoadString(IDS_DOMAIN_STATUSBAR);
|
|
OLECHAR pszStatus[1024] = {0};
|
|
_sntprintf( pszStatus, 1023, strMessage.c_str(), m_lUsers.size() );
|
|
spCons2->SetStatusText( pszStatus );
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case MMCN_REFRESH:
|
|
{
|
|
hr = S_OK;
|
|
|
|
// Get our Data Object
|
|
CComPtr<IDataObject> spDataObject = NULL;
|
|
GetDataObject(&spDataObject, CCT_SCOPE);
|
|
if( !spDataObject ) return E_FAIL;
|
|
|
|
// Update all the Views to have them remove their lists
|
|
hr = spConsole->UpdateAllViews( spDataObject, 1, (LONG_PTR)NAV_REFRESH );
|
|
if( FAILED(hr) ) return E_FAIL;
|
|
|
|
// Rebuild the users list
|
|
hr = BuildUsers();
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Update all the Views to have them re-Add their lists
|
|
hr = spConsole->UpdateAllViews( spDataObject, 0, (LONG_PTR)NAV_REFRESH );
|
|
|
|
break;
|
|
}
|
|
|
|
case MMCN_DELETE:
|
|
{
|
|
hr = S_OK;
|
|
|
|
tstring strMessage = _T("");
|
|
HWND hWnd = NULL;
|
|
spConsole->GetMainWindow(&hWnd);
|
|
|
|
strMessage = StrLoadString(IDS_DOMAIN_CONFIRMDELETE);
|
|
tstring strTitle = StrLoadString(IDS_SNAPINNAME);
|
|
if( MessageBox(hWnd, strMessage.c_str(), strTitle.c_str(), MB_YESNO | MB_ICONWARNING ) == IDYES )
|
|
{
|
|
hr = E_FAIL;
|
|
|
|
// The parent needs to do the deletion
|
|
if( m_pParent )
|
|
{
|
|
hr = m_pParent->DeleteDomain(this);
|
|
}
|
|
|
|
// Check for non-existance condition
|
|
if( hr == ERROR_PATH_NOT_FOUND )
|
|
{
|
|
strMessage = StrLoadString( IDS_WARNING_DOMAINMISSING );
|
|
MessageBox( hWnd, strMessage.c_str(), strTitle.c_str(), MB_OK | MB_ICONWARNING );
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = E_FAIL;
|
|
// Remove ourselves from the tree
|
|
CComQIPtr<IConsoleNameSpace2> spNameSpace = spConsole;
|
|
if( spNameSpace )
|
|
{
|
|
hr = spNameSpace->DeleteItem( m_scopeDataItem.ID, TRUE );
|
|
}
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Update our parent node, but ignore the result
|
|
CComPtr<IDataObject> spDataObject = NULL;
|
|
hr = m_pParent->GetDataObject( &spDataObject, CCT_SCOPE );
|
|
if( spDataObject )
|
|
{
|
|
spConsole->UpdateAllViews( spDataObject, (LPARAM)this, (LONG_PTR)NAV_DELETE );
|
|
}
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
strMessage = StrLoadString(IDS_ERROR_DELETEDOMAIN);
|
|
DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr );
|
|
}
|
|
}
|
|
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 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;
|
|
|
|
// Enable the Delete Menu
|
|
hr = spConsVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, TRUE);
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
hr = spConsVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, FALSE);
|
|
if( FAILED(hr) ) return hr;
|
|
}
|
|
}
|
|
|
|
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 %systemroot%\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
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::AddMenuItems
|
|
//
|
|
// Adds our context menus into the appropriate MMC provided menu
|
|
// locations.
|
|
|
|
HRESULT CDomainNode::AddMenuItems(LPCONTEXTMENUCALLBACK piCallback, long* pInsertionAllowed, DATA_OBJECT_TYPES type )
|
|
{
|
|
if( !pInsertionAllowed || !piCallback ) return E_INVALIDARG;
|
|
if( !m_spDomain ) return E_FAIL;
|
|
|
|
HRESULT hr = S_OK;
|
|
tstring strMenu = _T("");
|
|
tstring strDesc = _T("");
|
|
CONTEXTMENUITEM2 singleMenuItem;
|
|
ZeroMemory(&singleMenuItem, sizeof(CONTEXTMENUITEM2));
|
|
|
|
CComQIPtr<IContextMenuCallback2> spContext2 = piCallback;
|
|
if( !spContext2 ) return E_NOINTERFACE;
|
|
|
|
// Add the Lock or Unlock Menu to the "Top" part of the MMC Context Menu
|
|
if( *pInsertionAllowed & CCM_INSERTIONALLOWED_TOP )
|
|
{
|
|
singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
|
|
singleMenuItem.fFlags = MF_ENABLED;
|
|
singleMenuItem.fSpecialFlags = 0;
|
|
|
|
// Query the state of this domain to see which menu to load
|
|
BOOL bLocked = FALSE;
|
|
m_spDomain->get_Lock( &bLocked );
|
|
|
|
if( bLocked )
|
|
{
|
|
strMenu = StrLoadString(IDS_MENU_DOMAIN_UNLOCK);
|
|
strDesc = StrLoadString(IDS_MENU_DOMAIN_UNLOCK_DESC);
|
|
|
|
singleMenuItem.strName = (LPWSTR)strMenu.c_str();
|
|
singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str();
|
|
singleMenuItem.strLanguageIndependentName = L"DOMAIN_UNLOCK";
|
|
singleMenuItem.lCommandID = IDM_DOMAIN_TOP_UNLOCK;
|
|
}
|
|
else
|
|
{
|
|
strMenu = StrLoadString(IDS_MENU_DOMAIN_LOCK);
|
|
strDesc = StrLoadString(IDS_MENU_DOMAIN_LOCK_DESC);
|
|
|
|
singleMenuItem.strName = (LPWSTR)strMenu.c_str();
|
|
singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str();
|
|
singleMenuItem.strLanguageIndependentName = L"DOMAIN_LOCK";
|
|
singleMenuItem.lCommandID = IDM_DOMAIN_TOP_LOCK;
|
|
}
|
|
|
|
if( !strMenu.empty() )
|
|
{
|
|
hr = spContext2->AddItem( &singleMenuItem );
|
|
if( FAILED(hr) ) return hr;
|
|
}
|
|
}
|
|
|
|
// Add the User Menu to the "New" part of the MMC Context Menu
|
|
if( (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) )
|
|
{
|
|
singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_NEW;
|
|
singleMenuItem.fFlags = MF_ENABLED;
|
|
singleMenuItem.fSpecialFlags = 0;
|
|
|
|
strMenu = StrLoadString(IDS_MENU_DOMAIN_NEWUSER);
|
|
strDesc = StrLoadString(IDS_MENU_DOMAIN_NEWUSER_DESC);
|
|
|
|
singleMenuItem.strName = (LPWSTR)strMenu.c_str();
|
|
singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str();
|
|
singleMenuItem.strLanguageIndependentName = L"NEW_USER";
|
|
singleMenuItem.lCommandID = IDM_DOMAIN_NEW_USER;
|
|
|
|
if( !strMenu.empty() )
|
|
{
|
|
hr = spContext2->AddItem( &singleMenuItem );
|
|
if( FAILED(hr) ) return hr;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::OnDomainLock
|
|
//
|
|
// Lock or unlock the domain, depending on its current state
|
|
|
|
HRESULT CDomainNode::OnDomainLock( bool& bHandled, CSnapInObjectRootBase* pObj )
|
|
{
|
|
bHandled = true;
|
|
if( !pObj ) return E_INVALIDARG;
|
|
if( !m_spDomain ) return E_FAIL;
|
|
|
|
// Lock this domain
|
|
HRESULT hr = S_OK;
|
|
BOOL bLocked = FALSE;
|
|
CComPtr<IConsole> spConsole = NULL;
|
|
hr = GetConsole( pObj, &spConsole );
|
|
if( FAILED(hr) || !spConsole ) return E_NOINTERFACE;
|
|
|
|
hr = m_spDomain->get_Lock( &bLocked );
|
|
bLocked = !bLocked;
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = m_spDomain->put_Lock( bLocked );
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Set our icons here
|
|
m_scopeDataItem.nImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
m_scopeDataItem.nOpenImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
m_resultDataItem.nImage = (bLocked ? DOMAINNODE_LOCKED_ICON : DOMAINNODE_ICON);
|
|
|
|
// Insert it into the scope tree
|
|
CComQIPtr<IConsoleNameSpace2> spConsoleNameSpace = spConsole;
|
|
if( !spConsoleNameSpace ) return E_NOINTERFACE;
|
|
|
|
hr = spConsoleNameSpace->SetItem(&m_scopeDataItem);
|
|
}
|
|
|
|
// Do a FULL Refresh to update the user lists.
|
|
// Get our Data Object
|
|
CComPtr<IDataObject> spDataObject = NULL;
|
|
GetDataObject(&spDataObject, CCT_SCOPE);
|
|
if( !spDataObject ) return E_FAIL;
|
|
|
|
// Update all the Views to have them remove their lists
|
|
hr = spConsole->UpdateAllViews( spDataObject, 1, (LONG_PTR)NAV_REFRESH );
|
|
if( FAILED(hr) ) return E_FAIL;
|
|
|
|
// Rebuild the users list
|
|
hr = BuildUsers();
|
|
if( FAILED(hr) ) return hr;
|
|
|
|
// Update all the Views to have them re-Add their lists
|
|
hr = spConsole->UpdateAllViews( spDataObject, 0, (LONG_PTR)NAV_REFRESH );
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::OnNewUser
|
|
//
|
|
// Display the New User Dialog, and use the info to create a new POP3
|
|
// user/mailbox and update the Result view
|
|
|
|
HRESULT CDomainNode::OnNewUser( bool& bHandled, CSnapInObjectRootBase* pObj )
|
|
{
|
|
bHandled = true;
|
|
if( !pObj ) return E_INVALIDARG;
|
|
if( !m_pParent || !m_spDomain ) return E_FAIL;
|
|
|
|
// Grab our Current Authentication method
|
|
HRESULT hr = S_OK;
|
|
HWND hWnd = NULL;
|
|
CComPtr<IConsole> spConsole = NULL;
|
|
hr = GetConsole( pObj, &spConsole );
|
|
if( FAILED(hr) || !spConsole ) return E_NOINTERFACE;
|
|
|
|
CComQIPtr<IConsole2> spConsole2 = spConsole;
|
|
if( !spConsole2 ) return E_NOINTERFACE;
|
|
|
|
spConsole2->GetMainWindow(&hWnd);
|
|
|
|
BOOL bSAM = FALSE;
|
|
BOOL bHash = FALSE;
|
|
BOOL bConfirm = TRUE;
|
|
hr = GetAuth(&bHash, &bSAM);
|
|
if( FAILED(hr) )
|
|
{
|
|
// bail out here
|
|
tstring strMessage = StrLoadString(IDS_ERROR_RETRIEVEAUTH);
|
|
tstring strTitle = StrLoadString(IDS_SNAPINNAME);
|
|
::MessageBox( hWnd, strMessage.c_str(), strTitle.c_str(), MB_OK | MB_ICONWARNING );
|
|
return hr;
|
|
}
|
|
|
|
// Get the username and load a Dialog box that asks for a user name, and user email name
|
|
CComPtr<IP3Users> spUsers;
|
|
hr = m_spDomain->get_Users( &spUsers );
|
|
if ( S_OK == hr )
|
|
hr = GetConfirmAddUser( &bConfirm );
|
|
if( FAILED(hr) )
|
|
{
|
|
// Failed to add the user
|
|
tstring strMessage = StrLoadString(IDS_ERROR_CREATEMAIL);
|
|
tstring strTitle = StrLoadString(IDS_SNAPINNAME);
|
|
DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr );
|
|
return hr;
|
|
}
|
|
|
|
CNewUserDlg dlg(spUsers, m_bstrDisplayName, m_pParent->m_bCreateUser, bHash, bSAM, bConfirm );
|
|
|
|
if( dlg.DoModal() == IDOK )
|
|
{
|
|
if ( dlg.isHideDoNotShow() )
|
|
SetConfirmAddUser( FALSE );
|
|
CComVariant var;
|
|
CComPtr<IP3User> spUser;
|
|
VariantInit(&var);
|
|
var = dlg.m_strName.c_str();
|
|
hr = spUsers->get_Item( var, &spUser );
|
|
|
|
CUserNode* pUserNode = new CUserNode(spUser, this);
|
|
|
|
if( pUserNode )
|
|
{
|
|
m_lUsers.push_back( pUserNode );
|
|
}
|
|
|
|
// Re-Select our node to update the result
|
|
// Get our Data Object
|
|
CComPtr<IDataObject> spDataObject = NULL;
|
|
GetDataObject(&spDataObject, CCT_SCOPE);
|
|
if( !spDataObject ) return E_FAIL;
|
|
|
|
hr = spConsole2->UpdateAllViews( spDataObject, (LPARAM)pUserNode, (LONG_PTR)NAV_ADD );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Helper Functions
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::GetAuth
|
|
//
|
|
// pbHashPW : Return Boolean for Hash Password Authentication
|
|
// pbSAM : Return Boolean for Local SAM Authentication
|
|
|
|
HRESULT CDomainNode::GetAuth(BOOL* pbHashPW, BOOL* pbSAM)
|
|
{
|
|
if( !m_pParent ) return E_FAIL;
|
|
|
|
return m_pParent->GetAuth(pbHashPW, pbSAM);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::GetConfirmAddUser
|
|
//
|
|
// pbConfirm : Return Boolean for User Add Confirmation
|
|
|
|
HRESULT CDomainNode::GetConfirmAddUser( BOOL *pbConfirm )
|
|
{
|
|
if( !m_pParent ) return E_POINTER;
|
|
|
|
return m_pParent->GetConfirmAddUser( pbConfirm );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// CDomainNode::SetConfirmAddUser
|
|
//
|
|
// bConfirm : New Boolean Value for User Add Confirmation
|
|
|
|
HRESULT CDomainNode::SetConfirmAddUser( BOOL bConfirm )
|
|
{
|
|
if( !m_pParent ) return E_POINTER;
|
|
|
|
return m_pParent->SetConfirmAddUser( bConfirm );
|
|
}
|
|
|
|
|
|
|