SMBADMIN.CPP

// ----------------------------------------------------------------------------- 
// SMBADMIN.cpp : Implements an Exchange Administration property sheet dialog.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------

#include "edkafx.h"
#include "SMBADMIN.h"
#include "errcpp.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define MAX_STR_BUF 200

// -----------------------------------------------------------------------------

BEGIN_MESSAGE_MAP(CSMBAdminDlg, CAdminDialog)
//{{AFX_MSG_MAP(CSMBAdminDlg)
ON_EN_CHANGE(IDC_EDIT_POLL_INBOX_MSEC, OnEnChange)
ON_BN_CLICKED(IDC_CHECK_CONTACT, OnBnClicked)
ON_EN_CHANGE(IDC_EDIT_TOPIC_ROOT_FOLDER_COMMENT, OnEnChange)
ON_BN_CLICKED(IDC_CHECK_CREATE, OnBnClicked)
ON_BN_CLICKED(IDC_CHECK_DELETE, OnBnClicked)
ON_BN_CLICKED(IDC_CHECK_OWNER, OnBnClicked)
ON_BN_CLICKED(IDC_CHECK_PUBLIC_TOPIC_FOLDER, OnFolderBnClicked)
ON_BN_CLICKED(IDC_CHECK_READ, OnBnClicked)
ON_BN_CLICKED(IDC_CHECK_WRITE, OnBnClicked)
ON_EN_CHANGE(IDC_EDIT_TOPIC_ROOT_FOLDER_NAME, OnEnChange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//$--CSMBAdminDlg::OnEnChange()-------------------------------------------------
// Called when an edit control is changed.
// -----------------------------------------------------------------------------

void CSMBAdminDlg::OnEnChange()
{
if( !m_bRefresh)
DataHasChanged();
}

//$--CSMBAdminDlg::OnFolderBnClicked()------------------------------------------
// Called when public store check box is changed.
// -----------------------------------------------------------------------------

void CSMBAdminDlg::OnFolderBnClicked()
{
BOOL bPublicTopic = m_chkboxPublicTopicFolder.GetCheck();

m_chkboxRead.EnableWindow( bPublicTopic);
m_chkboxWrite.EnableWindow( bPublicTopic);
m_chkboxCreate.EnableWindow( bPublicTopic);
m_chkboxDelete.EnableWindow( bPublicTopic);
m_chkboxOwner.EnableWindow( bPublicTopic);
m_chkboxContact.EnableWindow( bPublicTopic);

if( !m_bRefresh)
DataHasChanged();
}

//$--CSMBAdminDlg::OnBnClicked()------------------------------------------------
// Called when a check box is changed.
// -----------------------------------------------------------------------------

void CSMBAdminDlg::OnBnClicked()
{
static BOOL bWarnedUser = FALSE;

if( !bWarnedUser)
{
MessageBox2(
IDS_WARNING_ACL_CHANGE,
IDS_MESSAGE_BOX_WARNING,
MB_ICONEXCLAMATION | MB_OK);

bWarnedUser = TRUE;
}

if( !m_bRefresh)
DataHasChanged();
}

//$--CSMBAdminDlg::bHasHelp()---------------------------------------------------
// Called to determine if you supply help. Return TRUE if you do.
// -----------------------------------------------------------------------------

BOOL CSMBAdminDlg::bHasHelp()
{
return( TRUE);
}

//$--CSMBAdminDlg::DoHelp()-----------------------------------------------------
// Called to start help.
// -----------------------------------------------------------------------------

VOID CSMBAdminDlg::DoHelp()
{
CHAR szDllPath[MAX_PATH+1] = {0};
DWORD cchDllPath = 0;

// Get the path and file name of this DLL.

cchDllPath = GetModuleFileName(
(HMODULE)(AfxGetInstanceHandle()),
szDllPath,
sizeof(szDllPath) - 1);

// If we got back something that ends in ".DLL", then change the
// extension to ".HLP" and call it as the help file.

if (cchDllPath >=4 && !stricmp(&szDllPath[cchDllPath-4],".DLL"))
{
strcpy(&szDllPath[cchDllPath-4], ".HLP");
::WinHelp( GetSafeHwnd(), szDllPath, HELP_CONTENTS, 0);
}

// Otherwise it's an error.

else
{
MODULE_WARNING(
"GWPERF_DLL_ENTRY_MODULE_NAME: GetModuleFileName() failed.");
}
}

//$--CSMBAdminDlg::Refresh()----------------------------------------------------
// Called so that property sheet can refresh with data that may have been
// changed by another property sheet. Even though this DLL does not have more
// than one property sheet that modifies the same data fields the Exchange SDK
// provides a sample that lets an Administrator view and modify any Exchange
// SDK packed extension data array.
// -----------------------------------------------------------------------------

void CSMBAdminDlg::Refresh()
{
BOOL bPublicTopic = FALSE;

// While in refresh mode we do not want to the enable the APPLY
// button if we are just repainting the screen.
m_bRefresh = TRUE;

// So initialize controls.
SetDlgItemText( IDC_EDIT_TOPIC_ROOT_FOLDER_NAME, GetExtString( IDX_TOPIC_ROOT_FOLDER_NAME));
SetDlgItemText( IDC_EDIT_TOPIC_ROOT_FOLDER_COMMENT, GetExtString( IDX_TOPIC_ROOT_FOLDER_COMMENT));

// Display the inbox polling frequency.
char szBuf[ 20];
DWORD dwPollFreq = GetExtDWord( IDX_POLL_INBOX_MSEC);
if( dwPollFreq == INFINITE)
SetDlgItemText( IDC_EDIT_POLL_INBOX_MSEC, "NONE");
else
{ // Display the non infinite polling frequency as a number.
wsprintf( szBuf, "%lu", dwPollFreq);
SetDlgItemText( IDC_EDIT_POLL_INBOX_MSEC, szBuf);
}

// Set check for public folders.
bPublicTopic = GetExtBool( IDX_PUBLIC_TOPIC_FOLDER);

m_chkboxPublicTopicFolder.SetCheck( bPublicTopic);

// Set all of the ACL Rights check boxes.
DWORD dwACLrights = GetExtDWord( IDX_ACL_RIGHTS);

m_chkboxRead.SetCheck( dwACLrights & frightsReadAny);
m_chkboxWrite.SetCheck( dwACLrights & frightsEditAny);
m_chkboxCreate.SetCheck( dwACLrights & frightsCreate);
m_chkboxDelete.SetCheck( dwACLrights & frightsDeleteAny);
m_chkboxOwner.SetCheck( dwACLrights & frightsOwner);
m_chkboxContact.SetCheck( dwACLrights & frightsContact);

m_chkboxRead.EnableWindow( bPublicTopic);
m_chkboxWrite.EnableWindow( bPublicTopic);
m_chkboxCreate.EnableWindow( bPublicTopic);
m_chkboxDelete.EnableWindow( bPublicTopic);
m_chkboxOwner.EnableWindow( bPublicTopic);
m_chkboxContact.EnableWindow( bPublicTopic);

// Ending refresh mode.
m_bRefresh = FALSE;
}

//$--CSMBAdminDlg::OnInitDialog()-----------------------------------------------
// Initialize the dialog with extension data. Create extension data if necessary.
// -----------------------------------------------------------------------------

BOOL CSMBAdminDlg::OnInitDialog()
{
CAdminDialog::OnInitDialog();

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Subclass all controls.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

if( FAILED( HrSubclassWindow( IDC_EDIT_TOPIC_ROOT_FOLDER_NAME, m_editTopicRootFolderName)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_EDIT_TOPIC_ROOT_FOLDER_COMMENT, m_editTopicRootFolderComment)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_EDIT_POLL_INBOX_MSEC, m_editPollInboxMSec)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_CHECK_PUBLIC_TOPIC_FOLDER, m_chkboxPublicTopicFolder)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_CHECK_READ, m_chkboxRead)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_CHECK_WRITE, m_chkboxWrite)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_CHECK_CREATE, m_chkboxCreate)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_CHECK_DELETE, m_chkboxDelete)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_CHECK_OWNER, m_chkboxOwner)))
return( TRUE);

if( FAILED( HrSubclassWindow( IDC_CHECK_CONTACT, m_chkboxContact)))
return( TRUE);

// Limit the amount of text a tester can enter into
// the string controls to a reasonable limit.
m_editTopicRootFolderName.LimitText( MAX_TOPIC_STRING);
m_editTopicRootFolderComment.LimitText( MAX_TOPIC_STRING);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Initialize the extension data to defaults if it does not exist.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Is extension data available?
if( GetExtCount() == 0)
{ // NO, extension data is not available so set the
// memory copy of this to the defaults.

// The following text string pointers are cast as LONGLONG here because
// a bug in the MIPS C++ compiler causes problems if we try to do the cast
// inside the ExtensionProps structure.

static const LONGLONG llszDfltFolderName = (LONGLONG) TEXT("Topics");
static const LONGLONG llszDfltFolderComment = (LONGLONG) TEXT("Root Topic Folder");

static SInitPropValue ExtensionProps[] =
{
{ PT_BOOLEAN, 0, TRUE}, // Public folder (TRUE or FALSE)
{ PT_LONG, 0, 60000}, // Polling frequency.
{ PT_LONG, 0, frightsReadAny}, // Public folder Access Control List settings.
{ PT_STRING8, 0, llszDfltFolderName},
{ PT_STRING8, 0, llszDfltFolderComment},
};

// Initialize the property value array used to create the extension data blob.
if( FAILED( HrSetExtProps( ARRAY_CNT( ExtensionProps), ExtensionProps)))
return( TRUE);

// Save it in Admin's memory buffer as well.
CAdminDialog::bSaveData();
}

return( TRUE); // return TRUE unless you set the focus to a control
}

//$--CSMBAdminDlg::bIsValidString()---------------------------------------------
// Validate that a string is not empty and modify the extension data property
// in memory.
// -----------------------------------------------------------------------------

BOOL CSMBAdminDlg::bIsValidString(
IN ULONG iProp, // Index of property
IN CEditExt& editCtrl) // Edit control containing data to validate.
{
CString str = editCtrl.GetString();
if( str.GetLength() == 0)
{
InvalidEntry( IDS_INVALID_STRING, editCtrl);
return( FALSE);
}
CHRESULT hr = HrModExtString( iProp, str);
if( FAILED( hr))
return( FALSE);

return( TRUE);
}

//$--CSMBAdminDlg::bIsValidULong()----------------------------------------------
// Validate that a ulong is within a specified range and modify the extension
// data property in memory.
// -----------------------------------------------------------------------------

BOOL CSMBAdminDlg::bIsValidULong(
IN ULONG iProp, // Index of property
IN CEditExt& editCtrl, // Edit control containing data to validate.
IN ULONG ulLow,
IN ULONG ulHigh,
IN int idErrMsg)
{
ULONG ul = editCtrl.GetULong();
if( ul < ulLow || ul > ulHigh)
{
InvalidEntry( idErrMsg, editCtrl);
return( FALSE);
}
CHRESULT hr = HrModExtDWord( iProp, ul);
if( FAILED( hr))
return( FALSE);

return( TRUE);
}

//$--CSMBAdminDlg::bSaveData()--------------------------------------------------
// Called when a different property sheet has been selected or when either the
// OK or APPLY NOW button is pressed. Returns TRUE if data has been validated
// and saved.
//
// When we call the CAdminDialog::bSaveData() function it gets saved in an
// admin memory space. This makes it available to other property sheets that
// might be viewing the same data.
// -----------------------------------------------------------------------------

BOOL CSMBAdminDlg::bSaveData()
{
CHRESULT hr;
TCHAR szBuf[ MAX_STR_BUF];

// Validate and modify the topic root folder name in memory.
if( !bIsValidString( IDX_TOPIC_ROOT_FOLDER_NAME, m_editTopicRootFolderName))
return( FALSE);

// Modify the topic root folder comment in memory.
CString str = m_editTopicRootFolderComment.GetString();
hr = HrModExtString( IDX_TOPIC_ROOT_FOLDER_COMMENT, str);
if( FAILED( hr))
return( FALSE);

// Modify the polling frequency in memory.
m_editPollInboxMSec.GetLine( 0, szBuf, sizeof( szBuf));
if( _tcsicmp( szBuf, TEXT( "NONE")) == 0)
{
hr = HrModExtDWord( IDX_POLL_INBOX_MSEC, INFINITE);
if( FAILED( hr))
return( FALSE);
}
else
if( !bIsValidULong( IDX_POLL_INBOX_MSEC, m_editPollInboxMSec, 60000, MAX_ULONG, IDS_INVALID_POLLING_FREQUENCY))
return( FALSE);

// Modify the public topic folder flag.
hr = HrModExtBool( IDX_PUBLIC_TOPIC_FOLDER, m_chkboxPublicTopicFolder.GetCheck());
if( FAILED( hr))
return( FALSE);

// Modify the ACL rights in memory.
DWORD dwACLrights =
(m_chkboxRead.GetCheck() * frightsReadAny) |
(m_chkboxWrite.GetCheck() * frightsEditAny) |
(m_chkboxCreate.GetCheck() * frightsCreate) |
(m_chkboxDelete.GetCheck() * frightsDeleteAny) |
(m_chkboxOwner.GetCheck() * frightsOwner) |
(m_chkboxContact.GetCheck() * frightsContact);
hr = HrModExtDWord( IDX_ACL_RIGHTS, dwACLrights);
if( FAILED( hr))
return( FALSE);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// We are complete, the data is valid, so lets save it.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return( CAdminDialog::bSaveData());
}

//$--CSMBAdminDlg::bCommitData()------------------------------------------------
// Called when either the OK or APPLY NOW button is pressed and after bSaveData().
// Return TRUE if it is OK to commit the saved data.
// -----------------------------------------------------------------------------

BOOL CSMBAdminDlg::bCommitData()
{
return( TRUE);
}

// -----------------------------------------------------------------------------
// Admin will call this function directly (it is not a member function). It is
// called once for each standard property sheet. We have the option to keep one
// or more of the standard property sheets from showing.
// -----------------------------------------------------------------------------
/*
BOOL PASCAL bShowPage( UINT iddAdminPage)
{
BOOL bRet = TRUE; // Show the standard property sheet.
return( bRet);
}

// $--iStartPage()--------------------------------------------------------------
// This function is called once durring initialization. Return -1 to cause the
// first standard property sheet to be displayed. Or return the index of one of
// our property sheets to have it come up first.
// -----------------------------------------------------------------------------

INT PASCAL iStartPage( void)
{
int i = -1; // Default to the first standard property sheet.
return( i);
}
*/
// -----------------------------------------------------------------------------