home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / cluster / smbsmp / smbsmpex / basepage.cpp next >
Encoding:
C/C++ Source or Header  |  1997-07-29  |  28.3 KB  |  1,097 lines

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