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); 
} 
*/ 
// -----------------------------------------------------------------------------