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.

793 lines
17 KiB

  1. /*++
  2. Copyright (c) 1994-1999 Microsoft Corporation
  3. Module Name :
  4. idlg.cpp
  5. Abstract:
  6. Inheritance Dialog
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager (cluster edition)
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "common.h"
  18. #include "inheritancedlg.h"
  19. //
  20. // Inheritance dialog
  21. //
  22. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  23. CInheritanceDlg::CInheritanceDlg(
  24. DWORD dwMetaID,
  25. BOOL fWrite,
  26. CComAuthInfo * pAuthInfo,
  27. LPCTSTR lpstrMetaRoot,
  28. CStringListEx& strlMetaChildNodes,
  29. LPCTSTR lpstrPropertyName,
  30. HWND hwndParent
  31. )
  32. /*++
  33. Routine Description:
  34. Inheritance dialog constructor. This constructor assumes GetDataPaths()
  35. has already been called.
  36. Arguments:
  37. DWORD dwMetaID : Meta ID
  38. BOOL fWrite : TRUE from write, FALSE from delete
  39. CIISServer * pAuthInfo : Auth info object or NULL
  40. LPCTSTR lpstrMetaRoot : Meta root
  41. CStringList & strlMetaChildNodes : List of child nodes from GetDataPaths
  42. LPCTSTR lpstrPropertyName : Optional text string for the property
  43. CWnd * pParent : Optional parent window
  44. Return Value:
  45. None
  46. --*/
  47. : m_fWrite(fWrite),
  48. m_fEmpty(TRUE),
  49. m_fUseTable(TRUE),
  50. m_strMetaRoot(lpstrMetaRoot),
  51. m_strPropertyName(lpstrPropertyName ? lpstrPropertyName : _T("")),
  52. m_mk(pAuthInfo)
  53. // CDialog(CInheritanceDlg::IDD, hwndParent)
  54. {
  55. m_strlMetaChildNodes = strlMetaChildNodes;
  56. VERIFY(CMetaKey::GetMDFieldDef(
  57. dwMetaID,
  58. m_dwMDIdentifier,
  59. m_dwMDAttributes,
  60. m_dwMDUserType,
  61. m_dwMDDataType
  62. ));
  63. Initialize();
  64. }
  65. CInheritanceDlg::CInheritanceDlg(
  66. DWORD dwMetaID,
  67. BOOL fWrite,
  68. CComAuthInfo * pAuthInfo,
  69. LPCTSTR lpstrMetaRoot,
  70. LPCTSTR lpstrPropertyName,
  71. HWND hwndParent
  72. )
  73. /*++
  74. Routine Description:
  75. Inheritance dialog constructor. This constructor will call GetDataPaths().
  76. Arguments:
  77. DWORD dwMetaID : Meta ID
  78. BOOL fWrite : TRUE from write, FALSE from delete
  79. CComAuthInfo * pAuthInfo : Auth info or NULL
  80. LPCTSTR lpstrMetaRoot : Meta root
  81. LPCTSTR lpstrPropertyName : Optional text string for the property
  82. CWnd * pParent : Optional parent window
  83. Return Value:
  84. None
  85. --*/
  86. : m_fWrite(fWrite),
  87. m_fEmpty(TRUE),
  88. m_fUseTable(TRUE),
  89. m_strMetaRoot(lpstrMetaRoot),
  90. m_strlMetaChildNodes(),
  91. m_strPropertyName(lpstrPropertyName ? lpstrPropertyName : _T("")),
  92. m_mk(pAuthInfo)
  93. // CDialog(CInheritanceDlg::IDD, pParent)
  94. {
  95. //
  96. // Specify the resources to use
  97. //
  98. // HINSTANCE hOldRes = AfxGetResourceHandle();
  99. // AfxSetResourceHandle(hDLLInstance);
  100. VERIFY(CMetaKey::GetMDFieldDef(
  101. dwMetaID,
  102. m_dwMDIdentifier,
  103. m_dwMDAttributes,
  104. m_dwMDUserType,
  105. m_dwMDDataType
  106. ));
  107. //
  108. // Need to do our own GetDataPaths()
  109. //
  110. CError err(GetDataPaths());
  111. if (!err.MessageBoxOnFailure())
  112. {
  113. Initialize();
  114. }
  115. //
  116. // Restore the resources
  117. //
  118. // AfxSetResourceHandle(hOldRes);
  119. }
  120. CInheritanceDlg::CInheritanceDlg(
  121. BOOL fTryToFindInTable,
  122. DWORD dwMDIdentifier,
  123. DWORD dwMDAttributes,
  124. DWORD dwMDUserType,
  125. DWORD dwMDDataType,
  126. LPCTSTR lpstrPropertyName,
  127. BOOL fWrite,
  128. CComAuthInfo * pAuthInfo,
  129. LPCTSTR lpstrMetaRoot,
  130. HWND hwndParent
  131. )
  132. /*++
  133. Routine Description:
  134. Inheritance dialog constructor. This constructor will call GetDataPaths(),
  135. and will use the specified parameters if the property ID does not exist
  136. in the property table
  137. Arguments:
  138. BOOL fTryToFindInTable : If TRUE, first look in table
  139. DWORD dwMDIdentifier : Metadata identifier
  140. DWORD dwMDAttributes : Metadata attributes
  141. DWORD dwMDUserType : Metadata user type
  142. DWORD dwMDDataType : Metadata data type
  143. LPCTSTR lpstrPropertyName : Text string for the property
  144. BOOL fWrite : TRUE from write, FALSE from delete
  145. CComAuthInfo * pAuthInfo : Authentication info or NULL.
  146. LPCTSTR lpstrMetaRoot : Meta root
  147. CWnd * pParent : Optional parent window
  148. Return Value:
  149. None
  150. --*/
  151. : m_fWrite(fWrite),
  152. m_fEmpty(TRUE),
  153. m_fUseTable(FALSE),
  154. m_strMetaRoot(lpstrMetaRoot),
  155. m_strlMetaChildNodes(),
  156. m_mk(pAuthInfo)
  157. // CDialog(CInheritanceDlg::IDD, pParent)
  158. {
  159. //
  160. // Specify the resources to use
  161. //
  162. // HINSTANCE hOldRes = AfxGetResourceHandle();
  163. // AfxSetResourceHandle(hDLLInstance);
  164. if (fTryToFindInTable && !CMetaKey::GetMDFieldDef(
  165. dwMDIdentifier,
  166. m_dwMDIdentifier,
  167. m_dwMDAttributes,
  168. m_dwMDUserType,
  169. m_dwMDDataType
  170. ))
  171. {
  172. //
  173. // Did not exist in the table, use specified parameters
  174. //
  175. m_dwMDIdentifier = dwMDIdentifier;
  176. m_dwMDAttributes = dwMDAttributes;
  177. m_dwMDUserType = dwMDUserType;
  178. m_dwMDDataType = dwMDDataType;
  179. m_strPropertyName = lpstrPropertyName;
  180. }
  181. //
  182. // Need to do our own GetDataPaths()
  183. //
  184. CError err(GetDataPaths());
  185. if (!err.MessageBoxOnFailure())
  186. {
  187. Initialize();
  188. }
  189. //
  190. // Restore the resources
  191. //
  192. // AfxSetResourceHandle(hOldRes);
  193. }
  194. HRESULT
  195. CInheritanceDlg::GetDataPaths()
  196. /*++
  197. Routine Description:
  198. GetDataPaths()
  199. Arguments:
  200. None
  201. Return Value:
  202. HRESULT
  203. --*/
  204. {
  205. //ASSERT(!m_strServer.IsEmpty());
  206. CError err(m_mk.QueryResult());
  207. if (err.Succeeded())
  208. {
  209. err = m_mk.GetDataPaths(
  210. m_strlMetaChildNodes,
  211. m_dwMDIdentifier,
  212. m_dwMDDataType,
  213. m_strMetaRoot
  214. );
  215. }
  216. return err;
  217. }
  218. void
  219. CInheritanceDlg::Initialize()
  220. /*++
  221. Routine Description:
  222. Initialize data members. Set the m_fEmpty flag to determine if
  223. it is necessary to proceed.
  224. Arguments:
  225. None
  226. Return Value:
  227. None
  228. --*/
  229. {
  230. CMetabasePath::CleanMetaPath(m_strMetaRoot);
  231. if (m_fUseTable && !CMetaKey::IsPropertyInheritable(m_dwMDIdentifier))
  232. {
  233. //
  234. // No point in displaying non-inheritable properties
  235. //
  236. return;
  237. }
  238. switch(m_dwMDIdentifier)
  239. {
  240. //
  241. // Ignore these properties, even though they are inheritable
  242. //
  243. case MD_VR_PATH:
  244. case MD_APP_ISOLATED:
  245. case MD_APP_FRIENDLY_NAME:
  246. return;
  247. }
  248. //
  249. // Check to see if the current metabase path contains an instance
  250. //
  251. CString strTmp;
  252. m_fHasInstanceInMaster = FriendlyInstance(m_strMetaRoot, strTmp);
  253. //
  254. // If property name was not specified in the constructor, load default
  255. // one from table.
  256. //
  257. if (m_strPropertyName.IsEmpty())
  258. {
  259. ASSERT(m_fUseTable);
  260. //
  261. // Specify the resources to use
  262. //
  263. // HINSTANCE hOldRes = AfxGetResourceHandle();
  264. // AfxSetResourceHandle(hDLLInstance);
  265. VERIFY(CMetaKey::GetPropertyDescription(
  266. m_dwMDIdentifier,
  267. m_strPropertyName
  268. ));
  269. // AfxSetResourceHandle(hOldRes);
  270. }
  271. //
  272. // Go through the list of metapaths, and clean them
  273. // up.
  274. //
  275. CStringListEx::iterator it = m_strlMetaChildNodes.begin();
  276. while (it != m_strlMetaChildNodes.end())
  277. {
  278. CString& strMetaPath = (*it++);
  279. CMetabasePath::CleanMetaPath(strMetaPath);
  280. }
  281. //
  282. // If the special info key (lm/service/info) is in the list, remove it.
  283. // We only need to this if the key that is getting the
  284. // change (m_strMetaRoot) is the service master property (lm/service).
  285. // If it is anything else, then the special "info" key cannot be below
  286. // it so we don't need to check. Thus the first test is to see if there
  287. // is only one "/" character. If there is only one, then we know it is
  288. // the service and we can go ahead and do the test. In some ways,
  289. // mfc is a pain, so we limited to the CString methods to do this
  290. // copy the root into the temp string.
  291. //
  292. int iSlash = m_strMetaRoot.ReverseFind(SZ_MBN_SEP_CHAR);
  293. if (iSlash >= 0)
  294. {
  295. strTmp = m_strMetaRoot.Left(iSlash);
  296. //
  297. // Now make sure that there aren't any more slashes
  298. //
  299. if (strTmp.Find(SZ_MBN_SEP_CHAR) == -1)
  300. {
  301. //
  302. // Now build the path to the special info key by adding it
  303. // to the meta root
  304. //
  305. strTmp = m_strMetaRoot + SZ_MBN_SEP_CHAR + IIS_MD_SVC_INFO_PATH;
  306. TRACE("Removing any descendants of %s\n", strTmp);
  307. //
  308. // Search the list for the info key and remove it if we find it
  309. //
  310. it = m_strlMetaChildNodes.begin();
  311. while (it != m_strlMetaChildNodes.end())
  312. {
  313. CString & strMetaPath = (*it);
  314. if (strTmp.CompareNoCase(strMetaPath.Left(strTmp.GetLength())) == 0)
  315. {
  316. TRACEEOLID("Removing service/info metapath from list");
  317. m_strlMetaChildNodes.erase(it);
  318. }
  319. it++;
  320. }
  321. }
  322. }
  323. //
  324. // Remove the first item if it's the current metapath
  325. //
  326. it = m_strlMetaChildNodes.begin();
  327. if (it != m_strlMetaChildNodes.end())
  328. {
  329. TRACE("Stripping %s\n", m_strMetaRoot);
  330. CString & strMetaPath = (*it);
  331. if (strMetaPath.CompareNoCase(m_strMetaRoot) == 0)
  332. {
  333. TRACEEOLID("Removing current metapath from list");
  334. m_strlMetaChildNodes.pop_front();
  335. }
  336. }
  337. m_fEmpty = m_strlMetaChildNodes.size() == 0;
  338. }
  339. #if 0
  340. int
  341. CInheritanceDlg::DoModal()
  342. /*++
  343. Routine Description:
  344. Display the dialog.
  345. Arguments:
  346. None
  347. Return Value:
  348. IDOK if the OK button was pressed, IDCANCEL otherwise.
  349. --*/
  350. {
  351. //
  352. // Specify the resources to use
  353. //
  354. // HINSTANCE hOldRes = AfxGetResourceHandle();
  355. // AfxSetResourceHandle(hDLLInstance);
  356. int answer = CDialog::DoModal();
  357. //
  358. // restore the resources
  359. //
  360. // AfxSetResourceHandle(hOldRes);
  361. return answer;
  362. }
  363. #endif
  364. #if 0
  365. void
  366. CInheritanceDlg::DoDataExchange(
  367. IN CDataExchange * pDX
  368. )
  369. /*++
  370. Routine Description:
  371. Initialise/Store control data
  372. Arguments:
  373. CDataExchange * pDX - DDX/DDV control structure
  374. Return Value:
  375. None
  376. --*/
  377. {
  378. CDialog::DoDataExchange(pDX);
  379. //{{AFX_DATA_MAP(CInheritanceDlg)
  380. DDX_Control(pDX, IDC_LIST_CHILD_NODES, m_list_ChildNodes);
  381. //}}AFX_DATA_MAP
  382. }
  383. //
  384. // Message Map
  385. //
  386. BEGIN_MESSAGE_MAP(CInheritanceDlg, CDialog)
  387. //{{AFX_MSG_MAP(CInheritanceDlg)
  388. ON_BN_CLICKED(IDC_BUTTON_SELECT_ALL, OnButtonSelectAll)
  389. //}}AFX_MSG_MAP
  390. END_MESSAGE_MAP()
  391. #endif
  392. BOOL
  393. CInheritanceDlg::FriendlyInstance(CString& strMetaRoot, CString& strFriendly)
  394. /*++
  395. Routine Description:
  396. Replace the instance number with its descriptive name.
  397. Arguments:
  398. CString & strMetaRoot : Metabase path
  399. CString & strFriendly : Converted output friendly path.
  400. Return Value:
  401. TRUE if the path contained an instance number.
  402. --*/
  403. {
  404. //
  405. // Break into fields
  406. //
  407. // CODEWORK: make static like BuildMetaPath
  408. //
  409. int n = CMetabasePath::GetInstanceNumber(strMetaRoot);
  410. if (n == 0)
  411. {
  412. // Master instance
  413. return FALSE;
  414. }
  415. CString service, instance;
  416. if (CMetabasePath::GetServicePath(strMetaRoot, service, NULL))
  417. {
  418. int len = strMetaRoot.GetLength();
  419. int pos = strMetaRoot.Find(SZ_MBN_SEP_CHAR);
  420. if (pos != -1)
  421. {
  422. HRESULT hr = m_mk.Open(METADATA_PERMISSION_READ, CMetabasePath(service, n));
  423. if (SUCCEEDED(hr))
  424. {
  425. CString comment;
  426. hr = m_mk.QueryValue(MD_SERVER_COMMENT, comment);
  427. m_mk.Close();
  428. if (FAILED(hr) || comment.IsEmpty())
  429. {
  430. strFriendly.Format(
  431. SZ_MBN_MACHINE SZ_MBN_SEP_STR _T("%s") SZ_MBN_SEP_STR _T("%d"),
  432. service,
  433. n
  434. );
  435. }
  436. else
  437. {
  438. strFriendly.Format(
  439. SZ_MBN_MACHINE SZ_MBN_SEP_STR _T("%s") SZ_MBN_SEP_STR _T("%s"),
  440. service,
  441. comment
  442. );
  443. }
  444. TRACEEOLID(strFriendly);
  445. //
  446. // Append the rest of the path
  447. //
  448. CString tail;
  449. CMetabasePath::SplitMetaPathAtInstance(strMetaRoot, instance, tail);
  450. strFriendly += tail;
  451. return TRUE;
  452. }
  453. }
  454. }
  455. return FALSE;
  456. }
  457. CString&
  458. CInheritanceDlg::CleanDescendantPath(CString& strMetaPath)
  459. /*++
  460. Routine Description:
  461. Clean the descendant metabase path. The path is shown
  462. as a descendant of the current metabase root, and instance
  463. numbers are replaced with their description names.
  464. Arguments:
  465. CString & strMetaPath : Metabase path to be treated
  466. Return Value:
  467. Reference to the cleaned-up path.
  468. --*/
  469. {
  470. //
  471. // This better be a descendant!
  472. //
  473. ASSERT(strMetaPath.GetLength() >= m_strMetaRoot.GetLength());
  474. ASSERT(!::_tcsnicmp(strMetaPath, m_strMetaRoot, m_strMetaRoot.GetLength()));
  475. if (!m_fHasInstanceInMaster)
  476. {
  477. //
  478. // Need to replace the instance number with the friendly
  479. // name.
  480. //
  481. CString strTmp;
  482. VERIFY(FriendlyInstance(strMetaPath, strTmp));
  483. strMetaPath = strTmp;
  484. }
  485. strMetaPath = strMetaPath.Mid(m_strMetaRoot.GetLength() + 1);
  486. return strMetaPath;
  487. }
  488. //
  489. // Message Handlers
  490. //
  491. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  492. LRESULT
  493. CInheritanceDlg::OnInitDialog(HWND hwnd, LPARAM lParam)
  494. /*++
  495. Routine Description:
  496. WM_INITDIALOG handler. Initialize the dialog.
  497. Arguments:
  498. None.
  499. Return Value:
  500. TRUE if focus is to be set automatically, FALSE if the focus
  501. is already set.
  502. --*/
  503. {
  504. //
  505. // Get friendly name for the property, and set the text.
  506. //
  507. CString strPrompt;
  508. strPrompt.Format(_Module.GetResourceInstance(),
  509. IDS_INHERITANCE_PROMPT, (LPCTSTR)m_strPropertyName);
  510. ::SetWindowText(GetDlgItem(IDC_STATIC_PROMPT), strPrompt);
  511. //
  512. // Turn inherited nodes into friendly paths, and add them
  513. // to the listbox. Note the "current" node should have been
  514. // deleted at this stage.
  515. //
  516. CStringListEx::iterator pos = m_strlMetaChildNodes.begin();
  517. while (pos != m_strlMetaChildNodes.end())
  518. {
  519. CString strNode = (*pos++);
  520. m_list_ChildNodes.AddString(CleanDescendantPath(strNode));
  521. }
  522. return TRUE;
  523. }
  524. void
  525. CInheritanceDlg::OnButtonSelectAll(WORD wNotifyCode, WORD wID, HWND hwndCtrl)
  526. /*++
  527. Routine Description:
  528. 'Select All' button handler
  529. Arguments:
  530. None
  531. Return Value:
  532. None
  533. --*/
  534. {
  535. ASSERT(wNotifyCode == BN_CLICKED);
  536. ASSERT(wID == IDC_BUTTON_SELECT_ALL);
  537. //
  538. // Select all entries
  539. //
  540. if (m_list_ChildNodes.GetCount() == 1)
  541. {
  542. //
  543. // SelItemRange refuses to do a single member
  544. //
  545. m_list_ChildNodes.SetSel(0, TRUE);
  546. }
  547. else
  548. {
  549. m_list_ChildNodes.SelItemRange(TRUE, 0, m_list_ChildNodes.GetCount() - 1);
  550. }
  551. }
  552. void
  553. CInheritanceDlg::OnOK(WORD wNotifyCode, WORD wID, HWND hwndCtrl)
  554. /*++
  555. Routine Description:
  556. 'OK' button handler
  557. Arguments:
  558. None
  559. Return Value:
  560. None
  561. --*/
  562. {
  563. ASSERT(wNotifyCode == BN_CLICKED);
  564. ASSERT(wID == IDOK);
  565. //
  566. // Now delete the property for all selected child nodes.
  567. // Grab from the orginal list, and not the listbox
  568. // as the latter have been frienly-fied, and is no longer
  569. // usable.
  570. //
  571. int cItems = m_list_ChildNodes.GetCount();
  572. ASSERT(cItems > 0);
  573. CString strMetaPath;
  574. CError err(m_mk.QueryResult());
  575. if (err.Succeeded())
  576. {
  577. int i = 0;
  578. CStringListEx::iterator pos = m_strlMetaChildNodes.begin();
  579. while (pos != m_strlMetaChildNodes.end())
  580. {
  581. strMetaPath = (*pos++);
  582. if (m_list_ChildNodes.GetSel(i++) > 0)
  583. {
  584. TRACE("Deleting property on %s\n", strMetaPath);
  585. err = m_mk.Open(METADATA_PERMISSION_WRITE, strMetaPath);
  586. if (err.Failed())
  587. {
  588. break;
  589. }
  590. err = m_mk.DeleteValue(m_dwMDIdentifier);
  591. m_mk.Close();
  592. if (err.Failed())
  593. {
  594. break;
  595. }
  596. }
  597. }
  598. }
  599. if (!err.MessageBoxOnFailure())
  600. {
  601. //
  602. // Dialog can be dismissed
  603. //
  604. EndDialog(IDOK);
  605. }
  606. }