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.

1106 lines
28 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 1998-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // BasePage.cpp
  7. //
  8. // Description:
  9. // Implementation of the CBasePropertyPage class.
  10. //
  11. // Maintained By:
  12. // Galen Barbee (GalenB) Mmmm DD, 1998
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include <clusapi.h>
  21. #include "DummyEx.h"
  22. #include "ExtObj.h"
  23. #include "BasePage.h"
  24. #include "BasePage.inl"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CBasePropertyPage property page
  32. /////////////////////////////////////////////////////////////////////////////
  33. IMPLEMENT_DYNCREATE(CBasePropertyPage, CPropertyPage)
  34. /////////////////////////////////////////////////////////////////////////////
  35. // Message Maps
  36. BEGIN_MESSAGE_MAP(CBasePropertyPage, CPropertyPage)
  37. //{{AFX_MSG_MAP(CBasePropertyPage)
  38. ON_WM_CREATE()
  39. ON_WM_DESTROY()
  40. //}}AFX_MSG_MAP
  41. END_MESSAGE_MAP()
  42. /////////////////////////////////////////////////////////////////////////////
  43. //++
  44. //
  45. // CBasePropertyPage::CBasePropertyPage
  46. //
  47. // Routine Description:
  48. // Default constructor.
  49. //
  50. // Arguments:
  51. // None.
  52. //
  53. // Return Value:
  54. // None.
  55. //
  56. //--
  57. /////////////////////////////////////////////////////////////////////////////
  58. CBasePropertyPage::CBasePropertyPage(void)
  59. {
  60. CommonConstruct();
  61. } //*** CBasePropertyPage::CBasePropertyPage()
  62. /////////////////////////////////////////////////////////////////////////////
  63. //++
  64. //
  65. // CBasePropertyPage::CBasePropertyPage
  66. //
  67. // Routine Description:
  68. // Default constructor.
  69. //
  70. // Arguments:
  71. // nIDTemplate [IN] Dialog template resource ID.
  72. // nIDCaption [IN] Caption string resource ID.
  73. //
  74. // Return Value:
  75. // None.
  76. //
  77. //--
  78. /////////////////////////////////////////////////////////////////////////////
  79. CBasePropertyPage::CBasePropertyPage(
  80. IN UINT nIDTemplate,
  81. IN UINT nIDCaption
  82. )
  83. : CPropertyPage(nIDTemplate, nIDCaption)
  84. {
  85. CommonConstruct();
  86. } //*** CBasePropertyPage::CBasePropertyPage(UINT, UINT)
  87. /////////////////////////////////////////////////////////////////////////////
  88. //++
  89. //
  90. // CBasePropertyPage::CommonConstruct
  91. //
  92. // Routine Description:
  93. // Common construction.
  94. //
  95. // Arguments:
  96. // None.
  97. //
  98. // Return Value:
  99. // None.
  100. //
  101. //--
  102. /////////////////////////////////////////////////////////////////////////////
  103. void CBasePropertyPage::CommonConstruct(void)
  104. {
  105. //{{AFX_DATA_INIT(CBasePropertyPage)
  106. //}}AFX_DATA_INIT
  107. m_peo = NULL;
  108. m_hpage = NULL;
  109. m_bBackPressed = FALSE;
  110. m_iddPropertyPage = NULL;
  111. m_iddWizardPage = NULL;
  112. m_idsCaption = NULL;
  113. m_bDoDetach = FALSE;
  114. } //*** CBasePropertyPage::CommonConstruct()
  115. /////////////////////////////////////////////////////////////////////////////
  116. //++
  117. //
  118. // CBasePropertyPage::BInit
  119. //
  120. // Routine Description:
  121. // Initialize the page.
  122. //
  123. // Arguments:
  124. // peo [IN OUT] Pointer to the extension object.
  125. //
  126. // Return Value:
  127. // TRUE Page initialized successfully.
  128. // FALSE Page failed to initialize.
  129. //
  130. //--
  131. /////////////////////////////////////////////////////////////////////////////
  132. BOOL CBasePropertyPage::BInit(IN OUT CExtObject * peo)
  133. {
  134. ASSERT(peo != NULL);
  135. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  136. CWaitCursor wc;
  137. m_peo = peo;
  138. // Don't display a help button.
  139. m_psp.dwFlags &= ~PSP_HASHELP;
  140. // Construct the property page.
  141. if (Peo()->BWizard())
  142. {
  143. ASSERT(IddWizardPage() != NULL);
  144. Construct(IddWizardPage(), IdsCaption());
  145. } // if: adding page to wizard
  146. else
  147. {
  148. ASSERT(IddPropertyPage() != NULL);
  149. Construct(IddPropertyPage(), IdsCaption());
  150. } // else: adding page to property sheet
  151. // Read the properties private to this resource and parse them.
  152. {
  153. DWORD dwStatus = ERROR_SUCCESS;
  154. CClusPropList cpl;
  155. ASSERT(Peo() != NULL);
  156. ASSERT(Peo()->PodObjData());
  157. // Read the properties.
  158. switch (Cot())
  159. {
  160. case CLUADMEX_OT_NODE:
  161. ASSERT(Peo()->PndNodeData()->m_hnode != NULL);
  162. dwStatus = cpl.DwGetNodeProperties(
  163. Peo()->PndNodeData()->m_hnode,
  164. CLUSCTL_NODE_GET_PRIVATE_PROPERTIES
  165. );
  166. break;
  167. case CLUADMEX_OT_GROUP:
  168. ASSERT(Peo()->PgdGroupData()->m_hgroup != NULL);
  169. dwStatus = cpl.DwGetGroupProperties(
  170. Peo()->PgdGroupData()->m_hgroup,
  171. CLUSCTL_GROUP_GET_PRIVATE_PROPERTIES
  172. );
  173. break;
  174. case CLUADMEX_OT_RESOURCE:
  175. ASSERT(Peo()->PrdResData()->m_hresource != NULL);
  176. dwStatus = cpl.DwGetResourceProperties(
  177. Peo()->PrdResData()->m_hresource,
  178. CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES
  179. );
  180. break;
  181. case CLUADMEX_OT_RESOURCETYPE:
  182. ASSERT(Peo()->PodObjData()->m_strName.GetLength() > 0);
  183. dwStatus = cpl.DwGetResourceTypeProperties(
  184. Hcluster(),
  185. Peo()->PodObjData()->m_strName,
  186. CLUSCTL_RESOURCE_TYPE_GET_PRIVATE_PROPERTIES
  187. );
  188. break;
  189. case CLUADMEX_OT_NETWORK:
  190. ASSERT(Peo()->PndNetworkData()->m_hnetwork != NULL);
  191. dwStatus = cpl.DwGetNetworkProperties(
  192. Peo()->PndNetworkData()->m_hnetwork,
  193. CLUSCTL_NETWORK_GET_PRIVATE_PROPERTIES
  194. );
  195. break;
  196. case CLUADMEX_OT_NETINTERFACE:
  197. ASSERT(Peo()->PndNetInterfaceData()->m_hnetinterface != NULL);
  198. dwStatus = cpl.DwGetNetInterfaceProperties(
  199. Peo()->PndNetInterfaceData()->m_hnetinterface,
  200. CLUSCTL_NETINTERFACE_GET_PRIVATE_PROPERTIES
  201. );
  202. break;
  203. default:
  204. ASSERT(0);
  205. } // switch: object type
  206. // Parse the properties.
  207. if (dwStatus == ERROR_SUCCESS)
  208. {
  209. // Parse the properties.
  210. try
  211. {
  212. dwStatus = DwParseProperties(cpl);
  213. } // try
  214. catch (CMemoryException * pme)
  215. {
  216. dwStatus = ERROR_NOT_ENOUGH_MEMORY;
  217. pme->Delete();
  218. } // catch: CMemoryException
  219. } // if: properties read successfully
  220. if (dwStatus != ERROR_SUCCESS)
  221. {
  222. return FALSE;
  223. } // if: error parsing getting or parsing properties
  224. } // Read the properties private to this resource and parse them
  225. return TRUE;
  226. } //*** CBasePropertyPage::BInit()
  227. /////////////////////////////////////////////////////////////////////////////
  228. //++
  229. //
  230. // CBasePropertyPage::DwParseProperties
  231. //
  232. // Routine Description:
  233. // Parse the properties of the resource. This is in a separate function
  234. // from BInit so that the optimizer can do a better job.
  235. //
  236. // Arguments:
  237. // rcpl [IN] Cluster property list to parse.
  238. //
  239. // Return Value:
  240. // ERROR_SUCCESS Properties were parsed successfully.
  241. //
  242. // Exceptions Thrown:
  243. // Any exceptions from CString::operator=().
  244. //
  245. //--
  246. /////////////////////////////////////////////////////////////////////////////
  247. DWORD CBasePropertyPage::DwParseProperties(IN const CClusPropList & rcpl)
  248. {
  249. DWORD cProps;
  250. DWORD cprop;
  251. DWORD cbProps;
  252. const CObjectProperty * pprop;
  253. CLUSPROP_BUFFER_HELPER props;
  254. CLUSPROP_PROPERTY_NAME const * pName;
  255. ASSERT(rcpl.PbProplist() != NULL);
  256. props.pb = rcpl.PbProplist();
  257. cbProps = rcpl.CbProplist();
  258. // Loop through each property.
  259. for (cProps = *(props.pdw++) ; cProps > 0 ; cProps--)
  260. {
  261. pName = props.pName;
  262. ASSERT(pName->Syntax.dw == CLUSPROP_SYNTAX_NAME);
  263. props.pb += sizeof(*pName) + ALIGN_CLUSPROP(pName->cbLength);
  264. // Decrement the counter by the size of the name.
  265. ASSERT(cbProps > sizeof(*pName) + ALIGN_CLUSPROP(pName->cbLength));
  266. cbProps -= sizeof(*pName) + ALIGN_CLUSPROP(pName->cbLength);
  267. ASSERT(cbProps > sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength));
  268. // Parse known properties.
  269. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  270. {
  271. if (lstrcmpiW(pName->sz, pprop->m_pwszName) == 0)
  272. {
  273. ASSERT(props.pSyntax->wFormat == pprop->m_propFormat);
  274. switch (pprop->m_propFormat)
  275. {
  276. case CLUSPROP_FORMAT_SZ:
  277. case CLUSPROP_FORMAT_EXPAND_SZ:
  278. ASSERT((props.pValue->cbLength == (lstrlenW(props.pStringValue->sz) + 1) * sizeof(WCHAR))
  279. || ((props.pValue->cbLength == 0) && (props.pStringValue->sz[0] == L'\0')));
  280. *pprop->m_value.pstr = props.pStringValue->sz;
  281. *pprop->m_valuePrev.pstr = props.pStringValue->sz;
  282. break;
  283. case CLUSPROP_FORMAT_DWORD:
  284. case CLUSPROP_FORMAT_LONG:
  285. ASSERT(props.pValue->cbLength == sizeof(DWORD));
  286. *pprop->m_value.pdw = props.pDwordValue->dw;
  287. *pprop->m_valuePrev.pdw = props.pDwordValue->dw;
  288. break;
  289. case CLUSPROP_FORMAT_BINARY:
  290. case CLUSPROP_FORMAT_MULTI_SZ:
  291. *pprop->m_value.ppb = props.pBinaryValue->rgb;
  292. *pprop->m_value.pcb = props.pBinaryValue->cbLength;
  293. *pprop->m_valuePrev.ppb = props.pBinaryValue->rgb;
  294. *pprop->m_valuePrev.pcb = props.pBinaryValue->cbLength;
  295. break;
  296. default:
  297. ASSERT(0); // don't know how to deal with this type
  298. } // switch: property format
  299. // Exit the loop since we found the parameter.
  300. break;
  301. } // if: found a match
  302. } // for: each property
  303. // If the property wasn't known, ask the derived class to parse it.
  304. if (cprop == 0)
  305. {
  306. DWORD dwStatus;
  307. dwStatus = DwParseUnknownProperty(pName->sz, props, cbProps);
  308. if (dwStatus != ERROR_SUCCESS)
  309. return dwStatus;
  310. } // if: property not parsed
  311. // Advance the buffer pointer past the value in the value list.
  312. while ((props.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK)
  313. && (cbProps > 0))
  314. {
  315. ASSERT(cbProps > sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength));
  316. cbProps -= sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength);
  317. props.pb += sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength);
  318. } // while: more values in the list
  319. // Advance the buffer pointer past the value list endmark.
  320. ASSERT(cbProps >= sizeof(*props.pSyntax));
  321. cbProps -= sizeof(*props.pSyntax);
  322. props.pb += sizeof(*props.pSyntax); // endmark
  323. } // for: each property
  324. return ERROR_SUCCESS;
  325. } //*** CBasePropertyPage::DwParseProperties()
  326. /////////////////////////////////////////////////////////////////////////////
  327. //++
  328. //
  329. // CBasePropertyPage::OnCreate
  330. //
  331. // Routine Description:
  332. // Handler for the WM_CREATE message.
  333. //
  334. // Arguments:
  335. // lpCreateStruct [IN OUT] Window create structure.
  336. //
  337. // Return Value:
  338. // -1 Error.
  339. // 0 Success.
  340. //
  341. //--
  342. /////////////////////////////////////////////////////////////////////////////
  343. int CBasePropertyPage::OnCreate(LPCREATESTRUCT lpCreateStruct)
  344. {
  345. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  346. // Attach the window to the property page structure.
  347. // This has been done once already in the main application, since the
  348. // main application owns the property sheet. It needs to be done here
  349. // so that the window handle can be found in the DLL's handle map.
  350. if (FromHandlePermanent(m_hWnd) == NULL) // is the window handle already in the handle map
  351. {
  352. HWND hWnd = m_hWnd;
  353. m_hWnd = NULL;
  354. Attach(hWnd);
  355. m_bDoDetach = TRUE;
  356. } // if: is the window handle in the handle map
  357. return CPropertyPage::OnCreate(lpCreateStruct);
  358. } //*** CBasePropertyPage::OnCreate()
  359. /////////////////////////////////////////////////////////////////////////////
  360. //++
  361. //
  362. // CBasePropertyPage::OnDestroy
  363. //
  364. // Routine Description:
  365. // Handler for the WM_DESTROY message.
  366. //
  367. // Arguments:
  368. // None.
  369. //
  370. // Return Value:
  371. // None.
  372. //
  373. //--
  374. /////////////////////////////////////////////////////////////////////////////
  375. void CBasePropertyPage::OnDestroy(void)
  376. {
  377. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  378. // Detach the window from the property page structure.
  379. // This will be done again by the main application, since it owns the
  380. // property sheet. It needs to be done here so that the window handle
  381. // can be removed from the DLL's handle map.
  382. if (m_bDoDetach)
  383. {
  384. if (m_hWnd != NULL)
  385. {
  386. HWND hWnd = m_hWnd;
  387. Detach();
  388. m_hWnd = hWnd;
  389. } // if: do we have a window handle?
  390. } // if: do we need to balance the attach we did with a detach?
  391. CPropertyPage::OnDestroy();
  392. } //*** CBasePropertyPage::OnDestroy()
  393. /////////////////////////////////////////////////////////////////////////////
  394. //++
  395. //
  396. // CBasePropertyPage::DoDataExchange
  397. //
  398. // Routine Description:
  399. // Do data exchange between the dialog and the class.
  400. //
  401. // Arguments:
  402. // pDX [IN OUT] Data exchange object
  403. //
  404. // Return Value:
  405. // None.
  406. //
  407. //--
  408. /////////////////////////////////////////////////////////////////////////////
  409. void CBasePropertyPage::DoDataExchange(CDataExchange * pDX)
  410. {
  411. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  412. //{{AFX_DATA_MAP(CBasePropertyPage)
  413. // NOTE: the ClassWizard will add DDX and DDV calls here
  414. //}}AFX_DATA_MAP
  415. DDX_Control(pDX, IDC_PP_ICON, m_staticIcon);
  416. DDX_Control(pDX, IDC_PP_TITLE, m_staticTitle);
  417. if (pDX->m_bSaveAndValidate)
  418. {
  419. if (!BBackPressed())
  420. {
  421. CWaitCursor wc;
  422. // Validate the data.
  423. if (!BSetPrivateProps(TRUE /*bValidateOnly*/))
  424. pDX->Fail();
  425. } // if: Back button not pressed
  426. } // if: saving data from dialog
  427. else
  428. {
  429. // Set the title.
  430. DDX_Text(pDX, IDC_PP_TITLE, m_strTitle);
  431. } // if: not saving data
  432. CPropertyPage::DoDataExchange(pDX);
  433. } //*** CBasePropertyPage::DoDataExchange()
  434. /////////////////////////////////////////////////////////////////////////////
  435. //++
  436. //
  437. // CBasePropertyPage::OnInitDialog
  438. //
  439. // Routine Description:
  440. // Handler for the WM_INITDIALOG message.
  441. //
  442. // Arguments:
  443. // None.
  444. //
  445. // Return Value:
  446. // TRUE We need the focus to be set for us.
  447. // FALSE We already set the focus to the proper control.
  448. //
  449. //--
  450. /////////////////////////////////////////////////////////////////////////////
  451. BOOL CBasePropertyPage::OnInitDialog(void)
  452. {
  453. ASSERT(Peo() != NULL);
  454. ASSERT(Peo()->PodObjData() != NULL);
  455. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  456. // Set the title string.
  457. m_strTitle = Peo()->PodObjData()->m_strName;
  458. // Call the base class method.
  459. CPropertyPage::OnInitDialog();
  460. // Display an icon for the object.
  461. if (Peo()->Hicon() != NULL)
  462. m_staticIcon.SetIcon(Peo()->Hicon());
  463. return TRUE; // return TRUE unless you set the focus to a control
  464. // EXCEPTION: OCX Property Pages should return FALSE
  465. } //*** CBasePropertyPage::OnInitDialog()
  466. /////////////////////////////////////////////////////////////////////////////
  467. //++
  468. //
  469. // CBasePropertyPage::OnSetActive
  470. //
  471. // Routine Description:
  472. // Handler for the PSN_SETACTIVE message.
  473. //
  474. // Arguments:
  475. // None.
  476. //
  477. // Return Value:
  478. // TRUE Page successfully initialized.
  479. // FALSE Page not initialized.
  480. //
  481. //--
  482. /////////////////////////////////////////////////////////////////////////////
  483. BOOL CBasePropertyPage::OnSetActive(void)
  484. {
  485. HRESULT hr;
  486. ASSERT(Peo() != NULL);
  487. ASSERT(Peo()->PodObjData() != NULL);
  488. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  489. // Reread the data.
  490. hr = Peo()->HrGetObjectInfo();
  491. if (hr != NOERROR)
  492. return FALSE;
  493. // Set the title string.
  494. m_strTitle = Peo()->PodObjData()->m_strName;
  495. m_bBackPressed = FALSE;
  496. return CPropertyPage::OnSetActive();
  497. } //*** CBasePropertyPage::OnSetActive()
  498. /////////////////////////////////////////////////////////////////////////////
  499. //++
  500. //
  501. // CBasePropertyPage::OnApply
  502. //
  503. // Routine Description:
  504. // Handler for the PSM_APPLY message.
  505. //
  506. // Arguments:
  507. // None.
  508. //
  509. // Return Value:
  510. // TRUE Page successfully applied.
  511. // FALSE Error applying page.
  512. //
  513. //--
  514. /////////////////////////////////////////////////////////////////////////////
  515. BOOL CBasePropertyPage::OnApply(void)
  516. {
  517. ASSERT(!BWizard());
  518. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  519. CWaitCursor wc;
  520. // Update the data in the class from the page.
  521. if (!UpdateData(TRUE /*bSaveAndValidate*/))
  522. return FALSE;
  523. if (!BApplyChanges())
  524. return FALSE;
  525. return CPropertyPage::OnApply();
  526. } //*** CBasePropertyPage::OnApply()
  527. /////////////////////////////////////////////////////////////////////////////
  528. //++
  529. //
  530. // CBasePropertyPage::OnWizardBack
  531. //
  532. // Routine Description:
  533. // Handler for the PSN_WIZBACK message.
  534. //
  535. // Arguments:
  536. // None.
  537. //
  538. // Return Value:
  539. // -1 Don't change the page.
  540. // 0 Change the page.
  541. //
  542. //--
  543. /////////////////////////////////////////////////////////////////////////////
  544. LRESULT CBasePropertyPage::OnWizardBack(void)
  545. {
  546. LRESULT lResult;
  547. ASSERT(BWizard());
  548. lResult = CPropertyPage::OnWizardBack();
  549. if (lResult != -1)
  550. m_bBackPressed = TRUE;
  551. return lResult;
  552. } //*** CBasePropertyPage::OnWizardBack()
  553. /////////////////////////////////////////////////////////////////////////////
  554. //++
  555. //
  556. // CBasePropertyPage::OnWizardNext
  557. //
  558. // Routine Description:
  559. // Handler for the PSN_WIZNEXT message.
  560. //
  561. // Arguments:
  562. // None.
  563. //
  564. // Return Value:
  565. // -1 Don't change the page.
  566. // 0 Change the page.
  567. //
  568. //--
  569. /////////////////////////////////////////////////////////////////////////////
  570. LRESULT CBasePropertyPage::OnWizardNext(void)
  571. {
  572. ASSERT(BWizard());
  573. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  574. CWaitCursor wc;
  575. // Update the data in the class from the page.
  576. if (!UpdateData(TRUE /*bSaveAndValidate*/))
  577. return -1;
  578. // Save the data in the sheet.
  579. if (!BApplyChanges())
  580. return -1;
  581. // Create the object.
  582. return CPropertyPage::OnWizardNext();
  583. } //*** CBasePropertyPage::OnWizardNext()
  584. /////////////////////////////////////////////////////////////////////////////
  585. //++
  586. //
  587. // CBasePropertyPage::OnWizardFinish
  588. //
  589. // Routine Description:
  590. // Handler for the PSN_WIZFINISH message.
  591. //
  592. // Arguments:
  593. // None.
  594. //
  595. // Return Value:
  596. // FALSE Don't change the page.
  597. // TRUE Change the page.
  598. //
  599. //--
  600. /////////////////////////////////////////////////////////////////////////////
  601. BOOL CBasePropertyPage::OnWizardFinish(void)
  602. {
  603. ASSERT(BWizard());
  604. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  605. CWaitCursor wc;
  606. // Update the data in the class from the page.
  607. if (!UpdateData(TRUE /*bSaveAndValidate*/))
  608. return FALSE;
  609. // Save the data in the sheet.
  610. if (!BApplyChanges())
  611. return FALSE;
  612. return CPropertyPage::OnWizardFinish();
  613. } //*** CBasePropertyPage::OnWizardFinish()
  614. /////////////////////////////////////////////////////////////////////////////
  615. //++
  616. //
  617. // CBasePropertyPage::OnChangeCtrl
  618. //
  619. // Routine Description:
  620. // Handler for the messages sent when a control is changed. This
  621. // method can be specified in a message map if all that needs to be
  622. // done is enable the Apply button.
  623. //
  624. // Arguments:
  625. // None.
  626. //
  627. // Return Value:
  628. // None.
  629. //
  630. //--
  631. /////////////////////////////////////////////////////////////////////////////
  632. void CBasePropertyPage::OnChangeCtrl(void)
  633. {
  634. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  635. SetModified(TRUE);
  636. } //*** CBasePropertyPage::OnChangeCtrl()
  637. /////////////////////////////////////////////////////////////////////////////
  638. //++
  639. //
  640. // CBasePropertyPage::EnableNext
  641. //
  642. // Routine Description:
  643. // Enables or disables the NEXT or FINISH button.
  644. //
  645. // Arguments:
  646. // bEnable [IN] TRUE = enable the button, FALSE = disable the button.
  647. //
  648. // Return Value:
  649. // None.
  650. //
  651. //--
  652. /////////////////////////////////////////////////////////////////////////////
  653. void CBasePropertyPage::EnableNext(IN BOOL bEnable /*TRUE*/)
  654. {
  655. ASSERT(BWizard());
  656. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  657. PiWizardCallback()->EnableNext((LONG *) Hpage(), bEnable);
  658. } //*** CBasePropertyPage::EnableNext()
  659. /////////////////////////////////////////////////////////////////////////////
  660. //++
  661. //
  662. // CBasePropertyPage::BApplyChanges
  663. //
  664. // Routine Description:
  665. // Apply changes made on the page.
  666. //
  667. // Arguments:
  668. // None.
  669. //
  670. // Return Value:
  671. // TRUE Page successfully applied.
  672. // FALSE Error applying page.
  673. //
  674. //--
  675. /////////////////////////////////////////////////////////////////////////////
  676. BOOL CBasePropertyPage::BApplyChanges(void)
  677. {
  678. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  679. CWaitCursor wc;
  680. // Save data.
  681. return BSetPrivateProps();
  682. } //*** CBasePropertyPage::BApplyChanges()
  683. /////////////////////////////////////////////////////////////////////////////
  684. //++
  685. //
  686. // CBasePropertyPage::BuildPropList
  687. //
  688. // Routine Description:
  689. // Build the property list.
  690. //
  691. // Arguments:
  692. // rcpl [IN OUT] Cluster property list.
  693. //
  694. // Return Value:
  695. // None.
  696. //
  697. // Exceptions Thrown:
  698. // Any exceptions thrown by CClusPropList::AddProp().
  699. //
  700. //--
  701. /////////////////////////////////////////////////////////////////////////////
  702. void CBasePropertyPage::BuildPropList(
  703. IN OUT CClusPropList & rcpl
  704. )
  705. {
  706. DWORD cprop;
  707. const CObjectProperty * pprop;
  708. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  709. {
  710. switch (pprop->m_propFormat)
  711. {
  712. case CLUSPROP_FORMAT_SZ:
  713. case CLUSPROP_FORMAT_EXPAND_SZ:
  714. rcpl.AddProp(
  715. pprop->m_pwszName,
  716. *pprop->m_value.pstr,
  717. *pprop->m_valuePrev.pstr
  718. );
  719. break;
  720. case CLUSPROP_FORMAT_DWORD:
  721. rcpl.AddProp(
  722. pprop->m_pwszName,
  723. *pprop->m_value.pdw,
  724. *pprop->m_valuePrev.pdw
  725. );
  726. break;
  727. case CLUSPROP_FORMAT_BINARY:
  728. case CLUSPROP_FORMAT_MULTI_SZ:
  729. rcpl.AddProp(
  730. pprop->m_pwszName,
  731. *pprop->m_value.ppb,
  732. *pprop->m_value.pcb,
  733. *pprop->m_valuePrev.ppb,
  734. *pprop->m_valuePrev.pcb
  735. );
  736. break;
  737. default:
  738. ASSERT(0); // don't know how to deal with this type
  739. return;
  740. } // switch: property format
  741. } // for: each property
  742. } //*** CBasePropertyPage::BuildPropList()
  743. /////////////////////////////////////////////////////////////////////////////
  744. //++
  745. //
  746. // CBasePropertyPage::BSetPrivateProps
  747. //
  748. // Routine Description:
  749. // Set the private properties for this object.
  750. //
  751. // Arguments:
  752. // bValidateOnly [IN] TRUE = only validate the data.
  753. //
  754. // Return Value:
  755. // ERROR_SUCCESS The operation was completed successfully.
  756. // !0 Failure.
  757. //
  758. //--
  759. /////////////////////////////////////////////////////////////////////////////
  760. BOOL CBasePropertyPage::BSetPrivateProps(IN BOOL bValidateOnly)
  761. {
  762. BOOL bSuccess = TRUE;
  763. CClusPropList cpl(BWizard() /*bAlwaysAddProp*/);
  764. CWaitCursor wc;
  765. ASSERT(Peo() != NULL);
  766. // Build the property list.
  767. try
  768. {
  769. BuildPropList(cpl);
  770. } // try
  771. catch (CException * pe)
  772. {
  773. pe->ReportError();
  774. pe->Delete();
  775. bSuccess = FALSE;
  776. } // catch: CException
  777. // Set the data.
  778. if (bSuccess)
  779. {
  780. if ((cpl.PbProplist() != NULL) && (cpl.CbProplist() > 0))
  781. {
  782. DWORD dwStatus = ERROR_SUCCESS;
  783. DWORD dwControlCode;
  784. DWORD cbProps;
  785. switch (Cot())
  786. {
  787. case CLUADMEX_OT_NODE:
  788. ASSERT(Peo()->PndNodeData() != NULL);
  789. ASSERT(Peo()->PndNodeData()->m_hnode != NULL);
  790. // Determine which control code to use.
  791. if (bValidateOnly)
  792. dwControlCode = CLUSCTL_NODE_VALIDATE_PRIVATE_PROPERTIES;
  793. else
  794. dwControlCode = CLUSCTL_NODE_SET_PRIVATE_PROPERTIES;
  795. // Set private properties.
  796. dwStatus = ClusterNodeControl(
  797. Peo()->PndNodeData()->m_hnode,
  798. NULL, // hNode
  799. dwControlCode,
  800. cpl.PbProplist(),
  801. cpl.CbProplist(),
  802. NULL, // lpOutBuffer
  803. 0, // nOutBufferSize
  804. &cbProps
  805. );
  806. break;
  807. case CLUADMEX_OT_GROUP:
  808. ASSERT(Peo()->PgdGroupData() != NULL);
  809. ASSERT(Peo()->PgdGroupData()->m_hgroup != NULL);
  810. // Determine which control code to use.
  811. if (bValidateOnly)
  812. dwControlCode = CLUSCTL_GROUP_VALIDATE_PRIVATE_PROPERTIES;
  813. else
  814. dwControlCode = CLUSCTL_GROUP_SET_PRIVATE_PROPERTIES;
  815. // Set private properties.
  816. dwStatus = ClusterGroupControl(
  817. Peo()->PgdGroupData()->m_hgroup,
  818. NULL, // hNode
  819. dwControlCode,
  820. cpl.PbProplist(),
  821. cpl.CbProplist(),
  822. NULL, // lpOutBuffer
  823. 0, // nOutBufferSize
  824. &cbProps
  825. );
  826. break;
  827. case CLUADMEX_OT_RESOURCE:
  828. ASSERT(Peo()->PrdResData() != NULL);
  829. ASSERT(Peo()->PrdResData()->m_hresource != NULL);
  830. // Determine which control code to use.
  831. if (bValidateOnly)
  832. dwControlCode = CLUSCTL_RESOURCE_VALIDATE_PRIVATE_PROPERTIES;
  833. else
  834. dwControlCode = CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES;
  835. // Set private properties.
  836. dwStatus = ClusterResourceControl(
  837. Peo()->PrdResData()->m_hresource,
  838. NULL, // hNode
  839. dwControlCode,
  840. cpl.PbProplist(),
  841. cpl.CbProplist(),
  842. NULL, // lpOutBuffer
  843. 0, // nOutBufferSize
  844. &cbProps
  845. );
  846. break;
  847. case CLUADMEX_OT_RESOURCETYPE:
  848. ASSERT(Peo()->PodObjData() != NULL);
  849. ASSERT(Peo()->PodObjData()->m_strName.GetLength() > 0);
  850. // Determine which control code to use.
  851. if (bValidateOnly)
  852. dwControlCode = CLUSCTL_RESOURCE_TYPE_VALIDATE_PRIVATE_PROPERTIES;
  853. else
  854. dwControlCode = CLUSCTL_RESOURCE_TYPE_SET_PRIVATE_PROPERTIES;
  855. // Set private properties.
  856. dwStatus = ClusterResourceTypeControl(
  857. Hcluster(),
  858. Peo()->PodObjData()->m_strName,
  859. NULL, // hNode
  860. dwControlCode,
  861. cpl.PbProplist(),
  862. cpl.CbProplist(),
  863. NULL, // lpOutBuffer
  864. 0, // nOutBufferSize
  865. &cbProps
  866. );
  867. break;
  868. case CLUADMEX_OT_NETWORK:
  869. ASSERT(Peo()->PndNetworkData() != NULL);
  870. ASSERT(Peo()->PndNetworkData()->m_hnetwork != NULL);
  871. // Determine which control code to use.
  872. if (bValidateOnly)
  873. dwControlCode = CLUSCTL_NETWORK_VALIDATE_PRIVATE_PROPERTIES;
  874. else
  875. dwControlCode = CLUSCTL_NETWORK_SET_PRIVATE_PROPERTIES;
  876. // Set private properties.
  877. dwStatus = ClusterNetworkControl(
  878. Peo()->PndNetworkData()->m_hnetwork,
  879. NULL, // hNode
  880. dwControlCode,
  881. cpl.PbProplist(),
  882. cpl.CbProplist(),
  883. NULL, // lpOutBuffer
  884. 0, // nOutBufferSize
  885. &cbProps
  886. );
  887. break;
  888. case CLUADMEX_OT_NETINTERFACE:
  889. ASSERT(Peo()->PndNetInterfaceData() != NULL);
  890. ASSERT(Peo()->PndNetInterfaceData()->m_hnetinterface != NULL);
  891. // Determine which control code to use.
  892. if (bValidateOnly)
  893. dwControlCode = CLUSCTL_NETINTERFACE_VALIDATE_PRIVATE_PROPERTIES;
  894. else
  895. dwControlCode = CLUSCTL_NETINTERFACE_SET_PRIVATE_PROPERTIES;
  896. // Set private properties.
  897. dwStatus = ClusterNetInterfaceControl(
  898. Peo()->PndNetInterfaceData()->m_hnetinterface,
  899. NULL, // hNode
  900. dwControlCode,
  901. cpl.PbProplist(),
  902. cpl.CbProplist(),
  903. NULL, // lpOutBuffer
  904. 0, // nOutBufferSize
  905. &cbProps
  906. );
  907. break;
  908. default:
  909. ASSERT(0);
  910. } // switch: object type
  911. // Handle errors.
  912. if (dwStatus != ERROR_SUCCESS)
  913. {
  914. CString strMsg;
  915. FormatError(strMsg, dwStatus);
  916. AfxMessageBox(strMsg);
  917. if (bValidateOnly
  918. || (dwStatus != ERROR_RESOURCE_PROPERTIES_STORED))
  919. bSuccess = FALSE;
  920. } // if: error setting/validating data
  921. } // if: there is data to set
  922. } // if: no errors building the property list
  923. // Save data locally.
  924. if (!bValidateOnly && bSuccess)
  925. {
  926. // Save new values as previous values.
  927. try
  928. {
  929. DWORD cprop;
  930. const CObjectProperty * pprop;
  931. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  932. {
  933. switch (pprop->m_propFormat)
  934. {
  935. case CLUSPROP_FORMAT_SZ:
  936. case CLUSPROP_FORMAT_EXPAND_SZ:
  937. ASSERT(pprop->m_value.pstr != NULL);
  938. ASSERT(pprop->m_valuePrev.pstr != NULL);
  939. *pprop->m_valuePrev.pstr = *pprop->m_value.pstr;
  940. break;
  941. case CLUSPROP_FORMAT_DWORD:
  942. ASSERT(pprop->m_value.pdw != NULL);
  943. ASSERT(pprop->m_valuePrev.pdw != NULL);
  944. *pprop->m_valuePrev.pdw = *pprop->m_value.pdw;
  945. break;
  946. case CLUSPROP_FORMAT_BINARY:
  947. case CLUSPROP_FORMAT_MULTI_SZ:
  948. ASSERT(pprop->m_value.ppb != NULL);
  949. ASSERT(*pprop->m_value.ppb != NULL);
  950. ASSERT(pprop->m_value.pcb != NULL);
  951. ASSERT(pprop->m_valuePrev.ppb != NULL);
  952. ASSERT(*pprop->m_valuePrev.ppb != NULL);
  953. ASSERT(pprop->m_valuePrev.pcb != NULL);
  954. delete [] *pprop->m_valuePrev.ppb;
  955. *pprop->m_valuePrev.ppb = new BYTE[*pprop->m_value.pcb];
  956. CopyMemory(*pprop->m_valuePrev.ppb, *pprop->m_value.ppb, *pprop->m_value.pcb);
  957. *pprop->m_valuePrev.pcb = *pprop->m_value.pcb;
  958. break;
  959. default:
  960. ASSERT(0); // don't know how to deal with this type
  961. } // switch: property format
  962. } // for: each property
  963. } // try
  964. catch (CException * pe)
  965. {
  966. pe->ReportError();
  967. pe->Delete();
  968. bSuccess = FALSE;
  969. } // catch: CException
  970. } // if: not just validating and successful so far
  971. return bSuccess;
  972. } //*** CBasePropertyPage::BSetPrivateProps()