Source code of Windows XP (NT5)
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.

609 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. /////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1997-2001.
  6. //
  7. // File: log.cpp
  8. //
  9. // Contents: Definition of CLogOnHoursDlg
  10. // Dialog displaying the weekly logging hours for a particular user.
  11. //
  12. // HISTORY
  13. // 17-Jul-97 t-danm Creation.
  14. /////////////////////////////////////////////////////////////////////
  15. #include "stdafx.h"
  16. #include "resource.h"
  17. #include "Log.h"
  18. #include "resource.h"
  19. #include "log_gmt.h" // NetpRotateLogonHours ()
  20. #define cbLogonArrayLength (7 * 24) // Number of bytes in Logon array
  21. /////////////////////////////////////////////////////////////////////////////
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CLogOnHoursDlg dialog
  24. CLogOnHoursDlg::CLogOnHoursDlg ( UINT nIDTemplate, CWnd* pParentWnd, bool fInputAsGMT, bool bAddDaylightBias)
  25. : CScheduleBaseDlg (nIDTemplate, bAddDaylightBias, pParentWnd),
  26. m_fInputAsGMT (fInputAsGMT)
  27. {
  28. Init();
  29. }
  30. CLogOnHoursDlg::CLogOnHoursDlg (CWnd* pParent, bool fInputAsGMT) :
  31. CScheduleBaseDlg (CLogOnHoursDlg::IDD, false, pParent),
  32. m_fInputAsGMT (fInputAsGMT)
  33. {
  34. Init();
  35. }
  36. void CLogOnHoursDlg::Init()
  37. {
  38. //{{AFX_DATA_INIT (CLogOnHoursDlg)
  39. // NOTE: the ClassWizard will add member initialization here
  40. //}}AFX_DATA_INIT
  41. m_prgbData21 = NULL;
  42. }
  43. void CLogOnHoursDlg::DoDataExchange (CDataExchange* pDX)
  44. {
  45. CScheduleBaseDlg::DoDataExchange (pDX);
  46. //{{AFX_DATA_MAP(CLogOnHoursDlg)
  47. DDX_Control ( pDX, IDC_BUTTON_ADD_HOURS, m_buttonAdd );
  48. DDX_Control ( pDX, IDC_BUTTON_REMOVE_HOURS, m_buttonRemove );
  49. // NOTE: the ClassWizard will add DDX and DDV calls here
  50. //}}AFX_DATA_MAP
  51. }
  52. BEGIN_MESSAGE_MAP (CLogOnHoursDlg, CScheduleBaseDlg)
  53. //{{AFX_MSG_MAP(CLogOnHoursDlg)
  54. ON_BN_CLICKED (IDC_BUTTON_ADD_HOURS, OnButtonAddHours)
  55. ON_BN_CLICKED (IDC_BUTTON_REMOVE_HOURS, OnButtonRemoveHours)
  56. //}}AFX_MSG_MAP
  57. END_MESSAGE_MAP ()
  58. BOOL CLogOnHoursDlg::OnInitDialog ()
  59. {
  60. CScheduleBaseDlg::OnInitDialog ();
  61. // Set up the "on" legend
  62. m_legendOn.Init ( this, IDC_STATIC_LEGEND_ON, &m_schedulematrix, 100);
  63. // Set up the "off" legend
  64. m_legendOff.Init ( this, IDC_STATIC_LEGEND_OFF, &m_schedulematrix, 0);
  65. if ( GetFlags () & SCHED_FLAG_READ_ONLY )
  66. {
  67. // Disable the add and remove buttons
  68. m_buttonAdd.EnableWindow (FALSE);
  69. m_buttonRemove.EnableWindow (FALSE);
  70. }
  71. return TRUE;
  72. } // CLogOnHoursDlg::OnInitDialog ()
  73. void CLogOnHoursDlg::OnOK ()
  74. {
  75. if (m_prgbData21 != NULL)
  76. {
  77. BYTE rgbDataT[cbLogonArrayLength];
  78. GetByteArray (OUT rgbDataT);
  79. ShrinkByteArrayToBitArray (IN rgbDataT, sizeof (rgbDataT), OUT m_prgbData21, 21);
  80. // Convert back the hours to GMT time.
  81. if ( m_fInputAsGMT )
  82. ConvertLogonHoursToGMT (INOUT m_prgbData21, m_bAddDaylightBias);
  83. }
  84. CScheduleBaseDlg::OnOK ();
  85. }
  86. void CLogOnHoursDlg::UpdateButtons ()
  87. {
  88. UINT nHour = 0;
  89. UINT nDay = 0;
  90. UINT nNumHours = 0;
  91. UINT nNumDays = 0;
  92. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  93. bool fAllSet = false; // fAllSet && fAllClear will be changed to true only if something is selected
  94. bool fAllClear = false;
  95. if (nNumHours > 0)
  96. {
  97. fAllSet = true;
  98. fAllClear = true;
  99. for (UINT iDayOfWeek = nDay; iDayOfWeek < nDay+nNumDays; iDayOfWeek++)
  100. {
  101. for (UINT iHour = nHour; iHour < nHour+nNumHours; iHour++)
  102. {
  103. if (100 == m_schedulematrix.GetPercentage (iHour, iDayOfWeek))
  104. {
  105. fAllClear = false;
  106. }
  107. else
  108. {
  109. fAllSet = false;
  110. }
  111. } // for
  112. } // for
  113. }
  114. ASSERT (! (fAllSet && fAllClear)); // these can't both be true!
  115. m_buttonAdd.SetCheck (fAllSet ? 1 : 0);
  116. m_buttonRemove.SetCheck (fAllClear ? 1 : 0);
  117. }
  118. void CLogOnHoursDlg::OnButtonAddHours ()
  119. {
  120. UINT nHour = 0;
  121. UINT nDay = 0;
  122. UINT nNumHours = 0;
  123. UINT nNumDays = 0;
  124. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  125. if (nNumHours <= 0)
  126. return; // Nothing selected
  127. m_schedulematrix.SetPercentage (100, nHour, nDay, nNumHours, nNumDays);
  128. UpdateButtons ();
  129. }
  130. void CLogOnHoursDlg::OnButtonRemoveHours ()
  131. {
  132. UINT nHour = 0;
  133. UINT nDay = 0;
  134. UINT nNumHours = 0;
  135. UINT nNumDays = 0;
  136. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  137. if (nNumHours <= 0)
  138. return; // Nothing selected
  139. m_schedulematrix.SetPercentage (0, nHour, nDay, nNumHours, nNumDays);
  140. UpdateButtons ();
  141. }
  142. /////////////////////////////////////////////////////////////////////
  143. // SetLogonBitArray ()
  144. //
  145. // Set the bit array representing the logon hours for a user.
  146. //
  147. // The parameter rgbData is used as both an input and output parameter.
  148. //
  149. void CLogOnHoursDlg::SetLogonBitArray (INOUT BYTE rgbData[21])
  150. {
  151. ASSERT (rgbData);
  152. m_prgbData21 = rgbData;
  153. } // SetLogonBitArray ()
  154. /////////////////////////////////////////////////////////////////////
  155. // ShrinkByteArrayToBitArray ()
  156. //
  157. // Convert an array of bytes into an array of bits. Each
  158. // byte will be stored as one bit in the array of bits.
  159. //
  160. // INTERFACE NOTES
  161. // The first bit of the array of bits is the boolean
  162. // value of the first byte of the array of bytes.
  163. //
  164. void
  165. ShrinkByteArrayToBitArray (
  166. const BYTE rgbDataIn[], // IN: Array of bytes
  167. int cbDataIn, // IN: Number of bytes in rgbDataIn
  168. BYTE rgbDataOut[], // OUT: Array of bits (stored as an array of bytes)
  169. int /*cbDataOut*/) // IN: Number of bytes in output buffer
  170. {
  171. ASSERT (rgbDataIn);
  172. ASSERT (rgbDataOut);
  173. const BYTE * pbSrc = rgbDataIn;
  174. BYTE * pbDst = rgbDataOut;
  175. while (cbDataIn > 0)
  176. {
  177. BYTE b = 0;
  178. for (int i = 8; i > 0; i--)
  179. {
  180. ASSERT (cbDataIn > 0);
  181. cbDataIn--;
  182. b >>= 1;
  183. if ( *pbSrc )
  184. b |= 0x80; // bit 0 is on the right, as in: 7 6 5 4 3 2 1 0
  185. pbSrc++;
  186. }
  187. *pbDst++ = b;
  188. } // while
  189. } // ShrinkByteArrayToBitArray ()
  190. /////////////////////////////////////////////////////////////////////
  191. void
  192. ExpandBitArrayToByteArray (
  193. const BYTE rgbDataIn[], // IN: Array of bits (stored as an array of bytes)
  194. int cbDataIn, // IN: Number of bytes in rgbDataIn
  195. BYTE rgbDataOut[], // OUT: Array of bytes
  196. int /*cbDataOut*/) // IN: Number of bytes in output buffer
  197. {
  198. ASSERT (rgbDataIn);
  199. ASSERT (rgbDataOut);
  200. const BYTE * pbSrc = rgbDataIn;
  201. BYTE * pbDst = rgbDataOut;
  202. while (cbDataIn > 0)
  203. {
  204. ASSERT (cbDataIn > 0);
  205. cbDataIn--;
  206. BYTE b = *pbSrc;
  207. pbSrc++;
  208. for (int i = 8; i > 0; i--)
  209. {
  210. *pbDst = (BYTE) ((b & 0x01) ? 1 : 0); // bit 0 is on the right of each bit
  211. pbDst++;
  212. b >>= 1;
  213. }
  214. } // while
  215. } // ExpandBitArrayToByteArray ()
  216. /////////////////////////////////////////////////////////////////////
  217. // Converts the logon hours from local time to GMT.
  218. void
  219. ConvertLogonHoursToGMT (INOUT BYTE rgbData[21], IN bool bAddDaylightBias)
  220. {
  221. VERIFY ( ::NetpRotateLogonHours (rgbData, 21 * 8, TRUE, bAddDaylightBias) );
  222. }
  223. /////////////////////////////////////////////////////////////////////
  224. // Converts the logon hours from GMT to local time.
  225. void
  226. ConvertLogonHoursFromGMT (INOUT BYTE rgbData[21], IN bool bAddDaylightBias)
  227. {
  228. VERIFY ( ::NetpRotateLogonHours (rgbData, 21 * 8, FALSE, bAddDaylightBias) );
  229. }
  230. /////////////////////////////////////////////////////////////////////
  231. // LogonScheduleDialog ()
  232. //
  233. // Invoke a dialog to set/modify a schedule, for example
  234. // -- the logon hours for a particular user
  235. // -- the schedule for a connection
  236. //
  237. // RETURNS
  238. // Return S_OK if the user clicked on the OK button.
  239. // Return S_FALSE if the user clicked on the Cancel button.
  240. // Return E_OUTOFMEMORY if there is not enough memory.
  241. /// Return E_UNEXPECTED if an expected error occured (eg: bad parameter)
  242. //
  243. // INTERFACE NOTES
  244. // Each bit in the array represents one hour. As a result, the
  245. // expected length of the array should be (24 / 8) * 7 = 21 bytes.
  246. // For convenience, the first day of the week is Sunday and
  247. // the last day is Saturday.
  248. // Consequently, the first bit of the array represents the schedule
  249. // for Sunday during period 12 AM to 1 AM.
  250. // - If *pprgbData is NULL, then the routine will allocate
  251. // an array of 21 bytes using LocalAlloc (). The caller
  252. // is responsible of releasing the memory using LocalFree ().
  253. // - If *pprgbData is not NULL, the routine re-use the array as its
  254. // output parameter.
  255. //
  256. // HISTORY
  257. // 17-Jul-97 t-danm Creation.
  258. // 16-Sep-97 jonn Changed to UiScheduleDialog
  259. //
  260. HRESULT
  261. LogonScheduleDialog(
  262. HWND hwndParent, // IN: Parent's window handle
  263. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  264. LPCTSTR pszTitle) // IN: Dialog title
  265. {
  266. return LogonScheduleDialogEx (hwndParent, pprgbData, pszTitle, SCHED_FLAG_INPUT_GMT);
  267. }
  268. HRESULT
  269. LogonScheduleDialogEx(
  270. HWND hwndParent, // IN: Parent's window handle
  271. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  272. LPCTSTR pszTitle, // IN: Dialog title
  273. DWORD dwFlags)
  274. {
  275. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  276. ASSERT(::IsWindow(hwndParent));
  277. ASSERT(pprgbData != NULL);
  278. ASSERT(pszTitle != NULL);
  279. ENDORSE(*pprgbData == NULL); // TRUE => Use default logon hours (7x24)
  280. if (*pprgbData == NULL)
  281. {
  282. BYTE * pargbData; // Pointer to allocated array of bytes
  283. pargbData = (BYTE *)LocalAlloc(0, 21); // Allocate 21 bytes
  284. if (pargbData == NULL)
  285. return E_OUTOFMEMORY;
  286. // Set the logon hours to be valid 24 hours a day and 7 days a week.
  287. memset(OUT pargbData, -1, 21);
  288. *pprgbData = pargbData;
  289. }
  290. // If hwndParent passed in, create a CWnd to pass as the parent window
  291. CWnd* pWnd = 0;
  292. if ( ::IsWindow (hwndParent) )
  293. {
  294. pWnd = new CWnd;
  295. if ( pWnd )
  296. {
  297. pWnd->Attach (hwndParent);
  298. }
  299. else
  300. return E_OUTOFMEMORY;
  301. }
  302. HRESULT hr = S_OK;
  303. bool fInputAsGMT = true;
  304. if ( dwFlags & SCHED_FLAG_INPUT_LOCAL_TIME )
  305. fInputAsGMT = false;
  306. CLogOnHoursDlg dlg (pWnd, fInputAsGMT);
  307. dlg.SetTitle (pszTitle);
  308. dlg.SetLogonBitArray(INOUT *pprgbData);
  309. dlg.SetFlags (dwFlags);
  310. if (IDOK != dlg.DoModal())
  311. hr = S_FALSE;
  312. if ( pWnd )
  313. {
  314. pWnd->Detach ();
  315. delete pWnd;
  316. }
  317. return hr;
  318. } // LogonScheduleDialog()
  319. HRESULT
  320. DialinHoursDialog (
  321. HWND hwndParent, // IN: Parent's window handle
  322. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  323. LPCTSTR pszTitle) // IN: Dialog title
  324. {
  325. return DialinHoursDialogEx (hwndParent, pprgbData, pszTitle, SCHED_FLAG_INPUT_GMT);
  326. }
  327. HRESULT
  328. DialinHoursDialogEx (
  329. HWND hwndParent, // IN: Parent's window handle
  330. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  331. LPCTSTR pszTitle, // IN: Dialog title
  332. DWORD dwFlags)
  333. {
  334. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  335. ASSERT(::IsWindow(hwndParent));
  336. ASSERT(pprgbData != NULL);
  337. ASSERT(pszTitle != NULL);
  338. ENDORSE(*pprgbData == NULL); // TRUE => Use default logon hours (7x24)
  339. if (*pprgbData == NULL)
  340. {
  341. BYTE * pargbData; // Pointer to allocated array of bytes
  342. pargbData = (BYTE *)LocalAlloc(0, 21); // Allocate 21 bytes
  343. if (pargbData == NULL)
  344. return E_OUTOFMEMORY;
  345. // Set the logon hours to be valid 24 hours a day and 7 days a week.
  346. memset(OUT pargbData, -1, 21);
  347. *pprgbData = pargbData;
  348. }
  349. // If hwndParent passed in, create a CWnd to pass as the parent window
  350. CWnd* pWnd = 0;
  351. if ( ::IsWindow (hwndParent) )
  352. {
  353. pWnd = new CWnd;
  354. if ( pWnd )
  355. {
  356. pWnd->Attach (hwndParent);
  357. }
  358. else
  359. return E_OUTOFMEMORY;
  360. }
  361. HRESULT hr = S_OK;
  362. bool fInputAsGMT = true;
  363. if ( dwFlags & SCHED_FLAG_INPUT_LOCAL_TIME )
  364. fInputAsGMT = false;
  365. CDialinHours dlg (pWnd, fInputAsGMT);
  366. dlg.SetTitle (pszTitle);
  367. dlg.SetLogonBitArray(INOUT *pprgbData);
  368. dlg.SetFlags (dwFlags);
  369. if (IDOK != dlg.DoModal())
  370. hr = S_FALSE;
  371. if ( pWnd )
  372. {
  373. pWnd->Detach ();
  374. delete pWnd;
  375. }
  376. return hr;
  377. } // DialinHoursDialog()
  378. void CLogOnHoursDlg::InitMatrix()
  379. {
  380. if ( m_prgbData21 )
  381. {
  382. BYTE rgbitData[21]; // Array of logonhours bits
  383. // Make a copy of the logon hours (in case the user click on cancel button)
  384. memcpy (OUT rgbitData, IN m_prgbData21, sizeof (rgbitData));
  385. // Convert the hours from GMT to local hours.
  386. if ( m_fInputAsGMT )
  387. ConvertLogonHoursFromGMT (INOUT rgbitData, m_bAddDaylightBias);
  388. BYTE rgbDataT[cbLogonArrayLength];
  389. ExpandBitArrayToByteArray (IN rgbitData, 21, OUT rgbDataT, sizeof (rgbDataT));
  390. // Initialize the matrix
  391. InitMatrix2 (IN rgbDataT);
  392. }
  393. }
  394. UINT CLogOnHoursDlg::GetPercentageToSet(const BYTE bData)
  395. {
  396. ASSERT (TRUE == bData || FALSE == bData);
  397. return (TRUE == bData) ? 100 : 0;
  398. }
  399. BYTE CLogOnHoursDlg::GetMatrixPercentage(UINT nHour, UINT nDay)
  400. {
  401. return (BYTE) ((100 == m_schedulematrix.GetPercentage (nHour, nDay)) ?
  402. TRUE : FALSE);
  403. }
  404. UINT CLogOnHoursDlg::GetExpectedArrayLength()
  405. {
  406. return cbLogonArrayLength;
  407. }
  408. // Called when WM_TIMECHANGE is received
  409. void CLogOnHoursDlg::TimeChange()
  410. {
  411. m_buttonAdd.EnableWindow (FALSE);
  412. m_buttonRemove.EnableWindow (FALSE);
  413. }
  414. /////////////////////////////////////////////////////////////////////////////
  415. // CDialinHours dialog
  416. CDialinHours::CDialinHours(CWnd* pParent, bool fInputAsGMT)
  417. : CLogOnHoursDlg(CDialinHours::IDD, pParent, fInputAsGMT, false)
  418. {
  419. //{{AFX_DATA_INIT(CDialinHours)
  420. // NOTE: the ClassWizard will add member initialization here
  421. //}}AFX_DATA_INIT
  422. }
  423. BEGIN_MESSAGE_MAP(CDialinHours, CLogOnHoursDlg)
  424. //{{AFX_MSG_MAP(CDialinHours)
  425. // NOTE: the ClassWizard will add message map macros here
  426. //}}AFX_MSG_MAP
  427. END_MESSAGE_MAP()
  428. /////////////////////////////////////////////////////////////////////////////
  429. // CDialinHours message handlers
  430. /////////////////////////////////////////////////////////////////////////////
  431. // CDirSyncScheduleDlg dialog
  432. CDirSyncScheduleDlg::CDirSyncScheduleDlg(CWnd* pParent /*=NULL*/)
  433. : CLogOnHoursDlg(CDirSyncScheduleDlg::IDD, pParent, true, false)
  434. {
  435. //{{AFX_DATA_INIT(CDirSyncScheduleDlg)
  436. // NOTE: the ClassWizard will add member initialization here
  437. //}}AFX_DATA_INIT
  438. }
  439. void CDirSyncScheduleDlg::DoDataExchange(CDataExchange* pDX)
  440. {
  441. CLogOnHoursDlg::DoDataExchange(pDX);
  442. //{{AFX_DATA_MAP(CDirSyncScheduleDlg)
  443. // NOTE: the ClassWizard will add DDX and DDV calls here
  444. //}}AFX_DATA_MAP
  445. }
  446. BEGIN_MESSAGE_MAP(CDirSyncScheduleDlg, CLogOnHoursDlg)
  447. //{{AFX_MSG_MAP(CDirSyncScheduleDlg)
  448. // NOTE: the ClassWizard will add message map macros here
  449. //}}AFX_MSG_MAP
  450. END_MESSAGE_MAP()
  451. BOOL CDirSyncScheduleDlg::OnInitDialog()
  452. {
  453. CLogOnHoursDlg::OnInitDialog();
  454. m_schedulematrix.SetSel (0, 0, 1, 1);
  455. return TRUE;
  456. }
  457. /////////////////////////////////////////////////////////////////////////////
  458. // CDirSyncScheduleDlg message handlers
  459. //
  460. // The data is passed in in GMT
  461. //
  462. HRESULT
  463. DirSyncScheduleDialog(
  464. HWND hwndParent, // IN: Parent's window handle
  465. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  466. LPCTSTR pszTitle) // IN: Dialog title
  467. {
  468. return DirSyncScheduleDialogEx (hwndParent, pprgbData, pszTitle, 0);
  469. } // DirSyncScheduleDialog()
  470. HRESULT
  471. DirSyncScheduleDialogEx(
  472. HWND hwndParent, // IN: Parent's window handle
  473. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  474. LPCTSTR pszTitle, // IN: Dialog title
  475. DWORD dwFlags) // IN: Option flags
  476. {
  477. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  478. ASSERT(::IsWindow(hwndParent));
  479. ASSERT(pprgbData != NULL);
  480. ASSERT(pszTitle != NULL);
  481. ENDORSE(*pprgbData == NULL); // TRUE => Use default logon hours (7x24)
  482. if (*pprgbData == NULL)
  483. {
  484. BYTE * pargbData; // Pointer to allocated array of bytes
  485. pargbData = (BYTE *)LocalAlloc(0, 21); // Allocate 21 bytes
  486. if (pargbData == NULL)
  487. return E_OUTOFMEMORY;
  488. // Set the logon hours to be valid 24 hours a day and 7 days a week.
  489. memset(OUT pargbData, -1, 21);
  490. *pprgbData = pargbData;
  491. }
  492. // If hwndParent passed in, create a CWnd to pass as the parent window
  493. CWnd* pWnd = 0;
  494. if ( ::IsWindow (hwndParent) )
  495. {
  496. pWnd = new CWnd;
  497. if ( pWnd )
  498. {
  499. pWnd->Attach (hwndParent);
  500. }
  501. else
  502. return E_OUTOFMEMORY;
  503. }
  504. HRESULT hr = S_OK;
  505. CDirSyncScheduleDlg dlg (pWnd);
  506. dlg.SetTitle (pszTitle);
  507. dlg.SetLogonBitArray(INOUT *pprgbData);
  508. dlg.SetFlags (dwFlags);
  509. if (IDOK != dlg.DoModal())
  510. hr = S_FALSE;
  511. if ( pWnd )
  512. {
  513. pWnd->Detach ();
  514. delete pWnd;
  515. }
  516. return hr;
  517. } // DirSyncScheduleDialogEx()