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.
 
 
 
 
 
 

671 lines
21 KiB

//+---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////
//
// 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()