windows-nt/Source/XPSP1/NT/admin/display/loghours/log.cpp
2020-09-26 16:20:57 +08:00

610 lines
16 KiB
C++

//+---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997-2001.
//
// 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 cbLogonArrayLength (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[cbLogonArrayLength];
GetByteArray (OUT rgbDataT);
ShrinkByteArrayToBitArray (IN rgbDataT, sizeof (rgbDataT), OUT m_prgbData21, 21);
// 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[21])
{
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.
//
void
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
{
ASSERT (rgbDataIn);
ASSERT (rgbDataOut);
const BYTE * pbSrc = rgbDataIn;
BYTE * pbDst = rgbDataOut;
while (cbDataIn > 0)
{
BYTE b = 0;
for (int i = 8; i > 0; i--)
{
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;
} // while
} // ShrinkByteArrayToBitArray ()
/////////////////////////////////////////////////////////////////////
void
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
{
ASSERT (rgbDataIn);
ASSERT (rgbDataOut);
const BYTE * pbSrc = rgbDataIn;
BYTE * pbDst = rgbDataOut;
while (cbDataIn > 0)
{
ASSERT (cbDataIn > 0);
cbDataIn--;
BYTE b = *pbSrc;
pbSrc++;
for (int i = 8; i > 0; i--)
{
*pbDst = (BYTE) ((b & 0x01) ? 1 : 0); // bit 0 is on the right of each bit
pbDst++;
b >>= 1;
}
} // while
} // ExpandBitArrayToByteArray ()
/////////////////////////////////////////////////////////////////////
// Converts the logon hours from local time to GMT.
void
ConvertLogonHoursToGMT (INOUT BYTE rgbData[21], IN bool bAddDaylightBias)
{
VERIFY ( ::NetpRotateLogonHours (rgbData, 21 * 8, TRUE, bAddDaylightBias) );
}
/////////////////////////////////////////////////////////////////////
// Converts the logon hours from GMT to local time.
void
ConvertLogonHoursFromGMT (INOUT BYTE rgbData[21], IN bool bAddDaylightBias)
{
VERIFY ( ::NetpRotateLogonHours (rgbData, 21 * 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());
ASSERT(::IsWindow(hwndParent));
ASSERT(pprgbData != 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, 21); // 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, 21);
*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());
ASSERT(::IsWindow(hwndParent));
ASSERT(pprgbData != 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, 21); // 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, 21);
*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[21]; // 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[cbLogonArrayLength];
ExpandBitArrayToByteArray (IN rgbitData, 21, OUT rgbDataT, 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 cbLogonArrayLength;
}
// 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());
ASSERT(::IsWindow(hwndParent));
ASSERT(pprgbData != 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, 21); // 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, 21);
*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()