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.
 
 
 
 
 
 

839 lines
26 KiB

//+---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998-2002
//
// File: SchedDlg.cpp
//
// Contents: Implementation of CConnectionScheduleDlg
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include "SchedDlg.h"
#include "log_gmt.h"
#include "loghrapi.h"
#ifdef _DEBUG
//#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// The schedule block has been redefined to have 1 byte for every hour.
// CODEWORK These should be defined in SCHEDULE.H. JonN 2/9/98
//
#define INTERVAL_MASK 0x0F
#define RESERVED 0xF0
#define FIRST_15_MINUTES 0x01
#define SECOND_15_MINUTES 0x02
#define THIRD_15_MINUTES 0x04
#define FOURTH_15_MINUTES 0x08
const int NONE_PER_HOUR = 0;
const int ONE_PER_HOUR = 33;
const int TWO_PER_HOUR = 67;
const int FOUR_PER_HOUR = 100;
/////////////////////////////////////////////////////////////////////
// ConnectionScheduleDialog ()
//
// Invoke a dialog to set/modify a schedule, for example
// -- the logon hours for a particular user
// -- the schedule for a connection
//
// RETURNS
// Return S_OK if the user clicked on the OK button.
// Return S_FALSE if the user clicked on the Cancel button.
// Return E_OUTOFMEMORY if there is not enough memory.
/// Return E_UNEXPECTED if an expected error occured (eg: bad parameter)
//
// INTERFACE NOTES
// Each bit in the array represents one hour. As a result, the
// expected length of the array should be (24 / 8) * 7 = 21 bytes.
// For convenience, the first day of the week is Sunday and
// the last day is Saturday.
// Consequently, the first bit of the array represents the schedule
// for Sunday during period 12 AM to 1 AM.
// - If *pprgbData is NULL, then the routine will allocate
// an array of 21 bytes using LocalAlloc (). The caller
// is responsible of releasing the memory using LocalFree ().
// - If *pprgbData is not NULL, the routine re-use the array as its
// output parameter.
//
// HISTORY
// 17-Jul-97 t-danm Creation.
// 16-Sep-97 jonn Changed to UiScheduleDialog
//
HRESULT
ConnectionScheduleDialog (
HWND hwndParent, // IN: Parent's window handle
BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
LPCTSTR pszTitle) // IN: Dialog title
{
return ConnectionScheduleDialogEx (hwndParent, pprgbData, pszTitle, 0);
}
// NTRAID#NTBUG9-547415-2002/02/18-artm Should catch out of memory exceptions and convert to HRESULT.
HRESULT
ConnectionScheduleDialogEx (
HWND hwndParent, // IN: Parent's window handle
BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
LPCTSTR pszTitle, // IN: Dialog title
DWORD dwFlags)
{
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
// These asserts are backed up by validation code.
ASSERT (::IsWindow (hwndParent));
ASSERT (pprgbData);
// NOTICE-NTRAID#NTBUG9-547381-2002/02/18-artm pszTitle okay to be NULL
// dlg.SetTitle() robustly handles NULL.
ASSERT (pszTitle);
ENDORSE (NULL == *pprgbData); // TRUE => Use default logon hours (7x24)
if (*pprgbData == NULL)
{
BYTE * pargbData; // Pointer to allocated array of bytes
// FUTURE-2002/02/18-artm Use named constant instead of magic 7*24.
pargbData = (BYTE *)LocalAlloc (0, 7*24); // Allocate 168 bytes
if ( !pargbData )
return E_OUTOFMEMORY;
// Set the logon hours to be valid 24 hours a day and 7 days a week.
// FUTURE-2002/02/18-artm Use named constant instead of magic 7*24.
memset (OUT pargbData, -1, 7*24);
*pprgbData = pargbData;
}
// If hwndParent passed in, create a CWnd to pass as the parent window
CWnd* pWnd = 0;
if ( ::IsWindow (hwndParent) )
{
pWnd = new CWnd;
if ( pWnd )
{
pWnd->Attach (hwndParent);
}
else
return E_OUTOFMEMORY;
}
HRESULT hr = S_OK;
CConnectionScheduleDlg dlg (pWnd);
dlg.SetTitle (pszTitle);
dlg.SetConnectionByteArray (INOUT *pprgbData, 7*24);
dlg.SetFlags (dwFlags);
if (IDOK != dlg.DoModal ())
hr = S_FALSE;
// Delete CWnd
if ( pWnd )
{
pWnd->Detach ();
delete pWnd;
}
return hr;
} // ConnectionScheduleDialog ()
HRESULT
ReplicationScheduleDialog (
HWND hwndParent, // IN: Parent's window handle
BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
LPCTSTR pszTitle) // IN: Dialog title
{
return ReplicationScheduleDialogEx (hwndParent, pprgbData, pszTitle, 0);
} // ReplicationScheduleDialog ()
// NTRAID#NTBUG9-547415-2002/02/18-artm Should catch out of memory exceptions and convert to HRESULT.
HRESULT ReplicationScheduleDialogEx (
HWND hwndParent, // parent window
BYTE ** pprgbData, // pointer to pointer to array of 84 bytes
LPCTSTR pszTitle, // dialog title
DWORD dwFlags) // option flags
{
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
// These asserts are backed up by validation code in release build.
ASSERT (::IsWindow (hwndParent));
ASSERT (pprgbData);
// NOTICE-NTRAID#NTBUG9-547381-2002/02/18-artm pszTitle okay to be NULL
// dlg.SetTitle() robustly handles NULL.
ASSERT (pszTitle);
ENDORSE (NULL == *pprgbData); // TRUE => Use default logon hours (7x24)
if (*pprgbData == NULL)
{
BYTE * pargbData; // Pointer to allocated array of bytes
// FUTURE-2002/02/18-artm Use named constant instead of magic 7*24.
pargbData = (BYTE *)LocalAlloc (0, 7*24); // Allocate 168 bytes
if ( !pargbData )
return E_OUTOFMEMORY;
// FUTURE-2002/02/18-artm Use named constant instead of magic 7*24.
// Set the logon hours to be valid 24 hours a day and 7 days a week.
memset (OUT pargbData, -1, 7*24);
*pprgbData = pargbData;
}
// If hwndParent passed in, create a CWnd to pass as the parent window
CWnd* pWnd = 0;
if ( ::IsWindow (hwndParent) )
{
pWnd = new CWnd;
if ( pWnd )
{
pWnd->Attach (hwndParent);
}
else
return E_OUTOFMEMORY;
}
HRESULT hr = S_OK;
CReplicationScheduleDlg dlg (pWnd);
dlg.SetTitle (pszTitle);
dlg.SetConnectionByteArray (INOUT *pprgbData, 7*24);
dlg.SetFlags (dwFlags);
if (IDOK != dlg.DoModal ())
hr = S_FALSE;
// Delete CWnd
if ( pWnd )
{
pWnd->Detach ();
delete pWnd;
}
return hr;
} // ReplicationScheduleDialogEx
/////////////////////////////////////////////////////////////////////////////
// CConnectionScheduleDlg dialog
CConnectionScheduleDlg::CConnectionScheduleDlg(CWnd* pParent)
: CScheduleBaseDlg(CConnectionScheduleDlg::IDD, true, pParent),
m_prgbData168 (0)
{
EnableAutomation();
//{{AFX_DATA_INIT(CConnectionScheduleDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CConnectionScheduleDlg::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CScheduleBaseDlg::OnFinalRelease();
}
void CConnectionScheduleDlg::DoDataExchange(CDataExchange* pDX)
{
CScheduleBaseDlg::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CConnectionScheduleDlg)
DDX_Control(pDX, IDC_RADIO_NONE, m_buttonNone);
DDX_Control(pDX, IDC_RADIO_ONE, m_buttonOne);
DDX_Control(pDX, IDC_RADIO_TWO, m_buttonTwo);
DDX_Control(pDX, IDC_RADIO_FOUR, m_buttonFour);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CConnectionScheduleDlg, CScheduleBaseDlg)
//{{AFX_MSG_MAP(CConnectionScheduleDlg)
ON_BN_CLICKED(IDC_RADIO_FOUR, OnRadioFour)
ON_BN_CLICKED(IDC_RADIO_NONE, OnRadioNone)
ON_BN_CLICKED(IDC_RADIO_ONE, OnRadioOne)
ON_BN_CLICKED(IDC_RADIO_TWO, OnRadioTwo)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CConnectionScheduleDlg, CScheduleBaseDlg)
//{{AFX_DISPATCH_MAP(CConnectionScheduleDlg)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
// Note: we add support for IID_IDSScheduleDlg to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {701CFB36-AEF8-11D1-9864-00C04FB94F17}
static const IID IID_IDSScheduleDlg =
{ 0x701cfb36, 0xaef8, 0x11d1, { 0x98, 0x64, 0x0, 0xc0, 0x4f, 0xb9, 0x4f, 0x17 } };
BEGIN_INTERFACE_MAP(CConnectionScheduleDlg, CScheduleBaseDlg)
INTERFACE_PART(CConnectionScheduleDlg, IID_IDSScheduleDlg, Dispatch)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CConnectionScheduleDlg message handlers
BOOL CConnectionScheduleDlg::OnInitDialog()
{
CScheduleBaseDlg::OnInitDialog();
// Set up the "none" legend
m_legendNone.Init (this, IDC_STATIC_LEGEND_NONE, &m_schedulematrix, NONE_PER_HOUR);
// Set up the "one" legend
m_legendOne.Init (this, IDC_STATIC_LEGEND_ONE, &m_schedulematrix, ONE_PER_HOUR);
// Set up the "two" legend
m_legendTwo.Init (this, IDC_STATIC_LEGEND_TWO, &m_schedulematrix, TWO_PER_HOUR);
// Set up the "four" legend
m_legendFour.Init (this, IDC_STATIC_LEGEND_FOUR, &m_schedulematrix, FOUR_PER_HOUR);
if ( GetFlags () & SCHED_FLAG_READ_ONLY )
{
// Disable the grid settings buttons
m_buttonNone.EnableWindow (FALSE);
m_buttonOne.EnableWindow (FALSE);
m_buttonTwo.EnableWindow (FALSE);
m_buttonFour.EnableWindow (FALSE);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CConnectionScheduleDlg::OnOK()
{
if ( m_prgbData168 )
{
GetByteArray (OUT m_prgbData168, m_cbArray);
// Convert back the hours to GMT time.
ConvertConnectionHoursToGMT (INOUT m_prgbData168, m_bAddDaylightBias);
}
CScheduleBaseDlg::OnOK();
}
void CConnectionScheduleDlg::UpdateButtons ()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
// Assume in each case that all selected squares are all set one way until
// proven otherwise. These are 'int' so that I can add them up afterwards
// to assure that only one of the buttons will be checked.
int fNoneAllSet = 1;
int fOneAllSet = 1;
int fTwoAllSet = 1;
int fFourAllSet = 1;
if (nNumHours > 0)
{
for (UINT iDayOfWeek = nDay; iDayOfWeek < nDay+nNumDays; iDayOfWeek++)
{
for (UINT iHour = nHour; iHour < nHour+nNumHours; iHour++)
{
switch (m_schedulematrix.GetPercentage (iHour, iDayOfWeek))
{
case NONE_PER_HOUR:
fOneAllSet = 0;
fTwoAllSet = 0;
fFourAllSet = 0;
break;
case ONE_PER_HOUR:
fNoneAllSet = 0;
fTwoAllSet = 0;
fFourAllSet = 0;
break;
case TWO_PER_HOUR:
fNoneAllSet = 0;
fOneAllSet = 0;
fFourAllSet = 0;
break;
case FOUR_PER_HOUR:
fNoneAllSet = 0;
fOneAllSet = 0;
fTwoAllSet = 0;
break;
default:
ASSERT (0);
break;
}
} // for
} // for
}
else
{
fNoneAllSet = 0;
fOneAllSet = 0;
fTwoAllSet = 0;
fFourAllSet = 0;
}
// Ensure that at most, only one of these is 'true'
ASSERT ((fNoneAllSet + fOneAllSet + fTwoAllSet + fFourAllSet <= 1));
m_buttonNone.SetCheck (fNoneAllSet);
m_buttonOne.SetCheck (fOneAllSet);
m_buttonTwo.SetCheck (fTwoAllSet);
m_buttonFour.SetCheck (fFourAllSet);
}
void CConnectionScheduleDlg::OnRadioFour()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
if (nNumHours <= 0)
return; // Nothing selected
m_schedulematrix.SetPercentage (FOUR_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
UpdateButtons ();
}
void CConnectionScheduleDlg::OnRadioNone()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
if (nNumHours <= 0)
return; // Nothing selected
m_schedulematrix.SetPercentage (NONE_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
UpdateButtons ();
}
void CConnectionScheduleDlg::OnRadioOne()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
if (nNumHours <= 0)
return; // Nothing selected
m_schedulematrix.SetPercentage (ONE_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
UpdateButtons ();
}
void CConnectionScheduleDlg::OnRadioTwo()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
if (nNumHours <= 0)
return; // Nothing selected
m_schedulematrix.SetPercentage (TWO_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
UpdateButtons ();
}
void CConnectionScheduleDlg::InitMatrix()
{
if ( m_prgbData168 )
{
BYTE rgData[SCHEDULE_DATA_ENTRIES]; // Array of logonhours bits
// Make a copy of the connection hours (in case the user click on cancel button)
memcpy (OUT rgData, IN m_prgbData168, sizeof (rgData));
// Convert the hours from GMT to local hours.
ConvertConnectionHoursFromGMT (INOUT rgData, m_bAddDaylightBias);
// Initialize the matrix
InitMatrix2 (IN rgData);
}
}
void CConnectionScheduleDlg::SetConnectionByteArray(INOUT BYTE rgbData [SCHEDULE_DATA_ENTRIES],
const size_t cbArray)
{
// NULL m_prgbData168 is checked for where it is dereferenced; ASSERT does not need to be backed up
ASSERT (rgbData);
if ( !IsBadWritePtr (rgbData, cbArray) )
{
m_prgbData168 = rgbData;
m_cbArray = cbArray;
}
}
// This table represent the numbers of bits set in the lower nibble of the BYTE.
// 0 bits -> 0
// 1 bit -> 25
// 2 or 3 bits -> 50
// 4 bits -> 100
static BYTE setConversionTable[16] =
{NONE_PER_HOUR, // 0000
ONE_PER_HOUR, // 0001
ONE_PER_HOUR, // 0010
TWO_PER_HOUR, // 0011
ONE_PER_HOUR, // 0100
TWO_PER_HOUR, // 0101
TWO_PER_HOUR, // 0110
TWO_PER_HOUR, // 0111
ONE_PER_HOUR, // 1000
TWO_PER_HOUR, // 1001
TWO_PER_HOUR, // 1010
TWO_PER_HOUR, // 1011
TWO_PER_HOUR, // 1100
TWO_PER_HOUR, // 1101
TWO_PER_HOUR, // 1110
FOUR_PER_HOUR}; // 1111
UINT CConnectionScheduleDlg::GetPercentageToSet(const BYTE bData)
{
ASSERT ((bData & 0x0F) < 16);
return setConversionTable[bData & 0x0F];
}
BYTE CConnectionScheduleDlg::GetMatrixPercentage(UINT nHour, UINT nDay)
{
BYTE byResult = 0;
switch (m_schedulematrix.GetPercentage (nHour, nDay))
{
case NONE_PER_HOUR:
// value remains 0n
break;
case ONE_PER_HOUR:
byResult = FIRST_15_MINUTES;
break;
case TWO_PER_HOUR:
byResult = FIRST_15_MINUTES | THIRD_15_MINUTES;
break;
case FOUR_PER_HOUR:
byResult = FIRST_15_MINUTES | SECOND_15_MINUTES | THIRD_15_MINUTES | FOURTH_15_MINUTES;
break;
default:
ASSERT (0);
break;
}
return byResult;
}
UINT CConnectionScheduleDlg::GetExpectedArrayLength()
{
return SCHEDULE_DATA_ENTRIES;
}
// Called when WM_TIMECHANGE is received
void CConnectionScheduleDlg::TimeChange()
{
m_buttonNone.EnableWindow (FALSE);
m_buttonOne.EnableWindow (FALSE);
m_buttonTwo.EnableWindow (FALSE);
m_buttonFour.EnableWindow (FALSE);
}
/////////////////////////////////////////////////////////////////////////////
// CReplicationScheduleDlg dialog
CReplicationScheduleDlg::CReplicationScheduleDlg(CWnd* pParent)
: CScheduleBaseDlg(CReplicationScheduleDlg::IDD, true, pParent),
m_prgbData168 (0)
{
EnableAutomation();
//{{AFX_DATA_INIT(CReplicationScheduleDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CReplicationScheduleDlg::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CScheduleBaseDlg::OnFinalRelease();
}
void CReplicationScheduleDlg::DoDataExchange(CDataExchange* pDX)
{
CScheduleBaseDlg::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CReplicationScheduleDlg)
DDX_Control(pDX, IDC_RADIO_NONE, m_buttonNone);
DDX_Control(pDX, IDC_RADIO_FOUR, m_buttonFour);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CReplicationScheduleDlg, CScheduleBaseDlg)
//{{AFX_MSG_MAP(CReplicationScheduleDlg)
ON_BN_CLICKED(IDC_RADIO_FOUR, OnRadioFour)
ON_BN_CLICKED(IDC_RADIO_NONE, OnRadioNone)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CReplicationScheduleDlg, CScheduleBaseDlg)
//{{AFX_DISPATCH_MAP(CReplicationScheduleDlg)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
// Note: we add support for IID_IDSScheduleDlg to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {8DE6E2DA-7B4E-11d2-AC13-00C04F79DDCA}
static const IID IID_IReplicationScheduleDlg =
{ 0x8de6e2da, 0x7b4e, 0x11d2, { 0xac, 0x13, 0x0, 0xc0, 0x4f, 0x79, 0xdd, 0xca } };
BEGIN_INTERFACE_MAP(CReplicationScheduleDlg, CScheduleBaseDlg)
INTERFACE_PART(CReplicationScheduleDlg, IID_IReplicationScheduleDlg, Dispatch)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CReplicationScheduleDlg message handlers
BOOL CReplicationScheduleDlg::OnInitDialog()
{
CScheduleBaseDlg::OnInitDialog();
// Set up the "none" legend
m_legendNone.Init (this, IDC_STATIC_LEGEND_NONE, &m_schedulematrix, NONE_PER_HOUR);
// Set up the "four" legend
m_legendFour.Init (this, IDC_STATIC_LEGEND_FOUR, &m_schedulematrix, FOUR_PER_HOUR);
if ( GetFlags () & SCHED_FLAG_READ_ONLY )
{
// Disable the grid settings buttons
m_buttonNone.EnableWindow (FALSE);
m_buttonFour.EnableWindow (FALSE);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CReplicationScheduleDlg::OnOK()
{
if ( m_prgbData168 )
{
GetByteArray (OUT m_prgbData168, m_cbArray);
// Convert back the hours to GMT time.
ConvertConnectionHoursToGMT (INOUT m_prgbData168, m_bAddDaylightBias);
}
CScheduleBaseDlg::OnOK();
}
void CReplicationScheduleDlg::UpdateButtons ()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
// Assume in each case that all selected squares are all set one way until
// proven otherwise. These are 'int' so that I can add them up afterwards
// to assure that only one of the buttons will be checked.
int fNoneAllSet = 1;
int fFourAllSet = 1;
if (nNumHours > 0)
{
for (UINT iDayOfWeek = nDay; iDayOfWeek < nDay+nNumDays; iDayOfWeek++)
{
for (UINT iHour = nHour; iHour < nHour+nNumHours; iHour++)
{
switch (m_schedulematrix.GetPercentage (iHour, iDayOfWeek))
{
case NONE_PER_HOUR:
fFourAllSet = 0;
break;
case FOUR_PER_HOUR:
fNoneAllSet = 0;
break;
default:
ASSERT (0);
break;
}
} // for
} // for
}
else
{
fNoneAllSet = 0;
}
ASSERT (fNoneAllSet + fFourAllSet <= 1);
m_buttonNone.SetCheck (fNoneAllSet);
m_buttonFour.SetCheck (fFourAllSet);
}
void CReplicationScheduleDlg::OnRadioFour()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
if (nNumHours <= 0)
return; // Nothing selected
m_schedulematrix.SetPercentage (FOUR_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
UpdateButtons ();
}
void CReplicationScheduleDlg::OnRadioNone()
{
UINT nHour = 0;
UINT nDay = 0;
UINT nNumHours = 0;
UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
if (nNumHours <= 0)
return; // Nothing selected
m_schedulematrix.SetPercentage (NONE_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
UpdateButtons ();
}
void CReplicationScheduleDlg::InitMatrix()
{
if ( m_prgbData168 )
{
BYTE rgData[SCHEDULE_DATA_ENTRIES]; // Array of logonhours bits
// Make a copy of the connection hours (in case the user click on cancel button)
memcpy (OUT rgData, IN m_prgbData168, sizeof (rgData));
// Convert the hours from GMT to local hours.
ConvertConnectionHoursFromGMT (INOUT rgData, m_bAddDaylightBias);
// Initialize the matrix
InitMatrix2 (IN rgData);
}
}
void CReplicationScheduleDlg::SetConnectionByteArray(INOUT BYTE rgbData [SCHEDULE_DATA_ENTRIES], const size_t cbArray)
{
// Code supports NULL rgbData; ASSERT() is early bug detection.
ASSERT (rgbData);
if ( !IsBadWritePtr (rgbData, cbArray) )
{
m_prgbData168 = rgbData;
m_cbArray = cbArray;
}
}
// This table represent the numbers of bits set in the lower nibble of the BYTE.
// 0 bits -> 0
// 1 bit -> 25
// 2 or 3 bits -> 50
// 4 bits -> 100
static BYTE setConversionTableForReplication[16] =
{NONE_PER_HOUR, // 0000
FOUR_PER_HOUR, // 0001
FOUR_PER_HOUR, // 0010
FOUR_PER_HOUR, // 0011
FOUR_PER_HOUR, // 0100
FOUR_PER_HOUR, // 0101
FOUR_PER_HOUR, // 0110
FOUR_PER_HOUR, // 0111
FOUR_PER_HOUR, // 1000
FOUR_PER_HOUR, // 1001
FOUR_PER_HOUR, // 1010
FOUR_PER_HOUR, // 1011
FOUR_PER_HOUR, // 1100
FOUR_PER_HOUR, // 1101
FOUR_PER_HOUR, // 1110
FOUR_PER_HOUR}; // 1111
UINT CReplicationScheduleDlg::GetPercentageToSet(const BYTE bData)
{
ASSERT ((bData & 0x0F) < 16);
return setConversionTableForReplication[bData & 0x0F];
}
BYTE CReplicationScheduleDlg::GetMatrixPercentage(UINT nHour, UINT nDay)
{
BYTE byResult = 0;
switch (m_schedulematrix.GetPercentage (nHour, nDay))
{
case NONE_PER_HOUR:
// value remains 0n
break;
case ONE_PER_HOUR:
case TWO_PER_HOUR:
case FOUR_PER_HOUR:
byResult = FIRST_15_MINUTES | SECOND_15_MINUTES | THIRD_15_MINUTES | FOURTH_15_MINUTES;
break;
default:
ASSERT (0);
break;
}
return byResult;
}
UINT CReplicationScheduleDlg::GetExpectedArrayLength()
{
return SCHEDULE_DATA_ENTRIES;
}
// Called when WM_TIMECHANGE is received
void CReplicationScheduleDlg::TimeChange()
{
m_buttonNone.EnableWindow (FALSE);
m_buttonFour.EnableWindow (FALSE);
}
/////////////////////////////////////////////////////////////////////
// Converts the connection hours from local time to GMT.
void
ConvertConnectionHoursToGMT (INOUT BYTE rgbData[SCHEDULE_DATA_ENTRIES], IN bool bAddDaylightBias)
{
// FUTURE-2002/02/18-artm Release code should check return value.
VERIFY ( ::NetpRotateLogonHoursBYTE (rgbData, SCHEDULE_DATA_ENTRIES, TRUE, bAddDaylightBias) );
}
/////////////////////////////////////////////////////////////////////
// Converts the connection hours from GMT to local time.
void
ConvertConnectionHoursFromGMT (INOUT BYTE rgbData[SCHEDULE_DATA_ENTRIES], IN bool bAddDaylightBias)
{
// FUTURE-2002/02/18-artm Release code should check return value.
VERIFY ( ::NetpRotateLogonHoursBYTE (rgbData, SCHEDULE_DATA_ENTRIES, FALSE, bAddDaylightBias) );
}