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.

764 lines
18 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. defws.cpp
  5. Abstract:
  6. Default Web Site Dialog
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. //
  15. // Include Files
  16. //
  17. #include "stdafx.h"
  18. #include "resource.h"
  19. #include "common.h"
  20. #include "inetmgrapp.h"
  21. #include "inetprop.h"
  22. #include "shts.h"
  23. #include "w3sht.h"
  24. #include "defws.h"
  25. //#include "mime.h"
  26. #include "iisobj.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. //
  33. // Directory Size Units
  34. //
  35. #define DS_UNITS MEGABYTE
  36. //
  37. // Default Web Site Property Page
  38. //
  39. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  40. IMPLEMENT_DYNCREATE(CDefWebSitePage, CInetPropertyPage)
  41. CDefWebSitePage::CDefWebSitePage(
  42. CInetPropertySheet * pSheet
  43. )
  44. /*++
  45. Routine Description:
  46. Constructor for WWW Default Web Site page
  47. Arguments:
  48. CInetPropertySheet * pSheet : Sheet object
  49. Return Value:
  50. N/A
  51. --*/
  52. : CInetPropertyPage(CDefWebSitePage::IDD, pSheet),
  53. m_ppropCompression(NULL),
  54. m_fFilterPathFound(FALSE),
  55. m_fCompressionDirectoryChanged(FALSE),
  56. m_fCompatMode(FALSE)
  57. {
  58. #if 0 // Keep Class Wizard happy
  59. //{{AFX_DATA_INIT(CDefWebSitePage)
  60. m_fEnableDynamic = FALSE;
  61. m_fEnableStatic = FALSE;
  62. m_fCompatMode = FALSE;
  63. m_strDirectory = _T("");
  64. m_nUnlimited = -1;
  65. m_ilSize = 0L;
  66. //}}AFX_DATA_INIT
  67. #endif // 0
  68. m_fInitCompatMode = m_fCompatMode;
  69. }
  70. CDefWebSitePage::~CDefWebSitePage()
  71. {
  72. }
  73. void
  74. CDefWebSitePage::DoDataExchange(
  75. IN CDataExchange * pDX
  76. )
  77. {
  78. CInetPropertyPage::DoDataExchange(pDX);
  79. //{{AFX_DATA_MAP(CDefWebSitePage)
  80. DDX_Control(pDX, IDC_EDIT_COMPRESS_DIRECTORY, m_edit_Directory);
  81. DDX_Control(pDX, IDC_BUTTON_BROWSE, m_button_Browse);
  82. DDX_Control(pDX, IDC_EDIT_COMPRESS_DIRECTORY_SIZE, m_edit_DirectorySize);
  83. DDX_Check(pDX, IDC_CHECK_DYNAMIC_COMPRESSION, m_fEnableDynamic);
  84. DDX_Check(pDX, IDC_CHECK_STATIC_COMPRESSION, m_fEnableStatic);
  85. DDX_Check(pDX, IDC_COMPAT_MODE, m_fCompatMode);
  86. DDX_Radio(pDX, IDC_RADIO_COMPRESS_UNLIMITED, m_nUnlimited);
  87. //}}AFX_DATA_MAP
  88. if (HasCompression())
  89. {
  90. if (!pDX->m_bSaveAndValidate || m_fEnableStatic)
  91. {
  92. DDX_Text(pDX, IDC_EDIT_COMPRESS_DIRECTORY, m_strDirectory);
  93. DDV_MaxCharsBalloon(pDX, m_strDirectory, _MAX_PATH);
  94. }
  95. if (pDX->m_bSaveAndValidate && m_fEnableStatic)
  96. {
  97. TCHAR buf[MAX_PATH];
  98. CString csPathMunged;
  99. DDX_Text(pDX, IDC_EDIT_COMPRESS_DIRECTORY, m_strDirectory);
  100. DDV_MaxCharsBalloon(pDX, m_strDirectory, _MAX_PATH);
  101. ExpandEnvironmentStrings(m_strDirectory, buf, MAX_PATH);
  102. csPathMunged = buf;
  103. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  104. GetSpecialPathRealPath(0,buf,csPathMunged);
  105. #endif
  106. if (!PathIsValid(csPathMunged,FALSE) || !IsFullyQualifiedPath(csPathMunged))
  107. {
  108. DDV_ShowBalloonAndFail(pDX, IDS_ERR_INVALID_PATH);
  109. }
  110. //
  111. // Perform some additional smart checking on the compression
  112. // directory if the current machine is local, and the
  113. // directory has changed
  114. //
  115. if (IsLocal() && m_fCompressionDirectoryChanged)
  116. {
  117. //
  118. // Should exist on the local machine.
  119. //
  120. DWORD dwAttr = GetFileAttributes(csPathMunged);
  121. if (dwAttr == 0xffffffff
  122. || (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0
  123. || IsNetworkPath(csPathMunged)
  124. )
  125. {
  126. DDV_ShowBalloonAndFail(pDX, IDS_ERR_COMPRESS_DIRECTORY);
  127. }
  128. //
  129. // Now check to make sure the volume is of the correct
  130. // type.
  131. //
  132. DWORD dwFileSystemFlags;
  133. if (::GetVolumeInformationSystemFlags(csPathMunged, &dwFileSystemFlags))
  134. {
  135. if (!(dwFileSystemFlags & FS_PERSISTENT_ACLS))
  136. {
  137. //
  138. // No ACLS
  139. //
  140. if (!NoYesMessageBox(IDS_NO_ACL_WARNING))
  141. {
  142. pDX->Fail();
  143. }
  144. }
  145. if (dwFileSystemFlags & FS_VOL_IS_COMPRESSED
  146. || dwAttr & FILE_ATTRIBUTE_COMPRESSED)
  147. {
  148. //
  149. // Compression cache directory is itself compressed
  150. //
  151. if (!NoYesMessageBox(IDS_COMPRESS_WARNING))
  152. {
  153. pDX->Fail();
  154. }
  155. }
  156. }
  157. }
  158. }
  159. if (!pDX->m_bSaveAndValidate || (m_fEnableLimiting && m_fEnableStatic))
  160. {
  161. // This Needs to come before DDX_Text which will try to put text big number into small number
  162. DDV_MinMaxBalloon(pDX, IDC_EDIT_COMPRESS_DIRECTORY_SIZE, 1, 1024L);
  163. DDX_Text(pDX, IDC_EDIT_COMPRESS_DIRECTORY_SIZE, m_ilSize);
  164. }
  165. }
  166. }
  167. //
  168. // Message Map
  169. //
  170. BEGIN_MESSAGE_MAP(CDefWebSitePage, CInetPropertyPage)
  171. //{{AFX_MSG_MAP(CDefWebSitePage)
  172. ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnButtonBrowse)
  173. ON_BN_CLICKED(IDC_RADIO_COMPRESS_LIMITED, OnRadioLimited)
  174. ON_BN_CLICKED(IDC_RADIO_COMPRESS_UNLIMITED, OnRadioUnlimited)
  175. ON_BN_CLICKED(IDC_CHECK_DYNAMIC_COMPRESSION, OnCheckDynamicCompression)
  176. ON_BN_CLICKED(IDC_CHECK_STATIC_COMPRESSION, OnCheckStaticCompression)
  177. ON_BN_CLICKED(IDC_COMPAT_MODE, OnCheckCompatMode)
  178. ON_EN_CHANGE(IDC_EDIT_COMPRESS_DIRECTORY, OnChangeEditCompressDirectory)
  179. ON_WM_DESTROY()
  180. //}}AFX_MSG_MAP
  181. ON_EN_CHANGE(IDC_EDIT_COMPRESS_DIRECTORY, OnItemChanged)
  182. ON_EN_CHANGE(IDC_EDIT_COMPRESS_DIRECTORY_SIZE, OnItemChanged)
  183. END_MESSAGE_MAP()
  184. void
  185. CDefWebSitePage::SetControlStates()
  186. /*++
  187. Routine Description:
  188. Enable/disable control states depending on the state of
  189. the dialog.
  190. Arguments:
  191. None
  192. Return Value:
  193. None
  194. --*/
  195. {
  196. GetDlgItem(IDC_STATIC_COMPRESS_DIRECTORY)->EnableWindow(m_fEnableStatic);
  197. m_edit_Directory.EnableWindow(m_fEnableStatic);
  198. m_edit_DirectorySize.EnableWindow(m_fEnableStatic && m_fEnableLimiting);
  199. GetDlgItem(IDC_RADIO_COMPRESS_LIMITED)->EnableWindow(m_fEnableStatic);
  200. GetDlgItem(IDC_RADIO_COMPRESS_UNLIMITED)->EnableWindow(m_fEnableStatic);
  201. GetDlgItem(IDC_STATIC_MAX_COMPRESS_SIZE)->EnableWindow(m_fEnableStatic);
  202. //
  203. // Browse on the local machine only
  204. //
  205. m_button_Browse.EnableWindow(IsLocal() && m_fEnableStatic);
  206. }
  207. /* virtual */
  208. HRESULT
  209. CDefWebSitePage::FetchLoadedValues()
  210. /*++
  211. Routine Description:
  212. Move configuration data from sheet to dialog controls
  213. Arguments:
  214. None
  215. Return Value:
  216. HRESULT
  217. --*/
  218. {
  219. CError err;
  220. ASSERT(m_ppropCompression == NULL);
  221. m_ppropCompression = new CIISCompressionProps(QueryAuthInfo());
  222. if (m_ppropCompression)
  223. {
  224. err = m_ppropCompression->LoadData();
  225. m_fFilterPathFound = err.Succeeded();
  226. if (err.Succeeded())
  227. {
  228. m_fEnableDynamic = m_ppropCompression->m_fEnableDynamicCompression;
  229. m_fEnableStatic = m_ppropCompression->m_fEnableStaticCompression;
  230. m_fEnableLimiting = m_ppropCompression->m_fLimitDirectorySize;
  231. m_strDirectory = m_ppropCompression->m_strDirectory;
  232. m_nUnlimited = m_fEnableLimiting ? RADIO_LIMITED : RADIO_UNLIMITED;
  233. if (m_ppropCompression->m_dwDirectorySize == 0xffffffff)
  234. {
  235. m_ilSize = DEF_MAX_COMPDIR_SIZE / DS_UNITS;
  236. }
  237. else
  238. {
  239. m_ilSize = m_ppropCompression->m_dwDirectorySize / DS_UNITS;
  240. }
  241. }
  242. else if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  243. {
  244. //
  245. // Fail quietly
  246. //
  247. TRACEEOLID("No compression filters installed");
  248. err.Reset();
  249. }
  250. }
  251. else
  252. {
  253. err = ERROR_NOT_ENOUGH_MEMORY;
  254. }
  255. if (err.Succeeded())
  256. {
  257. if (GetSheet()->QueryMajorVersion() >= 6)
  258. {
  259. CMetaKey mk(QueryAuthInfo(), QueryMetaPath(), METADATA_PERMISSION_READ);
  260. err = mk.QueryResult();
  261. if (err.Succeeded())
  262. {
  263. err = mk.QueryValue(MD_GLOBAL_STANDARD_APP_MODE_ENABLED, m_fCompatMode);
  264. if (err.Succeeded())
  265. {
  266. m_fInitCompatMode = m_fCompatMode;
  267. }
  268. }
  269. }
  270. else
  271. {
  272. m_fInitCompatMode = m_fCompatMode = TRUE;
  273. }
  274. }
  275. return err;
  276. }
  277. HRESULT
  278. CDefWebSitePage::SaveInfo()
  279. /*++
  280. Routine Description:
  281. Save the information on this property page
  282. Arguments:
  283. None
  284. Return Value:
  285. Error return code
  286. --*/
  287. {
  288. ASSERT(IsDirty());
  289. TRACEEOLID("Saving W3 default web site page now...");
  290. CError err;
  291. BeginWaitCursor();
  292. if (HasCompression())
  293. {
  294. ASSERT(m_ppropCompression);
  295. DWORD dwSize = m_ilSize * DS_UNITS;
  296. m_ppropCompression->m_fEnableDynamicCompression = m_fEnableDynamic;
  297. m_ppropCompression->m_fEnableStaticCompression = m_fEnableStatic;
  298. m_ppropCompression->m_fLimitDirectorySize = m_fEnableLimiting;
  299. // TODO: Replace back %WINDIR% or another system settings in path
  300. m_ppropCompression->m_strDirectory = m_strDirectory;
  301. m_ppropCompression->m_dwDirectorySize = dwSize;
  302. err = m_ppropCompression->WriteDirtyProps();
  303. if (err.Succeeded())
  304. {
  305. m_fCompressionDirectoryChanged = FALSE;
  306. }
  307. }
  308. if (err.Succeeded())
  309. {
  310. if (GetSheet()->QueryMajorVersion() >= 6)
  311. {
  312. CMetaKey mk(QueryAuthInfo(), QueryMetaPath(), METADATA_PERMISSION_WRITE);
  313. err = mk.QueryResult();
  314. if (err.Succeeded())
  315. {
  316. err = mk.SetValue(MD_GLOBAL_STANDARD_APP_MODE_ENABLED, m_fCompatMode);
  317. if (err.Succeeded() && m_fCompatMode != m_fInitCompatMode)
  318. {
  319. // We don't need to save this parameter to sheet,
  320. // it is important to App Protection combo only, and
  321. // this combo is disabled for Master props, so it doesn't matter.
  322. GetSheet()->SetRestartRequired(TRUE);
  323. m_fInitCompatMode = m_fCompatMode;
  324. }
  325. }
  326. }
  327. NotifyMMC(PROP_CHANGE_REENUM_VDIR | PROP_CHANGE_REENUM_FILES);
  328. }
  329. EndWaitCursor();
  330. return err;
  331. }
  332. //
  333. // Message Handlers
  334. //
  335. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  336. BOOL
  337. CDefWebSitePage::OnInitDialog()
  338. /*++
  339. Routine Description:
  340. WM_INITDIALOG handler. Initialize the dialog.
  341. Arguments:
  342. None.
  343. Return Value:
  344. TRUE if focus is to be set automatically, FALSE if the focus
  345. is already set.
  346. --*/
  347. {
  348. CInetPropertyPage::OnInitDialog();
  349. //
  350. // Check to make sure compression is supported
  351. //
  352. GetDlgItem(IDC_STATIC_COMPRESS_GROUP)->EnableWindow(HasCompression());
  353. GetDlgItem(IDC_CHECK_DYNAMIC_COMPRESSION)->EnableWindow(HasCompression());
  354. GetDlgItem(IDC_CHECK_STATIC_COMPRESSION)->EnableWindow(HasCompression());
  355. GetDlgItem(IDC_RADIO_COMPRESS_UNLIMITED)->EnableWindow(HasCompression());
  356. GetDlgItem(IDC_RADIO_COMPRESS_LIMITED)->EnableWindow(HasCompression());
  357. GetDlgItem(IDC_EDIT_COMPRESS_DIRECTORY)->EnableWindow(HasCompression());
  358. GetDlgItem(IDC_STATIC_MAX_COMPRESS_SIZE)->EnableWindow(HasCompression());
  359. GetDlgItem(IDC_STATIC_COMPRESS_DIRECTORY)->EnableWindow(HasCompression());
  360. GetDlgItem(IDC_EDIT_COMPRESS_DIRECTORY_SIZE)->EnableWindow(HasCompression());
  361. GetDlgItem(IDC_COMPAT_MODE)->EnableWindow(GetSheet()->QueryMajorVersion() >= 6);
  362. SetControlStates();
  363. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  364. LimitInputPath(CONTROL_HWND(IDC_EDIT_COMPRESS_DIRECTORY),TRUE);
  365. #else
  366. LimitInputPath(CONTROL_HWND(IDC_EDIT_COMPRESS_DIRECTORY),FALSE);
  367. #endif
  368. return TRUE;
  369. }
  370. void
  371. CDefWebSitePage::OnItemChanged()
  372. /*++
  373. Routine Description:
  374. Handle change in control data
  375. Arguments:
  376. None
  377. Return Value:
  378. None
  379. --*/
  380. {
  381. SetModified(TRUE);
  382. SetControlStates();
  383. }
  384. static int CALLBACK
  385. FileChooserCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
  386. {
  387. CDefWebSitePage * pThis = (CDefWebSitePage *)lpData;
  388. ASSERT(pThis != NULL);
  389. return pThis->BrowseForFolderCallback(hwnd, uMsg, lParam);
  390. }
  391. int
  392. CDefWebSitePage::BrowseForFolderCallback(HWND hwnd, UINT uMsg, LPARAM lParam)
  393. {
  394. switch (uMsg)
  395. {
  396. case BFFM_INITIALIZED:
  397. ASSERT(m_pPathTemp != NULL);
  398. if (::PathIsNetworkPath(m_pPathTemp))
  399. return 0;
  400. while (!::PathIsDirectory(m_pPathTemp))
  401. {
  402. if (0 == ::PathRemoveFileSpec(m_pPathTemp) && !::PathIsRoot(m_pPathTemp))
  403. {
  404. return 0;
  405. }
  406. DWORD attr = GetFileAttributes(m_pPathTemp);
  407. if ((attr & FILE_ATTRIBUTE_READONLY) == 0)
  408. break;
  409. }
  410. ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)m_pPathTemp);
  411. break;
  412. case BFFM_SELCHANGED:
  413. {
  414. LPITEMIDLIST pidl = (LPITEMIDLIST)lParam;
  415. TCHAR path[MAX_PATH];
  416. if (SHGetPathFromIDList(pidl, path))
  417. {
  418. ::SendMessage(hwnd, BFFM_ENABLEOK, 0, !PathIsNetworkPath(path));
  419. }
  420. }
  421. break;
  422. case BFFM_VALIDATEFAILED:
  423. break;
  424. }
  425. return 0;
  426. }
  427. void
  428. CDefWebSitePage::OnButtonBrowse()
  429. {
  430. ASSERT(IsLocal());
  431. BOOL bRes = FALSE;
  432. HRESULT hr;
  433. CString str;
  434. m_edit_Directory.GetWindowText(str);
  435. if (SUCCEEDED(hr = CoInitialize(NULL)))
  436. {
  437. LPITEMIDLIST pidl = NULL;
  438. if (SUCCEEDED(SHGetFolderLocation(NULL, CSIDL_DRIVES, NULL, 0, &pidl)))
  439. {
  440. LPITEMIDLIST pidList = NULL;
  441. BROWSEINFO bi;
  442. TCHAR buf[MAX_PATH];
  443. ZeroMemory(&bi, sizeof(bi));
  444. ExpandEnvironmentStrings(str, buf, MAX_PATH);
  445. str = buf;
  446. int drive = PathGetDriveNumber(str);
  447. if (GetDriveType(PathBuildRoot(buf, drive)) == DRIVE_FIXED)
  448. {
  449. StrCpy(buf, str);
  450. }
  451. else
  452. {
  453. buf[0] = 0;
  454. }
  455. bi.hwndOwner = m_hWnd;
  456. bi.pidlRoot = pidl;
  457. bi.pszDisplayName = m_pPathTemp = buf;
  458. bi.lpszTitle = NULL;
  459. bi.ulFlags |= BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS/* | BIF_EDITBOX*/;
  460. bi.lpfn = FileChooserCallback;
  461. bi.lParam = (LPARAM)this;
  462. pidList = SHBrowseForFolder(&bi);
  463. if ( pidList != NULL
  464. && SHGetPathFromIDList(pidList, buf)
  465. )
  466. {
  467. str = buf;
  468. bRes = TRUE;
  469. }
  470. IMalloc * pMalloc;
  471. VERIFY(SUCCEEDED(SHGetMalloc(&pMalloc)));
  472. if (pidl != NULL)
  473. pMalloc->Free(pidl);
  474. pMalloc->Release();
  475. }
  476. CoUninitialize();
  477. }
  478. if (bRes)
  479. {
  480. m_edit_Directory.SetWindowText(str);
  481. OnItemChanged();
  482. }
  483. }
  484. void
  485. CDefWebSitePage::OnChangeEditCompressDirectory()
  486. /*++
  487. Routine Description:
  488. Handle change in compression directory edit box.
  489. Arguments:
  490. None
  491. Return Value:
  492. None
  493. --*/
  494. {
  495. m_fCompressionDirectoryChanged = TRUE;
  496. OnItemChanged();
  497. }
  498. void
  499. CDefWebSitePage::OnRadioLimited()
  500. /*++
  501. Routine Description:
  502. 'Limited' radio button handler
  503. Arguments:
  504. None
  505. Return Value:
  506. None
  507. --*/
  508. {
  509. if (!m_fEnableLimiting)
  510. {
  511. m_nUnlimited = RADIO_LIMITED;
  512. m_fEnableLimiting = TRUE;
  513. OnItemChanged();
  514. m_edit_DirectorySize.SetSel(0, -1);
  515. m_edit_DirectorySize.SetFocus();
  516. }
  517. }
  518. void
  519. CDefWebSitePage::OnRadioUnlimited()
  520. /*++
  521. Routine Description:
  522. 'Unlimited' radio button handler
  523. Arguments:
  524. None
  525. Return Value:
  526. None
  527. --*/
  528. {
  529. if (m_fEnableLimiting)
  530. {
  531. m_nUnlimited = RADIO_UNLIMITED;
  532. m_fEnableLimiting = FALSE;
  533. OnItemChanged();
  534. }
  535. }
  536. void
  537. CDefWebSitePage::OnCheckDynamicCompression()
  538. /*++
  539. Routine Description:
  540. "Enable Dynamic Compression' checkbox handler
  541. Arguments:
  542. None
  543. Return Value:
  544. None
  545. --*/
  546. {
  547. m_fEnableDynamic = !m_fEnableDynamic;
  548. OnItemChanged();
  549. }
  550. void
  551. CDefWebSitePage::OnCheckStaticCompression()
  552. /*++
  553. Routine Description:
  554. "Enable Dynamic Compression' checkbox handler
  555. Arguments:
  556. None
  557. Return Value:
  558. None
  559. --*/
  560. {
  561. m_fEnableStatic = !m_fEnableStatic;
  562. OnItemChanged();
  563. if (m_fEnableStatic)
  564. {
  565. m_edit_Directory.SetSel(0, -1);
  566. m_edit_Directory.SetFocus();
  567. }
  568. }
  569. void
  570. CDefWebSitePage::OnDestroy()
  571. /*++
  572. Routine Description:
  573. WM_DESTROY handler. Clean up internal data
  574. Arguments:
  575. None
  576. Return Value:
  577. None
  578. --*/
  579. {
  580. CInetPropertyPage::OnDestroy();
  581. SAFE_DELETE(m_ppropCompression);
  582. }
  583. void
  584. CDefWebSitePage::OnCheckCompatMode()
  585. {
  586. OnItemChanged();
  587. }