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 / extobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-29  |  19.2 KB  |  779 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. //    Copyright (c) 1997 <company name>
  4. //
  5. //    Module Name:
  6. //        ExtObj.cpp
  7. //
  8. //    Abstract:
  9. //        Implementation of the CExtObject class, which implements the
  10. //        extension interfaces required by a Microsoft Windows NT Cluster
  11. //        Administrator Extension DLL.
  12. //
  13. //    Author:
  14. //        <name> (<e-mail name>) Mmmm DD, 1997
  15. //
  16. //    Revision History:
  17. //
  18. //    Notes:
  19. //
  20. /////////////////////////////////////////////////////////////////////////////
  21.  
  22. #include "stdafx.h"
  23. #include "SmbSmpEx.h"
  24. #include "ExtObj.h"
  25. #include "ResProp.h"
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Global Variables
  29. /////////////////////////////////////////////////////////////////////////////
  30.  
  31. const WCHAR g_wszResourceTypeNames[] =
  32.         L"SMB Sample\0"
  33.         L"\0"
  34.         ;
  35. const DWORD g_cchResourceTypeNames    = sizeof(g_wszResourceTypeNames) / sizeof(WCHAR);
  36.  
  37. static CRuntimeClass * g_rgprtcResPSPages[]    = {
  38.     RUNTIME_CLASS(CSmbSmpParamsPage),
  39.     NULL
  40.     };
  41. static CRuntimeClass ** g_rgpprtcResPSPages[]    = {
  42.     g_rgprtcResPSPages,
  43.     };
  44. static CRuntimeClass ** g_rgpprtcResWizPages[]    = {
  45.     g_rgprtcResPSPages,
  46.     };
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CExtObject
  50. /////////////////////////////////////////////////////////////////////////////
  51.  
  52. /////////////////////////////////////////////////////////////////////////////
  53. //++
  54. //
  55. //    CExtObject::CExtObject
  56. //
  57. //    Routine Description:
  58. //        Default constructor.
  59. //
  60. //    Arguments:
  61. //        None.
  62. //
  63. //    Return Value:
  64. //        None.
  65. //
  66. //--
  67. /////////////////////////////////////////////////////////////////////////////
  68. CExtObject::CExtObject(void)
  69. {
  70.     m_piData = NULL;
  71.     m_piWizardCallback = NULL;
  72.     m_bWizard = FALSE;
  73.     m_istrResTypeName = 0;
  74.  
  75.     m_lcid = NULL;
  76.     m_hfont = NULL;
  77.     m_hicon = NULL;
  78.     m_hcluster = NULL;
  79.     m_cobj = 0;
  80.     m_podObjData = NULL;
  81.  
  82. }  //*** CExtObject::CExtObject()
  83.  
  84. /////////////////////////////////////////////////////////////////////////////
  85. //++
  86. //
  87. //    CExtObject::~CExtObject
  88. //
  89. //    Routine Description:
  90. //        Destructor.
  91. //
  92. //    Arguments:
  93. //        None.
  94. //
  95. //    Return Value:
  96. //        None.
  97. //
  98. //--
  99. /////////////////////////////////////////////////////////////////////////////
  100. CExtObject::~CExtObject(void)
  101. {
  102.     // Release the data interface.
  103.     if (PiData() != NULL)
  104.     {
  105.         PiData()->Release();
  106.         m_piData = NULL;
  107.     }  // if:  we have a data interface pointer
  108.  
  109.     // Release the wizard callback interface.
  110.     if (PiWizardCallback() != NULL)
  111.     {
  112.         PiWizardCallback()->Release();
  113.         m_piWizardCallback = NULL;
  114.     }  // if:  we have a wizard callback interface pointer
  115.  
  116.     // Delete the pages.
  117.     {
  118.         POSITION    pos;
  119.  
  120.         pos = Lpg().GetHeadPosition();
  121.         while (pos != NULL)
  122.             delete Lpg().GetNext(pos);
  123.     }  // Delete the pages
  124.  
  125.     delete m_podObjData;
  126.  
  127. }  //*** CExtObject::~CExtObject()
  128.  
  129. /////////////////////////////////////////////////////////////////////////////
  130. // ISupportErrorInfo Implementation
  131.  
  132. /////////////////////////////////////////////////////////////////////////////
  133. //++
  134. //
  135. //    CExtObject::InterfaceSupportsErrorInfo (ISupportErrorInfo)
  136. //
  137. //    Routine Description:
  138. //        Indicates whether an interface suportes the IErrorInfo interface.
  139. //        This interface is provided by ATL.
  140. //
  141. //    Arguments:
  142. //        riid        Interface ID.
  143. //
  144. //    Return Value:
  145. //        S_OK        Interface supports IErrorInfo.
  146. //        S_FALSE        Interface does not support IErrorInfo.
  147. //
  148. //--
  149. /////////////////////////////////////////////////////////////////////////////
  150. STDMETHODIMP CExtObject::InterfaceSupportsErrorInfo(REFIID riid)
  151. {
  152.     static const IID * rgiid[] = 
  153.     {
  154.         &IID_IWEExtendPropertySheet,
  155.         &IID_IWEExtendWizard,
  156.     };
  157.     int        iiid;
  158.  
  159.     for (iiid = 0 ; iiid < sizeof(rgiid) / sizeof(rgiid[0]) ; iiid++)
  160.     {
  161.         if (InlineIsEqualGUID(*rgiid[iiid], riid))
  162.             return S_OK;
  163.     }
  164.     return S_FALSE;
  165.  
  166. }  //*** CExtObject::InterfaceSupportsErrorInfo()
  167.  
  168. /////////////////////////////////////////////////////////////////////////////
  169. // IWEExtendPropertySheet Implementation
  170.  
  171. /////////////////////////////////////////////////////////////////////////////
  172. //++
  173. //
  174. //    CExtObject::CreatePropertySheetPages (IWEExtendPropertySheet)
  175. //
  176. //    Routine Description:
  177. //        Create property sheet pages and add them to the sheet.
  178. //
  179. //    Arguments:
  180. //        piData            IUnkown pointer from which to obtain interfaces
  181. //                            for obtaining data describing the object for
  182. //                            which the sheet is being displayed.
  183. //        piCallback        Pointer to an IWCPropertySheetCallback interface
  184. //                            for adding pages to the sheet.
  185. //
  186. //    Return Value:
  187. //        NOERROR            Pages added successfully.
  188. //        E_INVALIDARG    Invalid arguments to the function.
  189. //        E_OUTOFMEMORY    Error allocating memory.
  190. //        E_FAIL            Error creating a page.
  191. //        E_NOTIMPL        Not implemented for this type of data.
  192. //        Any error codes from IDataObject::GetData() (through HrSaveData()).
  193. //
  194. //--
  195. /////////////////////////////////////////////////////////////////////////////
  196. STDMETHODIMP CExtObject::CreatePropertySheetPages(
  197.     IN IUnknown *                    piData,
  198.     IN IWCPropertySheetCallback *    piCallback
  199.     )
  200. {
  201.     HRESULT                hr        = NOERROR;
  202.     HPROPSHEETPAGE        hpage    = NULL;
  203.     CException            exc(FALSE /*bAutoDelete*/);
  204.     CRuntimeClass **    pprtc    = NULL;
  205.     int                    irtc;
  206.     CBasePropertyPage *    ppage;
  207.  
  208.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  209.  
  210.     // Validate the parameters.
  211.     if ((piData == NULL) || (piCallback == NULL))
  212.         return E_INVALIDARG;
  213.  
  214.     try 
  215.     {
  216.         // Get info about displaying UI.
  217.         hr = HrGetUIInfo(piData);
  218.         if (hr != NOERROR)
  219.             throw &exc;
  220.  
  221.         // Save the data.
  222.         hr = HrSaveData(piData);
  223.         if (hr != NOERROR)
  224.             throw &exc;
  225.  
  226.         // Delete any previous pages.
  227.         {
  228.             POSITION    pos;
  229.  
  230.             pos = Lpg().GetHeadPosition();
  231.             while (pos != NULL)
  232.                 delete Lpg().GetNext(pos);
  233.             Lpg().RemoveAll();
  234.         }  // Delete any previous pages
  235.  
  236.         // Create property pages.
  237.         ASSERT(PodObjData() != NULL);
  238.         switch (PodObjData()->m_cot)
  239.         {
  240.             case CLUADMEX_OT_RESOURCE:
  241.                 pprtc = g_rgpprtcResPSPages[IstrResTypeName()];
  242.                 break;
  243.             default:
  244.                 hr = E_NOTIMPL;
  245.                 throw &exc;
  246.                 break;
  247.         }  // switch:  object type
  248.  
  249.         // Create each page.
  250.         for (irtc = 0 ; pprtc[irtc] != NULL ; irtc++)
  251.         {
  252.             // Create the page.
  253.             ppage = (CBasePropertyPage *) pprtc[irtc]->CreateObject();
  254.             ASSERT(ppage->IsKindOf(pprtc[irtc]));
  255.  
  256.             // Add it to the list.
  257.             Lpg().AddTail(ppage);
  258.  
  259.             // Initialize the property page.
  260.             if (!ppage->BInit(this))
  261.                 throw &exc;
  262.  
  263.             // Create the page.
  264.             hpage = ::CreatePropertySheetPage(&ppage->m_psp);
  265.             if (hpage == NULL)
  266.                 throw &exc;
  267.  
  268.             // Save the hpage in the page itself.
  269.             ppage->SetHpage(hpage);
  270.  
  271.             // Add it to the property sheet.
  272.             hr = piCallback->AddPropertySheetPage((LONG *) hpage);
  273.             if (hr != NOERROR)
  274.                 throw &exc;
  275.         }  // for:  each page in the list
  276.  
  277.     }  // try
  278.     catch (CMemoryException * pme)
  279.     {
  280.         TRACE(_T("CExtObject::CreatePropetySheetPages() - Failed to add property page\n"));
  281.         pme->Delete();
  282.         hr = E_OUTOFMEMORY;
  283.     }  // catch:  anything
  284.     catch (CException * pe)
  285.     {
  286.         TRACE(_T("CExtObject::CreatePropetySheetPages() - Failed to add property page\n"));
  287.         pe->Delete();
  288.         if (hr == NOERROR)
  289.             hr = E_FAIL;
  290.     }  // catch:  anything
  291.  
  292.     if (hr != NOERROR)
  293.     {
  294.         if (hpage != NULL)
  295.             ::DestroyPropertySheetPage(hpage);
  296.         piData->Release();
  297.         m_piData = NULL;
  298.     }  // if:  error occurred
  299.  
  300.     piCallback->Release();
  301.     return hr;
  302.  
  303. }  //*** CExtObject::CreatePropertySheetPages()
  304.  
  305. /////////////////////////////////////////////////////////////////////////////
  306. // IWEExtendWizard Implementation
  307.  
  308. /////////////////////////////////////////////////////////////////////////////
  309. //++
  310. //
  311. //    CExtObject::CreateWizardPages (IWEExtendWizard)
  312. //
  313. //    Routine Description:
  314. //        Create property sheet pages and add them to the wizard.
  315. //
  316. //    Arguments:
  317. //        piData            IUnkown pointer from which to obtain interfaces
  318. //                            for obtaining data describing the object for
  319. //                            which the wizard is being displayed.
  320. //        piCallback        Pointer to an IWCPropertySheetCallback interface
  321. //                            for adding pages to the sheet.
  322. //
  323. //    Return Value:
  324. //        NOERROR            Pages added successfully.
  325. //        E_INVALIDARG    Invalid arguments to the function.
  326. //        E_OUTOFMEMORY    Error allocating memory.
  327. //        E_FAIL            Error creating a page.
  328. //        E_NOTIMPL        Not implemented for this type of data.
  329. //        Any error codes from IDataObject::GetData() (through HrSaveData()).
  330. //
  331. //--
  332. /////////////////////////////////////////////////////////////////////////////
  333. STDMETHODIMP CExtObject::CreateWizardPages(
  334.     IN IUnknown *            piData,
  335.     IN IWCWizardCallback *    piCallback
  336.     )
  337. {
  338.     HRESULT                hr        = NOERROR;
  339.     HPROPSHEETPAGE        hpage    = NULL;
  340.     CException            exc(FALSE /*bAutoDelete*/);
  341.     CRuntimeClass **    pprtc    = NULL;
  342.     int                    irtc;
  343.     CBasePropertyPage *    ppage;
  344.  
  345.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  346.  
  347.     // Validate the parameters.
  348.     if ((piData == NULL) || (piCallback == NULL))
  349.         return E_INVALIDARG;
  350.  
  351.     try 
  352.     {
  353.         // Get info about displaying UI.
  354.         hr = HrGetUIInfo(piData);
  355.         if (hr != NOERROR)
  356.             throw &exc;
  357.  
  358.         // Save the data.
  359.         hr = HrSaveData(piData);
  360.         if (hr != NOERROR)
  361.             throw &exc;
  362.  
  363.         // Delete any previous pages.
  364.         {
  365.             POSITION    pos;
  366.  
  367.             pos = Lpg().GetHeadPosition();
  368.             while (pos != NULL)
  369.                 delete Lpg().GetNext(pos);
  370.             Lpg().RemoveAll();
  371.         }  // Delete any previous pages
  372.  
  373.         m_piWizardCallback = piCallback;
  374.         m_bWizard = TRUE;
  375.  
  376.         // Create property pages.
  377.         ASSERT(PodObjData() != NULL);
  378.         switch (PodObjData()->m_cot)
  379.         {
  380.             case CLUADMEX_OT_RESOURCE:
  381.                 pprtc = g_rgpprtcResWizPages[IstrResTypeName()];
  382.                 break;
  383.             default:
  384.                 hr = E_NOTIMPL;
  385.                 throw &exc;
  386.                 break;
  387.         }  // switch:  object type
  388.  
  389.         // Create each page.
  390.         for (irtc = 0 ; pprtc[irtc] != NULL ; irtc++)
  391.         {
  392.             // Create the page.
  393.             ppage = (CBasePropertyPage *) pprtc[irtc]->CreateObject();
  394.             ASSERT(ppage->IsKindOf(pprtc[irtc]));
  395.  
  396.             // Add it to the list.
  397.             Lpg().AddTail(ppage);
  398.  
  399.             // Initialize the property page.
  400.             if (!ppage->BInit(this))
  401.                 throw &exc;
  402.  
  403.             // Create the page.
  404.             hpage = ::CreatePropertySheetPage(&ppage->m_psp);
  405.             if (hpage == NULL)
  406.                 throw &exc;
  407.  
  408.             // Save the hpage in the page itself.
  409.             ppage->SetHpage(hpage);
  410.  
  411.             // Add it to the property sheet.
  412.             hr = piCallback->AddWizardPage((LONG *) hpage);
  413.             if (hr != NOERROR)
  414.                 throw &exc;
  415.         }  // for:  each page in the list
  416.  
  417.     }  // try
  418.     catch (CMemoryException * pme)
  419.     {
  420.         TRACE(_T("CExtObject::CreateWizardPages() - Failed to add wizard page\n"));
  421.         pme->Delete();
  422.         hr = E_OUTOFMEMORY;
  423.     }  // catch:  anything
  424.     catch (CException * pe)
  425.     {
  426.         TRACE(_T("CExtObject::CreateWizardPages() - Failed to add wizard page\n"));
  427.         pe->Delete();
  428.         if (hr == NOERROR)
  429.             hr = E_FAIL;
  430.     }  // catch:  anything
  431.  
  432.     if (hr != NOERROR)
  433.     {
  434.         if (hpage != NULL)
  435.             ::DestroyPropertySheetPage(hpage);
  436.         piCallback->Release();
  437.         piData->Release();
  438.         m_piData = NULL;
  439.     }  // if:  error occurred
  440.  
  441.     return hr;
  442.  
  443. }  //*** CExtObject::CreateWizardPages()
  444.  
  445. /////////////////////////////////////////////////////////////////////////////
  446. //++
  447. //
  448. //    CExtObject::HrGetUIInfo
  449. //
  450. //    Routine Description:
  451. //        Get info about displaying UI.
  452. //
  453. //    Arguments:
  454. //        piData            IUnkown pointer from which to obtain interfaces
  455. //                            for obtaining data describing the object.
  456. //
  457. //    Return Value:
  458. //        NOERROR            Data saved successfully.
  459. //        E_NOTIMPL        Not implemented for this type of data.
  460. //        Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  461. //        or HrGetResourceName().
  462. //
  463. //--
  464. /////////////////////////////////////////////////////////////////////////////
  465. HRESULT CExtObject::HrGetUIInfo(IUnknown * piData)
  466. {
  467.     HRESULT            hr    = NOERROR;
  468.  
  469.     ASSERT(piData != NULL);
  470.  
  471.     // Save info about all types of objects.
  472.     {
  473.         IGetClusterUIInfo *    pi;
  474.  
  475.         hr = piData->QueryInterface(IID_IGetClusterUIInfo, (LPVOID *) &pi);
  476.         if (hr != NOERROR)
  477.             return hr;
  478.  
  479.         m_lcid = pi->GetLocale();
  480.         m_hfont = pi->GetFont();
  481.         m_hicon = pi->GetIcon();
  482.  
  483.         pi->Release();
  484.     }  // Save info about all types of objects
  485.  
  486.     return hr;
  487.  
  488. }  //*** CExtObject::HrGetUIInfo()
  489.  
  490. /////////////////////////////////////////////////////////////////////////////
  491. //++
  492. //
  493. //    CExtObject::HrSaveData
  494. //
  495. //    Routine Description:
  496. //        Save data from the object so that it can be used for the life
  497. //        of the object.
  498. //
  499. //    Arguments:
  500. //        piData            IUnkown pointer from which to obtain interfaces
  501. //                            for obtaining data describing the object.
  502. //
  503. //    Return Value:
  504. //        NOERROR            Data saved successfully.
  505. //        E_NOTIMPL        Not implemented for this type of data.
  506. //        Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  507. //        or HrGetResourceName().
  508. //
  509. //--
  510. /////////////////////////////////////////////////////////////////////////////
  511. HRESULT CExtObject::HrSaveData(IUnknown * piData)
  512. {
  513.     HRESULT            hr    = NOERROR;
  514.  
  515.     ASSERT(piData != NULL);
  516.  
  517.     if (piData != m_piData)
  518.     {
  519.         if (m_piData != NULL)
  520.             m_piData->Release();
  521.         m_piData = piData;
  522.     }  // if:  different data interface pointer
  523.  
  524.     // Save info about all types of objects.
  525.     {
  526.         IGetClusterDataInfo *    pi;
  527.  
  528.         hr = piData->QueryInterface(IID_IGetClusterDataInfo, (LPVOID *) &pi);
  529.         if (hr != NOERROR)
  530.             return hr;
  531.  
  532.         m_hcluster = pi->GetClusterHandle();
  533.         m_cobj = pi->GetObjectCount();
  534.         if (Cobj() != 1)    // Only have support for one selected object.
  535.             hr = E_NOTIMPL;
  536.  
  537.         pi->Release();
  538.         if (hr != NOERROR)
  539.             return hr;
  540.     }  // Save info about all types of objects
  541.  
  542.     // Save info about this object.
  543.     hr = HrGetObjectInfo();
  544.     if (hr != NOERROR)
  545.         return hr;
  546.  
  547.     return hr;
  548.  
  549. }  //*** CExtObject::HrSaveData()
  550.  
  551. /////////////////////////////////////////////////////////////////////////////
  552. //++
  553. //
  554. //    CExtObject::HrGetObjectInfo
  555. //
  556. //    Routine Description:
  557. //        Get information about the object.
  558. //
  559. //    Arguments:
  560. //        None.
  561. //
  562. //    Return Value:
  563. //        NOERROR            Data saved successfully.
  564. //        E_OUTOFMEMORY    Error allocating memory.
  565. //        E_NOTIMPL        Not implemented for this type of data.
  566. //        Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  567. //        or HrGetResourceTypeName().
  568. //
  569. //--
  570. /////////////////////////////////////////////////////////////////////////////
  571. HRESULT CExtObject::HrGetObjectInfo(void)
  572. {
  573.     HRESULT                        hr    = NOERROR;
  574.     IGetClusterObjectInfo *        piGcoi;
  575.     CLUADMEX_OBJECT_TYPE        cot;
  576.     CException                    exc(FALSE /*bAutoDelete*/);
  577.     const CString *                pstrResTypeName;
  578.  
  579.     ASSERT(PiData() != NULL);
  580.  
  581.     // Get object info.
  582.     {
  583.         // Get an IGetClusterObjectInfo interface pointer.
  584.         hr = PiData()->QueryInterface(IID_IGetClusterObjectInfo, (LPVOID *) &piGcoi);
  585.         if (hr != NOERROR)
  586.             return hr;
  587.  
  588.         // Read the object data.
  589.         try
  590.         {
  591.             // Delete the previous object data.
  592.             delete m_podObjData;
  593.             m_podObjData = NULL;
  594.  
  595.             // Get the type of the object.
  596.             cot = piGcoi->GetObjectType(0);
  597.             switch (cot)
  598.             {
  599.                 case CLUADMEX_OT_RESOURCE:
  600.                     {
  601.                         IGetClusterResourceInfo *    pi;
  602.  
  603.                         m_podObjData = new CResData;
  604.  
  605.                         // Get an IGetClusterResourceInfo interface pointer.
  606.                         hr = PiData()->QueryInterface(IID_IGetClusterResourceInfo, (LPVOID *) &pi);
  607.                         if (hr != NOERROR)
  608.                             throw &exc;
  609.  
  610.                         PrdResDataRW()->m_hresource = pi->GetResourceHandle(0);
  611.                         ASSERT(PrdResDataRW()->m_hresource != NULL);
  612.                         if (PrdResDataRW()->m_hresource == NULL)
  613.                             hr = E_INVALIDARG;
  614.                         else
  615.                             hr = HrGetResourceTypeName(pi);
  616.                         pi->Release();
  617.                         if (hr != NOERROR)
  618.                             throw &exc;
  619.  
  620.                         pstrResTypeName = &PrdResDataRW()->m_strResTypeName;
  621.                     }  // if:  object is a node
  622.                     break;
  623.                 default:
  624.                     hr = E_NOTIMPL;
  625.                     throw &exc;
  626.             }  // switch:  object type
  627.  
  628.             PodObjDataRW()->m_cot = cot;
  629.             hr = HrGetObjectName(piGcoi);
  630.         }  // try
  631.         catch (CException * pe)
  632.         {
  633.             pe->Delete();
  634.         }  // catch:  CException
  635.  
  636.         piGcoi->Release();
  637.         if (hr != NOERROR)
  638.             return hr;
  639.     }  // Get object info
  640.  
  641.     // If this is a resource or resource type, see if we know about this type.
  642.     if (((cot == CLUADMEX_OT_RESOURCE)
  643.             || (cot == CLUADMEX_OT_RESOURCETYPE))
  644.         && (hr == NOERROR))
  645.     {
  646.         LPCWSTR    pwszResTypeName;
  647.  
  648.         // Find the resource type name in our list.
  649.         // Save the index for use in other arrays.
  650.         for (m_istrResTypeName = 0, pwszResTypeName = g_wszResourceTypeNames
  651.                 ; *pwszResTypeName != L'\0'
  652.                 ; m_istrResTypeName++, pwszResTypeName += lstrlenW(pwszResTypeName) + 1
  653.                 )
  654.         {
  655.             if (pstrResTypeName->CompareNoCase(pwszResTypeName) == 0)
  656.                 break;
  657.         }  // for:  each resource type in the list
  658.         if (*pwszResTypeName == L'\0')
  659.             hr = E_NOTIMPL;
  660.     }  // See if we know about this resource type
  661.  
  662.     return hr;
  663.  
  664. }  //*** CExtObject::HrGetObjectInfo()
  665.  
  666. /////////////////////////////////////////////////////////////////////////////
  667. //++
  668. //
  669. //    CExtObject::HrGetObjectName
  670. //
  671. //    Routine Description:
  672. //        Get the name of the object.
  673. //
  674. //    Arguments:
  675. //        piData            IGetClusterObjectInfo interface pointer for getting
  676. //                            the object name.
  677. //
  678. //    Return Value:
  679. //        NOERROR            Data saved successfully.
  680. //        E_OUTOFMEMORY    Error allocating memory.
  681. //        E_NOTIMPL        Not implemented for this type of data.
  682. //        Any error codes from IGetClusterObjectInfo::GetObjectInfo().
  683. //
  684. //--
  685. /////////////////////////////////////////////////////////////////////////////
  686. HRESULT CExtObject::HrGetObjectName(
  687.     IN OUT IGetClusterObjectInfo *    pi
  688.     )
  689. {
  690.     HRESULT        hr            = NOERROR;
  691.     WCHAR *        pwszName    = NULL;
  692.     LONG        cchName;
  693.  
  694.     ASSERT(pi != NULL);
  695.  
  696.     hr = pi->GetObjectName(0, NULL, &cchName);
  697.     if (hr != NOERROR)
  698.         return hr;
  699.  
  700.     try
  701.     {
  702.         pwszName = new WCHAR[cchName];
  703.         hr = pi->GetObjectName(0, pwszName, &cchName);
  704.         if (hr != NOERROR)
  705.         {
  706.             delete [] pwszName;
  707.             pwszName = NULL;
  708.         }  // if:  error getting object name
  709.  
  710.         PodObjDataRW()->m_strName = pwszName;
  711.     }  // try
  712.     catch (CMemoryException * pme)
  713.     {
  714.         pme->Delete();
  715.         hr = E_OUTOFMEMORY;
  716.     }  // catch:  CMemoryException
  717.  
  718.     delete [] pwszName;
  719.     return hr;
  720.  
  721. }  //*** CExtObject::HrGetObjectName()
  722.  
  723. /////////////////////////////////////////////////////////////////////////////
  724. //++
  725. //
  726. //    CExtObject::HrGetResourceTypeName
  727. //
  728. //    Routine Description:
  729. //        Get the name of the resource's type.
  730. //
  731. //    Arguments:
  732. //        piData            IGetClusterResourceInfo interface pointer for getting
  733. //                            the resource type name.
  734. //
  735. //    Return Value:
  736. //        NOERROR            Data saved successfully.
  737. //        E_OUTOFMEMORY    Error allocating memory.
  738. //        E_NOTIMPL        Not implemented for this type of data.
  739. //        Any error codes from IGetClusterResourceInfo::GetResourceTypeName().
  740. //
  741. //--
  742. /////////////////////////////////////////////////////////////////////////////
  743. HRESULT CExtObject::HrGetResourceTypeName(
  744.     IN OUT IGetClusterResourceInfo *    pi
  745.     )
  746. {
  747.     HRESULT        hr            = NOERROR;
  748.     WCHAR *        pwszName    = NULL;
  749.     LONG        cchName;
  750.  
  751.     ASSERT(pi != NULL);
  752.  
  753.     hr = pi->GetResourceTypeName(0, NULL, &cchName);
  754.     if (hr != NOERROR)
  755.         return hr;
  756.  
  757.     try
  758.     {
  759.         pwszName = new WCHAR[cchName];
  760.         hr = pi->GetResourceTypeName(0, pwszName, &cchName);
  761.         if (hr != NOERROR)
  762.         {
  763.             delete [] pwszName;
  764.             pwszName = NULL;
  765.         }  // if:  error getting resource type name
  766.  
  767.         PrdResDataRW()->m_strResTypeName = pwszName;
  768.     }  // try
  769.     catch (CMemoryException * pme)
  770.     {
  771.         pme->Delete();
  772.         hr = E_OUTOFMEMORY;
  773.     }  // catch:  CMemoryException
  774.  
  775.     delete [] pwszName;
  776.     return hr;
  777.  
  778. }  //*** CExtObject::HrGetResourceTypeName()
  779.