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.

1079 lines
24 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation
  3. Module Name:
  4. compdata.cpp
  5. Abstract:
  6. This module implemets CComponentData class
  7. Author:
  8. William Hsieh (williamh) created
  9. Revision History:
  10. --*/
  11. #include "devmgr.h"
  12. #include "factory.h"
  13. #include "genpage.h"
  14. const WCHAR* const DM_COMPDATA_SIGNATURE = L"Device Manager";
  15. CComponentData::CComponentData()
  16. {
  17. m_pScope = NULL;
  18. m_pConsole = NULL;
  19. m_pCookieRoot = NULL;
  20. m_pScopeItemRoot = NULL;
  21. //
  22. // Static scope item default to device manager
  23. //
  24. m_ctRoot = COOKIE_TYPE_SCOPEITEM_DEVMGR;
  25. m_hwndMain = NULL;
  26. m_pMachine = NULL;
  27. m_IsDirty = FALSE;
  28. //
  29. // Increment object count (used by CanUnloadNow)
  30. //
  31. ::InterlockedIncrement(&CClassFactory::s_Objects);
  32. m_Ref = 1;
  33. }
  34. CComponentData::~CComponentData()
  35. {
  36. //
  37. // All QIed interfaces should be released during
  38. // Destroy method
  39. //
  40. ASSERT(NULL == m_pScope);
  41. ASSERT(NULL == m_pConsole);
  42. ASSERT(NULL == m_pCookieRoot);
  43. //
  44. // decrement object count(used by CanUnloadNow)
  45. //
  46. ASSERT( 0 != CClassFactory::s_Objects );
  47. ::InterlockedDecrement(&CClassFactory::s_Objects);
  48. }
  49. //
  50. // IUnknown interface
  51. //
  52. ULONG
  53. CComponentData::AddRef()
  54. {
  55. return ::InterlockedIncrement(&m_Ref);
  56. }
  57. ULONG
  58. CComponentData::Release()
  59. {
  60. ASSERT( 0 != m_Ref );
  61. ULONG cRef = ::InterlockedDecrement(&m_Ref);
  62. if ( 0 == cRef )
  63. {
  64. delete this;
  65. }
  66. return cRef;
  67. }
  68. STDMETHODIMP
  69. CComponentData::QueryInterface(
  70. REFIID riid,
  71. void** ppv
  72. )
  73. {
  74. if (!ppv)
  75. {
  76. return E_INVALIDARG;
  77. }
  78. HRESULT hr = S_OK;
  79. if (IsEqualIID(riid, IID_IUnknown))
  80. {
  81. *ppv = (IUnknown*)(IComponentData*)this;
  82. }
  83. else if (IsEqualIID(riid, IID_IComponentData))
  84. {
  85. *ppv = (IComponentData*)this;
  86. }
  87. else if (IsEqualIID(riid, IID_IExtendContextMenu))
  88. {
  89. *ppv = (IExtendContextMenu*)this;
  90. }
  91. else if (IsEqualIID(riid, IID_IExtendPropertySheet))
  92. {
  93. *ppv = (IExtendPropertySheet*)this;
  94. }
  95. else if (IsEqualIID(riid, IID_IPersistStream))
  96. {
  97. *ppv = (IPersistStream*)this;
  98. }
  99. else if (IsEqualIID(riid, IID_ISnapinHelp))
  100. {
  101. *ppv = (ISnapinHelp*)this;
  102. }
  103. else
  104. {
  105. *ppv = NULL;
  106. hr = E_NOINTERFACE;
  107. }
  108. if (SUCCEEDED(hr))
  109. {
  110. AddRef();
  111. }
  112. return hr;
  113. }
  114. /////////////////////////////////////////////////////////////////////////////
  115. // IComponentData implementation
  116. ///
  117. STDMETHODIMP
  118. CComponentData::Initialize(
  119. LPUNKNOWN pUnknown
  120. )
  121. {
  122. if (!pUnknown)
  123. {
  124. return E_INVALIDARG;
  125. }
  126. HRESULT hr;
  127. try
  128. {
  129. //
  130. // This function should be called only once.
  131. //
  132. ASSERT(NULL == m_pScope);
  133. //
  134. // Get the IConsoleNameSpace interface
  135. //
  136. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace, (void**)&m_pScope);
  137. if (SUCCEEDED(hr))
  138. {
  139. hr = pUnknown->QueryInterface(IID_IConsole, (void**)&m_pConsole);
  140. if (SUCCEEDED(hr))
  141. {
  142. //
  143. // Retreive the console main window. It will be used
  144. // as the parent window of property sheets and
  145. // parent handle for setupapi calls
  146. //
  147. m_pConsole->GetMainWindow(&m_hwndMain);
  148. LoadScopeIconsForScopePane();
  149. }
  150. else
  151. {
  152. //
  153. // Unable to get the IConsole Interface
  154. //
  155. m_pScope->Release();
  156. }
  157. }
  158. }
  159. catch (CMemoryException* e)
  160. {
  161. e->Delete();
  162. MsgBoxParam(m_hwndMain, 0, 0, 0);
  163. hr = E_OUTOFMEMORY;
  164. }
  165. return hr;
  166. }
  167. // This function creates a new CComponent
  168. // A Component will be created when a new "window" is being created.
  169. //
  170. STDMETHODIMP
  171. CComponentData::CreateComponent(
  172. LPCOMPONENT* ppComponent
  173. )
  174. {
  175. HRESULT hr;
  176. if (!ppComponent)
  177. {
  178. return E_INVALIDARG;
  179. }
  180. try
  181. {
  182. CComponent* pComponent = new CComponent(this);
  183. //
  184. // Return the IComponent interface
  185. //
  186. hr = pComponent->QueryInterface(IID_IComponent, (void**)ppComponent);
  187. pComponent->Release();
  188. if (SUCCEEDED(hr))
  189. {
  190. hr = CreateScopeItems();
  191. if (SUCCEEDED(hr))
  192. {
  193. hr = pComponent->CreateFolderList(m_pCookieRoot);
  194. }
  195. else
  196. {
  197. pComponent->Release();
  198. *ppComponent = NULL;
  199. }
  200. }
  201. }
  202. catch (CMemoryException* e)
  203. {
  204. e->Delete();
  205. MsgBoxParam(m_hwndMain, 0, 0, 0);
  206. hr = E_OUTOFMEMORY;
  207. }
  208. return hr;
  209. }
  210. STDMETHODIMP
  211. CComponentData::Notify(
  212. LPDATAOBJECT lpDataObject,
  213. MMC_NOTIFY_TYPE event,
  214. LPARAM arg,
  215. LPARAM param
  216. )
  217. {
  218. HRESULT hr;
  219. try
  220. {
  221. //
  222. // On MMCN_PROPERTY_CHANGE event, lpDataObject is invalid
  223. // Donot touch it.
  224. //
  225. if (MMCN_PROPERTY_CHANGE == event)
  226. {
  227. PPROPERTY_CHANGE_INFO pPCI = (PPROPERTY_CHANGE_INFO) param;
  228. if (pPCI && PCT_STARTUP_INFODATA == pPCI->Type)
  229. {
  230. PSTARTUP_INFODATA pSI = (PSTARTUP_INFODATA)&pPCI->InfoData;
  231. ASSERT(pSI->Size == sizeof(STARTUP_INFODATA));
  232. if (pSI->MachineName[0] != _T('\0'))
  233. {
  234. m_strMachineName = pSI->MachineName;
  235. }
  236. m_ctRoot = pSI->ct;
  237. SetDirty();
  238. }
  239. return S_OK;
  240. }
  241. else if (MMCN_EXPAND == event)
  242. {
  243. return OnExpand(lpDataObject, arg, param);
  244. }
  245. else if (MMCN_REMOVE_CHILDREN == event)
  246. {
  247. //
  248. // This is basically a hack!!!!
  249. // When the target computer is switched in Computer Management
  250. // snapin (we are an extention to it), we basically get
  251. // a MMCN_REMOVE_CHILDREN followed by MMCN_EXPAND.
  252. // The right thing for MMC to do is to create a new IComponent
  253. // for each new machine so that each IComponent can maintain
  254. // its own states (thus, its own folders).
  255. // Well, it is not a perfect world and we are forced to use
  256. // the old IComponent. So here we notify each scope node
  257. // which in turns will notify all the CFolders.
  258. //
  259. // After reset, each folder does not attach to any CMachine object
  260. // (thus, its m_pMachine will be NULL). Each folder will attach
  261. // to the new machine object when its OnShow method is called
  262. // the very "first" time.
  263. //
  264. if (!IsPrimarySnapin() && m_pScopeItemRoot)
  265. {
  266. m_pMachine->DestroyNotifyWindow();
  267. ResetScopeItem(m_pScopeItemRoot);
  268. }
  269. return S_OK;
  270. }
  271. ASSERT(m_pScope);
  272. INTERNAL_DATA tID;
  273. hr = ExtractData(lpDataObject, CDataObject::m_cfSnapinInternal,
  274. (PBYTE)&tID, sizeof(tID));
  275. if (SUCCEEDED(hr))
  276. {
  277. switch (event) {
  278. case MMCN_DELETE:
  279. hr = OnDelete(tID.cookie, arg, param);
  280. break;
  281. case MMCN_RENAME:
  282. hr = OnRename(tID.cookie, arg, param);
  283. break;
  284. case MMCN_CONTEXTMENU:
  285. hr = OnContextMenu(tID.cookie, arg, param);
  286. break;
  287. case MMCN_BTN_CLICK:
  288. hr = OnBtnClick(tID.cookie, arg, param);
  289. break;
  290. default:
  291. hr = S_OK;
  292. break;
  293. }
  294. }
  295. }
  296. catch(CMemoryException* e)
  297. {
  298. e->Delete();
  299. hr = E_OUTOFMEMORY;
  300. }
  301. return hr;
  302. }
  303. STDMETHODIMP
  304. CComponentData::GetDisplayInfo(
  305. SCOPEDATAITEM* pScopeDataItem
  306. )
  307. {
  308. if (!pScopeDataItem)
  309. {
  310. return E_INVALIDARG;
  311. }
  312. try
  313. {
  314. //
  315. // IComponentData::GetDisplayInfo only deals with scope pane items.
  316. // Snapin's IComponent::GetDisplayInfo will deal with result pane items
  317. //
  318. CCookie* pCookie = (CCookie*) pScopeDataItem->lParam;
  319. ASSERT(pCookie);
  320. return pCookie->GetScopeItem()->GetDisplayInfo(pScopeDataItem);
  321. }
  322. catch (CMemoryException* e)
  323. {
  324. e->Delete();
  325. MsgBoxParam(m_hwndMain, 0, 0, 0);
  326. return E_OUTOFMEMORY;
  327. }
  328. }
  329. STDMETHODIMP
  330. CComponentData::Destroy()
  331. {
  332. if (m_pCookieRoot)
  333. {
  334. delete m_pCookieRoot;
  335. m_pCookieRoot = NULL;
  336. }
  337. if (m_pScopeItemRoot)
  338. {
  339. delete m_pScopeItemRoot;
  340. }
  341. if (m_pScope)
  342. {
  343. m_pScope->Release();
  344. m_pScope = NULL;
  345. }
  346. if (m_pConsole)
  347. {
  348. m_pConsole->Release();
  349. m_pConsole = NULL;
  350. }
  351. return S_OK;
  352. }
  353. STDMETHODIMP
  354. CComponentData::QueryDataObject(
  355. MMC_COOKIE cookie,
  356. DATA_OBJECT_TYPES type,
  357. LPDATAOBJECT* ppDataObject
  358. )
  359. {
  360. CDataObject* pDataObject;
  361. COOKIE_TYPE ct;
  362. CCookie* pCookie;
  363. try
  364. {
  365. pCookie = GetActiveCookie(cookie);
  366. if (NULL == pCookie)
  367. {
  368. ct = m_ctRoot;
  369. }
  370. else
  371. {
  372. ct = pCookie->GetType();
  373. }
  374. pDataObject = new CDataObject;
  375. pDataObject->Initialize(type, ct, pCookie, m_strMachineName);
  376. pDataObject->AddRef();
  377. *ppDataObject = pDataObject;
  378. }
  379. catch (CMemoryException* e)
  380. {
  381. e->Delete();
  382. MsgBoxParam(m_hwndMain, 0, 0, 0);
  383. return E_OUTOFMEMORY;
  384. }
  385. return S_OK;
  386. }
  387. STDMETHODIMP
  388. CComponentData::CompareObjects(
  389. LPDATAOBJECT lpDataObjectA,
  390. LPDATAOBJECT lpDataObjectB
  391. )
  392. {
  393. HRESULT hr;
  394. try
  395. {
  396. INTERNAL_DATA tID_A, tID_B;
  397. hr = ExtractData(lpDataObjectA, CDataObject::m_cfSnapinInternal,
  398. (PBYTE)&tID_A, sizeof(tID_A));
  399. if (SUCCEEDED(hr))
  400. {
  401. hr = ExtractData(lpDataObjectB, CDataObject::m_cfSnapinInternal,
  402. (PBYTE)&tID_B, sizeof(tID_B));
  403. if (SUCCEEDED(hr))
  404. {
  405. hr = (tID_A.ct == tID_B.ct && tID_A.cookie == tID_B.cookie &&
  406. tID_A.dot == tID_B.dot) ? S_OK : S_FALSE;
  407. }
  408. }
  409. }
  410. catch(CMemoryException* e)
  411. {
  412. e->Delete();
  413. MsgBoxParam(m_hwndMain, 0, 0, 0);
  414. hr = E_OUTOFMEMORY;
  415. }
  416. return hr;
  417. }
  418. ///////////////////////////////////////////////////////////////////
  419. //// IExtendPropertySheet implementation
  420. ////
  421. STDMETHODIMP
  422. CComponentData::QueryPagesFor(
  423. LPDATAOBJECT lpDataObject
  424. )
  425. {
  426. HRESULT hr;
  427. if (!lpDataObject)
  428. {
  429. return E_INVALIDARG;
  430. }
  431. try
  432. {
  433. INTERNAL_DATA tID;
  434. hr = ExtractData(lpDataObject, CDataObject::m_cfSnapinInternal,
  435. (PBYTE)&tID, sizeof(tID));
  436. if (SUCCEEDED(hr))
  437. {
  438. CScopeItem* pScopeItem;
  439. pScopeItem = FindScopeItem(tID.cookie);
  440. if (CCT_SNAPIN_MANAGER == tID.dot && COOKIE_TYPE_SCOPEITEM_DEVMGR == tID.ct)
  441. {
  442. hr = S_OK;
  443. }
  444. else if (pScopeItem)
  445. {
  446. hr = pScopeItem->QueryPagesFor();
  447. }
  448. else
  449. {
  450. hr = S_FALSE;
  451. }
  452. }
  453. }
  454. catch (CMemoryException* e)
  455. {
  456. e->Delete();
  457. MsgBoxParam(m_hwndMain, 0, 0, 0);
  458. hr = E_OUTOFMEMORY;
  459. }
  460. return hr;
  461. }
  462. STDMETHODIMP
  463. CComponentData::CreatePropertyPages(
  464. LPPROPERTYSHEETCALLBACK lpProvider,
  465. LONG_PTR handle,
  466. LPDATAOBJECT lpDataObject
  467. )
  468. {
  469. if (!lpProvider || !lpDataObject)
  470. {
  471. return E_INVALIDARG;
  472. }
  473. HRESULT hr;
  474. try
  475. {
  476. INTERNAL_DATA tID;
  477. hr = ExtractData(lpDataObject, CDataObject::m_cfSnapinInternal,
  478. reinterpret_cast<BYTE*>(&tID), sizeof(tID)
  479. );
  480. if (SUCCEEDED(hr))
  481. {
  482. CScopeItem* pScopeItem = FindScopeItem(tID.cookie);
  483. if (CCT_SNAPIN_MANAGER == tID.dot && COOKIE_TYPE_SCOPEITEM_DEVMGR == tID.ct)
  484. {
  485. hr = DoStartupProperties(lpProvider, handle, lpDataObject);
  486. }
  487. else if (pScopeItem)
  488. {
  489. hr = pScopeItem->CreatePropertyPages(lpProvider, handle);
  490. }
  491. else
  492. {
  493. hr = S_OK;
  494. }
  495. }
  496. }
  497. catch(CMemoryException* e)
  498. {
  499. e->Delete();
  500. MsgBoxParam(m_hwndMain, 0, 0, 0);
  501. hr = E_OUTOFMEMORY;
  502. }
  503. return hr;
  504. }
  505. ////////////////////////////////////////////////////////////
  506. //// IExtendContextMenu implemantation
  507. ////
  508. STDMETHODIMP
  509. CComponentData::AddMenuItems(
  510. LPDATAOBJECT lpDataObject,
  511. LPCONTEXTMENUCALLBACK pCallbackUnknown,
  512. long *pInsertionAllowed
  513. )
  514. {
  515. if (!lpDataObject || !pCallbackUnknown || !pInsertionAllowed)
  516. {
  517. return E_INVALIDARG;
  518. }
  519. return S_OK;
  520. }
  521. STDMETHODIMP
  522. CComponentData::Command(
  523. long nCommandID,
  524. LPDATAOBJECT lpDataObject
  525. )
  526. {
  527. UNREFERENCED_PARAMETER(nCommandID);
  528. if (!lpDataObject)
  529. {
  530. return E_INVALIDARG;
  531. }
  532. return S_OK;
  533. }
  534. HRESULT
  535. CComponentData::CreateCookieSubtree(
  536. CScopeItem* pScopeItem,
  537. CCookie* pCookieParent
  538. )
  539. {
  540. ASSERT(pScopeItem);
  541. CScopeItem* pChild;
  542. CCookie* pCookieSibling;
  543. pCookieSibling = NULL;
  544. int Index = 0;
  545. while (pScopeItem->EnumerateChildren(Index, &pChild))
  546. {
  547. CCookie* pCookie;
  548. pCookie = new CCookie(pChild->GetType());
  549. if (pCookie) {
  550. pCookie->SetScopeItem(pChild);
  551. if (!pCookieSibling)
  552. {
  553. pCookieParent->SetChild(pCookie);
  554. }
  555. else
  556. {
  557. pCookieSibling->SetSibling(pCookie);
  558. }
  559. pCookie->SetParent(pCookieParent);
  560. if (pChild->GetChildCount())
  561. {
  562. CreateCookieSubtree(pChild, pCookie);
  563. }
  564. pCookieSibling = pCookie;
  565. }
  566. Index++;
  567. }
  568. return S_OK;
  569. }
  570. ////////////////////////////////////////////////////////////
  571. /// IPersistStream implementation
  572. ///
  573. STDMETHODIMP
  574. CComponentData::GetClassID(
  575. CLSID* pClassID
  576. )
  577. {
  578. if(!pClassID)
  579. {
  580. return E_INVALIDARG;
  581. }
  582. *pClassID = GetCoClassID();
  583. return S_OK;
  584. }
  585. STDMETHODIMP
  586. CComponentData::IsDirty()
  587. {
  588. return m_IsDirty ? S_OK : S_FALSE;
  589. }
  590. STDMETHODIMP
  591. CComponentData::Load(
  592. IStream* pStm
  593. )
  594. {
  595. HRESULT hr;
  596. SafeInterfacePtr<IStream> StmPtr(pStm);
  597. //
  598. // Fix up the MachineName that we got from the command line if there was one.
  599. // We need to prepend "\\" to the MachineName if it does not start with two
  600. // backslashes, and then we will verify the machine name by calling CM_Connect_Machine
  601. // to verify that this user has access to that machine. If they do not then we
  602. // will set the MachineName to NULL.
  603. //
  604. if (!g_strStartupMachineName.IsEmpty())
  605. {
  606. if (_T('\\') != g_strStartupMachineName[0])
  607. {
  608. g_strStartupMachineName = TEXT("\\\\") + g_strStartupMachineName;
  609. }
  610. }
  611. COMPDATA_PERSISTINFO Info;
  612. ULONG BytesRead;
  613. ASSERT(pStm);
  614. //
  615. // Read the persist data and verify that we have the right data
  616. //
  617. hr = pStm->Read(&Info, sizeof(Info), &BytesRead);
  618. if (SUCCEEDED(hr) &&
  619. (BytesRead >= sizeof(Info)) &&
  620. (Info.Size >= sizeof(Info)) &&
  621. (!wcscmp(Info.Signature, DM_COMPDATA_SIGNATURE)))
  622. {
  623. try
  624. {
  625. m_ctRoot = Info.RootCookie;
  626. m_strMachineName.Empty();
  627. if (UNICODE_NULL != Info.ComputerFullName[0])
  628. {
  629. m_strMachineName = Info.ComputerFullName;
  630. }
  631. if (COOKIE_TYPE_SCOPEITEM_DEVMGR == m_ctRoot)
  632. {
  633. //
  634. // Parameters from command line has the priority
  635. //
  636. if (!g_strStartupMachineName.IsEmpty())
  637. {
  638. m_strMachineName = g_strStartupMachineName;
  639. }
  640. m_strStartupDeviceId = g_strStartupDeviceId;
  641. m_strStartupCommand = g_strStartupCommand;
  642. }
  643. hr = CreateScopeItems();
  644. if (SUCCEEDED(hr))
  645. {
  646. if (!m_pMachine)
  647. {
  648. if (!g_MachineList.CreateMachine(m_strMachineName, &m_pMachine))
  649. {
  650. hr = HRESULT_FROM_WIN32(GetLastError());
  651. }
  652. }
  653. }
  654. }
  655. catch(CMemoryException* e)
  656. {
  657. e->Delete();
  658. MsgBoxParam(m_hwndMain, 0, 0, 0);
  659. hr = E_OUTOFMEMORY;
  660. }
  661. } else {
  662. //
  663. // No persistant data, so use the command line parameters.
  664. //
  665. m_strMachineName = g_strStartupMachineName;
  666. m_strStartupDeviceId = g_strStartupDeviceId;
  667. m_strStartupCommand = g_strStartupCommand;
  668. }
  669. m_IsDirty = FALSE;
  670. return hr;
  671. }
  672. STDMETHODIMP
  673. CComponentData::Save(
  674. IStream* pStm,
  675. BOOL fClearDirty
  676. )
  677. {
  678. SafeInterfacePtr<IStream> StmPtr(pStm);
  679. HRESULT hr;
  680. try
  681. {
  682. COMPDATA_PERSISTINFO Info;
  683. Info.Size = sizeof(Info);
  684. Info.RootCookie = m_ctRoot;
  685. StringCchCopy(Info.Signature, ARRAYLEN(Info.Signature), DM_COMPDATA_SIGNATURE);
  686. //
  687. // Assuming it is on local machine. The machine name is saved
  688. // in UNICODE
  689. //
  690. Info.ComputerFullName[0] = UNICODE_NULL;
  691. if (m_strMachineName.GetLength())
  692. StringCchCopy(Info.ComputerFullName, ARRAYLEN(Info.ComputerFullName), m_strMachineName);
  693. hr = pStm->Write(&Info, sizeof(Info), NULL);
  694. }
  695. catch (CMemoryException* e)
  696. {
  697. e->Delete();
  698. MsgBoxParam(m_hwndMain, 0, 0, 0);
  699. hr = E_OUTOFMEMORY;
  700. }
  701. if (fClearDirty)
  702. {
  703. m_IsDirty = FALSE;
  704. }
  705. return hr;
  706. }
  707. STDMETHODIMP
  708. CComponentData::GetSizeMax(
  709. ULARGE_INTEGER* pcbSize
  710. )
  711. {
  712. if (!pcbSize)
  713. {
  714. return E_INVALIDARG;
  715. }
  716. int len;
  717. len = sizeof(m_ctRoot) + sizeof(len) + (m_strMachineName.GetLength() + 1) * sizeof(TCHAR);
  718. ULISet32(*pcbSize, len);
  719. return S_OK;
  720. }
  721. //
  722. // Method to support html help.
  723. //
  724. //
  725. STDMETHODIMP
  726. CComponentData::GetHelpTopic(
  727. LPOLESTR* lpCompileHelpFile
  728. )
  729. {
  730. if (!lpCompileHelpFile)
  731. {
  732. return E_INVALIDARG;
  733. }
  734. *lpCompileHelpFile = NULL;
  735. String strHelpFile;
  736. if (strHelpFile.GetSystemWindowsDirectory()) {
  737. strHelpFile += (LPCTSTR)DEVMGR_HTML_HELP_FILE_NAME;
  738. *lpCompileHelpFile = AllocOleTaskString((LPCTSTR)strHelpFile);
  739. }
  740. return S_OK;
  741. }
  742. CScopeItem*
  743. CComponentData::FindScopeItem(
  744. MMC_COOKIE cookie
  745. )
  746. {
  747. CCookie* pCookie = GetActiveCookie(cookie);
  748. if (pCookie) {
  749. return pCookie->GetScopeItem();
  750. }
  751. return NULL;
  752. }
  753. //
  754. // This function loads icons for the scope items
  755. //
  756. HRESULT
  757. CComponentData::LoadScopeIconsForScopePane()
  758. {
  759. ASSERT(m_pScope);
  760. ASSERT(m_pConsole);
  761. LPIMAGELIST lpScopeImage;
  762. HRESULT hr;
  763. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  764. if (SUCCEEDED(hr))
  765. {
  766. HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DEVMGR));
  767. if (hIcon)
  768. {
  769. hr = lpScopeImage->ImageListSetIcon((PLONG_PTR)hIcon, IMAGE_INDEX_DEVMGR);
  770. DestroyIcon(hIcon);
  771. }
  772. hr = lpScopeImage->Release();
  773. }
  774. return hr;
  775. }
  776. //
  777. // This function create the startup wizard property sheet
  778. //
  779. // INPUT:
  780. // lpProvider -- Interface for us to add pages
  781. // handle -- notify console handle
  782. // lpDataObject -- the data object
  783. //
  784. // OUTPUT:
  785. // standard OLE HRESULT
  786. HRESULT
  787. CComponentData::DoStartupProperties(
  788. LPPROPERTYSHEETCALLBACK lpProvider,
  789. LONG_PTR handle,
  790. LPDATAOBJECT lpDataObject
  791. )
  792. {
  793. CGeneralPage* pGenPage;
  794. HPROPSHEETPAGE hPage;
  795. UNREFERENCED_PARAMETER(lpDataObject);
  796. pGenPage = new CGeneralPage();
  797. if (pGenPage)
  798. {
  799. hPage = pGenPage->Create(handle);
  800. if (hPage)
  801. {
  802. lpProvider->AddPage(hPage);
  803. //
  804. // If no console handle is provided, we have to use
  805. // our call back function
  806. //
  807. if(!handle)
  808. {
  809. pGenPage->SetOutputBuffer(&m_strMachineName, &m_ctRoot);
  810. }
  811. return S_OK;
  812. }
  813. else
  814. {
  815. throw &g_MemoryException;
  816. }
  817. }
  818. else
  819. {
  820. throw &g_MemoryException;
  821. }
  822. }
  823. //
  824. // This function creates all the necessary classes represent
  825. // our scope items
  826. //
  827. HRESULT
  828. CComponentData::CreateScopeItems()
  829. {
  830. HRESULT hr = S_OK;
  831. //
  832. // All classes are linked by cookie with m_pCookieRoot
  833. // points to the "root" scope item
  834. //
  835. if (!m_pScopeItemRoot)
  836. {
  837. switch (m_ctRoot) {
  838. case COOKIE_TYPE_SCOPEITEM_DEVMGR:
  839. m_pScopeItemRoot = new CScopeItem(COOKIE_TYPE_SCOPEITEM_DEVMGR,
  840. IMAGE_INDEX_DEVMGR,
  841. OPEN_IMAGE_INDEX_DEVMGR,
  842. IDS_NAME_DEVMGR,
  843. IDS_DESC_DEVMGR,
  844. IDS_DISPLAYNAME_SCOPE_DEVMGR);
  845. break;
  846. default:
  847. ASSERT(FALSE);
  848. break;
  849. }
  850. if (m_pScopeItemRoot->Create()) {
  851. //
  852. // Bind scope items and cookies together.
  853. // Cookies know its scopeitem.
  854. // Scopeitems do not know cookies.
  855. //
  856. m_pCookieRoot = new CCookie(m_ctRoot);
  857. if (m_pCookieRoot) {
  858. ASSERT(m_pScopeItemRoot->GetType() == m_ctRoot);
  859. m_pCookieRoot->SetScopeItem(m_pScopeItemRoot);
  860. CreateCookieSubtree(m_pScopeItemRoot, m_pCookieRoot);
  861. } else {
  862. hr = E_OUTOFMEMORY;
  863. }
  864. }
  865. }
  866. return hr;
  867. }
  868. //
  869. // This function resets the given scopeitem.
  870. //
  871. HRESULT
  872. CComponentData::ResetScopeItem(
  873. CScopeItem* pScopeItem
  874. )
  875. {
  876. HRESULT hr = S_OK;
  877. if (pScopeItem)
  878. {
  879. CScopeItem* pChild;
  880. int Index;
  881. Index = 0;
  882. while (SUCCEEDED(hr) && pScopeItem->EnumerateChildren(Index, &pChild))
  883. {
  884. hr = ResetScopeItem(pChild);
  885. Index++;
  886. }
  887. if (SUCCEEDED(hr))
  888. {
  889. return pScopeItem->Reset();
  890. }
  891. }
  892. return hr;
  893. }