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.

827 lines
14 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. machine.cpp
  5. Abstract:
  6. IIS Machine properties 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 "comprop.h"
  18. #include "mime.h"
  19. #define DLL_BASED __declspec(dllimport)
  20. #include "mmc.h"
  21. #include "machine.h"
  22. #include "inetprop.h"
  23. #include "..\mmc\constr.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. IMPLEMENT_DYNCREATE(CIISMachinePage, CPropertyPage)
  30. typedef struct tagMASTER_DLL
  31. {
  32. LPCTSTR lpszDllName;
  33. UINT nID;
  34. } MASTER_DLL;
  35. MASTER_DLL rgMasters[] =
  36. {
  37. //
  38. // Note: path should not be neccesary for these
  39. // config DLLs, because they should really already
  40. // be loaded by inetmgr at this point.
  41. //
  42. { _T("W3SCFG.DLL"), IDS_WWW_MASTER },
  43. { _T("FSCFG.DLL"), IDS_FTP_MASTER },
  44. };
  45. #define NUM_MASTER_DLL ARRAY_SIZE(rgMasters)
  46. CMasterDll::CMasterDll(
  47. IN UINT nID,
  48. IN LPCTSTR lpszDllName,
  49. IN LPCTSTR lpszMachineName
  50. )
  51. /*++
  52. Routine Description:
  53. Construct master dll object
  54. Arguments:
  55. UINT nID : Resource ID
  56. LPCTSTR lpszDllName : Dll filename and path
  57. LPCTSTR lpszMachineName : Current machine name
  58. Return Value:
  59. N/A
  60. --*/
  61. : m_hDll(NULL),
  62. m_pfnConfig(NULL),
  63. m_strText()
  64. {
  65. m_hDll = ::AfxLoadLibrary(lpszDllName);
  66. if (m_hDll != NULL)
  67. {
  68. //
  69. // Check to see if this service is installed
  70. //
  71. pfnQueryServerInfo pfnInfo = (pfnQueryServerInfo)
  72. ::GetProcAddress(m_hDll, SZ_SERVERINFO_PROC);
  73. if (pfnInfo != NULL)
  74. {
  75. ISMSERVERINFO ism;
  76. ism.dwSize = ISMSERVERINFO_SIZE;
  77. CError err((*pfnInfo)(lpszMachineName, &ism));
  78. if (err.Succeeded())
  79. {
  80. m_pfnConfig = (pfnConfigure)::GetProcAddress(
  81. m_hDll,
  82. SZ_CONFIGURE_PROC
  83. );
  84. if (m_pfnConfig != NULL)
  85. {
  86. HINSTANCE hOld = AfxGetResourceHandle();
  87. AfxSetResourceHandle(GetModuleHandle(COMPROP_DLL_NAME));
  88. VERIFY(m_strText.LoadString(nID));
  89. AfxSetResourceHandle(hOld);
  90. //
  91. // Success!
  92. //
  93. return;
  94. }
  95. }
  96. }
  97. }
  98. //
  99. // Library didn't exist, was bogus, or unable to provide information
  100. // about itself.
  101. //
  102. SAFE_AFXFREELIBRARY(m_hDll);
  103. }
  104. CMasterDll::~CMasterDll()
  105. /*++
  106. Routine Description:
  107. Destructor -- decrement library reference count
  108. Arguments:
  109. N/A
  110. Return Value:
  111. N/A
  112. --*/
  113. {
  114. TRACEEOLID("Deleting: " << m_strText);
  115. SAFE_AFXFREELIBRARY(m_hDll);
  116. }
  117. /* static */
  118. void
  119. CIISMachinePage::ParseMaxNetworkUse(
  120. IN OUT CILong & nMaxNetworkUse,
  121. OUT BOOL & fLimitNetworkUse
  122. )
  123. /*++
  124. Routine Description:
  125. Break out max network use function
  126. Arguments:
  127. CILong & nMaxNetworkUse : Maximum network value (will be changed)
  128. BOOL & fLimitMaxNetworkUse : TRUE if max network is not infinite
  129. Return Value
  130. None/
  131. --*/
  132. {
  133. fLimitNetworkUse = (nMaxNetworkUse != INFINITE_BANDWIDTH);
  134. nMaxNetworkUse = fLimitNetworkUse
  135. ? (nMaxNetworkUse / KILOBYTE)
  136. : (DEF_BANDWIDTH / KILOBYTE);
  137. }
  138. CIISMachinePage::CIISMachinePage(
  139. IN LPCTSTR lpstrMachineName,
  140. IN HINSTANCE hInstance
  141. )
  142. /*++
  143. Routine Description:
  144. Constructor for IIS Machine property page
  145. Arguments:
  146. LPCTSTR lpstrMachineName : Machine name
  147. HINSTANCE hInstance : Instance handle
  148. Return Value:
  149. N/A
  150. --*/
  151. : CPropertyPage(CIISMachinePage::IDD),
  152. m_strMachineName(lpstrMachineName),
  153. m_fLocal(IsServerLocal(lpstrMachineName)),
  154. m_ppropMimeTypes(NULL),
  155. m_ppropMachine(NULL),
  156. m_lstMasterDlls(),
  157. m_hr(S_OK)
  158. {
  159. #if 0 // Keep class wizard happy
  160. //{{AFX_DATA_INIT(CIISMachinePage)
  161. m_fLimitNetworkUse = FALSE;
  162. m_nMasterType = -1;
  163. //}}AFX_DATA_INIT
  164. m_nMaxNetworkUse = 0;
  165. #endif
  166. m_nMasterType = 0;
  167. //
  168. // Data will be fetched later to prevent marshalling across
  169. // threads errors. The dialog is constructed in one thread,
  170. // and operates in another.
  171. //
  172. }
  173. CIISMachinePage::~CIISMachinePage()
  174. /*++
  175. Routine Description:
  176. Destructor
  177. Arguments:
  178. N/A
  179. Return Value:
  180. N/A
  181. --*/
  182. {
  183. }
  184. //
  185. // COMPILER ISSUE::: Inlining this function doesn't
  186. // work on x86 using NT 5!
  187. //
  188. HRESULT CIISMachinePage::QueryResult() const
  189. {
  190. return m_hr;
  191. }
  192. void
  193. CIISMachinePage::DoDataExchange(
  194. IN CDataExchange * pDX
  195. )
  196. /*++
  197. Routine Description:
  198. Initialise/Store control data
  199. Arguments:
  200. CDataExchange * pDX - DDX/DDV control structure
  201. Return Value:
  202. None
  203. --*/
  204. {
  205. //
  206. // Make sure data was fetched
  207. //
  208. ASSERT(m_ppropMachine != NULL);
  209. ASSERT(m_ppropMimeTypes != NULL);
  210. CPropertyPage::DoDataExchange(pDX);
  211. //{{AFX_DATA_MAP(CIISMachinePage)
  212. DDX_CBIndex(pDX, IDC_COMBO_MASTER_TYPE, m_nMasterType);
  213. DDX_Control(pDX, IDC_EDIT_MAX_NETWORK_USE, m_edit_MaxNetworkUse);
  214. DDX_Control(pDX, IDC_STATIC_THROTTLE_PROMPT, m_static_ThrottlePrompt);
  215. DDX_Control(pDX, IDC_STATIC_MAX_NETWORK_USE, m_static_MaxNetworkUse);
  216. DDX_Control(pDX, IDC_STATIC_KBS, m_static_KBS);
  217. DDX_Control(pDX, IDC_BUTTON_EDIT_DEFAULT, m_button_EditDefault);
  218. DDX_Control(pDX, IDC_CHECK_LIMIT_NETWORK_USE, m_check_LimitNetworkUse);
  219. DDX_Control(pDX, IDC_COMBO_MASTER_TYPE, m_combo_MasterType);
  220. DDX_Check(pDX, IDC_CHECK_LIMIT_NETWORK_USE, m_fLimitNetworkUse);
  221. //}}AFX_DATA_MAP
  222. if (m_edit_MaxNetworkUse.IsWindowEnabled())
  223. {
  224. DDX_Text(pDX, IDC_EDIT_MAX_NETWORK_USE, m_nMaxNetworkUse);
  225. DDV_MinMaxLong(pDX, m_nMaxNetworkUse, 1, UD_MAXVAL);
  226. }
  227. }
  228. //
  229. // Message Map
  230. //
  231. BEGIN_MESSAGE_MAP(CIISMachinePage, CPropertyPage)
  232. //{{AFX_MSG_MAP(CIISMachinePage)
  233. ON_BN_CLICKED(IDC_CHECK_LIMIT_NETWORK_USE, OnCheckLimitNetworkUse)
  234. ON_BN_CLICKED(IDC_BUTTON_EDIT_DEFAULT, OnButtonEditDefault)
  235. ON_BN_CLICKED(IDC_BUTTON_FILE_TYPES, OnButtonFileTypes)
  236. ON_COMMAND(ID_HELP, OnHelp)
  237. ON_COMMAND(ID_CONTEXT_HELP, OnHelp)
  238. ON_WM_DESTROY()
  239. ON_WM_HELPINFO()
  240. //}}AFX_MSG_MAP
  241. ON_EN_CHANGE(IDC_EDIT_MAX_NETWORK_USE, OnItemChanged)
  242. END_MESSAGE_MAP()
  243. BOOL
  244. CIISMachinePage::SetControlStates()
  245. /*++
  246. Routine Description:
  247. Set button states depending on contents of the controls.
  248. Return whether or not "Limit network use" is on.
  249. Arguments:
  250. None
  251. Return Value:
  252. TRUE if "Limit network use" is checked
  253. --*/
  254. {
  255. BOOL fLimitOn = m_check_LimitNetworkUse.GetCheck() > 0;
  256. m_static_MaxNetworkUse.EnableWindow(fLimitOn);
  257. m_static_ThrottlePrompt.EnableWindow(fLimitOn);
  258. m_edit_MaxNetworkUse.EnableWindow(fLimitOn);
  259. m_static_KBS.EnableWindow(fLimitOn);
  260. return fLimitOn;
  261. }
  262. HRESULT
  263. CIISMachinePage::LoadDelayedValues()
  264. /*++
  265. Routine Description:
  266. Load the metabase parameters
  267. Arguments:
  268. None
  269. Return Value:
  270. HRESULT
  271. --*/
  272. {
  273. //
  274. // Fetch the properties from the metabase
  275. //
  276. ASSERT(m_ppropMachine == NULL);
  277. ASSERT(m_ppropMimeTypes == NULL);
  278. //
  279. // Share interface between the objects here
  280. //
  281. m_ppropMachine = new CMachineProps(m_strMachineName);
  282. if (NULL == m_ppropMachine)
  283. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  284. else if (FAILED(m_ppropMachine->QueryResult()))
  285. return m_ppropMachine->QueryResult();
  286. m_ppropMimeTypes = new CMimeTypes(m_ppropMachine);
  287. if (NULL == m_ppropMimeTypes)
  288. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  289. else if (FAILED(m_ppropMimeTypes->QueryResult()))
  290. return m_ppropMimeTypes->QueryResult();
  291. m_hr = m_ppropMachine->LoadData();
  292. if (SUCCEEDED(m_hr))
  293. {
  294. m_nMaxNetworkUse = m_ppropMachine->m_nMaxNetworkUse;
  295. ParseMaxNetworkUse(m_nMaxNetworkUse, m_fLimitNetworkUse);
  296. m_hr = m_ppropMimeTypes->LoadData();
  297. if (SUCCEEDED(m_hr))
  298. {
  299. m_strlMimeTypes = m_ppropMimeTypes->m_strlMimeTypes;
  300. }
  301. }
  302. return S_OK;
  303. }
  304. //
  305. // Message Handlers
  306. //
  307. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  308. void
  309. CIISMachinePage::OnHelp()
  310. /*++
  311. Routine Description:
  312. 'Help' button handler
  313. Arguments:
  314. None
  315. Return Value:
  316. None
  317. --*/
  318. {
  319. if (m_strHelpFile.IsEmpty())
  320. {
  321. CRMCRegKey rk(REG_KEY, SZ_PARAMETERS, KEY_READ);
  322. rk.QueryValue(SZ_HELPPATH, m_strHelpFile, EXPANSION_ON);
  323. m_strHelpFile += _T("\\inetmgr.hlp");
  324. TRACEEOLID("Initialized help file " << m_strHelpFile);
  325. }
  326. CWnd * pWnd = ::AfxGetMainWnd();
  327. HWND hWndParent = pWnd != NULL
  328. ? pWnd->m_hWnd
  329. : NULL;
  330. ::WinHelp(m_hWnd, m_strHelpFile, HELP_CONTEXT, HIDD_IIS_MACHINE);
  331. }
  332. BOOL
  333. CIISMachinePage::OnHelpInfo(HELPINFO * pHelpInfo)
  334. {
  335. OnHelp();
  336. return FALSE;
  337. }
  338. void
  339. CIISMachinePage::OnCheckLimitNetworkUse()
  340. /*++
  341. Routine Description:
  342. The "limit network use" checkbox has been clicked
  343. Enable/disable the "max network use" controls.
  344. Arguments:
  345. None
  346. Return Value:
  347. None
  348. --*/
  349. {
  350. if (SetControlStates())
  351. {
  352. m_edit_MaxNetworkUse.SetSel(0,-1);
  353. m_edit_MaxNetworkUse.SetFocus();
  354. }
  355. OnItemChanged();
  356. }
  357. void
  358. CIISMachinePage::OnItemChanged()
  359. /*++
  360. Routine Description:
  361. All EN_CHANGE messages map to this function
  362. Arguments:
  363. None
  364. Return Value:
  365. None
  366. --*/
  367. {
  368. SetModified(TRUE);
  369. }
  370. void
  371. CIISMachinePage::OnButtonEditDefault()
  372. /*++
  373. Routine Description:
  374. 'edit default' button handler
  375. Arguments:
  376. None
  377. Return Value:
  378. None
  379. --*/
  380. {
  381. //
  382. // Get selection, and convert to index into server table
  383. // via associative array.
  384. //
  385. CError err;
  386. int nSel = m_combo_MasterType.GetCurSel();
  387. ASSERT(nSel >= 0 && nSel < NUM_MASTER_DLL);
  388. POSITION pos = m_lstMasterDlls.FindIndex(nSel);
  389. ASSERT(pos != NULL);
  390. CMasterDll * pDll = m_lstMasterDlls.GetAt(pos);
  391. ASSERT(pDll != NULL);
  392. //
  393. // Allocate string with 2 terminating NULLS
  394. //
  395. int nLen = m_strMachineName.GetLength();
  396. LPTSTR lpServers = AllocTString(nLen + 2);
  397. if (lpServers == NULL)
  398. {
  399. err = ERROR_NOT_ENOUGH_MEMORY;
  400. }
  401. else
  402. {
  403. ::lstrcpy(lpServers, m_strMachineName);
  404. lpServers[nLen + 1] = _T('\0');
  405. err = pDll->Config(m_hWnd, lpServers);
  406. }
  407. SAFE_FREEMEM(lpServers);
  408. err.MessageBoxOnFailure();
  409. }
  410. void
  411. CIISMachinePage::OnButtonFileTypes()
  412. /*++
  413. Routine Description:
  414. 'file types' button handler - bring up mime types dialog.
  415. Arguments:
  416. None
  417. Return Value:
  418. None
  419. --*/
  420. {
  421. HINSTANCE hOld = AfxGetResourceHandle();
  422. AfxSetResourceHandle(GetModuleHandle(COMPROP_DLL_NAME));
  423. CMimeDlg dlg(m_strlMimeTypes, this);
  424. if (dlg.DoModal() == IDOK)
  425. {
  426. OnItemChanged();
  427. }
  428. AfxSetResourceHandle(hOld);
  429. }
  430. BOOL
  431. CIISMachinePage::OnInitDialog()
  432. /*++
  433. Routine Description:
  434. WM_INITDIALOG handler. Initialize the dialog.
  435. Arguments:
  436. None.
  437. Return Value:
  438. TRUE if no focus is to be set automatically, FALSE if the focus
  439. is already set.
  440. --*/
  441. {
  442. CServerCapabilities caps(m_strMachineName, SZ_MBN_WEB);
  443. BOOL fHasThrottling = caps.HasBwThrottling();
  444. CError err(LoadDelayedValues());
  445. if (err.Failed())
  446. {
  447. fHasThrottling = FALSE;
  448. }
  449. CPropertyPage::OnInitDialog();
  450. //
  451. // Fill the master combo box
  452. //
  453. int cServices = 0;
  454. CMasterDll * pDll;
  455. for (int n = 0; n < NUM_MASTER_DLL; ++n)
  456. {
  457. pDll = new CMasterDll(
  458. rgMasters[n].nID,
  459. rgMasters[n].lpszDllName,
  460. m_strMachineName
  461. );
  462. if (pDll == NULL)
  463. {
  464. err = ERROR_NOT_ENOUGH_MEMORY;
  465. break;
  466. }
  467. if (pDll->IsLoaded())
  468. {
  469. m_combo_MasterType.AddString(*pDll);
  470. m_lstMasterDlls.AddTail(pDll);
  471. ++cServices;
  472. }
  473. else
  474. {
  475. //
  476. // Dll didn't load, toss it.
  477. //
  478. delete pDll;
  479. }
  480. }
  481. if (cServices == 0)
  482. {
  483. //
  484. // No master-programmable services installed, so disallow
  485. // master editing.
  486. //
  487. GetDlgItem(IDC_BUTTON_EDIT_DEFAULT)->EnableWindow(FALSE);
  488. GetDlgItem(IDC_GROUP_MASTER)->EnableWindow(FALSE);
  489. GetDlgItem(IDC_STATIC_MASTER_PROMPT1)->EnableWindow(FALSE);
  490. GetDlgItem(IDC_STATIC_MASTER_PROMPT2)->EnableWindow(FALSE);
  491. m_combo_MasterType.EnableWindow(FALSE);
  492. }
  493. m_check_LimitNetworkUse.EnableWindow(fHasThrottling);
  494. m_combo_MasterType.SetCurSel(0);
  495. SetControlStates();
  496. err.MessageBoxOnFailure();
  497. return TRUE;
  498. }
  499. BOOL
  500. CIISMachinePage::OnApply()
  501. /*++
  502. Routine Description:
  503. 'Apply' button handler. Called when OK or APPLY is pressed.
  504. Arguments:
  505. None.
  506. Return Value:
  507. TRUE to continue, FALSE otherwise
  508. --*/
  509. {
  510. //
  511. // Don't use m_nMaxNetworkUse, because it would
  512. // alter the values on the screen when DDX happens next.
  513. //
  514. CILong nMaxNetworkUse = m_nMaxNetworkUse;
  515. BuildMaxNetworkUse(nMaxNetworkUse, m_fLimitNetworkUse);
  516. m_ppropMachine->m_nMaxNetworkUse = nMaxNetworkUse;
  517. CError err(m_ppropMachine->WriteDirtyProps());
  518. if (err.Succeeded())
  519. {
  520. m_ppropMimeTypes->m_strlMimeTypes = m_strlMimeTypes;
  521. err = m_ppropMimeTypes->WriteDirtyProps();
  522. }
  523. if (err.Succeeded())
  524. {
  525. return CPropertyPage::OnApply();
  526. }
  527. //
  528. // Failed
  529. //
  530. err.MessageBox();
  531. return FALSE;
  532. }
  533. void
  534. CIISMachinePage::OnDestroy()
  535. /*++
  536. Routine Description:
  537. Window is being destroyed. Time to clean up
  538. Arguments:
  539. None.
  540. Return Value:
  541. None.
  542. --*/
  543. {
  544. ASSERT(m_ppropMachine != NULL);
  545. ASSERT(m_ppropMimeTypes != NULL);
  546. SAFE_DELETE(m_ppropMachine);
  547. SAFE_DELETE(m_ppropMimeTypes);
  548. while (!m_lstMasterDlls.IsEmpty())
  549. {
  550. CMasterDll * pDll = m_lstMasterDlls.RemoveHead();
  551. delete pDll;
  552. }
  553. //
  554. // Remove the help window if it's currently open
  555. //
  556. ::WinHelp(m_hWnd, NULL, HELP_QUIT, 0L);
  557. CPropertyPage::OnDestroy();
  558. }
  559. void
  560. CIISMachinePage::PostNcDestroy()
  561. /*++
  562. Routine Description:
  563. handle destruction of the window by freeing the this
  564. pointer (as this modeless dialog must have been created
  565. on the heap)
  566. Arguments:
  567. None.
  568. Return Value:
  569. None
  570. --*/
  571. {
  572. delete this;
  573. }