Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

911 lines
25 KiB

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