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.

935 lines
29 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // BasePage.cpp
  7. //
  8. // Description:
  9. // Implementation of the CBasePropertyPage class.
  10. //
  11. // Maintained By:
  12. // David Potter (DavidP) Mmmm DD, 1997
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include <clusapi.h>
  21. #include "DebugEx.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. ON_WM_HELPINFO()
  41. ON_WM_CONTEXTMENU()
  42. ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
  43. //}}AFX_MSG_MAP
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. //++
  47. //
  48. // CBasePropertyPage::CBasePropertyPage
  49. //
  50. // Routine Description:
  51. // Default constructor.
  52. //
  53. // Arguments:
  54. // None.
  55. //
  56. // Return Value:
  57. // None.
  58. //
  59. //--
  60. /////////////////////////////////////////////////////////////////////////////
  61. CBasePropertyPage::CBasePropertyPage(void)
  62. {
  63. CommonConstruct();
  64. } //*** CBasePropertyPage::CBasePropertyPage()
  65. /////////////////////////////////////////////////////////////////////////////
  66. //++
  67. //
  68. // CBasePropertyPage::CBasePropertyPage
  69. //
  70. // Routine Description:
  71. // Default constructor.
  72. //
  73. // Arguments:
  74. // idd [IN] Dialog template resource ID.
  75. // pdwHelpMap [IN] Control-to-help ID map.
  76. // pdwWizardHelpMap [IN] Control-to-help ID map if this is a wizard page.
  77. // nIDCaption [IN] Caption string resource ID.
  78. //
  79. // Return Value:
  80. // None.
  81. //
  82. //--
  83. /////////////////////////////////////////////////////////////////////////////
  84. CBasePropertyPage::CBasePropertyPage(
  85. IN UINT idd,
  86. IN const DWORD * pdwHelpMap,
  87. IN const DWORD * pdwWizardHelpMap,
  88. IN UINT nIDCaption
  89. )
  90. : CPropertyPage(idd, nIDCaption)
  91. , m_dlghelp(pdwHelpMap, idd)
  92. {
  93. CommonConstruct();
  94. m_pdwWizardHelpMap = pdwWizardHelpMap;
  95. } //*** CBasePropertyPage::CBasePropertyPage(UINT, UINT)
  96. /////////////////////////////////////////////////////////////////////////////
  97. //++
  98. //
  99. // CBasePropertyPage::CommonConstruct
  100. //
  101. // Routine Description:
  102. // Common construction.
  103. //
  104. // Arguments:
  105. // None.
  106. //
  107. // Return Value:
  108. // None.
  109. //
  110. //--
  111. /////////////////////////////////////////////////////////////////////////////
  112. void CBasePropertyPage::CommonConstruct(void)
  113. {
  114. //{{AFX_DATA_INIT(CBasePropertyPage)
  115. //}}AFX_DATA_INIT
  116. m_peo = NULL;
  117. m_hpage = NULL;
  118. m_bBackPressed = FALSE;
  119. m_iddPropertyPage = NULL;
  120. m_iddWizardPage = NULL;
  121. m_idsCaption = NULL;
  122. m_pdwWizardHelpMap = NULL;
  123. m_bDoDetach = FALSE;
  124. } //*** CBasePropertyPage::CommonConstruct()
  125. /////////////////////////////////////////////////////////////////////////////
  126. //++
  127. //
  128. // CBasePropertyPage::BInit
  129. //
  130. // Routine Description:
  131. // Initialize the page.
  132. //
  133. // Arguments:
  134. // peo [IN OUT] Pointer to the extension object.
  135. //
  136. // Return Value:
  137. // TRUE Page initialized successfully.
  138. // FALSE Page failed to initialize.
  139. //
  140. //--
  141. /////////////////////////////////////////////////////////////////////////////
  142. BOOL CBasePropertyPage::BInit(IN OUT CExtObject * peo)
  143. {
  144. ASSERT(peo != NULL);
  145. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  146. CWaitCursor wc;
  147. m_peo = peo;
  148. // Change the help map if this is a wizard page.
  149. if (Peo()->BWizard())
  150. m_dlghelp.SetMap(m_pdwWizardHelpMap);
  151. // Don't display a help button.
  152. m_psp.dwFlags &= ~PSP_HASHELP;
  153. // Construct the property page.
  154. if (Peo()->BWizard())
  155. {
  156. ASSERT(IddWizardPage() != NULL);
  157. Construct(IddWizardPage(), IdsCaption());
  158. m_dlghelp.SetHelpMask(IddWizardPage());
  159. } // if: adding page to wizard
  160. else
  161. {
  162. ASSERT(IddPropertyPage() != NULL);
  163. Construct(IddPropertyPage(), IdsCaption());
  164. m_dlghelp.SetHelpMask(IddPropertyPage());
  165. } // else: adding page to property sheet
  166. // Read the properties common to this resource and parse them.
  167. {
  168. DWORD dwStatus;
  169. CClusPropList cpl;
  170. // Read the properties.
  171. ASSERT(Peo() != NULL);
  172. if (Peo()->PodObjData()->m_cot == CLUADMEX_OT_RESOURCE)
  173. {
  174. ASSERT(Peo()->PrdResData() != NULL);
  175. ASSERT(Peo()->PrdResData()->m_hresource != NULL);
  176. dwStatus = cpl.ScGetResourceProperties(
  177. Peo()->PrdResData()->m_hresource,
  178. CLUSCTL_RESOURCE_GET_COMMON_PROPERTIES
  179. );
  180. } // if: resource object
  181. else
  182. {
  183. ASSERT(Peo()->PodObjData() != NULL);
  184. ASSERT(Peo()->PodObjData()->m_strName.GetLength() != 0);
  185. dwStatus = cpl.ScGetResourceTypeProperties(
  186. Hcluster(),
  187. Peo()->PodObjData()->m_strName,
  188. CLUSCTL_RESOURCE_TYPE_GET_COMMON_PROPERTIES
  189. );
  190. } // else: resource type object
  191. // Parse the properties.
  192. if (dwStatus == ERROR_SUCCESS)
  193. {
  194. // Parse the properties.
  195. try
  196. {
  197. dwStatus = DwParseProperties(cpl);
  198. } // try
  199. catch (CMemoryException * pme)
  200. {
  201. dwStatus = ERROR_NOT_ENOUGH_MEMORY;
  202. pme->Delete();
  203. } // catch: CMemoryException
  204. } // if: properties read successfully
  205. if (dwStatus != ERROR_SUCCESS)
  206. {
  207. return FALSE;
  208. } // if: error parsing getting or parsing properties
  209. } // Read the properties private to this resource and parse them
  210. return TRUE;
  211. } //*** CBasePropertyPage::BInit()
  212. /////////////////////////////////////////////////////////////////////////////
  213. //++
  214. //
  215. // CBasePropertyPage::DwParseProperties
  216. //
  217. // Routine Description:
  218. // Parse the properties of the resource. This is in a separate function
  219. // from BInit so that the optimizer can do a better job.
  220. //
  221. // Arguments:
  222. // rcpl [IN] Cluster property list to parse.
  223. //
  224. // Return Value:
  225. // ERROR_SUCCESS Properties were parsed successfully.
  226. //
  227. // Exceptions Thrown:
  228. // Any exceptions from CString::operator=().
  229. //
  230. //--
  231. /////////////////////////////////////////////////////////////////////////////
  232. DWORD CBasePropertyPage::DwParseProperties(IN const CClusPropList & rcpl)
  233. {
  234. DWORD cProps;
  235. DWORD cprop;
  236. DWORD cbProps;
  237. const CObjectProperty * pprop;
  238. CLUSPROP_BUFFER_HELPER props;
  239. CLUSPROP_PROPERTY_NAME const * pName;
  240. ASSERT(rcpl.PbPropList() != NULL);
  241. props.pb = rcpl.PbPropList();
  242. cbProps = static_cast< DWORD >( rcpl.CbPropList() );
  243. // Loop through each property.
  244. for (cProps = *(props.pdw++) ; cProps > 0 ; cProps--)
  245. {
  246. pName = props.pName;
  247. ASSERT(pName->Syntax.dw == CLUSPROP_SYNTAX_NAME);
  248. props.pb += sizeof(*pName) + ALIGN_CLUSPROP(pName->cbLength);
  249. // Decrement the counter by the size of the name.
  250. ASSERT(cbProps > sizeof(*pName) + ALIGN_CLUSPROP(pName->cbLength));
  251. cbProps -= sizeof(*pName) + ALIGN_CLUSPROP(pName->cbLength);
  252. ASSERT(cbProps > sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength));
  253. // Parse known properties.
  254. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  255. {
  256. if (lstrcmpiW(pName->sz, pprop->m_pwszName) == 0)
  257. {
  258. ASSERT(props.pSyntax->wFormat == pprop->m_propFormat);
  259. switch (pprop->m_propFormat)
  260. {
  261. case CLUSPROP_FORMAT_SZ:
  262. ASSERT((props.pValue->cbLength == (lstrlenW(props.pStringValue->sz) + 1) * sizeof(WCHAR))
  263. || ((props.pValue->cbLength == 0) && (props.pStringValue->sz[0] == L'\0')));
  264. *pprop->m_value.pstr = props.pStringValue->sz;
  265. *pprop->m_valuePrev.pstr = props.pStringValue->sz;
  266. break;
  267. case CLUSPROP_FORMAT_DWORD:
  268. case CLUSPROP_FORMAT_LONG:
  269. ASSERT(props.pValue->cbLength == sizeof(DWORD));
  270. *pprop->m_value.pdw = props.pDwordValue->dw;
  271. *pprop->m_valuePrev.pdw = props.pDwordValue->dw;
  272. break;
  273. case CLUSPROP_FORMAT_BINARY:
  274. case CLUSPROP_FORMAT_MULTI_SZ:
  275. *pprop->m_value.ppb = props.pBinaryValue->rgb;
  276. *pprop->m_value.pcb = props.pBinaryValue->cbLength;
  277. *pprop->m_valuePrev.ppb = props.pBinaryValue->rgb;
  278. *pprop->m_valuePrev.pcb = props.pBinaryValue->cbLength;
  279. break;
  280. default:
  281. ASSERT(0); // don't know how to deal with this type
  282. } // switch: property format
  283. // Exit the loop since we found the parameter.
  284. break;
  285. } // if: found a match
  286. } // for: each property
  287. // If the property wasn't known, ask the derived class to parse it.
  288. if (cprop == 0)
  289. {
  290. DWORD dwStatus;
  291. dwStatus = DwParseUnknownProperty(pName->sz, props, cbProps);
  292. if (dwStatus != ERROR_SUCCESS)
  293. return dwStatus;
  294. } // if: property not parsed
  295. // Advance the buffer pointer past the value in the value list.
  296. while ((props.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK)
  297. && (cbProps > 0))
  298. {
  299. ASSERT(cbProps > sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength));
  300. cbProps -= sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength);
  301. props.pb += sizeof(*props.pValue) + ALIGN_CLUSPROP(props.pValue->cbLength);
  302. } // while: more values in the list
  303. // Advance the buffer pointer past the value list endmark.
  304. ASSERT(cbProps >= sizeof(*props.pSyntax));
  305. cbProps -= sizeof(*props.pSyntax);
  306. props.pb += sizeof(*props.pSyntax); // endmark
  307. } // for: each property
  308. return ERROR_SUCCESS;
  309. } //*** CBasePropertyPage::DwParseProperties()
  310. /////////////////////////////////////////////////////////////////////////////
  311. //++
  312. //
  313. // CBasePropertyPage::OnCreate
  314. //
  315. // Routine Description:
  316. // Handler for the WM_CREATE message.
  317. //
  318. // Arguments:
  319. // lpCreateStruct [IN OUT] Window create structure.
  320. //
  321. // Return Value:
  322. // -1 Error.
  323. // 0 Success.
  324. //
  325. //--
  326. /////////////////////////////////////////////////////////////////////////////
  327. int CBasePropertyPage::OnCreate(LPCREATESTRUCT lpCreateStruct)
  328. {
  329. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  330. // Attach the window to the property page structure.
  331. // This has been done once already in the main application, since the
  332. // main application owns the property sheet. It needs to be done here
  333. // so that the window handle can be found in the DLL's handle map.
  334. if (FromHandlePermanent(m_hWnd) == NULL) // is the window handle already in the handle map
  335. {
  336. HWND hWnd = m_hWnd;
  337. m_hWnd = NULL;
  338. Attach(hWnd);
  339. m_bDoDetach = TRUE;
  340. } // if: is the window handle in the handle map
  341. return CPropertyPage::OnCreate(lpCreateStruct);
  342. } //*** CBasePropertyPage::OnCreate()
  343. /////////////////////////////////////////////////////////////////////////////
  344. //++
  345. //
  346. // CBasePropertyPage::OnDestroy
  347. //
  348. // Routine Description:
  349. // Handler for the WM_DESTROY message.
  350. //
  351. // Arguments:
  352. // None.
  353. //
  354. // Return Value:
  355. // None.
  356. //
  357. //--
  358. /////////////////////////////////////////////////////////////////////////////
  359. void CBasePropertyPage::OnDestroy(void)
  360. {
  361. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  362. // Detach the window from the property page structure.
  363. // This will be done again by the main application, since it owns the
  364. // property sheet. It needs to be done here so that the window handle
  365. // can be removed from the DLL's handle map.
  366. if (m_bDoDetach)
  367. {
  368. if (m_hWnd != NULL)
  369. {
  370. HWND hWnd = m_hWnd;
  371. Detach();
  372. m_hWnd = hWnd;
  373. } // if: do we have a window handle?
  374. } // if: do we need to balance the attach we did with a detach?
  375. CPropertyPage::OnDestroy();
  376. } //*** CBasePropertyPage::OnDestroy()
  377. /////////////////////////////////////////////////////////////////////////////
  378. //++
  379. //
  380. // CBasePropertyPage::DoDataExchange
  381. //
  382. // Routine Description:
  383. // Do data exchange between the dialog and the class.
  384. //
  385. // Arguments:
  386. // pDX [IN OUT] Data exchange object
  387. //
  388. // Return Value:
  389. // None.
  390. //
  391. //--
  392. /////////////////////////////////////////////////////////////////////////////
  393. void CBasePropertyPage::DoDataExchange(CDataExchange * pDX)
  394. {
  395. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  396. //{{AFX_DATA_MAP(CBasePropertyPage)
  397. // NOTE: the ClassWizard will add DDX and DDV calls here
  398. //}}AFX_DATA_MAP
  399. DDX_Control(pDX, IDC_PP_ICON, m_staticIcon);
  400. DDX_Control(pDX, IDC_PP_TITLE, m_staticTitle);
  401. if (!pDX->m_bSaveAndValidate)
  402. {
  403. // Set the title.
  404. DDX_Text(pDX, IDC_PP_TITLE, m_strTitle);
  405. } // if: not saving data
  406. CPropertyPage::DoDataExchange(pDX);
  407. } //*** CBasePropertyPage::DoDataExchange()
  408. /////////////////////////////////////////////////////////////////////////////
  409. //++
  410. //
  411. // CBasePropertyPage::OnInitDialog
  412. //
  413. // Routine Description:
  414. // Handler for the WM_INITDIALOG message.
  415. //
  416. // Arguments:
  417. // None.
  418. //
  419. // Return Value:
  420. // TRUE We need the focus to be set for us.
  421. // FALSE We already set the focus to the proper control.
  422. //
  423. //--
  424. /////////////////////////////////////////////////////////////////////////////
  425. BOOL CBasePropertyPage::OnInitDialog(void)
  426. {
  427. ASSERT(Peo() != NULL);
  428. ASSERT(Peo()->PodObjData() != NULL);
  429. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  430. // Set the title string.
  431. m_strTitle = Peo()->PodObjData()->m_strName;
  432. // Call the base class method.
  433. CPropertyPage::OnInitDialog();
  434. // Display an icon for the object.
  435. if (Peo()->Hicon() != NULL)
  436. m_staticIcon.SetIcon(Peo()->Hicon());
  437. return TRUE; // return TRUE unless you set the focus to a control
  438. // EXCEPTION: OCX Property Pages should return FALSE
  439. } //*** CBasePropertyPage::OnInitDialog()
  440. /////////////////////////////////////////////////////////////////////////////
  441. //++
  442. //
  443. // CBasePropertyPage::OnSetActive
  444. //
  445. // Routine Description:
  446. // Handler for the PSN_SETACTIVE message.
  447. //
  448. // Arguments:
  449. // None.
  450. //
  451. // Return Value:
  452. // TRUE Page successfully initialized.
  453. // FALSE Page not initialized.
  454. //
  455. //--
  456. /////////////////////////////////////////////////////////////////////////////
  457. BOOL CBasePropertyPage::OnSetActive(void)
  458. {
  459. HRESULT hr;
  460. ASSERT(Peo() != NULL);
  461. ASSERT(Peo()->PodObjData() != NULL);
  462. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  463. // Reread the data.
  464. hr = Peo()->HrGetObjectInfo();
  465. if (hr != NOERROR)
  466. return FALSE;
  467. // Set the title string.
  468. m_strTitle = Peo()->PodObjData()->m_strName;
  469. m_bBackPressed = FALSE;
  470. return CPropertyPage::OnSetActive();
  471. } //*** CBasePropertyPage::OnSetActive()
  472. /////////////////////////////////////////////////////////////////////////////
  473. //++
  474. //
  475. // CBasePropertyPage::OnApply
  476. //
  477. // Routine Description:
  478. // Handler for the PSM_APPLY message.
  479. //
  480. // Arguments:
  481. // None.
  482. //
  483. // Return Value:
  484. // TRUE Page successfully applied.
  485. // FALSE Error applying page.
  486. //
  487. //--
  488. /////////////////////////////////////////////////////////////////////////////
  489. BOOL CBasePropertyPage::OnApply(void)
  490. {
  491. ASSERT(!BWizard());
  492. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  493. CWaitCursor wc;
  494. // Update the data in the class from the page.
  495. if (!UpdateData(TRUE /*bSaveAndValidate*/))
  496. return FALSE;
  497. if (!BApplyChanges())
  498. return FALSE;
  499. return CPropertyPage::OnApply();
  500. } //*** CBasePropertyPage::OnApply()
  501. /////////////////////////////////////////////////////////////////////////////
  502. //++
  503. //
  504. // CBasePropertyPage::OnChangeCtrl
  505. //
  506. // Routine Description:
  507. // Handler for the messages sent when a control is changed. This
  508. // method can be specified in a message map if all that needs to be
  509. // done is enable the Apply button.
  510. //
  511. // Arguments:
  512. // None.
  513. //
  514. // Return Value:
  515. // None.
  516. //
  517. //--
  518. /////////////////////////////////////////////////////////////////////////////
  519. void CBasePropertyPage::OnChangeCtrl(void)
  520. {
  521. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  522. SetModified(TRUE);
  523. } //*** CBasePropertyPage::OnChangeCtrl()
  524. /////////////////////////////////////////////////////////////////////////////
  525. //++
  526. //
  527. // CBasePropertyPage::BApplyChanges
  528. //
  529. // Routine Description:
  530. // Apply changes made on the page.
  531. //
  532. // Arguments:
  533. // None.
  534. //
  535. // Return Value:
  536. // TRUE Page successfully applied.
  537. // FALSE Error applying page.
  538. //
  539. //--
  540. /////////////////////////////////////////////////////////////////////////////
  541. BOOL CBasePropertyPage::BApplyChanges(void)
  542. {
  543. DWORD dwStatus = ERROR_SUCCESS;
  544. CClusPropList cpl(BWizard() /*bAlwaysAddProp*/);
  545. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  546. CWaitCursor wc;
  547. // Save data.
  548. {
  549. // Build the property list.
  550. try
  551. {
  552. BuildPropList(cpl);
  553. } // try
  554. catch (CMemoryException * pme)
  555. {
  556. pme->Delete();
  557. dwStatus = ERROR_NOT_ENOUGH_MEMORY;
  558. } // catch: CMemoryException
  559. // Set the data.
  560. if (dwStatus == ERROR_SUCCESS)
  561. dwStatus = DwSetCommonProps(cpl);
  562. // Handle errors.
  563. if (dwStatus != ERROR_SUCCESS)
  564. {
  565. CString strError;
  566. CString strMsg;
  567. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  568. FormatError(strError, dwStatus);
  569. if (dwStatus == ERROR_RESOURCE_PROPERTIES_STORED)
  570. {
  571. AfxMessageBox(strError, MB_OK | MB_ICONEXCLAMATION);
  572. dwStatus = ERROR_SUCCESS;
  573. } // if: properties were stored
  574. else
  575. {
  576. strMsg.FormatMessage(IDS_APPLY_PARAM_CHANGES_ERROR, strError);
  577. AfxMessageBox(strMsg, MB_OK | MB_ICONEXCLAMATION);
  578. return FALSE;
  579. } // else: error setting properties.
  580. } // if: error setting properties
  581. if (dwStatus == ERROR_SUCCESS)
  582. {
  583. // Save new values as previous values.
  584. try
  585. {
  586. DWORD cprop;
  587. const CObjectProperty * pprop;
  588. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  589. {
  590. switch (pprop->m_propFormat)
  591. {
  592. case CLUSPROP_FORMAT_SZ:
  593. ASSERT(pprop->m_value.pstr != NULL);
  594. ASSERT(pprop->m_valuePrev.pstr != NULL);
  595. *pprop->m_valuePrev.pstr = *pprop->m_value.pstr;
  596. break;
  597. case CLUSPROP_FORMAT_DWORD:
  598. ASSERT(pprop->m_value.pdw != NULL);
  599. ASSERT(pprop->m_valuePrev.pdw != NULL);
  600. *pprop->m_valuePrev.pdw = *pprop->m_value.pdw;
  601. break;
  602. case CLUSPROP_FORMAT_BINARY:
  603. case CLUSPROP_FORMAT_MULTI_SZ:
  604. ASSERT(pprop->m_value.ppb != NULL);
  605. ASSERT(*pprop->m_value.ppb != NULL);
  606. ASSERT(pprop->m_value.pcb != NULL);
  607. ASSERT(pprop->m_valuePrev.ppb != NULL);
  608. ASSERT(*pprop->m_valuePrev.ppb != NULL);
  609. ASSERT(pprop->m_valuePrev.pcb != NULL);
  610. delete [] *pprop->m_valuePrev.ppb;
  611. *pprop->m_valuePrev.ppb = new BYTE[*pprop->m_value.pcb];
  612. CopyMemory(*pprop->m_valuePrev.ppb, *pprop->m_value.ppb, *pprop->m_value.pcb);
  613. *pprop->m_valuePrev.pcb = *pprop->m_value.pcb;
  614. break;
  615. default:
  616. ASSERT(0); // don't know how to deal with this type
  617. } // switch: property format
  618. } // for: each property
  619. } // try
  620. catch (CMemoryException * pme)
  621. {
  622. pme->ReportError();
  623. pme->Delete();
  624. } // catch: CMemoryException
  625. } // if: properties set successfully
  626. } // Save data
  627. return TRUE;
  628. } //*** CBasePropertyPage::BApplyChanges()
  629. /////////////////////////////////////////////////////////////////////////////
  630. //++
  631. //
  632. // CBasePropertyPage::BuildPropList
  633. //
  634. // Routine Description:
  635. // Build the property list.
  636. //
  637. // Arguments:
  638. // rcpl [IN OUT] Cluster property list.
  639. //
  640. // Return Value:
  641. // None.
  642. //
  643. // Exceptions Thrown:
  644. // Any exceptions thrown by CClusPropList::ScAddProp().
  645. //
  646. //--
  647. /////////////////////////////////////////////////////////////////////////////
  648. void CBasePropertyPage::BuildPropList(
  649. IN OUT CClusPropList & rcpl
  650. )
  651. {
  652. DWORD cprop;
  653. const CObjectProperty * pprop;
  654. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  655. {
  656. switch (pprop->m_propFormat)
  657. {
  658. case CLUSPROP_FORMAT_SZ:
  659. rcpl.ScAddProp(
  660. pprop->m_pwszName,
  661. *pprop->m_value.pstr,
  662. *pprop->m_valuePrev.pstr
  663. );
  664. break;
  665. case CLUSPROP_FORMAT_DWORD:
  666. rcpl.ScAddProp(
  667. pprop->m_pwszName,
  668. *pprop->m_value.pdw,
  669. *pprop->m_valuePrev.pdw
  670. );
  671. break;
  672. case CLUSPROP_FORMAT_BINARY:
  673. case CLUSPROP_FORMAT_MULTI_SZ:
  674. rcpl.ScAddProp(
  675. pprop->m_pwszName,
  676. *pprop->m_value.ppb,
  677. *pprop->m_value.pcb,
  678. *pprop->m_valuePrev.ppb,
  679. *pprop->m_valuePrev.pcb
  680. );
  681. break;
  682. default:
  683. ASSERT(0); // don't know how to deal with this type
  684. return;
  685. } // switch: property format
  686. } // for: each property
  687. } //*** CBasePropertyPage::BuildPropList()
  688. /////////////////////////////////////////////////////////////////////////////
  689. //++
  690. //
  691. // CBasePropertyPage::DwSetCommonProps
  692. //
  693. // Routine Description:
  694. // Set the private properties for this object.
  695. //
  696. // Arguments:
  697. // rcpl [IN] Property list to set on the object.
  698. //
  699. // Return Value:
  700. // ERROR_SUCCESS The operation was completed successfully.
  701. // !0 Failure.
  702. //
  703. //--
  704. /////////////////////////////////////////////////////////////////////////////
  705. DWORD CBasePropertyPage::DwSetCommonProps(
  706. IN const CClusPropList & rcpl
  707. )
  708. {
  709. DWORD dwStatus;
  710. DWORD cbProps;
  711. ASSERT(Peo() != NULL);
  712. ASSERT(Peo()->PrdResData());
  713. ASSERT(Peo()->PrdResData()->m_hresource);
  714. if ((rcpl.PbPropList() != NULL) && (rcpl.CbPropList() > 0))
  715. {
  716. // Set private properties.
  717. if (Cot() == CLUADMEX_OT_RESOURCE)
  718. dwStatus = ClusterResourceControl(
  719. Peo()->PrdResData()->m_hresource,
  720. NULL, // hNode
  721. CLUSCTL_RESOURCE_SET_COMMON_PROPERTIES,
  722. rcpl.PbPropList(),
  723. static_cast< DWORD >( rcpl.CbPropList() ),
  724. NULL, // lpOutBuffer
  725. 0, // nOutBufferSize
  726. &cbProps
  727. );
  728. else
  729. dwStatus = ClusterResourceTypeControl(
  730. Hcluster(),
  731. Peo()->PodObjData()->m_strName,
  732. NULL, // hNode
  733. CLUSCTL_RESOURCE_TYPE_SET_COMMON_PROPERTIES,
  734. rcpl.PbPropList(),
  735. static_cast< DWORD >( rcpl.CbPropList() ),
  736. NULL, // lpOutBuffer
  737. 0, // nOutBufferSize
  738. &cbProps
  739. );
  740. } // if: there is data to set
  741. else
  742. dwStatus = ERROR_SUCCESS;
  743. return dwStatus;
  744. } //*** CBasePropertyPage::DwSetCommonProps()
  745. /////////////////////////////////////////////////////////////////////////////
  746. //++
  747. //
  748. // CBasePropertyPage::OnContextMenu
  749. //
  750. // Routine Description:
  751. // Handler for the WM_CONTEXTMENU message.
  752. //
  753. // Arguments:
  754. // pWnd Window in which user clicked the right mouse button.
  755. // point Position of the cursor, in screen coordinates.
  756. //
  757. // Return Value:
  758. // TRUE Help processed.
  759. // FALSE Help not processed.
  760. //
  761. //--
  762. /////////////////////////////////////////////////////////////////////////////
  763. void CBasePropertyPage::OnContextMenu(CWnd * pWnd, CPoint point)
  764. {
  765. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  766. m_dlghelp.OnContextMenu(pWnd, point);
  767. } //*** CBasePropertyPage::OnContextMenu()
  768. /////////////////////////////////////////////////////////////////////////////
  769. //++
  770. //
  771. // CBasePropertyPage::OnHelpInfo
  772. //
  773. // Routine Description:
  774. // Handler for the WM_HELPINFO message.
  775. //
  776. // Arguments:
  777. // pHelpInfo Structure containing info about displaying help.
  778. //
  779. // Return Value:
  780. // TRUE Help processed.
  781. // FALSE Help not processed.
  782. //
  783. //--
  784. /////////////////////////////////////////////////////////////////////////////
  785. BOOL CBasePropertyPage::OnHelpInfo(HELPINFO * pHelpInfo)
  786. {
  787. BOOL bProcessed;
  788. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  789. bProcessed = m_dlghelp.OnHelpInfo(pHelpInfo);
  790. if (!bProcessed)
  791. bProcessed = CPropertyPage::OnHelpInfo(pHelpInfo);
  792. return bProcessed;
  793. } //*** CBasePropertyPage::OnHelpInfo()
  794. /////////////////////////////////////////////////////////////////////////////
  795. //++
  796. //
  797. // CBasePropertyPage::OnCommandHelp
  798. //
  799. // Routine Description:
  800. // Handler for the WM_COMMANDHELP message.
  801. //
  802. // Arguments:
  803. // wParam [IN] WPARAM.
  804. // lParam [IN] LPARAM.
  805. //
  806. // Return Value:
  807. // TRUE Help processed.
  808. // FALSE Help not processed.
  809. //
  810. //--
  811. /////////////////////////////////////////////////////////////////////////////
  812. LRESULT CBasePropertyPage::OnCommandHelp(WPARAM wParam, LPARAM lParam)
  813. {
  814. LRESULT lProcessed;
  815. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  816. lProcessed = m_dlghelp.OnCommandHelp(wParam, lParam);
  817. if (!lProcessed)
  818. lProcessed = CPropertyPage::OnCommandHelp(wParam, lParam);
  819. return lProcessed;
  820. } //*** CBasePropertyPage::OnCommandHelp()