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.

580 lines
12 KiB

  1. //
  2. // Microsoft Corporation 1998
  3. //
  4. // COMPDATA.CPP - CComponentData and CComponentDataCF routines
  5. //
  6. #include "main.h"
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // CComponentData object implementation
  9. CComponentData::CComponentData()
  10. {
  11. m_cRef = 1;
  12. InterlockedIncrement(&g_cRefThisDll);
  13. m_hwndFrame = NULL;
  14. m_pScope = NULL;
  15. m_pConsole = NULL;
  16. m_hRoot = NULL;
  17. m_pGPTInformation = NULL;
  18. }
  19. CComponentData::~CComponentData()
  20. {
  21. if (m_pScope)
  22. {
  23. m_pScope->Release();
  24. }
  25. if (m_pConsole)
  26. {
  27. m_pConsole->Release();
  28. }
  29. if (m_pGPTInformation)
  30. {
  31. m_pGPTInformation->Release();
  32. }
  33. InterlockedDecrement(&g_cRefThisDll);
  34. }
  35. ///////////////////////////////////////////////////////////////////////////////
  36. // CComponentData object implementation (IUnknown)
  37. HRESULT CComponentData::QueryInterface (REFIID riid, void **ppv)
  38. {
  39. if (IsEqualIID(riid, IID_IComponentData) || IsEqualIID(riid, IID_IUnknown))
  40. {
  41. *ppv = (LPCOMPONENT)this;
  42. m_cRef++;
  43. return S_OK;
  44. }
  45. else if (IsEqualIID(riid, IID_ISnapinHelp ))
  46. {
  47. *ppv = (ISnapinHelp *) this;
  48. m_cRef++;
  49. return S_OK;
  50. }
  51. else if (IsEqualIID(riid, IID_IPersistStreamInit))
  52. {
  53. *ppv = (LPPERSISTSTREAMINIT)this;
  54. m_cRef++;
  55. return S_OK;
  56. }
  57. else
  58. {
  59. *ppv = NULL;
  60. return E_NOINTERFACE;
  61. }
  62. }
  63. ULONG CComponentData::AddRef (void)
  64. {
  65. return ++m_cRef;
  66. }
  67. ULONG CComponentData::Release (void)
  68. {
  69. if (--m_cRef == 0) {
  70. delete this;
  71. return 0;
  72. }
  73. return m_cRef;
  74. }
  75. ///////////////////////////////////////////////////////////////////////////////
  76. // CComponentData object implementation (IComponentData)
  77. STDMETHODIMP CComponentData::Initialize(LPUNKNOWN pUnknown)
  78. {
  79. HRESULT hr;
  80. HBITMAP bmp16x16;
  81. LPIMAGELIST lpScopeImage;
  82. //
  83. // QI for IConsoleNameSpace
  84. //
  85. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace, (LPVOID *)&m_pScope);
  86. if (FAILED(hr))
  87. {
  88. DebugMsg((DM_WARNING, TEXT("CComponentData::Initialize: Failed to QI for IConsoleNameSpace.")));
  89. return hr;
  90. }
  91. //
  92. // QI for IConsole
  93. //
  94. hr = pUnknown->QueryInterface(IID_IConsole, (LPVOID *)&m_pConsole);
  95. if (FAILED(hr))
  96. {
  97. DebugMsg((DM_WARNING, TEXT("CComponentData::Initialize: Failed to QI for IConsole.")));
  98. m_pScope->Release();
  99. m_pScope = NULL;
  100. return hr;
  101. }
  102. m_pConsole->GetMainWindow (&m_hwndFrame);
  103. //
  104. // Query for the scope imagelist interface
  105. //
  106. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  107. if (FAILED(hr))
  108. {
  109. DebugMsg((DM_WARNING, TEXT("CComponentData::Initialize: Failed to QI for scope imagelist.")));
  110. m_pScope->Release();
  111. m_pScope = NULL;
  112. m_pConsole->Release();
  113. m_pConsole=NULL;
  114. return hr;
  115. }
  116. // Load the bitmaps from the dll
  117. bmp16x16=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16));
  118. // Set the images
  119. lpScopeImage->ImageListSetStrip(reinterpret_cast<PLONG_PTR>(bmp16x16),
  120. reinterpret_cast<PLONG_PTR>(bmp16x16),
  121. 0, RGB(255, 0, 255));
  122. lpScopeImage->Release();
  123. DeleteObject( bmp16x16 );
  124. return S_OK;
  125. }
  126. STDMETHODIMP CComponentData::Destroy(VOID)
  127. {
  128. return S_OK;
  129. }
  130. STDMETHODIMP CComponentData::CreateComponent(LPCOMPONENT *ppComponent)
  131. {
  132. HRESULT hr;
  133. CSnapIn *pSnapIn;
  134. DebugMsg((DM_VERBOSE, TEXT("CComponentData::CreateComponent: Entering.")));
  135. //
  136. // Initialize
  137. //
  138. *ppComponent = NULL;
  139. //
  140. // Create the snapin view
  141. //
  142. pSnapIn = new CSnapIn(this);
  143. if (!pSnapIn)
  144. {
  145. DebugMsg((DM_WARNING, TEXT("CComponentData::CreateComponent: Failed to create CSnapIn.")));
  146. return E_OUTOFMEMORY;
  147. }
  148. //
  149. // QI for IComponent
  150. //
  151. hr = pSnapIn->QueryInterface(IID_IComponent, (LPVOID *)ppComponent);
  152. pSnapIn->Release(); // release QI
  153. return hr;
  154. }
  155. STDMETHODIMP CComponentData::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  156. LPDATAOBJECT* ppDataObject)
  157. {
  158. HRESULT hr = E_NOINTERFACE;
  159. CDataObject *pDataObject;
  160. LPGPTDATAOBJECT pGPTDataObject;
  161. //
  162. // Create a new DataObject
  163. //
  164. pDataObject = new CDataObject(this); // ref == 1
  165. if (!pDataObject)
  166. return E_OUTOFMEMORY;
  167. //
  168. // QI for the private GPTDataObject interface so we can set the cookie
  169. // and type information.
  170. //
  171. hr = pDataObject->QueryInterface(IID_IGPTDataObject, (LPVOID *)&pGPTDataObject);
  172. if (FAILED(hr))
  173. {
  174. pDataObject->Release();
  175. return (hr);
  176. }
  177. pGPTDataObject->SetType(type);
  178. pGPTDataObject->SetCookie(cookie);
  179. pGPTDataObject->Release();
  180. //
  181. // QI for a normal IDataObject to return.
  182. //
  183. hr = pDataObject->QueryInterface(IID_IDataObject, (LPVOID *)ppDataObject);
  184. pDataObject->Release(); // release initial ref
  185. return hr;
  186. }
  187. STDMETHODIMP CComponentData::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  188. {
  189. HRESULT hr = S_OK;
  190. switch(event)
  191. {
  192. case MMCN_EXPAND:
  193. if (arg == TRUE)
  194. if (!m_pGPTInformation)
  195. {
  196. lpDataObject->QueryInterface(IID_IGPEInformation, (LPVOID *)&m_pGPTInformation);
  197. }
  198. if (m_pGPTInformation)
  199. {
  200. hr = EnumerateScopePane(lpDataObject, (HSCOPEITEM)param);
  201. }
  202. break;
  203. default:
  204. break;
  205. }
  206. return hr;
  207. }
  208. STDMETHODIMP CComponentData::GetDisplayInfo(LPSCOPEDATAITEM pItem)
  209. {
  210. DWORD dwIndex;
  211. if (pItem == NULL)
  212. return E_POINTER;
  213. for (dwIndex = 0; dwIndex < NUM_NAMESPACE_ITEMS; dwIndex++)
  214. {
  215. if (g_NameSpace[dwIndex].dwID == (DWORD) pItem->lParam)
  216. break;
  217. }
  218. if (dwIndex == NUM_NAMESPACE_ITEMS)
  219. pItem->displayname = NULL;
  220. else
  221. {
  222. pItem->displayname = g_NameSpace[dwIndex].szDisplayName;
  223. }
  224. return S_OK;
  225. }
  226. STDMETHODIMP CComponentData::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  227. {
  228. HRESULT hr = S_FALSE;
  229. LPGPTDATAOBJECT pGPTDataObjectA, pGPTDataObjectB;
  230. MMC_COOKIE cookie1, cookie2;
  231. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  232. return E_POINTER;
  233. //
  234. // QI for the private GPTDataObject interface
  235. //
  236. if (FAILED(lpDataObjectA->QueryInterface(IID_IGPTDataObject,
  237. (LPVOID *)&pGPTDataObjectA)))
  238. {
  239. return S_FALSE;
  240. }
  241. if (FAILED(lpDataObjectB->QueryInterface(IID_IGPTDataObject,
  242. (LPVOID *)&pGPTDataObjectB)))
  243. {
  244. pGPTDataObjectA->Release();
  245. return S_FALSE;
  246. }
  247. pGPTDataObjectA->GetCookie(&cookie1);
  248. pGPTDataObjectB->GetCookie(&cookie2);
  249. if (cookie1 == cookie2)
  250. {
  251. hr = S_OK;
  252. }
  253. pGPTDataObjectA->Release();
  254. pGPTDataObjectB->Release();
  255. return hr;
  256. }
  257. ///////////////////////////////////////////////////////////////////////////////
  258. // CComponentData object implementation (IPersistStreamInit)
  259. STDMETHODIMP CComponentData::GetClassID(CLSID *pClassID)
  260. {
  261. if (!pClassID)
  262. {
  263. return E_POINTER;
  264. }
  265. *pClassID = CLSID_GPTRemoteInstall;
  266. return S_OK;
  267. }
  268. STDMETHODIMP CComponentData::IsDirty(VOID)
  269. {
  270. return S_FALSE;
  271. }
  272. STDMETHODIMP CComponentData::Load(IStream *pStm)
  273. {
  274. return S_OK;
  275. }
  276. STDMETHODIMP CComponentData::Save(IStream *pStm, BOOL fClearDirty)
  277. {
  278. return S_OK;
  279. }
  280. STDMETHODIMP CComponentData::GetSizeMax(ULARGE_INTEGER *pcbSize)
  281. {
  282. DWORD dwSize = 0;
  283. if (!pcbSize)
  284. {
  285. return E_POINTER;
  286. }
  287. ULISet32(*pcbSize, dwSize);
  288. return S_OK;
  289. }
  290. STDMETHODIMP CComponentData::InitNew(void)
  291. {
  292. return S_OK;
  293. }
  294. ///////////////////////////////////////////////////////////////////////////////
  295. // CComponentData object implementation (Internal functions)
  296. HRESULT CComponentData::EnumerateScopePane (LPDATAOBJECT lpDataObject, HSCOPEITEM hParent)
  297. {
  298. SCOPEDATAITEM item;
  299. HRESULT hr;
  300. DWORD dwIndex, i;
  301. if (!m_hRoot)
  302. m_hRoot = hParent;
  303. if (m_hRoot == hParent)
  304. dwIndex = 0;
  305. else
  306. {
  307. item.mask = SDI_PARAM;
  308. item.ID = hParent;
  309. hr = m_pScope->GetItem (&item);
  310. if (FAILED(hr))
  311. return hr;
  312. dwIndex = (DWORD) item.lParam;
  313. }
  314. for (i = 0; i < NUM_NAMESPACE_ITEMS; i++)
  315. {
  316. if (g_NameSpace[i].dwParent == dwIndex)
  317. {
  318. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  319. item.displayname = MMC_CALLBACK;
  320. item.nImage = 0;
  321. item.nOpenImage = 0;
  322. item.nState = 0;
  323. item.cChildren = g_NameSpace[i].cChildren;
  324. item.lParam = g_NameSpace[i].dwID;
  325. item.relativeID = hParent;
  326. m_pScope->InsertItem (&item);
  327. }
  328. }
  329. return S_OK;
  330. }
  331. ///////////////////////////////////////////////////////////////////////////////
  332. // Class factory object implementation
  333. CComponentDataCF::CComponentDataCF()
  334. {
  335. m_cRef = 1;
  336. InterlockedIncrement(&g_cRefThisDll);
  337. }
  338. CComponentDataCF::~CComponentDataCF()
  339. {
  340. InterlockedDecrement(&g_cRefThisDll);
  341. }
  342. ///////////////////////////////////////////////////////////////////////////////
  343. // Class factory object implementation (IUnknown)
  344. STDMETHODIMP_(ULONG)
  345. CComponentDataCF::AddRef()
  346. {
  347. return ++m_cRef;
  348. }
  349. STDMETHODIMP_(ULONG)
  350. CComponentDataCF::Release()
  351. {
  352. if (--m_cRef == 0)
  353. {
  354. delete this;
  355. return 0;
  356. }
  357. return m_cRef;
  358. }
  359. STDMETHODIMP
  360. CComponentDataCF::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  361. {
  362. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  363. {
  364. *ppv = (LPCLASSFACTORY)this;
  365. m_cRef++;
  366. return S_OK;
  367. }
  368. else
  369. {
  370. *ppv = NULL;
  371. return E_NOINTERFACE;
  372. }
  373. }
  374. ///////////////////////////////////////////////////////////////////////////////
  375. // Class factory object implementation (IClassFactory)
  376. STDMETHODIMP
  377. CComponentDataCF::CreateInstance(LPUNKNOWN pUnkOuter,
  378. REFIID riid,
  379. LPVOID FAR* ppvObj)
  380. {
  381. *ppvObj = NULL;
  382. if (pUnkOuter)
  383. return CLASS_E_NOAGGREGATION;
  384. CComponentData *pComponentData = new CComponentData(); // ref count == 1
  385. if (!pComponentData)
  386. return E_OUTOFMEMORY;
  387. HRESULT hr = pComponentData->QueryInterface(riid, ppvObj);
  388. pComponentData->Release(); // release initial ref
  389. return hr;
  390. }
  391. STDMETHODIMP
  392. CComponentDataCF::LockServer(BOOL fLock)
  393. {
  394. return E_NOTIMPL;
  395. }
  396. ///////////////////////////////////////////////////////////////////////////////
  397. // Class factory object creation (IClassFactory)
  398. HRESULT CreateComponentDataClassFactory (REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  399. {
  400. HRESULT hr;
  401. if (IsEqualCLSID (rclsid, CLSID_GPTRemoteInstall)) {
  402. CComponentDataCF *pComponentDataCF = new CComponentDataCF(); // ref == 1
  403. if (!pComponentDataCF)
  404. return E_OUTOFMEMORY;
  405. hr = pComponentDataCF->QueryInterface(riid, ppv);
  406. pComponentDataCF->Release(); // release initial ref
  407. return hr;
  408. }
  409. return CLASS_E_CLASSNOTAVAILABLE;
  410. }
  411. ///////////////////////////////////////////////////////////////////////////////
  412. //
  413. // CComponentData object implementation (ISnapinHelp)
  414. //
  415. STDMETHODIMP CComponentData::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
  416. {
  417. LPOLESTR lpHelpFile;
  418. lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
  419. if (!lpHelpFile)
  420. {
  421. return E_OUTOFMEMORY;
  422. }
  423. ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\ris.chm",
  424. lpHelpFile, MAX_PATH);
  425. *lpCompiledHelpFile = lpHelpFile;
  426. return S_OK;
  427. }