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.

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