|
|
//+---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997-2002.
//
// File: log.cpp
//
// Contents: Definition of CLogOnHoursDlg
// Dialog displaying the weekly logging hours for a particular user.
//
// HISTORY
// 17-Jul-97 t-danm Creation.
/////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "Log.h"
#include "resource.h"
#include "log_gmt.h" // NetpRotateLogonHours ()
#define CB_LOGON_ARRAY_LENGTH (7 * 24) // Number of bytes in logon array.
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CLogOnHoursDlg dialog
CLogOnHoursDlg::CLogOnHoursDlg ( UINT nIDTemplate, CWnd* pParentWnd, bool fInputAsGMT, bool bAddDaylightBias) : CScheduleBaseDlg (nIDTemplate, bAddDaylightBias, pParentWnd), m_fInputAsGMT (fInputAsGMT) { Init(); }
CLogOnHoursDlg::CLogOnHoursDlg (CWnd* pParent, bool fInputAsGMT) : CScheduleBaseDlg (CLogOnHoursDlg::IDD, false, pParent), m_fInputAsGMT (fInputAsGMT) { Init(); }
void CLogOnHoursDlg::Init() { //{{AFX_DATA_INIT (CLogOnHoursDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_prgbData21 = NULL;
}
void CLogOnHoursDlg::DoDataExchange (CDataExchange* pDX) { CScheduleBaseDlg::DoDataExchange (pDX); //{{AFX_DATA_MAP(CLogOnHoursDlg)
DDX_Control ( pDX, IDC_BUTTON_ADD_HOURS, m_buttonAdd ); DDX_Control ( pDX, IDC_BUTTON_REMOVE_HOURS, m_buttonRemove ); // NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP (CLogOnHoursDlg, CScheduleBaseDlg) //{{AFX_MSG_MAP(CLogOnHoursDlg)
ON_BN_CLICKED (IDC_BUTTON_ADD_HOURS, OnButtonAddHours) ON_BN_CLICKED (IDC_BUTTON_REMOVE_HOURS, OnButtonRemoveHours) //}}AFX_MSG_MAP
END_MESSAGE_MAP ()
BOOL CLogOnHoursDlg::OnInitDialog () { CScheduleBaseDlg::OnInitDialog ();
// Set up the "on" legend
m_legendOn.Init ( this, IDC_STATIC_LEGEND_ON, &m_schedulematrix, 100);
// Set up the "off" legend
m_legendOff.Init ( this, IDC_STATIC_LEGEND_OFF, &m_schedulematrix, 0);
if ( GetFlags () & SCHED_FLAG_READ_ONLY ) { // Disable the add and remove buttons
m_buttonAdd.EnableWindow (FALSE); m_buttonRemove.EnableWindow (FALSE); }
return TRUE; } // CLogOnHoursDlg::OnInitDialog ()
void CLogOnHoursDlg::OnOK () { if (m_prgbData21 != NULL) { BYTE rgbDataT[CB_LOGON_ARRAY_LENGTH]; GetByteArray (OUT rgbDataT, sizeof (rgbDataT)); ShrinkByteArrayToBitArray (IN rgbDataT, sizeof (rgbDataT), OUT m_prgbData21, CB_SCHEDULE_ARRAY_LENGTH); // Convert back the hours to GMT time.
if ( m_fInputAsGMT ) ConvertLogonHoursToGMT (INOUT m_prgbData21, m_bAddDaylightBias); } CScheduleBaseDlg::OnOK (); }
void CLogOnHoursDlg::UpdateButtons () { UINT nHour = 0; UINT nDay = 0; UINT nNumHours = 0; UINT nNumDays = 0;
m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays); bool fAllSet = false; // fAllSet && fAllClear will be changed to true only if something is selected
bool fAllClear = false;
if (nNumHours > 0) { fAllSet = true; fAllClear = true; for (UINT iDayOfWeek = nDay; iDayOfWeek < nDay+nNumDays; iDayOfWeek++) { for (UINT iHour = nHour; iHour < nHour+nNumHours; iHour++) { if (100 == m_schedulematrix.GetPercentage (iHour, iDayOfWeek)) { fAllClear = false; } else { fAllSet = false; } } // for
} // for
}
ASSERT (! (fAllSet && fAllClear)); // these can't both be true!
m_buttonAdd.SetCheck (fAllSet ? 1 : 0); m_buttonRemove.SetCheck (fAllClear ? 1 : 0); }
void CLogOnHoursDlg::OnButtonAddHours () { 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 (100, nHour, nDay, nNumHours, nNumDays); UpdateButtons (); }
void CLogOnHoursDlg::OnButtonRemoveHours () { 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 (0, nHour, nDay, nNumHours, nNumDays); UpdateButtons (); }
/////////////////////////////////////////////////////////////////////
// SetLogonBitArray ()
//
// Set the bit array representing the logon hours for a user.
//
// The parameter rgbData is used as both an input and output parameter.
//
void CLogOnHoursDlg::SetLogonBitArray (INOUT BYTE rgbData[CB_SCHEDULE_ARRAY_LENGTH]) { // Catch development errors early. The code that dereferences m_prgbData21
// is robust so the check here is not necessary for release build.
ASSERT (rgbData); m_prgbData21 = rgbData; } // SetLogonBitArray ()
/////////////////////////////////////////////////////////////////////
// ShrinkByteArrayToBitArray ()
//
// Convert an array of bytes into an array of bits. Each
// byte will be stored as one bit in the array of bits.
//
// INTERFACE NOTES
// The first bit of the array of bits is the boolean
// value of the first byte of the array of bytes.
//
HRESULT ShrinkByteArrayToBitArray ( const BYTE rgbDataIn[], // IN: Array of bytes
int cbDataIn, // IN: Number of bytes in rgbDataIn
BYTE rgbDataOut[], // OUT: Array of bits (stored as an array of bytes)
int cbDataOut) // IN: Number of bytes in output buffer
{ // NOTICE-NTRAID#NTBUG9-547746-2002/03/12-artm Need to check not NULL in release code.
// Both rbgDataIn and rgbDataOut need to be checked for NULL before using.
// In array must be 8 times the size of out array
ASSERT (cbDataIn == cbDataOut*8); if ( cbDataIn != cbDataOut*8 ) return E_INVALIDARG;
ASSERT (rgbDataIn); ASSERT (rgbDataOut); if ( !rgbDataIn || !rgbDataOut ) return E_POINTER;
// NOTICE-NTRAID#NTBUG9-547718 Size of rgbDataOut verified above.
//
// Use cbDataOut to check that rgbDataOut is CB_SCHEDULE_ARRAY_LENGTH in size. If not
// use a return value to indicate failure.
const BYTE * pbSrc = rgbDataIn; BYTE * pbDst = rgbDataOut; while (cbDataIn > 0 && cbDataOut > 0) { BYTE b = 0; for (int i = 8; i > 0; i--) { // NOTICE-NTRAID#NTBUG-547746-2002/02/18-artm Assert should be supplemented with release code.
//
// The logic in this assert is part of the algorithm, and should be in
// the release code as part of the for loop's conditional check.
// We are guaranteed to never get here as long as the check above for
// "cbDataIn != cbDataOut*8" is in the code. Thus, the below ASSERT() should
// never fire.
ASSERT (cbDataIn > 0); cbDataIn--; b >>= 1;
if ( *pbSrc ) b |= 0x80; // bit 0 is on the right, as in: 7 6 5 4 3 2 1 0
pbSrc++; } *pbDst++ = b; cbDataOut--; } // while
return S_OK; } // ShrinkByteArrayToBitArray ()
/////////////////////////////////////////////////////////////////////
HRESULT ExpandBitArrayToByteArray ( const BYTE rgbDataIn[], // IN: Array of bits (stored as an array of bytes)
int cbDataIn, // IN: Number of bytes in rgbDataIn
BYTE rgbDataOut[], // OUT: Array of bytes
int cbDataOut) // IN: Number of bytes in output buffer
{ // NOTICE-NTRAID#NTBUG9-547746-2002/03/12-artm Need to check not NULL in release code.
// Both rbgDataIn and rgbDataOut need to be checked for NULL before using.
// Out array must be 8 times the size of in array
ASSERT (cbDataOut == cbDataIn*8); if ( cbDataOut != cbDataIn*8 ) return E_INVALIDARG; ASSERT (rgbDataIn); ASSERT (rgbDataOut); if ( !rgbDataIn || !rgbDataOut ) return E_POINTER;
// NOTICE-NTRAID#NTBUG9-547718 Size of rgbDataOut verified.
//
// Use cbDataOut to check that rgbDataOut is large enough.
const BYTE * pbSrc = rgbDataIn; BYTE * pbDst = rgbDataOut; while (cbDataIn > 0) { // NOTICE-NTRAID#NTBUG-547746-2002/02/18-artm Assert should be supplemented with release code.
//
// The logic in this assert is part of the algorithm, and should be in
// the release code as part of the for loop's conditional check.
ASSERT (cbDataIn > 0); cbDataIn--; BYTE b = *pbSrc; pbSrc++; for (int i = 8; i > 0 && cbDataOut > 0; i--, cbDataOut--) { *pbDst = (BYTE) ((b & 0x01) ? 1 : 0); // bit 0 is on the right of each bit
pbDst++; b >>= 1; } } // while
return S_OK; } // ExpandBitArrayToByteArray ()
/////////////////////////////////////////////////////////////////////
// Converts the logon hours from local time to GMT.
void ConvertLogonHoursToGMT ( INOUT BYTE rgbData[CB_SCHEDULE_ARRAY_LENGTH], IN bool bAddDaylightBias) { VERIFY ( ::NetpRotateLogonHours (rgbData, CB_SCHEDULE_ARRAY_LENGTH * 8, TRUE, bAddDaylightBias) ); }
/////////////////////////////////////////////////////////////////////
// Converts the logon hours from GMT to local time.
void ConvertLogonHoursFromGMT ( INOUT BYTE rgbData[CB_SCHEDULE_ARRAY_LENGTH], IN bool bAddDaylightBias) { VERIFY ( ::NetpRotateLogonHours (rgbData, CB_SCHEDULE_ARRAY_LENGTH * 8, FALSE, bAddDaylightBias) ); }
/////////////////////////////////////////////////////////////////////
// LogonScheduleDialog ()
//
// 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 LogonScheduleDialog( 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 LogonScheduleDialogEx (hwndParent, pprgbData, pszTitle, SCHED_FLAG_INPUT_GMT); }
HRESULT LogonScheduleDialogEx( 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());
// All of these asserts are backed up by validation checks.
ASSERT(::IsWindow(hwndParent)); ASSERT(pprgbData != NULL); // NOTICE-NTRAID#NTBUG9-547381-2002/02/18-artm pszTitle okay to be NULL
// dlg.SetTitle() robustly handles NULL case
ASSERT(pszTitle != NULL); ENDORSE(*pprgbData == NULL); // TRUE => Use default logon hours (7x24)
if (*pprgbData == NULL) { BYTE * pargbData; // Pointer to allocated array of bytes
pargbData = (BYTE *)LocalAlloc(0, CB_SCHEDULE_ARRAY_LENGTH); // Allocate 21 bytes
if (pargbData == NULL) return E_OUTOFMEMORY; // Set the logon hours to be valid 24 hours a day and 7 days a week.
memset(OUT pargbData, -1, CB_SCHEDULE_ARRAY_LENGTH); *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; bool fInputAsGMT = true;
if ( dwFlags & SCHED_FLAG_INPUT_LOCAL_TIME ) fInputAsGMT = false; CLogOnHoursDlg dlg (pWnd, fInputAsGMT); dlg.SetTitle (pszTitle); dlg.SetLogonBitArray(INOUT *pprgbData); dlg.SetFlags (dwFlags); if (IDOK != dlg.DoModal()) hr = S_FALSE;
if ( pWnd ) { pWnd->Detach (); delete pWnd; }
return hr; } // LogonScheduleDialog()
HRESULT DialinHoursDialog ( 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 DialinHoursDialogEx (hwndParent, pprgbData, pszTitle, SCHED_FLAG_INPUT_GMT); }
HRESULT DialinHoursDialogEx ( 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 in release code.
ASSERT(::IsWindow(hwndParent)); ASSERT(pprgbData != NULL); // NOTICE-NTRAID#NTBUG9-547381-2002/02/18-artm pszTitle okay to be NULL
// dlg.SetTitle() robustly handles NULL.
ASSERT(pszTitle != NULL); ENDORSE(*pprgbData == NULL); // TRUE => Use default logon hours (7x24)
if (*pprgbData == NULL) { BYTE * pargbData; // Pointer to allocated array of bytes
pargbData = (BYTE *)LocalAlloc(0, CB_SCHEDULE_ARRAY_LENGTH); // Allocate 21 bytes
if (pargbData == NULL) return E_OUTOFMEMORY; // Set the logon hours to be valid 24 hours a day and 7 days a week.
memset(OUT pargbData, -1, CB_SCHEDULE_ARRAY_LENGTH); *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; bool fInputAsGMT = true;
if ( dwFlags & SCHED_FLAG_INPUT_LOCAL_TIME ) fInputAsGMT = false; CDialinHours dlg (pWnd, fInputAsGMT); dlg.SetTitle (pszTitle); dlg.SetLogonBitArray(INOUT *pprgbData); dlg.SetFlags (dwFlags); if (IDOK != dlg.DoModal()) hr = S_FALSE;
if ( pWnd ) { pWnd->Detach (); delete pWnd; }
return hr; } // DialinHoursDialog()
void CLogOnHoursDlg::InitMatrix() { if ( m_prgbData21 ) { BYTE rgbitData[CB_SCHEDULE_ARRAY_LENGTH]; // Array of logonhours bits
// Make a copy of the logon hours (in case the user click on cancel button)
memcpy (OUT rgbitData, IN m_prgbData21, sizeof (rgbitData)); // Convert the hours from GMT to local hours.
if ( m_fInputAsGMT ) ConvertLogonHoursFromGMT (INOUT rgbitData, m_bAddDaylightBias); BYTE rgbDataT[CB_LOGON_ARRAY_LENGTH]; if ( SUCCEEDED (ExpandBitArrayToByteArray (IN rgbitData, CB_SCHEDULE_ARRAY_LENGTH, OUT rgbDataT, sizeof (rgbDataT))) ) { m_cbArray = sizeof (rgbDataT); } // Initialize the matrix
InitMatrix2 (IN rgbDataT); } }
UINT CLogOnHoursDlg::GetPercentageToSet(const BYTE bData) { ASSERT (TRUE == bData || FALSE == bData); return (TRUE == bData) ? 100 : 0; }
BYTE CLogOnHoursDlg::GetMatrixPercentage(UINT nHour, UINT nDay) { return (BYTE) ((100 == m_schedulematrix.GetPercentage (nHour, nDay)) ? TRUE : FALSE); }
UINT CLogOnHoursDlg::GetExpectedArrayLength() { return CB_LOGON_ARRAY_LENGTH; }
// Called when WM_TIMECHANGE is received
void CLogOnHoursDlg::TimeChange() { m_buttonAdd.EnableWindow (FALSE); m_buttonRemove.EnableWindow (FALSE); }
/////////////////////////////////////////////////////////////////////////////
// CDialinHours dialog
CDialinHours::CDialinHours(CWnd* pParent, bool fInputAsGMT) : CLogOnHoursDlg(CDialinHours::IDD, pParent, fInputAsGMT, false) { //{{AFX_DATA_INIT(CDialinHours)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
BEGIN_MESSAGE_MAP(CDialinHours, CLogOnHoursDlg) //{{AFX_MSG_MAP(CDialinHours)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDialinHours message handlers
/////////////////////////////////////////////////////////////////////////////
// CDirSyncScheduleDlg dialog
CDirSyncScheduleDlg::CDirSyncScheduleDlg(CWnd* pParent /*=NULL*/) : CLogOnHoursDlg(CDirSyncScheduleDlg::IDD, pParent, true, false) { //{{AFX_DATA_INIT(CDirSyncScheduleDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CDirSyncScheduleDlg::DoDataExchange(CDataExchange* pDX) { CLogOnHoursDlg::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDirSyncScheduleDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDirSyncScheduleDlg, CLogOnHoursDlg) //{{AFX_MSG_MAP(CDirSyncScheduleDlg)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CDirSyncScheduleDlg::OnInitDialog() { CLogOnHoursDlg::OnInitDialog();
m_schedulematrix.SetSel (0, 0, 1, 1);
return TRUE; }
/////////////////////////////////////////////////////////////////////////////
// CDirSyncScheduleDlg message handlers
//
// The data is passed in in GMT
//
HRESULT DirSyncScheduleDialog( 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 DirSyncScheduleDialogEx (hwndParent, pprgbData, pszTitle, 0); } // DirSyncScheduleDialog()
HRESULT DirSyncScheduleDialogEx( 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) // IN: Option flags
{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); // These asserts are backed up by validation code in release.
ASSERT(::IsWindow(hwndParent)); ASSERT(pprgbData != NULL); // NOTICE-NTRAID#NTBUG9-547381-2002/02/18-artm pszTitle okay to be NULL
// dlg.SetTitle() robustly handles NULL.
ASSERT(pszTitle != NULL); ENDORSE(*pprgbData == NULL); // TRUE => Use default logon hours (7x24)
if (*pprgbData == NULL) { BYTE * pargbData; // Pointer to allocated array of bytes
pargbData = (BYTE *)LocalAlloc(0, CB_SCHEDULE_ARRAY_LENGTH); // Allocate 21 bytes
if (pargbData == NULL) return E_OUTOFMEMORY; // Set the logon hours to be valid 24 hours a day and 7 days a week.
memset(OUT pargbData, -1, CB_SCHEDULE_ARRAY_LENGTH); *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; CDirSyncScheduleDlg dlg (pWnd); dlg.SetTitle (pszTitle); dlg.SetLogonBitArray(INOUT *pprgbData); dlg.SetFlags (dwFlags); if (IDOK != dlg.DoModal()) hr = S_FALSE;
if ( pWnd ) { pWnd->Detach (); delete pWnd; }
return hr; } // DirSyncScheduleDialogEx()
|