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.

1450 lines
24 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. httppage.cpp
  5. Abstract:
  6. HTTP Headers property page
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "w3scfg.h"
  18. #include "hdrdlg.h"
  19. #include "HTTPPage.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. /* static */
  26. void
  27. CHeader::CrackDisplayString(
  28. IN LPCTSTR lpstrDisplayString,
  29. OUT CString & strHeader,
  30. OUT CString & strValue
  31. )
  32. /*++
  33. Routine Description:
  34. Crack the display string into component formats
  35. Arguments:
  36. LPCTSTR lpstrDisplayString : Input display string
  37. CString & strHeader : Header
  38. CString & strValue : Value
  39. Return Value:
  40. N/A
  41. --*/
  42. {
  43. strHeader = lpstrDisplayString;
  44. strHeader.TrimLeft();
  45. strHeader.TrimRight();
  46. int nColon = strHeader.Find(_T(':'));
  47. if (nColon >= 0)
  48. {
  49. strValue = (lpstrDisplayString + nColon + 1);
  50. strHeader.ReleaseBuffer(nColon);
  51. }
  52. strValue.TrimLeft();
  53. strValue.TrimRight();
  54. }
  55. //
  56. // HTTP Custom Header Property Page
  57. //
  58. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  59. #define MINUTE (60L)
  60. #define HOUR (60L * MINUTE)
  61. #define DAY (24L * HOUR)
  62. #define YEAR (365 * DAY)
  63. #define EXPIRE_IMMEDIATELY ((LONG)(0L))
  64. #define EXPIRE_INFINITE ((LONG)(0xffffffff))
  65. #define EXPIRE_DEFAULT ((LONG)(1L * DAY)) // 1 day
  66. #define DEFAULT_DYN_EXPIRE (10L * DAY)
  67. #define EXPIRE_MIN_NUMBER (1)
  68. #define EXPIRE_MAX_NUMBER (32767)
  69. IMPLEMENT_DYNCREATE(CW3HTTPPage, CInetPropertyPage)
  70. CW3HTTPPage::CW3HTTPPage(
  71. IN CInetPropertySheet * pSheet
  72. )
  73. /*++
  74. Routine Description:
  75. Property page constructor
  76. Arguments:
  77. CInetPropertySheet * pSheet : Sheet data
  78. Return Value:
  79. N/A
  80. --*/
  81. : CInetPropertyPage(CW3HTTPPage::IDD, pSheet),
  82. m_fValuesAdjusted(FALSE),
  83. m_ppropMimeTypes(NULL),
  84. m_tmNow(CTime::GetCurrentTime())
  85. {
  86. #if 0 // Keep Class Wizard happy
  87. //{{AFX_DATA_INIT(CW3HTTPPage)
  88. m_nTimeSelector = -1;
  89. m_nImmediateTemporary = -1;
  90. m_fEnableExpiration = FALSE;
  91. m_nExpiration = 0L;
  92. m_strlCustomHeaders = _T("");
  93. //}}AFX_DATA_INIT
  94. #endif // 0
  95. }
  96. CW3HTTPPage::~CW3HTTPPage()
  97. /*++
  98. Routine Description:
  99. Destructor
  100. Arguments:
  101. N/A
  102. Return Value:
  103. N/A
  104. --*/
  105. {
  106. }
  107. void
  108. CW3HTTPPage::DoDataExchange(
  109. IN CDataExchange * pDX
  110. )
  111. /*++
  112. Routine Description:
  113. Initialise/Store control data
  114. Arguments:
  115. CDataExchange * pDX - DDX/DDV control structure
  116. Return Value:
  117. None
  118. --*/
  119. {
  120. CInetPropertyPage::DoDataExchange(pDX);
  121. //{{AFX_DATA_MAP(CW3HTTPPage)
  122. DDX_Control(pDX, IDC_BUTTON_FILE_TYPES, m_button_FileTypes);
  123. DDX_Radio(pDX, IDC_RADIO_IMMEDIATELY, m_nImmediateTemporary);
  124. DDX_Check(pDX, IDC_CHECK_EXPIRATION, m_fEnableExpiration);
  125. DDX_Control(pDX, IDC_EDIT_EXPIRE, m_edit_Expire);
  126. DDX_Control(pDX, IDC_RADIO_IMMEDIATELY, m_radio_Immediately);
  127. DDX_Control(pDX, IDC_BUTTON_DELETE, m_button_Delete);
  128. DDX_Control(pDX, IDC_BUTTON_EDIT, m_button_Edit);
  129. DDX_Control(pDX, IDC_STATIC_CONTENT_SHOULD, m_static_Contents);
  130. DDX_Control(pDX, IDC_COMBO_TIME, m_combo_Time);
  131. //}}AFX_DATA_MAP
  132. //
  133. // Only store and validate immediate expiration date if immediate
  134. // is selected.
  135. //
  136. if (!pDX->m_bSaveAndValidate || m_nImmediateTemporary == RADIO_EXPIRE)
  137. {
  138. DDX_CBIndex(pDX, IDC_COMBO_TIME, m_nTimeSelector);
  139. DDX_Text(pDX, IDC_EDIT_EXPIRE, m_nExpiration);
  140. DDV_MinMaxLong(pDX, m_nExpiration, EXPIRE_MIN_NUMBER, EXPIRE_MAX_NUMBER);
  141. }
  142. DDX_Control(pDX, IDC_RADIO_TIME, m_radio_Time);
  143. DDX_Control(pDX, IDC_RADIO_ABS_TIME, m_radio_AbsTime);
  144. DDX_Control(pDX, IDC_DTP_ABS_DATE, m_dtpDate);
  145. DDX_Control(pDX, IDC_DTP_ABS_TIME, m_dtpTime);
  146. DDX_Control(pDX, IDC_LIST_HEADERS, m_list_Headers);
  147. if (pDX->m_bSaveAndValidate)
  148. {
  149. StoreTime();
  150. StoreHeaders();
  151. }
  152. }
  153. //
  154. // Message Map
  155. //
  156. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  157. BEGIN_MESSAGE_MAP(CW3HTTPPage, CInetPropertyPage)
  158. //{{AFX_MSG_MAP(CW3HTTPPage)
  159. ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
  160. ON_BN_CLICKED(IDC_BUTTON_DELETE, OnButtonDelete)
  161. ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit)
  162. ON_BN_CLICKED(IDC_BUTTON_FILE_TYPES, OnButtonFileTypes)
  163. ON_BN_CLICKED(IDC_BUTTON_RATINGS_TEMPLATE, OnButtonRatingsTemplate)
  164. ON_BN_CLICKED(IDC_CHECK_EXPIRATION, OnCheckExpiration)
  165. ON_CBN_SELCHANGE(IDC_COMBO_TIME, OnSelchangeComboTime)
  166. ON_LBN_SELCHANGE(IDC_LIST_HEADERS, OnSelchangeListHeaders)
  167. ON_LBN_DBLCLK(IDC_LIST_HEADERS, OnDblclkListHeaders)
  168. ON_BN_CLICKED(IDC_RADIO_IMMEDIATELY, OnRadioImmediately)
  169. ON_BN_CLICKED(IDC_RADIO_TIME, OnRadioTime)
  170. ON_BN_CLICKED(IDC_RADIO_ABS_TIME, OnRadioAbsTime)
  171. ON_WM_DESTROY()
  172. //}}AFX_MSG_MAP
  173. ON_EN_CHANGE(IDC_EDIT_EXPIRE, OnItemChanged)
  174. END_MESSAGE_MAP()
  175. BOOL
  176. AdjustIfEvenMultiple(
  177. IN OUT CILong & ilValue,
  178. IN LONG lMultiple
  179. )
  180. /*++
  181. Routine Description:
  182. Check to see if ilValue is an even multiple of lMultiple.
  183. If so, divide ilValue by lMultiple
  184. Arguments:
  185. CILong & ilValue : Value
  186. LONG lMultiple : Multiple
  187. Return Value:
  188. TRUE if ilValue is an even multiple of lMultiple.
  189. --*/
  190. {
  191. DWORD dw = (DWORD)(LONG)ilValue / (DWORD)lMultiple;
  192. if (dw * (DWORD)lMultiple == (DWORD)(LONG)ilValue)
  193. {
  194. ilValue = (LONG)dw;
  195. return TRUE;
  196. }
  197. return FALSE;
  198. }
  199. BOOL
  200. CW3HTTPPage::CrackExpirationString(
  201. IN CString & strExpiration
  202. )
  203. /*++
  204. Routine Description:
  205. Crack the expiration string into component parts. Using either N or a blank
  206. string to signify "No expiration"
  207. Arguments:
  208. None
  209. Return Value:
  210. return TRUE if the values had to be adjusted because they were out of
  211. range.
  212. --*/
  213. {
  214. strExpiration.TrimLeft();
  215. strExpiration.TrimRight();
  216. BOOL fValueAdjusted = FALSE;
  217. m_fEnableExpiration = !strExpiration.IsEmpty();
  218. LPCTSTR lp = strExpiration;
  219. BOOL fAbs = FALSE;
  220. if (m_fEnableExpiration)
  221. {
  222. switch(*lp)
  223. {
  224. case _T('D'):
  225. case _T('d'):
  226. lp += 2;
  227. while (_istspace(*lp)) ++lp;
  228. CvtStringToLong(lp, &m_dwRelTime);
  229. break;
  230. case _T('S'):
  231. case _T('s'):
  232. lp += 2;
  233. while (_istspace(*lp)) ++lp;
  234. m_dwRelTime = EXPIRE_DEFAULT;
  235. time_t tm;
  236. if (!CvtGMTStringToInternal(lp, &tm))
  237. {
  238. ::AfxMessageBox(IDS_ERR_EXPIRE_RANGE, MB_ICONINFORMATION | MB_OK);
  239. fValueAdjusted = TRUE;
  240. }
  241. m_tm = tm;
  242. fAbs = TRUE;
  243. break;
  244. case _T('N'):
  245. case _T('n'):
  246. m_fEnableExpiration = FALSE;
  247. break;
  248. default:
  249. TRACEEOLID("Expiration string in bogus format");
  250. m_fEnableExpiration = FALSE;
  251. }
  252. }
  253. //
  254. // Set Values:
  255. //
  256. m_nExpiration = (LONG)m_dwRelTime;
  257. m_nImmediateTemporary = fAbs
  258. ? RADIO_EXPIRE_ABS
  259. : (m_nExpiration == EXPIRE_IMMEDIATELY)
  260. ? RADIO_IMMEDIATELY
  261. : RADIO_EXPIRE;
  262. //
  263. // Adjust time
  264. //
  265. if (m_nExpiration == EXPIRE_INFINITE
  266. || m_nExpiration == EXPIRE_IMMEDIATELY)
  267. {
  268. m_nExpiration = EXPIRE_DEFAULT;
  269. }
  270. if (AdjustIfEvenMultiple(m_nExpiration, DAY))
  271. {
  272. m_nTimeSelector = COMBO_DAYS;
  273. }
  274. else if (AdjustIfEvenMultiple(m_nExpiration, HOUR))
  275. {
  276. m_nTimeSelector = COMBO_HOURS;
  277. }
  278. else
  279. {
  280. m_nExpiration /= MINUTE;
  281. m_nExpiration = __max((DWORD)(LONG)m_nExpiration, 1L);
  282. if (m_nExpiration < EXPIRE_MIN_NUMBER ||
  283. m_nExpiration > EXPIRE_MAX_NUMBER)
  284. {
  285. m_nExpiration = (EXPIRE_DEFAULT / MINUTE);
  286. ::AfxMessageBox(IDS_ERR_EXPIRE_RANGE, MB_ICONINFORMATION | MB_OK);
  287. }
  288. m_nTimeSelector = COMBO_MINUTES;
  289. }
  290. return fValueAdjusted;
  291. }
  292. void
  293. CW3HTTPPage::MakeExpirationString(
  294. OUT CString & strExpiration
  295. )
  296. /*++
  297. Routine Description:
  298. Make the expiration string from component parts
  299. Arguments:
  300. None
  301. Return Value:
  302. None
  303. --*/
  304. {
  305. strExpiration.Empty();
  306. DWORD dwExpiration = m_nExpiration;
  307. if (m_fEnableExpiration)
  308. {
  309. switch(m_nImmediateTemporary)
  310. {
  311. case RADIO_IMMEDIATELY:
  312. strExpiration = _T("D, 0");
  313. break;
  314. case RADIO_EXPIRE:
  315. switch(m_nTimeSelector)
  316. {
  317. case COMBO_MINUTES:
  318. dwExpiration *= MINUTE;
  319. break;
  320. case COMBO_HOURS:
  321. dwExpiration *= HOUR;
  322. break;
  323. case COMBO_DAYS:
  324. dwExpiration *= DAY;
  325. break;
  326. default:
  327. ASSERT(FALSE);
  328. }
  329. strExpiration.Format(_T("D, 0x%0x"), dwExpiration);
  330. break;
  331. case RADIO_EXPIRE_ABS:
  332. CvtInternalToGMTString(m_tm.GetTime(), strExpiration);
  333. strExpiration = _T("S, ") + strExpiration;
  334. break;
  335. default:
  336. TRACEEOLID("Unknown expiration format");
  337. ASSERT(FALSE);
  338. return;
  339. }
  340. }
  341. }
  342. /* virtual */
  343. HRESULT
  344. CW3HTTPPage::FetchLoadedValues()
  345. /*++
  346. Routine Description:
  347. Move configuration data from sheet to dialog controls
  348. Arguments:
  349. None
  350. Return Value:
  351. HRESULT
  352. --*/
  353. {
  354. BEGIN_META_DIR_READ(CW3Sheet)
  355. CString m_strExpiration;
  356. FETCH_DIR_DATA_FROM_SHEET(m_strExpiration);
  357. FETCH_DIR_DATA_FROM_SHEET(m_strlCustomHeaders);
  358. //
  359. // Set up some defaults.
  360. //
  361. m_dwRelTime = EXPIRE_DEFAULT;
  362. m_tm = CTime(
  363. m_tmNow.GetYear(),
  364. m_tmNow.GetMonth(),
  365. m_tmNow.GetDay(),
  366. 0, 0, 0 // Midnight
  367. );
  368. m_tm += DEFAULT_DYN_EXPIRE;
  369. m_fValuesAdjusted = CrackExpirationString(m_strExpiration);
  370. END_META_DIR_READ(err)
  371. //
  372. // Fetch the properties from the metabase
  373. //
  374. ASSERT(m_ppropMimeTypes == NULL);
  375. CError err;
  376. m_ppropMimeTypes = new CMimeTypes(
  377. GetServerName(),
  378. g_cszSvc,
  379. QueryInstance(),
  380. QueryParent(),
  381. QueryAlias()
  382. );
  383. if (m_ppropMimeTypes)
  384. {
  385. err = m_ppropMimeTypes->LoadData();
  386. if (err.Succeeded())
  387. {
  388. m_strlMimeTypes = m_ppropMimeTypes->m_strlMimeTypes;
  389. }
  390. }
  391. else
  392. {
  393. err = ERROR_NOT_ENOUGH_MEMORY;
  394. }
  395. return err;
  396. }
  397. void
  398. CW3HTTPPage::StoreTime()
  399. /*++
  400. Routine Description:
  401. Built datetime by combining current date with the time from the time
  402. controls.
  403. Arguments:
  404. None
  405. Return Value:
  406. None
  407. --*/
  408. {
  409. SYSTEMTIME tmDate, tmTime;
  410. m_dtpDate.GetSystemTime(&tmDate);
  411. m_dtpTime.GetSystemTime(&tmTime);
  412. m_tm = CTime(
  413. tmDate.wYear,
  414. tmDate.wMonth,
  415. tmDate.wDay,
  416. tmTime.wHour,
  417. tmTime.wMinute,
  418. tmTime.wSecond
  419. );
  420. }
  421. void
  422. CW3HTTPPage::SetTimeFields()
  423. /*++
  424. Routine Description:
  425. Set time fields from CTime structure
  426. Arguments:
  427. None
  428. Return Value:
  429. None
  430. --*/
  431. {
  432. SYSTEMTIME stm =
  433. {
  434. (WORD)m_tm.GetYear(),
  435. (WORD)m_tm.GetMonth(),
  436. (WORD)m_tm.GetDayOfWeek(),
  437. (WORD)m_tm.GetDay(),
  438. (WORD)m_tm.GetHour(),
  439. (WORD)m_tm.GetMinute(),
  440. (WORD)m_tm.GetSecond(),
  441. 0 // Milliseconds
  442. };
  443. m_dtpDate.SetSystemTime(&stm);
  444. m_dtpTime.SetSystemTime(&stm);
  445. }
  446. void
  447. CW3HTTPPage::FillListBox()
  448. /*++
  449. Routine Description:
  450. Fill the custom headers listbox with the custom headers entries
  451. Arguments:
  452. None
  453. Return Value:
  454. None
  455. --*/
  456. {
  457. CObListIter obli(m_oblHeaders);
  458. CHeader * pHeader;
  459. //
  460. // Remember the selection.
  461. //
  462. int nCurSel = m_list_Headers.GetCurSel();
  463. m_list_Headers.SetRedraw(FALSE);
  464. m_list_Headers.ResetContent();
  465. int cItems = 0 ;
  466. CString strCustom;
  467. for ( /**/ ; pHeader = (CHeader *)obli.Next() ; cItems++ )
  468. {
  469. m_list_Headers.AddString(pHeader->DisplayString(strCustom));
  470. }
  471. m_list_Headers.SetRedraw(TRUE);
  472. m_list_Headers.SetCurSel(nCurSel);
  473. }
  474. BOOL
  475. CW3HTTPPage::SetControlStates()
  476. /*++
  477. Routine Description:
  478. Set the control enabled/disabled states depending on the state of the
  479. dialog
  480. Arguments:
  481. None
  482. Return Value:
  483. TRUE if an item was selected in the headers listbox, FALSE otherwise.
  484. --*/
  485. {
  486. BOOL fSingleSelection = m_list_Headers.GetSelCount() == 1;
  487. m_button_Edit.EnableWindow(fSingleSelection);
  488. m_button_Delete.EnableWindow(m_list_Headers.GetSelCount() > 0);
  489. BOOL fExpire = (m_nImmediateTemporary == RADIO_EXPIRE);
  490. BOOL fExpireAbs = (m_nImmediateTemporary == RADIO_EXPIRE_ABS);
  491. m_static_Contents.EnableWindow(m_fEnableExpiration);
  492. m_radio_Immediately.EnableWindow(m_fEnableExpiration);
  493. m_radio_Time.EnableWindow(m_fEnableExpiration);
  494. m_radio_AbsTime.EnableWindow(m_fEnableExpiration);
  495. m_edit_Expire.EnableWindow(m_fEnableExpiration && fExpire);
  496. m_combo_Time.EnableWindow(m_fEnableExpiration && fExpire);
  497. m_dtpDate.EnableWindow(m_fEnableExpiration && fExpireAbs);
  498. m_dtpTime.EnableWindow(m_fEnableExpiration && fExpireAbs);
  499. return fSingleSelection;
  500. }
  501. void
  502. CW3HTTPPage::FetchHeaders()
  503. /*++
  504. Routine Description:
  505. Build custom headers oblist
  506. Arguments:
  507. None
  508. Return Value:
  509. None
  510. --*/
  511. {
  512. POSITION pos = m_strlCustomHeaders.GetHeadPosition();
  513. while(pos)
  514. {
  515. CString & str = m_strlCustomHeaders.GetNext(pos);
  516. m_oblHeaders.AddTail(new CHeader(str));
  517. }
  518. }
  519. BOOL
  520. CW3HTTPPage::HeaderExists(
  521. IN LPCTSTR lpHeader
  522. )
  523. /*++
  524. Routine Description:
  525. Check to see if a given header exists in the list
  526. Arguments:
  527. LPCTSTR strHeader : Header name
  528. Return Value:
  529. TRUE if the entry exists, FALSE otherwise.
  530. --*/
  531. {
  532. POSITION pos = m_oblHeaders.GetHeadPosition();
  533. while(pos)
  534. {
  535. CHeader * pHeader = (CHeader *)m_oblHeaders.GetNext(pos);
  536. ASSERT(pHeader);
  537. if (!pHeader->GetHeader().CompareNoCase(lpHeader))
  538. {
  539. return TRUE;
  540. }
  541. }
  542. return FALSE;
  543. }
  544. void
  545. CW3HTTPPage::StoreHeaders()
  546. /*++
  547. Routine Description:
  548. Convert the headers oblist to a stringlist
  549. Arguments:
  550. None
  551. Return Value:
  552. None
  553. --*/
  554. {
  555. m_strlCustomHeaders.RemoveAll();
  556. POSITION pos = m_oblHeaders.GetHeadPosition();
  557. while(pos)
  558. {
  559. CHeader * pHdr = (CHeader *)m_oblHeaders.GetNext(pos);
  560. ASSERT(pHdr != NULL);
  561. CString str;
  562. pHdr->DisplayString(str);
  563. m_strlCustomHeaders.AddTail(str);
  564. }
  565. }
  566. INT_PTR
  567. CW3HTTPPage::ShowPropertiesDialog(
  568. IN BOOL fAdd
  569. )
  570. /*++
  571. Routine Description:
  572. Bring up the dialog used for add or edit.
  573. return the value returned by the dialog
  574. Arguments:
  575. None
  576. Return Value:
  577. Return value of the dialog (IDOK or IDCANCEL)
  578. --*/
  579. {
  580. //
  581. // Bring up the dialog
  582. //
  583. CHeader * pHeader = NULL;
  584. LPCTSTR lpstrHeader = NULL;
  585. LPCTSTR lpstrValue = NULL;
  586. int nCurSel = LB_ERR;
  587. INT_PTR nReturn;
  588. if (!fAdd)
  589. {
  590. nCurSel = m_list_Headers.GetCurSel();
  591. ASSERT(nCurSel != LB_ERR);
  592. pHeader = (CHeader *)m_oblHeaders.GetAt(m_oblHeaders.FindIndex(nCurSel));
  593. ASSERT(pHeader != NULL);
  594. lpstrHeader = pHeader->QueryHeader();
  595. lpstrValue = pHeader->QueryValue();
  596. }
  597. CHeaderDlg dlg(lpstrHeader, lpstrValue, this);
  598. nReturn = dlg.DoModal();
  599. if (nReturn == IDOK)
  600. {
  601. CString strEntry;
  602. if (fAdd)
  603. {
  604. if (HeaderExists(dlg.GetHeader()))
  605. {
  606. ::AfxMessageBox(IDS_ERR_DUP_HEADER);
  607. return IDCANCEL;
  608. }
  609. pHeader = new CHeader(dlg.GetHeader(), dlg.GetValue());
  610. m_oblHeaders.AddTail(pHeader);
  611. m_list_Headers.SetCurSel(m_list_Headers.AddString(
  612. pHeader->DisplayString(strEntry))
  613. );
  614. }
  615. else
  616. {
  617. pHeader->SetHeader(dlg.GetHeader());
  618. pHeader->SetValue(dlg.GetValue());
  619. m_list_Headers.DeleteString(nCurSel);
  620. m_list_Headers.InsertString(
  621. nCurSel,
  622. pHeader->DisplayString(strEntry)
  623. );
  624. m_list_Headers.SetCurSel(nCurSel);
  625. }
  626. }
  627. return nReturn;
  628. }
  629. //
  630. // Message Handlers
  631. //
  632. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  633. void
  634. CW3HTTPPage::OnItemChanged()
  635. /*++
  636. Routine Description:
  637. All EN_CHANGE messages map to this function
  638. Arguments:
  639. None
  640. Return Value:
  641. None
  642. --*/
  643. {
  644. SetModified(TRUE);
  645. }
  646. void
  647. CW3HTTPPage::OnButtonAdd()
  648. /*++
  649. Routine Description:
  650. 'add' button handler
  651. Arguments:
  652. None
  653. Return Value:
  654. None
  655. --*/
  656. {
  657. if (ShowPropertiesDialog(TRUE) == IDOK)
  658. {
  659. SetControlStates();
  660. OnItemChanged();
  661. }
  662. }
  663. void
  664. CW3HTTPPage::OnButtonDelete()
  665. /*++
  666. Routine Description:
  667. 'delete' button handler
  668. Arguments:
  669. None
  670. Return Value:
  671. None
  672. --*/
  673. {
  674. int nCurSel = m_list_Headers.GetCurSel();
  675. int nSel = 0;
  676. int cChanges = 0;
  677. while (nSel < m_list_Headers.GetCount())
  678. {
  679. if (m_list_Headers.GetSel(nSel))
  680. {
  681. m_oblHeaders.RemoveIndex(nSel);
  682. m_list_Headers.DeleteString(nSel);
  683. ++cChanges;
  684. continue;
  685. }
  686. ++nSel;
  687. }
  688. if (cChanges)
  689. {
  690. m_list_Headers.SetCurSel(nCurSel);
  691. if (!SetControlStates())
  692. {
  693. //
  694. // Delete button will be disabled, move focus elsewhere
  695. //
  696. GetDlgItem(IDC_BUTTON_ADD)->SetFocus();
  697. }
  698. OnItemChanged();
  699. }
  700. }
  701. void
  702. CW3HTTPPage::OnButtonEdit()
  703. /*++
  704. Routine Description:
  705. 'edit' button handler
  706. Arguments:
  707. None
  708. Return Value:
  709. None
  710. --*/
  711. {
  712. if (ShowPropertiesDialog(FALSE) == IDOK)
  713. {
  714. SetControlStates();
  715. OnItemChanged();
  716. }
  717. }
  718. void
  719. CW3HTTPPage::OnCheckExpiration()
  720. /*++
  721. Routine Description:
  722. 'expiration' checkbox
  723. Arguments:
  724. None
  725. Return Value:
  726. None
  727. --*/
  728. {
  729. m_fEnableExpiration = !m_fEnableExpiration;
  730. SetControlStates();
  731. OnItemChanged();
  732. }
  733. void
  734. CW3HTTPPage::OnSelchangeComboTime()
  735. /*++
  736. Routine Description:
  737. 'selection change' in time combobox handler
  738. Arguments:
  739. None
  740. Return Value:
  741. None
  742. --*/
  743. {
  744. SetControlStates();
  745. OnItemChanged();
  746. }
  747. void
  748. CW3HTTPPage::OnSelchangeListHeaders()
  749. /*++
  750. Routine Description:
  751. 'selection change' in headers listbox handler
  752. Arguments:
  753. None
  754. Return Value:
  755. None
  756. --*/
  757. {
  758. SetControlStates();
  759. }
  760. void
  761. CW3HTTPPage::OnDblclkListHeaders()
  762. /*++
  763. Routine Description:
  764. 'double click' in headers listbox handler
  765. Arguments:
  766. None
  767. Return Value:
  768. None
  769. --*/
  770. {
  771. OnButtonEdit();
  772. }
  773. void
  774. CW3HTTPPage::OnRadioImmediately()
  775. /*++
  776. Routine Description:
  777. 'immediate' radio button handler
  778. Arguments:
  779. None
  780. Return Value:
  781. None
  782. --*/
  783. {
  784. m_nImmediateTemporary = RADIO_IMMEDIATELY;
  785. SetControlStates();
  786. OnItemChanged();
  787. }
  788. void
  789. CW3HTTPPage::OnRadioTime()
  790. /*++
  791. Routine Description:
  792. 'expire' radio button
  793. Arguments:
  794. None
  795. Return Value:
  796. None
  797. --*/
  798. {
  799. m_nImmediateTemporary = RADIO_EXPIRE;
  800. SetControlStates();
  801. OnItemChanged();
  802. }
  803. void
  804. CW3HTTPPage::OnRadioAbsTime()
  805. /*++
  806. Routine Description:
  807. 'absolute expire' radio button
  808. Arguments:
  809. None
  810. Return Value:
  811. None
  812. --*/
  813. {
  814. m_nImmediateTemporary = RADIO_EXPIRE_ABS;
  815. SetControlStates();
  816. OnItemChanged();
  817. }
  818. BOOL
  819. CW3HTTPPage::OnInitDialog()
  820. /*++
  821. Routine Description:
  822. WM_INITDIALOG handler. Initialize the dialog.
  823. Arguments:
  824. None.
  825. Return Value:
  826. TRUE if focus is to be set automatically, FALSE if the focus
  827. is already set.
  828. --*/
  829. {
  830. CInetPropertyPage::OnInitDialog();
  831. m_button_FileTypes.EnableWindow(m_ppropMimeTypes != NULL);
  832. m_list_Headers.Initialize();
  833. //
  834. // Fill combo box with (Minutes, hours, days)
  835. //
  836. for (UINT n = IDS_MINUTES; n <= IDS_DAYS; ++n)
  837. {
  838. CString str;
  839. VERIFY(str.LoadString(n));
  840. m_combo_Time.AddString(str);
  841. }
  842. m_combo_Time.SetCurSel(m_nTimeSelector);
  843. //
  844. // Set the minimum of the date picker to today
  845. // and the maximum to Dec 31, 2035.
  846. //
  847. SYSTEMTIME stmRange[2] =
  848. {
  849. {
  850. (WORD)m_tmNow.GetYear(),
  851. (WORD)m_tmNow.GetMonth(),
  852. (WORD)m_tmNow.GetDayOfWeek(),
  853. (WORD)m_tmNow.GetDay(),
  854. (WORD)m_tmNow.GetHour(),
  855. (WORD)m_tmNow.GetMinute(),
  856. (WORD)m_tmNow.GetSecond(),
  857. 0
  858. },
  859. {
  860. 2035,
  861. 12,
  862. 1, // A Monday as it turns out
  863. 31,
  864. 23,
  865. 59,
  866. 59,
  867. }
  868. };
  869. m_dtpDate.SetRange(GDTR_MIN | GDTR_MAX, stmRange);
  870. //
  871. // Create a hidden ratings OCX, which is activated by a press
  872. // on the ratings button. We never did get our problems with
  873. // mnemonics straightened out so that we could use the ocx
  874. // directly.
  875. //
  876. m_ocx_Ratings.Create(
  877. _T("Rat"),
  878. WS_BORDER,
  879. CRect(0, 0, 0, 0),
  880. this,
  881. IDC_BUTTON_RATINGS
  882. );
  883. SetTimeFields();
  884. FetchHeaders();
  885. FillListBox();
  886. SetControlStates();
  887. m_ocx_Ratings.SetAdminTarget(GetServerName(), QueryMetaPath());
  888. if (m_fValuesAdjusted)
  889. {
  890. //
  891. // One or more input values was adjusted
  892. //
  893. OnItemChanged();
  894. m_fValuesAdjusted = FALSE;
  895. }
  896. return TRUE;
  897. }
  898. HRESULT
  899. CW3HTTPPage::SaveInfo()
  900. /*++
  901. Routine Description:
  902. Save the information on this property page
  903. Arguments:
  904. None
  905. Return Value:
  906. Error return code
  907. --*/
  908. {
  909. ASSERT(IsDirty());
  910. TRACEEOLID("Saving W3 HTTP directory page now...");
  911. CError err;
  912. CString m_strExpiration;
  913. MakeExpirationString(m_strExpiration);
  914. BeginWaitCursor();
  915. BEGIN_META_DIR_WRITE(CW3Sheet)
  916. STORE_DIR_DATA_ON_SHEET(m_strExpiration)
  917. STORE_DIR_DATA_ON_SHEET(m_strlCustomHeaders)
  918. END_META_DIR_WRITE(err)
  919. if (err.Succeeded() && m_ppropMimeTypes)
  920. {
  921. m_ppropMimeTypes->m_strlMimeTypes = m_strlMimeTypes;
  922. err = m_ppropMimeTypes->WriteDirtyProps();
  923. }
  924. EndWaitCursor();
  925. return err;
  926. }
  927. void
  928. CW3HTTPPage::OnButtonFileTypes()
  929. /*++
  930. Routine Description:
  931. 'file types' button handler
  932. Arguments:
  933. None
  934. Return Value:
  935. None
  936. --*/
  937. {
  938. CMimeDlg dlg(m_strlMimeTypes, this);
  939. if (dlg.DoModal() == IDOK)
  940. {
  941. OnItemChanged();
  942. }
  943. }
  944. void
  945. CW3HTTPPage::OnButtonRatingsTemplate()
  946. /*++
  947. Routine Description:
  948. Pass on "ratings" button click to the ocx.
  949. Arguments:
  950. None
  951. Return Value:
  952. None
  953. --*/
  954. {
  955. m_ocx_Ratings.DoClick();
  956. }
  957. void
  958. CW3HTTPPage::OnDestroy()
  959. /*++
  960. Routine Description:
  961. WM_DESTROY handler. Clean up internal data
  962. Arguments:
  963. None
  964. Return Value:
  965. None
  966. --*/
  967. {
  968. CInetPropertyPage::OnDestroy();
  969. SAFE_DELETE(m_ppropMimeTypes);
  970. }
  971. BOOL
  972. CW3HTTPPage::OnNotify(
  973. WPARAM wParam,
  974. LPARAM lParam,
  975. LRESULT * pResult
  976. )
  977. /*++
  978. Routine Description:
  979. Handle notification changes
  980. Arguments:
  981. WPARAM wParam : Control ID
  982. LPARAM lParam : NMHDR *
  983. LRESULT * pResult : Result pointer
  984. Return Value:
  985. TRUE if handled, FALSE if not
  986. --*/
  987. {
  988. //
  989. // Message cracker crashes - so checking this here instead
  990. //
  991. if (wParam == IDC_DTP_ABS_DATE || wParam == IDC_DTP_ABS_TIME)
  992. {
  993. NMHDR * pHdr = (NMHDR *)lParam;
  994. if (pHdr->code == DTN_DATETIMECHANGE)
  995. {
  996. OnItemChanged();
  997. }
  998. }
  999. //
  1000. // Default behaviour -- go to the message map
  1001. //
  1002. return CInetPropertyPage::OnNotify(wParam, lParam, pResult);
  1003. }