Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1043 lines
27 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-1997 Microsoft Corporation
  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. // David Potter (davidp) August 29, 1996
  15. //
  16. // Revision History:
  17. //
  18. // Notes:
  19. //
  20. /////////////////////////////////////////////////////////////////////////////
  21. #include "stdafx.h"
  22. #include "IISClEx4.h"
  23. #include "ExtObj.h"
  24. #include "Iis.h"
  25. #include "smtpprop.h"
  26. #include "nntpprop.h"
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Global Variables
  29. /////////////////////////////////////////////////////////////////////////////
  30. const WCHAR g_wszResourceTypeNames[] =
  31. RESTYPE_NAME_IIS_VIRTUAL_ROOT L"\0"
  32. RESTYPE_NAME_SMTP_VIRTUAL_ROOT L"\0"
  33. RESTYPE_NAME_NNTP_VIRTUAL_ROOT L"\0"
  34. L"\0"
  35. ;
  36. const DWORD g_cchResourceTypeNames = sizeof(g_wszResourceTypeNames) / sizeof(WCHAR);
  37. static CRuntimeClass * g_rgprtcPSIISPages[] = {
  38. RUNTIME_CLASS(CIISVirtualRootParamsPage),
  39. NULL
  40. };
  41. static CRuntimeClass * g_rgprtcPSSMTPPages[] = {
  42. RUNTIME_CLASS(CSMTPVirtualRootParamsPage),
  43. NULL
  44. };
  45. static CRuntimeClass * g_rgprtcPSNNTPPages[] = {
  46. RUNTIME_CLASS(CNNTPVirtualRootParamsPage),
  47. NULL
  48. };
  49. static CRuntimeClass ** g_rgpprtcPSPages[] = {
  50. g_rgprtcPSIISPages,
  51. g_rgprtcPSSMTPPages,
  52. g_rgprtcPSNNTPPages
  53. };
  54. // Wizard pages and property sheet pages are the same.
  55. static CRuntimeClass ** g_rgpprtcWizPages[] = {
  56. g_rgprtcPSIISPages,
  57. g_rgprtcPSSMTPPages,
  58. g_rgprtcPSNNTPPages
  59. };
  60. /////////////////////////////////////////////////////////////////////////////
  61. // CExtObject
  62. /////////////////////////////////////////////////////////////////////////////
  63. /////////////////////////////////////////////////////////////////////////////
  64. //++
  65. //
  66. // CExtObject::CExtObject
  67. //
  68. // Routine Description:
  69. // Default constructor.
  70. //
  71. // Arguments:
  72. // None.
  73. //
  74. // Return Value:
  75. // None.
  76. //
  77. //--
  78. /////////////////////////////////////////////////////////////////////////////
  79. CExtObject::CExtObject(void)
  80. {
  81. m_piData = NULL;
  82. m_piWizardCallback = NULL;
  83. m_bWizard = FALSE;
  84. m_istrResTypeName = 0;
  85. m_hcluster = NULL;
  86. m_lcid = NULL;
  87. m_hfont = NULL;
  88. m_hicon = NULL;
  89. } //*** CExtObject::CExtObject()
  90. /////////////////////////////////////////////////////////////////////////////
  91. //++
  92. //
  93. // CExtObject::~CExtObject
  94. //
  95. // Routine Description:
  96. // Destructor.
  97. //
  98. // Arguments:
  99. // None.
  100. //
  101. // Return Value:
  102. // None.
  103. //
  104. //--
  105. /////////////////////////////////////////////////////////////////////////////
  106. CExtObject::~CExtObject(void)
  107. {
  108. // Release the data interface.
  109. if (PiData() != NULL)
  110. {
  111. PiData()->Release();
  112. m_piData = NULL;
  113. } // if: we have a data interface pointer
  114. // Release the wizard callback interface.
  115. if (PiWizardCallback() != NULL)
  116. {
  117. PiWizardCallback()->Release();
  118. m_piWizardCallback = NULL;
  119. } // if: we have a wizard callback interface pointer
  120. // Delete the pages.
  121. {
  122. POSITION pos;
  123. pos = Lpg().GetHeadPosition();
  124. while (pos != NULL)
  125. delete Lpg().GetNext(pos);
  126. } // Delete the pages
  127. } //*** CExtObject::~CExtObject()
  128. /////////////////////////////////////////////////////////////////////////////
  129. // ISupportErrorInfo Implementation
  130. /////////////////////////////////////////////////////////////////////////////
  131. //++
  132. //
  133. // CExtObject::InterfaceSupportsErrorInfo (ISupportErrorInfo)
  134. //
  135. // Routine Description:
  136. // Indicates whether an interface suportes the IErrorInfo interface.
  137. // This interface is provided by ATL.
  138. //
  139. // Arguments:
  140. // riid Interface ID.
  141. //
  142. // Return Value:
  143. // S_OK Interface supports IErrorInfo.
  144. // S_FALSE Interface does not support IErrorInfo.
  145. //
  146. //--
  147. /////////////////////////////////////////////////////////////////////////////
  148. STDMETHODIMP CExtObject::InterfaceSupportsErrorInfo(REFIID riid)
  149. {
  150. static const IID * rgiid[] =
  151. {
  152. &IID_IWEExtendPropertySheet,
  153. &IID_IWEExtendWizard,
  154. #ifdef _DEMO_CTX_MENUS
  155. &IID_IWEExtendContextMenu,
  156. #endif
  157. };
  158. int iiid;
  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. } //*** CExtObject::InterfaceSupportsErrorInfo()
  166. /////////////////////////////////////////////////////////////////////////////
  167. // IWEExtendPropertySheet Implementation
  168. /////////////////////////////////////////////////////////////////////////////
  169. //++
  170. //
  171. // CExtObject::CreatePropertySheetPages (IWEExtendPropertySheet)
  172. //
  173. // Routine Description:
  174. // Create property sheet pages and add them to the sheet.
  175. //
  176. // Arguments:
  177. // piData IUnkown pointer from which to obtain interfaces
  178. // for obtaining data describing the object for
  179. // which the sheet is being displayed.
  180. // piCallback Pointer to an IWCPropertySheetCallback interface
  181. // for adding pages to the sheet.
  182. //
  183. // Return Value:
  184. // NOERROR Pages added successfully.
  185. // E_INVALIDARG Invalid arguments to the function.
  186. // E_OUTOFMEMORY Error allocating memory.
  187. // E_FAIL Error creating a page.
  188. // E_NOTIMPL Not implemented for this type of data.
  189. // Any error codes from IDataObject::GetData() (through HrSaveData()).
  190. //
  191. //--
  192. /////////////////////////////////////////////////////////////////////////////
  193. STDMETHODIMP CExtObject::CreatePropertySheetPages(
  194. IN IUnknown * piData,
  195. IN IWCPropertySheetCallback * piCallback
  196. )
  197. {
  198. HRESULT hr = NOERROR;
  199. HPROPSHEETPAGE hpage = NULL;
  200. CException exc(FALSE /*bAutoDelete*/);
  201. int irtc;
  202. CBasePropertyPage * ppage;
  203. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  204. // Validate the parameters.
  205. if ((piData == NULL) || (piCallback == NULL))
  206. return E_INVALIDARG;
  207. try
  208. {
  209. // Get info about displaying UI.
  210. hr = HrGetUIInfo(piData);
  211. if (hr != NOERROR)
  212. throw &exc;
  213. // Save the data.
  214. hr = HrSaveData(piData);
  215. if (hr != NOERROR)
  216. throw &exc;
  217. // Delete any previous pages.
  218. {
  219. POSITION pos;
  220. pos = Lpg().GetHeadPosition();
  221. while (pos != NULL)
  222. delete Lpg().GetNext(pos);
  223. Lpg().RemoveAll();
  224. } // Delete any previous pages
  225. // Add each page for this type of resource.
  226. for (irtc = 0 ; g_rgpprtcPSPages[IstrResTypeName()][irtc] != NULL ; irtc++)
  227. {
  228. // Create the property pages.
  229. ppage = (CBasePropertyPage *) g_rgpprtcPSPages[IstrResTypeName()][irtc]->CreateObject();
  230. ASSERT(ppage->IsKindOf(g_rgpprtcPSPages[IstrResTypeName()][irtc]));
  231. // Add it to the list.
  232. Lpg().AddTail(ppage);
  233. // Initialize the property page.
  234. if (!ppage->BInit(this))
  235. throw &exc;
  236. // Create the page.
  237. hpage = ::CreatePropertySheetPage(&ppage->m_psp);
  238. if (hpage == NULL)
  239. throw &exc;
  240. // Save the hpage in the page itself.
  241. ppage->SetHpage(hpage);
  242. // Add it to the property sheet.
  243. hr = piCallback->AddPropertySheetPage((LONG *) hpage);
  244. if (hr != NOERROR)
  245. throw &exc;
  246. } // for: each page for the type of resource
  247. } // try
  248. catch (CMemoryException * pme)
  249. {
  250. TRACE(_T("CExtObject::CreatePropetySheetPages: Failed to add property page\n"));
  251. pme->Delete();
  252. hr = E_OUTOFMEMORY;
  253. } // catch: anything
  254. catch (CException * pe)
  255. {
  256. TRACE(_T("CExtObject::CreatePropetySheetPages: Failed to add property page\n"));
  257. pe->Delete();
  258. if (hr == NOERROR)
  259. hr = E_FAIL;
  260. } // catch: anything
  261. if (hr != NOERROR)
  262. {
  263. if (hpage != NULL)
  264. ::DestroyPropertySheetPage(hpage);
  265. piData->Release();
  266. m_piData = NULL;
  267. } // if: error occurred
  268. piCallback->Release();
  269. return hr;
  270. } //*** CExtObject::CreatePropertySheetPages()
  271. /////////////////////////////////////////////////////////////////////////////
  272. // IWEExtendWizard Implementation
  273. /////////////////////////////////////////////////////////////////////////////
  274. //++
  275. //
  276. // CExtObject::CreateWizardPages (IWEExtendWizard)
  277. //
  278. // Routine Description:
  279. // Create property sheet pages and add them to the wizard.
  280. //
  281. // Arguments:
  282. // piData IUnkown pointer from which to obtain interfaces
  283. // for obtaining data describing the object for
  284. // which the wizard is being displayed.
  285. // piCallback Pointer to an IWCPropertySheetCallback interface
  286. // for adding pages to the sheet.
  287. //
  288. // Return Value:
  289. // NOERROR Pages added successfully.
  290. // E_INVALIDARG Invalid arguments to the function.
  291. // E_OUTOFMEMORY Error allocating memory.
  292. // E_FAIL Error creating a page.
  293. // E_NOTIMPL Not implemented for this type of data.
  294. // Any error codes from IDataObject::GetData() (through HrSaveData()).
  295. //
  296. //--
  297. /////////////////////////////////////////////////////////////////////////////
  298. STDMETHODIMP CExtObject::CreateWizardPages(
  299. IN IUnknown * piData,
  300. IN IWCWizardCallback * piCallback
  301. )
  302. {
  303. HRESULT hr = NOERROR;
  304. HPROPSHEETPAGE hpage = NULL;
  305. CException exc(FALSE /*bAutoDelete*/);
  306. int irtc;
  307. CBasePropertyPage * ppage;
  308. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  309. // Validate the parameters.
  310. if ((piData == NULL) || (piCallback == NULL))
  311. return E_INVALIDARG;
  312. try
  313. {
  314. // Get info about displaying UI.
  315. hr = HrGetUIInfo(piData);
  316. if (hr != NOERROR)
  317. throw &exc;
  318. // Save the data.
  319. hr = HrSaveData(piData);
  320. if (hr != NOERROR)
  321. throw &exc;
  322. // Delete any previous pages.
  323. {
  324. POSITION pos;
  325. pos = Lpg().GetHeadPosition();
  326. while (pos != NULL)
  327. delete Lpg().GetNext(pos);
  328. Lpg().RemoveAll();
  329. } // Delete any previous pages
  330. m_piWizardCallback = piCallback;
  331. m_bWizard = TRUE;
  332. // Add each page for this type of resource.
  333. for (irtc = 0 ; g_rgpprtcWizPages[IstrResTypeName()][irtc] != NULL ; irtc++)
  334. {
  335. // Create the property pages.
  336. ppage = (CBasePropertyPage *) g_rgpprtcWizPages[IstrResTypeName()][irtc]->CreateObject();
  337. ASSERT(ppage->IsKindOf(g_rgpprtcWizPages[IstrResTypeName()][irtc]));
  338. // Add it to the list.
  339. Lpg().AddTail(ppage);
  340. // Initialize the property page.
  341. if (!ppage->BInit(this))
  342. throw &exc;
  343. // Create the page.
  344. hpage = ::CreatePropertySheetPage(&ppage->m_psp);
  345. if (hpage == NULL)
  346. throw &exc;
  347. // Save the hpage in the page itself.
  348. ppage->SetHpage(hpage);
  349. // Add it to the property sheet.
  350. hr = piCallback->AddWizardPage((LONG *) hpage);
  351. if (hr != NOERROR)
  352. throw &exc;
  353. } // for: each page for the type of resource
  354. } // try
  355. catch (CMemoryException * pme)
  356. {
  357. TRACE(_T("CExtObject::CreatePropetySheetPages: Failed to add wizard page\n"));
  358. pme->Delete();
  359. hr = E_OUTOFMEMORY;
  360. } // catch: anything
  361. catch (CException * pe)
  362. {
  363. TRACE(_T("CExtObject::CreatePropetySheetPages: Failed to add wizard page\n"));
  364. pe->Delete();
  365. if (hr == NOERROR)
  366. hr = E_FAIL;
  367. } // catch: anything
  368. if (hr != NOERROR)
  369. {
  370. if (hpage != NULL)
  371. ::DestroyPropertySheetPage(hpage);
  372. piCallback->Release();
  373. // see description of bug #298124
  374. if (m_piWizardCallback == piCallback)
  375. {
  376. m_piWizardCallback = NULL;
  377. }
  378. piData->Release();
  379. m_piData = NULL;
  380. } // if: error occurred
  381. return hr;
  382. } //*** CExtObject::CreateWizardPages()
  383. #ifdef _DEMO_CTX_MENUS
  384. /////////////////////////////////////////////////////////////////////////////
  385. // IWEExtendContextMenu Implementation
  386. /////////////////////////////////////////////////////////////////////////////
  387. //++
  388. //
  389. // CExtObject::AddContextMenuItems (IWEExtendContextMenu)
  390. //
  391. // Routine Description:
  392. // Add items to a context menu.
  393. //
  394. // Arguments:
  395. // piData IUnkown pointer from which to obtain interfaces
  396. // for obtaining data describing the object for
  397. // which the context menu is being displayed.
  398. // piCallback Pointer to an IWCContextMenuCallback interface
  399. // for adding menu items to the context menu.
  400. //
  401. // Return Value:
  402. // NOERROR Pages added successfully.
  403. // E_INVALIDARG Invalid arguments to the function.
  404. // E_FAIL Error adding context menu item.
  405. // E_NOTIMPL Not implemented for this type of data.
  406. // Any error codes returned by HrSaveData() or IWCContextMenuCallback::
  407. // AddExtensionMenuItem().
  408. //
  409. //--
  410. /////////////////////////////////////////////////////////////////////////////
  411. STDMETHODIMP CExtObject::AddContextMenuItems(
  412. IN IUnknown * piData,
  413. IN IWCContextMenuCallback * piCallback
  414. )
  415. {
  416. HRESULT hr = NOERROR;
  417. CException exc(FALSE /*bAutoDelete*/);
  418. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  419. // Validate the parameters.
  420. if ((piData == NULL) || (piCallback == NULL))
  421. return E_INVALIDARG;
  422. try
  423. {
  424. // Save the data.
  425. hr = HrSaveData(piData);
  426. if (hr != NOERROR)
  427. throw &exc;
  428. // Add menu items specific to this resource type.
  429. {
  430. ULONG iCommandID;
  431. LPWSTR pwsz = g_rgpwszContextMenuItems[IstrResTypeName()];
  432. LPWSTR pwszName;
  433. LPWSTR pwszStatusBarText;
  434. for (iCommandID = 0 ; *pwsz != L'\0' ; iCommandID++)
  435. {
  436. pwszName = pwsz;
  437. pwszStatusBarText = pwszName + (::wcslen(pwszName) + 1);
  438. hr = piCallback->AddExtensionMenuItem(
  439. pwszName, // lpszName
  440. pwszStatusBarText, // lpszStatusBarText
  441. iCommandID, // lCommandID
  442. 0, // lSubCommandID
  443. 0 // uFlags
  444. );
  445. if (hr != NOERROR)
  446. throw &exc;
  447. pwsz = pwszStatusBarText + (::wcslen(pwszStatusBarText) + 1);
  448. } // while: more menu items to add
  449. } // Add menu items specific to this resource type
  450. } // try
  451. catch (CException * pe)
  452. {
  453. TRACE(_T("CExtObject::CreatePropetySheetPages: Failed to add context menu item\n"));
  454. pe->Delete();
  455. if (hr == NOERROR)
  456. hr = E_FAIL;
  457. } // catch: anything
  458. if (hr != NOERROR)
  459. {
  460. piData->Release();
  461. m_piData = NULL;
  462. } // if: error occurred
  463. piCallback->Release();
  464. return hr;
  465. } //*** CExtObject::AddContextMenuItems()
  466. /////////////////////////////////////////////////////////////////////////////
  467. // IWEInvokeCommand Implementation
  468. /////////////////////////////////////////////////////////////////////////////
  469. //++
  470. //
  471. // CExtObject::InvokeCommand (IWEInvokeCommand)
  472. //
  473. // Routine Description:
  474. // Invoke a command offered by a context menu.
  475. //
  476. // Arguments:
  477. // lCommandID ID of the menu item to execute. This is the same
  478. // ID passed to the IWCContextMenuCallback
  479. // ::AddExtensionMenuItem() method.
  480. // piData IUnkown pointer from which to obtain interfaces
  481. // for obtaining data describing the object for
  482. // which the command is to be invoked.
  483. //
  484. // Return Value:
  485. // NOERROR Command invoked successfully.
  486. // E_INVALIDARG Invalid arguments to the function.
  487. // E_OUTOFMEMORY Error allocating memory.
  488. // E_NOTIMPL Not implemented for this type of data.
  489. // Any error codes from IDataObject::GetData() (through HrSaveData()).
  490. //
  491. //--
  492. /////////////////////////////////////////////////////////////////////////////
  493. HRESULT CExtObject::InvokeCommand(
  494. IN ULONG nCommandID,
  495. IN IUnknown * piData
  496. )
  497. {
  498. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  499. // Find the item that was executed in our table.
  500. hr = HrSaveData(piData);
  501. if (hr == NOERROR)
  502. {
  503. ULONG iCommandID;
  504. LPWSTR pwsz = g_rgpwszContextMenuItems[IstrResTypeName()];
  505. LPWSTR pwszName;
  506. LPWSTR pwszStatusBarText;
  507. for (iCommandID = 0 ; *pwsz != L'\0' ; iCommandID++)
  508. {
  509. pwszName = pwsz;
  510. pwszStatusBarText = pwszName + (::wcslen(pwszName) + 1);
  511. if (iCommandID == nCommandID)
  512. break;
  513. pwsz = pwszStatusBarText + (::wcslen(pwszStatusBarText) + 1);
  514. } // while: more menu items to add
  515. if (iCommandID == nCommandID)
  516. {
  517. CString strMsg;
  518. CString strName;
  519. try
  520. {
  521. strName = pwszName;
  522. strMsg.Format(_T("Item %s was executed"), strName);
  523. AfxMessageBox(strMsg);
  524. } // try
  525. catch (CException * pe)
  526. {
  527. pe->Delete();
  528. } // catch: CException
  529. } // if: command ID found
  530. } // if: no errors saving the data
  531. piData->Release();
  532. m_piData = NULL;
  533. return NOERROR;
  534. } //*** CExtObject::InvokeCommand()
  535. #endif
  536. /////////////////////////////////////////////////////////////////////////////
  537. //++
  538. //
  539. // CExtObject::HrGetUIInfo
  540. //
  541. // Routine Description:
  542. // Get info about displaying UI.
  543. //
  544. // Arguments:
  545. // piData IUnkown pointer from which to obtain interfaces
  546. // for obtaining data describing the object.
  547. //
  548. // Return Value:
  549. // NOERROR Data saved successfully.
  550. // E_NOTIMPL Not implemented for this type of data.
  551. // Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  552. // or HrGetResourceName().
  553. //
  554. //--
  555. /////////////////////////////////////////////////////////////////////////////
  556. HRESULT CExtObject::HrGetUIInfo(IUnknown * piData)
  557. {
  558. HRESULT hr = NOERROR;
  559. ASSERT(piData != NULL);
  560. // Save info about all types of objects.
  561. {
  562. IGetClusterUIInfo * pi;
  563. hr = piData->QueryInterface(IID_IGetClusterUIInfo, (LPVOID *) &pi);
  564. if (hr != NOERROR)
  565. return hr;
  566. m_lcid = pi->GetLocale();
  567. m_hfont = pi->GetFont();
  568. m_hicon = pi->GetIcon();
  569. pi->Release();
  570. } // Save info about all types of objects
  571. return hr;
  572. } //*** CExtObject::HrGetUIInfo()
  573. /////////////////////////////////////////////////////////////////////////////
  574. //++
  575. //
  576. // CExtObject::HrSaveData
  577. //
  578. // Routine Description:
  579. // Save data from the object so that it can be used for the life
  580. // of the object.
  581. //
  582. // Arguments:
  583. // piData IUnkown pointer from which to obtain interfaces
  584. // for obtaining data describing the object.
  585. //
  586. // Return Value:
  587. // NOERROR Data saved successfully.
  588. // E_NOTIMPL Not implemented for this type of data.
  589. // Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  590. // or HrGetResourceName().
  591. //
  592. //--
  593. /////////////////////////////////////////////////////////////////////////////
  594. HRESULT CExtObject::HrSaveData(IUnknown * piData)
  595. {
  596. HRESULT hr = NOERROR;
  597. ASSERT(piData != NULL);
  598. if (piData != m_piData)
  599. {
  600. if (m_piData != NULL)
  601. m_piData->Release();
  602. m_piData = piData;
  603. } // if: different data interface pointer
  604. // Save info about all types of objects.
  605. {
  606. IGetClusterDataInfo * pi;
  607. hr = piData->QueryInterface(IID_IGetClusterDataInfo, (LPVOID *) &pi);
  608. if (hr != NOERROR)
  609. return hr;
  610. m_hcluster = pi->GetClusterHandle();
  611. m_cobj = pi->GetObjectCount();
  612. if (Cobj() != 1)
  613. hr = E_NOTIMPL;
  614. else
  615. hr = HrGetClusterName(pi);
  616. pi->Release();
  617. if (hr != NOERROR)
  618. return hr;
  619. } // Save info about all types of objects
  620. // Save info about this object.
  621. hr = HrGetObjectInfo();
  622. if (hr != NOERROR)
  623. return hr;
  624. //
  625. // Get the handle of the node we are running on.
  626. //
  627. WCHAR wcsNodeName[MAX_COMPUTERNAME_LENGTH+1] = L"";
  628. DWORD dwLength = MAX_COMPUTERNAME_LENGTH+1;
  629. if ( ClusterResourceStateUnknown !=
  630. GetClusterResourceState(m_rdResData.m_hresource, wcsNodeName, &dwLength, NULL, 0))
  631. {
  632. m_strNodeName = wcsNodeName;
  633. }
  634. return hr;
  635. } //*** CExtObject::HrSaveData()
  636. /////////////////////////////////////////////////////////////////////////////
  637. //++
  638. //
  639. // CExtObject::HrGetObjectInfo
  640. //
  641. // Routine Description:
  642. // Get information about the object.
  643. //
  644. // Arguments:
  645. // None.
  646. //
  647. // Return Value:
  648. // NOERROR Data saved successfully.
  649. // E_OUTOFMEMORY Error allocating memory.
  650. // E_NOTIMPL Not implemented for this type of data.
  651. // Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  652. // or HrGetResourceName().
  653. //
  654. //--
  655. /////////////////////////////////////////////////////////////////////////////
  656. HRESULT CExtObject::HrGetObjectInfo(void)
  657. {
  658. HRESULT hr = NOERROR;
  659. IGetClusterObjectInfo * piGcoi;
  660. IGetClusterResourceInfo * piGcri;
  661. CException exc(FALSE /*bAutoDelete*/);
  662. ASSERT(PiData() != NULL);
  663. // Get an IGetClusterObjectInfo interface pointer.
  664. hr = PiData()->QueryInterface(IID_IGetClusterObjectInfo, (LPVOID *) &piGcoi);
  665. if (hr != NOERROR)
  666. return hr;
  667. // Read the object data.
  668. try
  669. {
  670. // Get the type of the object.
  671. m_rdResData.m_cot = piGcoi->GetObjectType(0);
  672. if (m_rdResData.m_cot != CLUADMEX_OT_RESOURCE)
  673. {
  674. hr = E_NOTIMPL;
  675. throw &exc;
  676. } // if: not a resource
  677. hr = HrGetObjectName(piGcoi);
  678. } // try
  679. catch (CException * pe)
  680. {
  681. pe->Delete();
  682. } // catch: CException
  683. piGcoi->Release();
  684. if (hr != NOERROR)
  685. return hr;
  686. // Get an IGetClusterResourceInfo interface pointer.
  687. hr = PiData()->QueryInterface(IID_IGetClusterResourceInfo, (LPVOID *) &piGcri);
  688. if (hr != NOERROR)
  689. return hr;
  690. m_rdResData.m_hresource = piGcri->GetResourceHandle(0);
  691. hr = HrGetResourceTypeName(piGcri);
  692. // See if we know about this resource type.
  693. if (hr == NOERROR)
  694. {
  695. LPCWSTR pwszResTypeName;
  696. // Find the resource type name in our list.
  697. // Save the index for use in other arrays.
  698. for (m_istrResTypeName = 0, pwszResTypeName = g_wszResourceTypeNames
  699. ; *pwszResTypeName != L'\0'
  700. ; m_istrResTypeName++, pwszResTypeName += ::wcslen(pwszResTypeName) + 1
  701. )
  702. {
  703. if (RrdResData().m_strResTypeName.CompareNoCase(pwszResTypeName) == 0 )
  704. break;
  705. } // for: each resource type in the list
  706. if (*pwszResTypeName == L'\0')
  707. hr = E_NOTIMPL;
  708. } // See if we know about this resource type
  709. piGcoi->Release();
  710. return hr;
  711. } //*** CExtObject::HrGetObjectInfo()
  712. /////////////////////////////////////////////////////////////////////////////
  713. //++
  714. //
  715. // CExtObject::HrGetClusterName
  716. //
  717. // Routine Description:
  718. // Get the name of the cluster.
  719. //
  720. // Arguments:
  721. // piData IGetClusterDataInfo interface pointer for getting
  722. // the object name.
  723. //
  724. // Return Value:
  725. // NOERROR Data saved successfully.
  726. // E_NOTIMPL Not implemented for this type of data.
  727. // Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  728. // or HrGetResourceName().
  729. //
  730. //--
  731. /////////////////////////////////////////////////////////////////////////////
  732. HRESULT CExtObject::HrGetClusterName(
  733. IN OUT IGetClusterDataInfo * pi
  734. )
  735. {
  736. HRESULT hr = NOERROR;
  737. WCHAR * pwszName = NULL;
  738. LONG cchName;
  739. ASSERT(pi != NULL);
  740. hr = pi->GetClusterName(NULL, &cchName);
  741. if (hr != NOERROR)
  742. return hr;
  743. try
  744. {
  745. pwszName = new WCHAR[cchName];
  746. hr = pi->GetClusterName(pwszName, &cchName);
  747. if (hr != NOERROR)
  748. {
  749. delete [] pwszName;
  750. pwszName = NULL;
  751. } // if: error getting cluster name
  752. m_strClusterName = pwszName;
  753. } // try
  754. catch (CMemoryException * pme)
  755. {
  756. pme->Delete();
  757. hr = E_OUTOFMEMORY;
  758. } // catch: CMemoryException
  759. delete [] pwszName;
  760. return hr;
  761. } //*** CExtObject::HrGetClusterName()
  762. /////////////////////////////////////////////////////////////////////////////
  763. //++
  764. //
  765. // CExtObject::HrGetObjectName
  766. //
  767. // Routine Description:
  768. // Get the name of the object.
  769. //
  770. // Arguments:
  771. // piData IGetClusterObjectInfo interface pointer for getting
  772. // the object name.
  773. //
  774. // Return Value:
  775. // NOERROR Data saved successfully.
  776. // E_NOTIMPL Not implemented for this type of data.
  777. // Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  778. // or HrGetResourceName().
  779. //
  780. //--
  781. /////////////////////////////////////////////////////////////////////////////
  782. HRESULT CExtObject::HrGetObjectName(
  783. IN OUT IGetClusterObjectInfo * pi
  784. )
  785. {
  786. HRESULT hr = NOERROR;
  787. WCHAR * pwszName = NULL;
  788. LONG cchName;
  789. ASSERT(pi != NULL);
  790. hr = pi->GetObjectName(0, NULL, &cchName);
  791. if (hr != NOERROR)
  792. return hr;
  793. try
  794. {
  795. pwszName = new WCHAR[cchName];
  796. hr = pi->GetObjectName(0, pwszName, &cchName);
  797. if (hr != NOERROR)
  798. {
  799. delete [] pwszName;
  800. pwszName = NULL;
  801. } // if: error getting object name
  802. m_rdResData.m_strName = pwszName;
  803. } // try
  804. catch (CMemoryException * pme)
  805. {
  806. pme->Delete();
  807. hr = E_OUTOFMEMORY;
  808. } // catch: CMemoryException
  809. delete [] pwszName;
  810. return hr;
  811. } //*** CExtObject::HrGetObjectName()
  812. /////////////////////////////////////////////////////////////////////////////
  813. //++
  814. //
  815. // CExtObject::HrGetResourceTypeName
  816. //
  817. // Routine Description:
  818. // Get the name of the resource's type.
  819. //
  820. // Arguments:
  821. // piData IGetClusterResourceInfo interface pointer for getting
  822. // the resource type name.
  823. //
  824. // Return Value:
  825. // NOERROR Data saved successfully.
  826. // E_NOTIMPL Not implemented for this type of data.
  827. // Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
  828. // or HrGetResourceName().
  829. //
  830. //--
  831. /////////////////////////////////////////////////////////////////////////////
  832. HRESULT CExtObject::HrGetResourceTypeName(
  833. IN OUT IGetClusterResourceInfo * pi
  834. )
  835. {
  836. HRESULT hr = NOERROR;
  837. WCHAR * pwszName = NULL;
  838. LONG cchName;
  839. ASSERT(pi != NULL);
  840. hr = pi->GetResourceTypeName(0, NULL, &cchName);
  841. if (hr != NOERROR)
  842. return hr;
  843. try
  844. {
  845. pwszName = new WCHAR[cchName];
  846. hr = pi->GetResourceTypeName(0, pwszName, &cchName);
  847. if (hr != NOERROR)
  848. {
  849. delete [] pwszName;
  850. pwszName = NULL;
  851. } // if: error getting resource type name
  852. m_rdResData.m_strResTypeName = pwszName;
  853. } // try
  854. catch (CMemoryException * pme)
  855. {
  856. pme->Delete();
  857. hr = E_OUTOFMEMORY;
  858. } // catch: CMemoryException
  859. delete [] pwszName;
  860. return hr;
  861. } //*** CExtObject::HrGetResourceTypeName()
  862. /////////////////////////////////////////////////////////////////////////////
  863. //++
  864. //
  865. // CExtObject::BGetResourceNetworkName
  866. //
  867. // Routine Description:
  868. // Get the name of the resource's type.
  869. //
  870. // Arguments:
  871. // lpszNetName [OUT] String in which to return the network name resource name.
  872. // pcchNetName [IN OUT] Points to a variable that specifies the
  873. // maximum size, in characters, of the buffer. This
  874. // value shold be large enough to contain
  875. // MAX_COMPUTERNAME_LENGTH + 1 characters. Upon
  876. // return it contains the actual number of characters
  877. // copied.
  878. //
  879. // Return Value:
  880. // TRUE Resource is dependent on a network name resource.
  881. // FALSE Resource is NOT dependent on a network name resource.
  882. //
  883. //--
  884. /////////////////////////////////////////////////////////////////////////////
  885. BOOL CExtObject::BGetResourceNetworkName(
  886. OUT WCHAR * lpszNetName,
  887. IN OUT DWORD * pcchNetName
  888. )
  889. {
  890. BOOL bSuccess;
  891. IGetClusterResourceInfo * piGcri;
  892. ASSERT(PiData() != NULL);
  893. // Get an IGetClusterResourceInfo interface pointer.
  894. {
  895. HRESULT hr;
  896. hr = PiData()->QueryInterface(IID_IGetClusterResourceInfo, (LPVOID *) &piGcri);
  897. if (hr != NOERROR)
  898. {
  899. SetLastError(hr);
  900. return FALSE;
  901. } // if: error getting the interface
  902. } // Get an IGetClusterResourceInfo interface pointer
  903. // Get the resource network name.
  904. bSuccess = piGcri->GetResourceNetworkName(0, lpszNetName, pcchNetName);
  905. piGcri->Release();
  906. return bSuccess;
  907. } //*** CExtObject::BGetResourceNetworkName()