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.

569 lines
19 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: ccomp.cpp
  7. //
  8. // Contents:
  9. //
  10. //
  11. // History: TaroonM
  12. // 10/30/01
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "stdafx.h"
  16. #include <atlimpl.cpp>
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. /////////////////////////////////////////////////////////////////////////////
  23. // contruction/descruction
  24. DEBUG_DECLARE_INSTANCE_COUNTER(CComponentImpl);
  25. CComponentImpl::CComponentImpl()
  26. {
  27. DEBUG_INCREMENT_INSTANCE_COUNTER(CComponentImpl);
  28. Construct();
  29. }
  30. CComponentImpl::~CComponentImpl()
  31. {
  32. #if DBG==1
  33. ASSERT(dbg_cRef == 0);
  34. #endif
  35. DEBUG_DECREMENT_INSTANCE_COUNTER(CComponentImpl);
  36. // Make sure the interfaces have been released
  37. ASSERT(m_pConsole == NULL);
  38. ASSERT(m_pHeader == NULL);
  39. }
  40. void CComponentImpl::Construct()
  41. {
  42. #if DBG==1
  43. dbg_cRef = 0;
  44. #endif
  45. m_pConsole = NULL;
  46. m_pHeader = NULL;
  47. m_pResultData = NULL;
  48. m_pComponentData = NULL;
  49. m_pConsoleVerb = NULL;
  50. m_CustomViewID = VIEW_DEFAULT_LV;
  51. m_dwSortOrder = 0; // default is 0, else RSI_DESCENDING
  52. m_nSortColumn = 0;
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CComponentImpl's IComponent multiple view/instance helper functions
  56. STDMETHODIMP CComponentImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  57. {
  58. OPT_TRACE( _T("CComponentImpl::QueryDataObject this-%p, cookie-%p\n"), this, cookie );
  59. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  60. if (ppDataObject == NULL)
  61. {
  62. TRACE(_T("CComponentImpl::QueryDataObject called with ppDataObject==NULL \n"));
  63. return E_UNEXPECTED;
  64. }
  65. if (cookie == NULL)
  66. {
  67. TRACE(_T("CComponentImpl::QueryDataObject called with cookie==NULL \n"));
  68. return E_UNEXPECTED;
  69. }
  70. *ppDataObject = NULL;
  71. IUnknown* pUnk = (IUnknown *) cookie;
  72. #ifdef _DEBUG
  73. HRESULT hr = pUnk->QueryInterface( IID_IDataObject, (void**)ppDataObject );
  74. OPT_TRACE(_T(" QI on cookie-%p -> pDataObj-%p\n"), cookie, *ppDataObject);
  75. return hr;
  76. #else
  77. return pUnk->QueryInterface( IID_IDataObject, (void**)ppDataObject );
  78. #endif //#ifdef _DEBUG
  79. }
  80. void CComponentImpl::SetIComponentData(CComponentDataImpl* pData)
  81. {
  82. ASSERT(pData);
  83. ASSERT(m_pComponentData == NULL);
  84. LPUNKNOWN pUnk = pData->GetUnknown();
  85. HRESULT hr;
  86. // store their IComponentData for later use
  87. hr = pUnk->QueryInterface(IID_IComponentData, reinterpret_cast<void**>(&m_pComponentData));
  88. // store their CComponentData for later use
  89. m_pCComponentData = pData;
  90. }
  91. STDMETHODIMP CComponentImpl::GetResultViewType(MMC_COOKIE cookie, LPOLESTR* ppViewType, long* pViewOptions)
  92. {
  93. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  94. ASSERT (m_CustomViewID == VIEW_DEFAULT_LV);
  95. return S_FALSE;
  96. }
  97. STDMETHODIMP CComponentImpl::Initialize(LPCONSOLE lpConsole)
  98. {
  99. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  100. HRESULT hr = E_UNEXPECTED;
  101. ASSERT(lpConsole != NULL);
  102. // Save the IConsole pointer
  103. m_pConsole = lpConsole;
  104. m_pConsole->AddRef();
  105. // QI for IHeaderCtrl
  106. hr = m_pConsole->QueryInterface(IID_IHeaderCtrl, reinterpret_cast<void**>(&m_pHeader));
  107. ASSERT (hr == S_OK);
  108. if (hr != S_OK)
  109. {
  110. return hr;
  111. }
  112. // Pass the IHeaderCtrl Interface on to the console
  113. m_pConsole->SetHeader(m_pHeader);
  114. // QI for IResultData
  115. hr = m_pConsole->QueryInterface(IID_IResultData, reinterpret_cast<void**>(&m_pResultData));
  116. ASSERT (hr == S_OK);
  117. if (hr != S_OK)
  118. {
  119. return hr;
  120. }
  121. // m_pCComponentData->SetResultData (m_pResultData);
  122. // get the IControlVerb interface to support enable/disable of verbs (ie CUT/PASTE etc)
  123. hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
  124. ASSERT(hr == S_OK);
  125. return hr;
  126. }
  127. STDMETHODIMP CComponentImpl::Destroy(MMC_COOKIE cookie)
  128. {
  129. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  130. // Release the interfaces that we QI'ed
  131. if (m_pConsole != NULL)
  132. {
  133. // Tell the console to release the header control interface
  134. m_pConsole->SetHeader(NULL);
  135. SAFE_RELEASE(m_pHeader);
  136. SAFE_RELEASE(m_pResultData);
  137. // Release the IConsole interface last
  138. SAFE_RELEASE(m_pConsole);
  139. SAFE_RELEASE(m_pComponentData); // QI'ed in IComponentDataImpl::CreateComponent
  140. SAFE_RELEASE(m_pConsoleVerb);
  141. }
  142. return S_OK;
  143. }
  144. /////////////////////////////////////////////////////////////////////////////
  145. // CComponentImpl's IComponent view/data helper functions
  146. STDMETHODIMP CComponentImpl::GetDisplayInfo(LPRESULTDATAITEM pResult)
  147. {
  148. OPT_TRACE(_T("CComponentImpl::GetDisplayInfo this-%p pUnk-%p\n"), this, pResult->lParam);
  149. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  150. ASSERT(pResult != NULL);
  151. if (NULL == pResult)
  152. // gack!
  153. return E_INVALIDARG;
  154. ASSERT( NULL != pResult->lParam );
  155. if (NULL == pResult->lParam)
  156. {
  157. TRACE(_T("CComponentImpl::GetDisplayInfo RESULTDATAITEM.lParam == NULL\n"));
  158. ASSERT( FALSE );
  159. return E_UNEXPECTED;
  160. }
  161. IUnknown* pUnk = (IUnknown*)pResult->lParam;
  162. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
  163. if (spData == NULL)
  164. {
  165. TRACE(_T("CComponentImpl::GetDisplayInfo QI for IWirelessSnapInDataObject FAILED\n"));
  166. return E_UNEXPECTED;
  167. }
  168. return spData->GetResultDisplayInfo( pResult );
  169. }
  170. /////////////////////////////////////////////////////////////////////////////
  171. // CComponentImpl's I????? misc helper functions
  172. // TODO: Some misc functions don't appear to ever be called?
  173. STDMETHODIMP CComponentImpl::GetClassID(CLSID *pClassID)
  174. {
  175. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  176. ASSERT (0);
  177. // TODO: CComponentDataImpl::GetClassID and CComponentImpl::GetClassID are identical (?)
  178. ASSERT(pClassID != NULL);
  179. // Copy the CLSID for this snapin
  180. *pClassID = CLSID_Snapin;
  181. return E_NOTIMPL;
  182. }
  183. // This compares two data objects to see if they are the same object.
  184. STDMETHODIMP CComponentImpl::CompareObjects(LPDATAOBJECT pDataObjectA, LPDATAOBJECT pDataObjectB)
  185. {
  186. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  187. if (NULL == pDataObjectA || NULL == pDataObjectB)
  188. return E_INVALIDARG;
  189. HRESULT res = S_FALSE;
  190. // we need to check to make sure both objects belong to us...
  191. if (m_pCComponentData)
  192. {
  193. HRESULT hr;
  194. GUID guidA;
  195. GUID guidB;
  196. // Obtain GUID for A
  197. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataA(pDataObjectA);
  198. if (spDataA == NULL)
  199. {
  200. TRACE(_T("CComponentImpl::CompareObjects - QI for IWirelessSnapInDataObject[A] FAILED\n"));
  201. return E_UNEXPECTED;
  202. }
  203. hr = spDataA->GetGuidForCompare( &guidA );
  204. ASSERT(hr == S_OK);
  205. // Obtain GUID for B
  206. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataB(pDataObjectB);
  207. if (spDataB == NULL)
  208. {
  209. TRACE(_T("CComponentImpl::CompareObjects - QI for IWirelessSnapInDataObject[B] FAILED\n"));
  210. return E_UNEXPECTED;
  211. }
  212. hr &= spDataB->GetGuidForCompare( &guidB );
  213. ASSERT(hr == S_OK);
  214. // Compare GUIDs
  215. if (IsEqualGUID( guidA, guidB ))
  216. {
  217. return S_OK;
  218. }
  219. }
  220. // they were not ours, or they couldn't have been ours...
  221. return E_UNEXPECTED;
  222. }
  223. // This Compare is used to sort the item's in the result pane using the C runtime's
  224. // string comparison function.
  225. STDMETHODIMP CComponentImpl::Compare(LPARAM lUserParam, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int* pnResult)
  226. {
  227. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  228. OPT_TRACE(_T("CComponentImpl::Compare cookieA-%p, cookieB-%p, Column-%i, userParam-%i\n"), cookieA, cookieB, *pnResult, lUserParam );
  229. // Get pDataObject for item A
  230. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataA((LPDATAOBJECT)cookieA);
  231. if (spDataA == NULL)
  232. {
  233. TRACE(_T("CComponentImpl::Compare - QI for IWirelessSnapInDataObject[A] FAILED\n"));
  234. return E_UNEXPECTED;
  235. }
  236. // Get pDataObject for item B
  237. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spDataB((LPDATAOBJECT)cookieB);
  238. if (spDataB == NULL)
  239. {
  240. TRACE(_T("CComponentImpl::Compare - QI for IWirelessSnapInDataObject[B] FAILED\n"));
  241. return E_UNEXPECTED;
  242. }
  243. HRESULT hr = S_OK;
  244. do
  245. {
  246. RESULTDATAITEM rdiA;
  247. RESULTDATAITEM rdiB;
  248. // Obtain item A's sort string
  249. rdiA.mask = RDI_STR;
  250. rdiA.nCol = *pnResult; // obtain string for this column
  251. hr = spDataA->GetResultDisplayInfo( &rdiA );
  252. if (hr != S_OK)
  253. {
  254. TRACE(_T("CComponentImpl::Compare - IWirelessSnapInDataObject[A].GetResultDisplayInfo FAILED\n"));
  255. hr = E_UNEXPECTED;
  256. break;
  257. }
  258. // Obtain item B's sort string
  259. rdiB.mask = RDI_STR;
  260. rdiB.nCol = *pnResult; // obtain string for this column
  261. hr = spDataB->GetResultDisplayInfo( &rdiB );
  262. if (hr != S_OK)
  263. {
  264. TRACE(_T("CComponentImpl::Compare - IWirelessSnapInDataObject[B].GetResultDisplayInfo FAILED\n"));
  265. hr = E_UNEXPECTED;
  266. break;
  267. }
  268. // Compare strings for sort
  269. *pnResult = _tcsicmp( rdiA.str, rdiB.str );
  270. } while (0); // simulate try block
  271. return hr;
  272. }
  273. /////////////////////////////////////////////////////////////////////////////
  274. // Event handlers for IFrame::Notify
  275. STDMETHODIMP CComponentImpl::Notify(LPDATAOBJECT pDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  276. {
  277. OPT_TRACE(_T("CComponentImpl::Notify pDataObject-%p\n"), pDataObject);
  278. if (pDataObject == NULL)
  279. {
  280. if (MMCN_PROPERTY_CHANGE == event)
  281. {
  282. if (param)
  283. {
  284. IWirelessSnapInDataObject * pData = (IWirelessSnapInDataObject *)param;
  285. //used IComponentData's IIconsole, fix for bug 464858
  286. //pData->Notify(event, arg, param, FALSE, m_pConsole, m_pHeader );
  287. pData->Notify(event, arg, param, FALSE, m_pCComponentData->m_pConsole, m_pHeader );
  288. }
  289. }
  290. if (MMCN_COLUMN_CLICK == event)
  291. {
  292. ASSERT( NULL != m_pCComponentData ); // should always have this
  293. // MMCN_COLUMN_CLICK is specified as having a NULL pDataObject.
  294. ASSERT( NULL != m_pResultData );
  295. if (NULL != m_pResultData)
  296. {
  297. // Save sort request details
  298. m_nSortColumn = arg;
  299. m_dwSortOrder = param;
  300. // Sort all result items
  301. HRESULT hr = m_pResultData->Sort( arg, param, 0 );
  302. return hr;
  303. }
  304. return E_UNEXPECTED;
  305. }
  306. TRACE(_T("CComponentImpl::Notify ERROR(?) called with pDataObject==NULL for event-%i\n"), event);
  307. // If this asserts, look at "event" and determine whether it is normal for
  308. // pDataObject to be NULL. If so add code above to handle event.
  309. ASSERT( FALSE );
  310. return E_UNEXPECTED;
  311. }
  312. if (MMCN_VIEW_CHANGE == event)
  313. {
  314. // Pack info for sorting result view into the hint for this event. Its safe
  315. // to do this because all calls to IConsole::UpdateAllViews from within this
  316. // snap-in do not use the hint.
  317. param = MAKELONG( m_nSortColumn, m_dwSortOrder );
  318. }
  319. // Pass call to result item.
  320. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pDataObject );
  321. if (spData == NULL)
  322. {
  323. // If we are loaded as an extension snapin, let our static node handle this.
  324. if (NULL != m_pCComponentData->GetStaticScopeObject()->GetExtScopeObject())
  325. {
  326. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject>
  327. spExtData( m_pCComponentData->GetStaticScopeObject()->GetExtScopeObject() );
  328. if (spExtData != NULL)
  329. {
  330. HRESULT hr;
  331. hr = spExtData->Notify( event, arg, param, FALSE, m_pConsole, m_pHeader );
  332. return hr;
  333. }
  334. ASSERT( FALSE );
  335. }
  336. TRACE(_T("CComponentImpl::Notify - QI for IWirelessSnapInDataObject FAILED\n"));
  337. ASSERT( FALSE );
  338. return E_UNEXPECTED;
  339. }
  340. return spData->Notify( event, arg, param, FALSE, m_pConsole, m_pHeader );
  341. }
  342. /////////////////////////////////////////////////////////////////////////////
  343. // IExtendPropertySheet Implementation
  344. STDMETHODIMP CComponentImpl::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT pDataObject)
  345. {
  346. if (pDataObject == NULL)
  347. {
  348. TRACE(_T("CComponentImpl::CreatePropertyPages called with pDataObject == NULL\n"));
  349. return E_UNEXPECTED;
  350. }
  351. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
  352. if (spData == NULL)
  353. {
  354. TRACE(_T("CComponentImpl::CreatePropertyPages - QI for IWirelessSnapInDataObject FAILED\n"));
  355. ASSERT( FALSE );
  356. return E_UNEXPECTED;
  357. }
  358. return spData->CreatePropertyPages( lpProvider, handle );
  359. }
  360. STDMETHODIMP CComponentImpl::QueryPagesFor(LPDATAOBJECT pDataObject)
  361. {
  362. if (pDataObject == NULL)
  363. {
  364. TRACE(_T("CComponentImpl::QueryPagesFor called with pDataObject == NULL\n"));
  365. return E_UNEXPECTED;
  366. }
  367. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
  368. if (spData == NULL)
  369. {
  370. TRACE(_T("CComponentImpl::QueryPagesFor - QI for IWirelessSnapInDataObject FAILED\n"));
  371. ASSERT( FALSE );
  372. return E_UNEXPECTED;
  373. }
  374. return spData->QueryPagesFor();
  375. }
  376. /////////////////////////////////////////////////////////////////////////////
  377. // IExtendContextMenus Implementation
  378. STDMETHODIMP CComponentImpl::AddMenuItems(LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pContextMenuCallback, long *pInsertionAllowed)
  379. {
  380. if (pDataObject == NULL)
  381. {
  382. TRACE(_T("CComponentImpl::AddMenuItems called with pDataObject == NULL\n"));
  383. return E_UNEXPECTED;
  384. }
  385. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
  386. if (spData == NULL)
  387. {
  388. TRACE(_T("CComponentImpl::AddMenuItems - QI for IWirelessSnapInDataObject FAILED\n"));
  389. ASSERT( FALSE );
  390. return E_UNEXPECTED;
  391. }
  392. return spData->AddMenuItems( pContextMenuCallback, pInsertionAllowed );
  393. }
  394. STDMETHODIMP CComponentImpl::Command(long nCommandID, LPDATAOBJECT pDataObject)
  395. {
  396. if (pDataObject == NULL)
  397. {
  398. TRACE(_T("CComponentImpl::Command called with pDataObject == NULL\n"));
  399. return E_UNEXPECTED;
  400. }
  401. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
  402. if (spData == NULL)
  403. {
  404. TRACE(_T("CComponentImpl::Command - QI for IWirelessSnapInDataObject FAILED\n"));
  405. ASSERT( FALSE );
  406. return E_UNEXPECTED;
  407. }
  408. return spData->Command( nCommandID, NULL /*IConsoleNameSpace* */ );
  409. }
  410. /////////////////////////////////////////////////////////////////////////////
  411. // IExtendControlbar Implementation
  412. STDMETHODIMP CComponentImpl::SetControlbar( LPCONTROLBAR pControlbar )
  413. {
  414. OPT_TRACE( _T("CComponentImpl::IExtendControlbar::SetControlbar\n") );
  415. // pControlbar was obtained by MMC (MMCNDMGR) from our CComponentImpl by doing
  416. // a QI on IExtendControlbar. Save it so we can use it later.
  417. // Note: Always assign pControlbar to our smart pointer. pControlbar == NULL
  418. // when MMC wants us to release the interface we already have.
  419. m_spControlbar = pControlbar;
  420. return S_OK;
  421. }
  422. STDMETHODIMP CComponentImpl::ControlbarNotify( MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param )
  423. {
  424. OPT_TRACE( _T("CComponentImpl::IExtendControlbar::ControlbarNotify\n") );
  425. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  426. // Obtain the data obj of the currently selected item.
  427. LPDATAOBJECT pDataObject = NULL;
  428. if (event == MMCN_BTN_CLICK)
  429. {
  430. pDataObject = (LPDATAOBJECT)arg;
  431. }
  432. else if (event == MMCN_SELECT)
  433. {
  434. pDataObject = (LPDATAOBJECT)param;
  435. }
  436. if (NULL == pDataObject)
  437. {
  438. // This can happen on a MMCN_BTN_CLICK if the result pane is clicked, but not
  439. // on a result item, then a scope item toolbar button is pressed. In this case
  440. // check for one of the known scope item toolbar commands.
  441. if (IDM_CREATENEWSECPOL == param )
  442. {
  443. pDataObject = m_pCComponentData->GetStaticScopeObject();
  444. }
  445. else
  446. {
  447. TRACE(_T("CComponentImpl::ControlbarNotify - ERROR no IDataObject available\n"));
  448. return E_UNEXPECTED;
  449. }
  450. }
  451. // Let selected item handle command
  452. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pDataObject );
  453. if (spData == NULL)
  454. {
  455. TRACE(_T("CComponentImpl::ControlbarNotify - QI for IWirelessSnapInDataObject FAILED\n"));
  456. ASSERT( FALSE );
  457. return E_UNEXPECTED;
  458. }
  459. HRESULT hr = spData->ControlbarNotify( m_spControlbar, (IExtendControlbar*)this,
  460. event, arg, param );
  461. // If the command was not handled by the selected item, pass it to our static
  462. // scope obj.
  463. if (E_NOTIMPL == hr || S_FALSE == hr)
  464. {
  465. if (m_pCComponentData->GetStaticScopeObject() != pDataObject)
  466. {
  467. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject>
  468. spScopeData( m_pCComponentData->GetStaticScopeObject() );
  469. if (spScopeData == NULL)
  470. {
  471. TRACE(_T("CComponentImpl::ControlbarNotify - StaticScopeObj.QI for IWirelessSnapInDataObject FAILED\n"));
  472. ASSERT( FALSE );
  473. return E_UNEXPECTED;
  474. }
  475. hr = spScopeData->ControlbarNotify( m_spControlbar, (IExtendControlbar*)this,
  476. event, arg, param );
  477. }
  478. }
  479. return hr;
  480. }