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.

1087 lines
23 KiB

  1. /*++
  2. Copyright (C) 1997-1999 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. ::InterlockedDecrement(&CClassFactory::s_Objects);
  47. }
  48. //
  49. // IUnknown interface
  50. //
  51. ULONG
  52. CComponentData::AddRef()
  53. {
  54. ::InterlockedIncrement((LONG*)&m_Ref);
  55. return m_Ref;
  56. }
  57. ULONG
  58. CComponentData::Release()
  59. {
  60. ::InterlockedDecrement((LONG*)&m_Ref);
  61. if (!m_Ref)
  62. {
  63. delete this;
  64. return 0;
  65. }
  66. return m_Ref;
  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 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. ResetScopeItem(m_pScopeItemRoot);
  267. }
  268. return S_OK;
  269. }
  270. ASSERT(m_pScope);
  271. INTERNAL_DATA tID;
  272. hr = ExtractData(lpDataObject, CDataObject::m_cfSnapinInternal,
  273. (PBYTE)&tID, sizeof(tID));
  274. if (SUCCEEDED(hr))
  275. {
  276. switch (event) {
  277. case MMCN_DELETE:
  278. hr = OnDelete(tID.cookie, arg, param);
  279. break;
  280. case MMCN_RENAME:
  281. hr = OnRename(tID.cookie, arg, param);
  282. break;
  283. case MMCN_CONTEXTMENU:
  284. hr = OnContextMenu(tID.cookie, arg, param);
  285. break;
  286. case MMCN_BTN_CLICK:
  287. hr = OnBtnClick(tID.cookie, arg, param);
  288. break;
  289. default:
  290. hr = S_OK;
  291. break;
  292. }
  293. }
  294. }
  295. catch(CMemoryException* e)
  296. {
  297. e->Delete();
  298. hr = E_OUTOFMEMORY;
  299. }
  300. return hr;
  301. }
  302. STDMETHODIMP
  303. CComponentData::GetDisplayInfo(
  304. SCOPEDATAITEM* pScopeDataItem
  305. )
  306. {
  307. if (!pScopeDataItem)
  308. {
  309. return E_INVALIDARG;
  310. }
  311. try
  312. {
  313. //
  314. // IComponentData::GetDisplayInfo only deals with scope pane items.
  315. // Snapin's IComponent::GetDisplayInfo will deal with result pane items
  316. //
  317. CCookie* pCookie = (CCookie*) pScopeDataItem->lParam;
  318. ASSERT(pCookie);
  319. return pCookie->GetScopeItem()->GetDisplayInfo(pScopeDataItem);
  320. }
  321. catch (CMemoryException* e)
  322. {
  323. e->Delete();
  324. MsgBoxParam(m_hwndMain, 0, 0, 0);
  325. return E_OUTOFMEMORY;
  326. }
  327. }
  328. STDMETHODIMP
  329. CComponentData::Destroy()
  330. {
  331. if (m_pCookieRoot)
  332. {
  333. delete m_pCookieRoot;
  334. m_pCookieRoot = NULL;
  335. }
  336. if (m_pScopeItemRoot)
  337. {
  338. delete m_pScopeItemRoot;
  339. }
  340. if (m_pScope)
  341. {
  342. m_pScope->Release();
  343. m_pScope = NULL;
  344. }
  345. if (m_pConsole)
  346. {
  347. m_pConsole->Release();
  348. m_pConsole = NULL;
  349. }
  350. return S_OK;
  351. }
  352. STDMETHODIMP
  353. CComponentData::QueryDataObject(
  354. MMC_COOKIE cookie,
  355. DATA_OBJECT_TYPES type,
  356. LPDATAOBJECT* ppDataObject
  357. )
  358. {
  359. CDataObject* pDataObject;
  360. COOKIE_TYPE ct;
  361. CCookie* pCookie;
  362. try
  363. {
  364. pCookie = GetActiveCookie(cookie);
  365. if (NULL == pCookie)
  366. {
  367. ct = m_ctRoot;
  368. }
  369. else
  370. {
  371. ct = pCookie->GetType();
  372. }
  373. pDataObject = new CDataObject;
  374. pDataObject->Initialize(type, ct, pCookie, m_strMachineName);
  375. pDataObject->AddRef();
  376. *ppDataObject = pDataObject;
  377. }
  378. catch (CMemoryException* e)
  379. {
  380. e->Delete();
  381. MsgBoxParam(m_hwndMain, 0, 0, 0);
  382. return E_OUTOFMEMORY;
  383. }
  384. return S_OK;
  385. }
  386. STDMETHODIMP
  387. CComponentData::CompareObjects(
  388. LPDATAOBJECT lpDataObjectA,
  389. LPDATAOBJECT lpDataObjectB
  390. )
  391. {
  392. HRESULT hr;
  393. try
  394. {
  395. INTERNAL_DATA tID_A, tID_B;
  396. hr = ExtractData(lpDataObjectA, CDataObject::m_cfSnapinInternal,
  397. (PBYTE)&tID_A, sizeof(tID_A));
  398. if (SUCCEEDED(hr))
  399. {
  400. hr = ExtractData(lpDataObjectB, CDataObject::m_cfSnapinInternal,
  401. (PBYTE)&tID_B, sizeof(tID_B));
  402. if (SUCCEEDED(hr))
  403. {
  404. hr = (tID_A.ct == tID_B.ct && tID_A.cookie == tID_B.cookie &&
  405. tID_A.dot == tID_B.dot) ? S_OK : S_FALSE;
  406. }
  407. }
  408. }
  409. catch(CMemoryException* e)
  410. {
  411. e->Delete();
  412. MsgBoxParam(m_hwndMain, 0, 0, 0);
  413. hr = E_OUTOFMEMORY;
  414. }
  415. return hr;
  416. }
  417. ///////////////////////////////////////////////////////////////////
  418. //// IExtendPropertySheet implementation
  419. ////
  420. STDMETHODIMP
  421. CComponentData::QueryPagesFor(
  422. LPDATAOBJECT lpDataObject
  423. )
  424. {
  425. HRESULT hr;
  426. if (!lpDataObject)
  427. {
  428. return E_INVALIDARG;
  429. }
  430. try
  431. {
  432. INTERNAL_DATA tID;
  433. hr = ExtractData(lpDataObject, CDataObject::m_cfSnapinInternal,
  434. (PBYTE)&tID, sizeof(tID));
  435. if (SUCCEEDED(hr))
  436. {
  437. CScopeItem* pScopeItem;
  438. pScopeItem = FindScopeItem(tID.cookie);
  439. if (CCT_SNAPIN_MANAGER == tID.dot && COOKIE_TYPE_SCOPEITEM_DEVMGR == tID.ct)
  440. {
  441. hr = S_OK;
  442. }
  443. else if (pScopeItem)
  444. {
  445. hr = pScopeItem->QueryPagesFor();
  446. }
  447. else
  448. {
  449. hr = S_FALSE;
  450. }
  451. }
  452. }
  453. catch (CMemoryException* e)
  454. {
  455. e->Delete();
  456. MsgBoxParam(m_hwndMain, 0, 0, 0);
  457. hr = E_OUTOFMEMORY;
  458. }
  459. return hr;
  460. }
  461. STDMETHODIMP
  462. CComponentData::CreatePropertyPages(
  463. LPPROPERTYSHEETCALLBACK lpProvider,
  464. LONG_PTR handle,
  465. LPDATAOBJECT lpDataObject
  466. )
  467. {
  468. if (!lpProvider || !lpDataObject)
  469. {
  470. return E_INVALIDARG;
  471. }
  472. HRESULT hr;
  473. try
  474. {
  475. INTERNAL_DATA tID;
  476. hr = ExtractData(lpDataObject, CDataObject::m_cfSnapinInternal,
  477. reinterpret_cast<BYTE*>(&tID), sizeof(tID)
  478. );
  479. if (SUCCEEDED(hr))
  480. {
  481. CScopeItem* pScopeItem = FindScopeItem(tID.cookie);
  482. if (CCT_SNAPIN_MANAGER == tID.dot && COOKIE_TYPE_SCOPEITEM_DEVMGR == tID.ct)
  483. {
  484. hr = DoStartupProperties(lpProvider, handle, lpDataObject);
  485. }
  486. else if (pScopeItem)
  487. {
  488. hr = pScopeItem->CreatePropertyPages(lpProvider, handle);
  489. }
  490. else
  491. {
  492. hr = S_OK;
  493. }
  494. }
  495. }
  496. catch(CMemoryException* e)
  497. {
  498. e->Delete();
  499. MsgBoxParam(m_hwndMain, 0, 0, 0);
  500. hr = E_OUTOFMEMORY;
  501. }
  502. return hr;
  503. }
  504. ////////////////////////////////////////////////////////////
  505. //// IExtendContextMenu implemantation
  506. ////
  507. STDMETHODIMP
  508. CComponentData::AddMenuItems(
  509. LPDATAOBJECT lpDataObject,
  510. LPCONTEXTMENUCALLBACK pCallbackUnknown,
  511. long *pInsertionAllowed
  512. )
  513. {
  514. if (!lpDataObject || !pCallbackUnknown || !pInsertionAllowed)
  515. {
  516. return E_INVALIDARG;
  517. }
  518. return S_OK;
  519. }
  520. STDMETHODIMP
  521. CComponentData::Command(
  522. long nCommandID,
  523. LPDATAOBJECT lpDataObject
  524. )
  525. {
  526. if (!lpDataObject)
  527. {
  528. return E_INVALIDARG;
  529. }
  530. return S_OK;
  531. }
  532. HRESULT
  533. CComponentData::CreateCookieSubtree(
  534. CScopeItem* pScopeItem,
  535. CCookie* pCookieParent
  536. )
  537. {
  538. ASSERT(pScopeItem);
  539. CScopeItem* pChild;
  540. CCookie* pCookieSibling;
  541. pCookieSibling = NULL;
  542. int Index = 0;
  543. while (pScopeItem->EnumerateChildren(Index, &pChild))
  544. {
  545. CCookie* pCookie;
  546. pCookie = new CCookie(pChild->GetType());
  547. if (pCookie) {
  548. pCookie->SetScopeItem(pChild);
  549. if (!pCookieSibling)
  550. {
  551. pCookieParent->SetChild(pCookie);
  552. }
  553. else
  554. {
  555. pCookieSibling->SetSibling(pCookie);
  556. }
  557. pCookie->SetParent(pCookieParent);
  558. if (pChild->GetChildCount())
  559. {
  560. CreateCookieSubtree(pChild, pCookie);
  561. }
  562. pCookieSibling = pCookie;
  563. }
  564. Index++;
  565. }
  566. return S_OK;
  567. }
  568. ////////////////////////////////////////////////////////////
  569. /// IPersistStream implementation
  570. ///
  571. STDMETHODIMP
  572. CComponentData::GetClassID(
  573. CLSID* pClassID
  574. )
  575. {
  576. if(!pClassID)
  577. {
  578. return E_INVALIDARG;
  579. }
  580. *pClassID = GetCoClassID();
  581. return S_OK;
  582. }
  583. STDMETHODIMP
  584. CComponentData::IsDirty()
  585. {
  586. return m_IsDirty ? S_OK : S_FALSE;
  587. }
  588. STDMETHODIMP
  589. CComponentData::Load(
  590. IStream* pStm
  591. )
  592. {
  593. HRESULT hr;
  594. SafeInterfacePtr<IStream> StmPtr(pStm);
  595. //
  596. // Fix up the MachineName that we got from the command line if there was one.
  597. // We need to prepend "\\" to the MachineName if it does not start with two
  598. // backslashes, and then we will verify the machine name by calling CM_Connect_Machine
  599. // to verify that this user has access to that machine. If they do not then we
  600. // will set the MachineName to NULL.
  601. //
  602. if (!g_strStartupMachineName.IsEmpty())
  603. {
  604. if (_T('\\') != g_strStartupMachineName[0])
  605. {
  606. g_strStartupMachineName = TEXT("\\\\") + g_strStartupMachineName;
  607. }
  608. if (!VerifyMachineName(g_strStartupMachineName))
  609. {
  610. g_strStartupMachineName.Empty();
  611. }
  612. }
  613. COMPDATA_PERSISTINFO Info;
  614. ULONG BytesRead;
  615. ASSERT(pStm);
  616. //
  617. // Read the persist data and verify that we have the right data
  618. //
  619. hr = pStm->Read(&Info, sizeof(Info), &BytesRead);
  620. if (SUCCEEDED(hr) &&
  621. (BytesRead >= sizeof(Info)) &&
  622. (Info.Size >= sizeof(Info)) &&
  623. (!wcscmp(Info.Signature, DM_COMPDATA_SIGNATURE)))
  624. {
  625. try
  626. {
  627. m_ctRoot = Info.RootCookie;
  628. m_strMachineName.Empty();
  629. if (UNICODE_NULL != Info.ComputerFullName[0])
  630. {
  631. #ifdef UNICODE
  632. m_strMachineName = Info.ComputerFullName;
  633. #else
  634. CHAR ComputerNameA[MAX_PATH + 3];
  635. WideCharToMultiByte(CP_ACP, 0, Info.ComputerFullName, -1,
  636. ComputerNameA, sizeof(ComputerNameA) / sizeof(CHAR), NULL, ULL);
  637. m_strMachineName = ComputerNameA;
  638. #endif
  639. }
  640. if (COOKIE_TYPE_SCOPEITEM_DEVMGR == m_ctRoot)
  641. {
  642. //
  643. // Parameters from command line has the priority
  644. //
  645. if (!g_strStartupMachineName.IsEmpty())
  646. {
  647. m_strMachineName = g_strStartupMachineName;
  648. }
  649. m_strStartupDeviceId = g_strStartupDeviceId;
  650. m_strStartupCommand = g_strStartupCommand;
  651. }
  652. hr = CreateScopeItems();
  653. if (SUCCEEDED(hr))
  654. {
  655. if (!m_pMachine)
  656. {
  657. if (!g_MachineList.CreateMachine(m_hwndMain, m_strMachineName, &m_pMachine))
  658. {
  659. hr = HRESULT_FROM_WIN32(GetLastError());
  660. }
  661. }
  662. }
  663. }
  664. catch(CMemoryException* e)
  665. {
  666. e->Delete();
  667. MsgBoxParam(m_hwndMain, 0, 0, 0);
  668. hr = E_OUTOFMEMORY;
  669. }
  670. }
  671. m_IsDirty = FALSE;
  672. return hr;
  673. }
  674. STDMETHODIMP
  675. CComponentData::Save(
  676. IStream* pStm,
  677. BOOL fClearDirty
  678. )
  679. {
  680. SafeInterfacePtr<IStream> StmPtr(pStm);
  681. HRESULT hr;
  682. try
  683. {
  684. COMPDATA_PERSISTINFO Info;
  685. Info.Size = sizeof(Info);
  686. Info.RootCookie = m_ctRoot;
  687. wcscpy(Info.Signature, DM_COMPDATA_SIGNATURE);
  688. //
  689. // Assuming it is on local machine. The machine name is saved
  690. // in UNICODE
  691. //
  692. Info.ComputerFullName[0] = UNICODE_NULL;
  693. if (m_strMachineName.GetLength())
  694. #ifdef UNICODE
  695. wcscpy(Info.ComputerFullName, m_strMachineName);
  696. #else
  697. MultiByteToWideChar((CP_ACP, 0, chBuffer, -1, Info.ComputerFullName,
  698. sizeof(Info.ComputerFullName) / sizeof(WCHAR));
  699. #endif
  700. hr = pStm->Write(&Info, sizeof(Info), NULL);
  701. }
  702. catch (CMemoryException* e)
  703. {
  704. e->Delete();
  705. MsgBoxParam(m_hwndMain, 0, 0, 0);
  706. hr = E_OUTOFMEMORY;
  707. }
  708. if (fClearDirty)
  709. {
  710. m_IsDirty = FALSE;
  711. }
  712. return hr;
  713. }
  714. STDMETHODIMP
  715. CComponentData::GetSizeMax(
  716. ULARGE_INTEGER* pcbSize
  717. )
  718. {
  719. if (!pcbSize)
  720. {
  721. return E_INVALIDARG;
  722. }
  723. int len;
  724. len = sizeof(m_ctRoot) + sizeof(len) + (m_strMachineName.GetLength() + 1) * sizeof(TCHAR);
  725. ULISet32(*pcbSize, len);
  726. return S_OK;
  727. }
  728. //
  729. // Method to support html help.
  730. //
  731. //
  732. STDMETHODIMP
  733. CComponentData::GetHelpTopic(
  734. LPOLESTR* lpCompileHelpFile
  735. )
  736. {
  737. if (!lpCompileHelpFile)
  738. {
  739. return E_INVALIDARG;
  740. }
  741. *lpCompileHelpFile = NULL;
  742. UINT Size;
  743. TCHAR HelpFile[MAX_PATH];
  744. Size = GetSystemWindowsDirectory(HelpFile, ARRAYLEN(HelpFile));
  745. if (Size && Size < ARRAYLEN(HelpFile))
  746. {
  747. StrCatN(HelpFile, DEVMGR_HTML_HELP_FILE_NAME, ARRAYLEN(HelpFile));
  748. *lpCompileHelpFile = AllocOleTaskString(HelpFile);
  749. }
  750. return S_OK;
  751. }
  752. CScopeItem*
  753. CComponentData::FindScopeItem(
  754. MMC_COOKIE cookie
  755. )
  756. {
  757. CCookie* pCookie = GetActiveCookie(cookie);
  758. if (pCookie)
  759. return pCookie->GetScopeItem();
  760. return NULL;
  761. }
  762. //
  763. // This function loads icons for the scope items
  764. //
  765. HRESULT
  766. CComponentData::LoadScopeIconsForScopePane()
  767. {
  768. ASSERT(m_pScope);
  769. ASSERT(m_pConsole);
  770. LPIMAGELIST lpScopeImage;
  771. HRESULT hr;
  772. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  773. if (SUCCEEDED(hr))
  774. {
  775. HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DEVMGR));
  776. if (hIcon)
  777. {
  778. hr = lpScopeImage->ImageListSetIcon((PLONG_PTR)hIcon, IMAGE_INDEX_DEVMGR);
  779. DestroyIcon(hIcon);
  780. }
  781. hr = lpScopeImage->Release();
  782. }
  783. return hr;
  784. }
  785. //
  786. // This function create the startup wizard property sheet
  787. //
  788. // INPUT:
  789. // lpProvider -- Interface for us to add pages
  790. // handle -- notify console handle
  791. // lpDataObject -- the data object
  792. //
  793. // OUTPUT:
  794. // standard OLE HRESULT
  795. HRESULT
  796. CComponentData::DoStartupProperties(
  797. LPPROPERTYSHEETCALLBACK lpProvider,
  798. LONG_PTR handle,
  799. LPDATAOBJECT lpDataObject
  800. )
  801. {
  802. CGeneralPage* pGenPage;
  803. HPROPSHEETPAGE hPage;
  804. pGenPage = new CGeneralPage();
  805. if (pGenPage)
  806. {
  807. hPage = pGenPage->Create(handle);
  808. if (hPage)
  809. {
  810. lpProvider->AddPage(hPage);
  811. //
  812. // If no console handle is provided, we have to use
  813. // our call back function
  814. //
  815. if(!handle)
  816. {
  817. pGenPage->SetOutputBuffer(&m_strMachineName, &m_ctRoot);
  818. }
  819. return S_OK;
  820. }
  821. else
  822. {
  823. throw &g_MemoryException;
  824. }
  825. }
  826. else
  827. {
  828. throw &g_MemoryException;
  829. }
  830. return E_OUTOFMEMORY;
  831. }
  832. //
  833. // This function creates all the necessary classes represent
  834. // our scope items
  835. //
  836. HRESULT
  837. CComponentData::CreateScopeItems()
  838. {
  839. //
  840. // All classes are linked by cookie with m_pCookieRoot
  841. // points to the "root" scope item
  842. //
  843. if (!m_pScopeItemRoot)
  844. {
  845. switch (m_ctRoot)
  846. {
  847. case COOKIE_TYPE_SCOPEITEM_DEVMGR:
  848. m_pScopeItemRoot = new CScopeItem(COOKIE_TYPE_SCOPEITEM_DEVMGR,
  849. IMAGE_INDEX_DEVMGR,
  850. OPEN_IMAGE_INDEX_DEVMGR,
  851. IDS_NAME_DEVMGR,
  852. IDS_DESC_DEVMGR,
  853. IDS_DISPLAYNAME_SCOPE_DEVMGR);
  854. break;
  855. default:
  856. ASSERT(FALSE);
  857. break;
  858. }
  859. if (m_pScopeItemRoot->Create())
  860. {
  861. //
  862. // Bind scope items and cookies together.
  863. // Cookies know its scopeitem.
  864. // Scopeitems do not know cookies.
  865. //
  866. m_pCookieRoot = new CCookie(m_ctRoot);
  867. if (m_pCookieRoot)
  868. {
  869. ASSERT(m_pScopeItemRoot->GetType() == m_ctRoot);
  870. m_pCookieRoot->SetScopeItem(m_pScopeItemRoot);
  871. CreateCookieSubtree(m_pScopeItemRoot, m_pCookieRoot);
  872. }
  873. }
  874. }
  875. return S_OK;
  876. }
  877. //
  878. // This function resets the given scopeitem.
  879. //
  880. HRESULT
  881. CComponentData::ResetScopeItem(
  882. CScopeItem* pScopeItem
  883. )
  884. {
  885. HRESULT hr = S_OK;
  886. if (pScopeItem)
  887. {
  888. CScopeItem* pChild;
  889. int Index;
  890. Index = 0;
  891. while (SUCCEEDED(hr) && pScopeItem->EnumerateChildren(Index, &pChild))
  892. {
  893. hr = ResetScopeItem(pChild);
  894. Index++;
  895. }
  896. if (SUCCEEDED(hr))
  897. {
  898. return pScopeItem->Reset();
  899. }
  900. }
  901. return hr;
  902. }