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.

697 lines
17 KiB

  1. #include "comp.h"
  2. #include "dataobj.h"
  3. #include <crtdbg.h>
  4. #include "resource.h"
  5. #include "delebase.h"
  6. #include "compdata.h"
  7. #include "globals.h"
  8. #include <commctrl.h>
  9. CComponent::CComponent( CComponentData *parent )
  10. : m_pComponentData( parent )
  11. , m_cref( 0 )
  12. , m_ipConsole( NULL )
  13. , m_ipControlBar( NULL )
  14. , m_ipToolbar( NULL )
  15. {
  16. OBJECT_CREATED
  17. m_hBMapSm = LoadBitmap( g_hinst, MAKEINTRESOURCE(IDR_SMICONS) );
  18. m_hBMapLg = LoadBitmap( g_hinst, MAKEINTRESOURCE(IDR_LGICONS) );
  19. }
  20. CComponent::~CComponent()
  21. {
  22. OBJECT_DESTROYED
  23. if( NULL != m_hBMapSm )
  24. {
  25. DeleteObject( m_hBMapSm );
  26. }
  27. if( NULL != m_hBMapLg )
  28. {
  29. DeleteObject( m_hBMapLg );
  30. }
  31. }
  32. STDMETHODIMP CComponent::QueryInterface( REFIID riid, LPVOID *ppv )
  33. {
  34. if( !ppv )
  35. return E_FAIL;
  36. *ppv = NULL;
  37. if( IsEqualIID( riid, IID_IUnknown ) )
  38. *ppv = static_cast<IComponent *>(this);
  39. else if( IsEqualIID(riid, IID_IComponent) )
  40. *ppv = static_cast<IComponent *>(this);
  41. else if( IsEqualIID( riid, IID_IExtendPropertySheet ) )
  42. *ppv = static_cast<IExtendPropertySheet2 *>(this);
  43. else if( IsEqualIID(riid, IID_IExtendPropertySheet2 ) )
  44. *ppv = static_cast<IExtendPropertySheet2 *>(this);
  45. else if( IsEqualIID(riid, IID_IExtendControlbar ) )
  46. *ppv = static_cast<IExtendControlbar *>(this);
  47. else if( IsEqualIID(riid, IID_IExtendContextMenu ) )
  48. *ppv = static_cast<IExtendContextMenu *>(this);
  49. if( *ppv )
  50. {
  51. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  52. return S_OK;
  53. }
  54. return E_NOINTERFACE;
  55. }
  56. STDMETHODIMP_(ULONG) CComponent::AddRef()
  57. {
  58. return InterlockedIncrement( (LONG *)&m_cref );
  59. }
  60. STDMETHODIMP_(ULONG) CComponent::Release()
  61. {
  62. if( 0 == InterlockedDecrement( (LONG *)&m_cref ) )
  63. {
  64. delete this;
  65. return 0;
  66. }
  67. return m_cref;
  68. }
  69. ///////////////////////////////
  70. // Interface IComponent
  71. ///////////////////////////////
  72. STDMETHODIMP CComponent::Initialize( /* [in] */ LPCONSOLE lpConsole )
  73. {
  74. HRESULT hr = S_OK;
  75. //
  76. // Save away all the interfaces we'll need.
  77. // Fail if we can't QI the required interfaces.
  78. //
  79. m_ipConsole = lpConsole;
  80. m_ipConsole->AddRef();
  81. hr = m_ipConsole->QueryInterface(IID_IDisplayHelp, (void **)&m_ipDisplayHelp);
  82. return hr;
  83. }
  84. STDMETHODIMP CComponent::Notify(
  85. /* [in] */ LPDATAOBJECT lpDataObject,
  86. /* [in] */ MMC_NOTIFY_TYPE event,
  87. /* [in] */ LPARAM arg,
  88. /* [in] */ LPARAM param )
  89. {
  90. MMCN_Crack( FALSE, lpDataObject, NULL, this, event, arg, param );
  91. HRESULT hr = S_FALSE;
  92. CDelegationBase *base = NULL;
  93. //
  94. // We need to watch for property change and delegate it
  95. // a little differently, we're actually going to send
  96. // the CDelegationBase object pointer in the property page
  97. // PSN_APPLY handler via MMCPropPageNotify()
  98. //
  99. if( MMCN_PROPERTY_CHANGE != event && MMCN_VIEW_CHANGE != event )
  100. {
  101. if( NULL == lpDataObject )
  102. return S_FALSE;
  103. CDataObject *pDataObject = GetOurDataObject( lpDataObject );
  104. if( NULL != pDataObject )
  105. {
  106. base = pDataObject->GetBaseNodeObject();
  107. }
  108. if( ( NULL == base ) && ( MMCN_ADD_IMAGES != event ) )
  109. {
  110. return S_FALSE;
  111. }
  112. }
  113. else if( MMCN_PROPERTY_CHANGE == event )
  114. {
  115. base = (CDelegationBase *) param;
  116. }
  117. //
  118. // MMCN_VIEW_CHANGE
  119. //
  120. if( MMCN_VIEW_CHANGE == event )
  121. {
  122. //
  123. // Arg holds the data. For a scope item, this is the
  124. // item's myhscopeitem. For a result item, this is
  125. // the item's nId value, but we don't use it
  126. // param holds the hint passed to IConsole::UpdateAllViews.
  127. // hint is a value of the UPDATE_VIEWS_HINT enumeration
  128. //
  129. CDataObject *pDataObject = GetOurDataObject(lpDataObject);
  130. if( NULL == pDataObject )
  131. {
  132. return S_FALSE;
  133. }
  134. else
  135. {
  136. base = pDataObject->GetBaseNodeObject();
  137. if( NULL == base )
  138. {
  139. return S_FALSE;
  140. }
  141. }
  142. switch( param )
  143. {
  144. case UPDATE_SCOPEITEM:
  145. {
  146. hr = base->OnUpdateItem( m_ipConsole, (long)arg, SCOPE );
  147. break;
  148. }
  149. case UPDATE_RESULTITEM:
  150. {
  151. hr = base->OnUpdateItem( m_ipConsole, (long)arg, RESULT );
  152. break;
  153. }
  154. }
  155. return S_OK;
  156. }
  157. //
  158. // The remaining notifications
  159. //
  160. switch( event )
  161. {
  162. case MMCN_SHOW:
  163. {
  164. hr = base->OnShow( m_ipConsole, (BOOL) arg, (HSCOPEITEM) param );
  165. break;
  166. }
  167. case MMCN_ADD_IMAGES:
  168. {
  169. if( NULL == base )
  170. {
  171. IImageList *pResultImageList = (IImageList *)arg;
  172. if( ( NULL != pResultImageList ) && ( NULL != m_hBMapSm ) && ( NULL != m_hBMapLg ) )
  173. {
  174. hr = pResultImageList->ImageListSetStrip(
  175. (LONG_PTR *)m_hBMapSm,
  176. (LONG_PTR *)m_hBMapLg,
  177. 0,
  178. RGB(0, 128, 128));
  179. }
  180. }
  181. else
  182. {
  183. hr = base->OnAddImages( (IImageList *) arg, (HSCOPEITEM) param );
  184. }
  185. break;
  186. }
  187. case MMCN_SELECT:
  188. {
  189. hr = base->OnSelect( this, m_ipConsole, (BOOL) LOWORD(arg), (BOOL) HIWORD(arg) );
  190. break;
  191. }
  192. case MMCN_RENAME:
  193. {
  194. hr = base->OnRename( (LPOLESTR) param );
  195. //
  196. // Now call IConsole::UpdateAllViews to redraw the item in all views.
  197. //
  198. hr = m_pComponentData->m_ipConsole->UpdateAllViews( lpDataObject, 0, UPDATE_RESULTITEM );
  199. _ASSERT( S_OK == hr);
  200. break;
  201. }
  202. case MMCN_REFRESH:
  203. {
  204. //
  205. // We pass CComponentData's stored IConsole pointer here,
  206. // so that the IConsole::UpdateAllViews can be called in OnRefresh
  207. //
  208. hr = base->OnRefresh( m_pComponentData->m_ipConsole );
  209. break;
  210. }
  211. case MMCN_DELETE:
  212. {
  213. //
  214. // First delete the selected result item
  215. //
  216. hr = base->OnDelete( m_pComponentData->m_ipConsoleNameSpace, m_ipConsole );
  217. //
  218. // Now call IConsole::UpdateAllViews to redraw all views
  219. // owned by the parent scope item. OnRefresh already does
  220. // this for us, so use it.
  221. //
  222. hr = base->OnRefresh( m_pComponentData->m_ipConsole );
  223. break;
  224. }
  225. //
  226. // Handle the property change notification if we need to do anything
  227. // special with it
  228. //
  229. case MMCN_PROPERTY_CHANGE:
  230. {
  231. //
  232. // We pass CComponentData's stored IConsole pointer here,
  233. // so that the IConsole::UpdateAllViews can be called in OnPropertyChange
  234. //
  235. hr = base->OnPropertyChange( m_pComponentData->m_ipConsole, this );
  236. break;
  237. }
  238. case MMCN_CONTEXTHELP:
  239. {
  240. hr = base->OnShowContextHelp( m_ipDisplayHelp, (LPOLESTR) base->GetHelpFile().c_str() );
  241. break;
  242. }
  243. }
  244. return hr;
  245. }
  246. STDMETHODIMP CComponent::Destroy( MMC_COOKIE cookie )
  247. {
  248. if( m_ipConsole )
  249. {
  250. m_ipConsole->Release();
  251. m_ipConsole = NULL;
  252. }
  253. if( m_ipDisplayHelp )
  254. {
  255. m_ipDisplayHelp->Release();
  256. m_ipDisplayHelp = NULL;
  257. }
  258. return S_OK;
  259. }
  260. STDMETHODIMP CComponent::QueryDataObject(
  261. /* [in] */ MMC_COOKIE cookie,
  262. /* [in] */ DATA_OBJECT_TYPES type,
  263. /* [out] */ LPDATAOBJECT __RPC_FAR *ppDataObject )
  264. {
  265. CDataObject *pObj = NULL;
  266. if( 0 == cookie )
  267. pObj = new CDataObject( (MMC_COOKIE) m_pComponentData->m_pStaticNode, type );
  268. else
  269. pObj = new CDataObject( cookie, type );
  270. if( !pObj )
  271. return E_OUTOFMEMORY;
  272. pObj->QueryInterface( IID_IDataObject, (void **)ppDataObject );
  273. return S_OK;
  274. }
  275. STDMETHODIMP CComponent::GetResultViewType(
  276. /* [in] */ MMC_COOKIE cookie,
  277. /* [out] */ LPOLESTR __RPC_FAR *ppViewType,
  278. /* [out] */ long __RPC_FAR *pViewOptions )
  279. {
  280. CDelegationBase *base = (CDelegationBase*) cookie;
  281. //
  282. // Ask for default listview.
  283. //
  284. if( NULL == base )
  285. {
  286. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  287. *ppViewType = NULL;
  288. }
  289. else
  290. return base->GetResultViewType( ppViewType, pViewOptions );
  291. return S_OK;
  292. }
  293. STDMETHODIMP CComponent::GetDisplayInfo( RESULTDATAITEM __RPC_FAR *pResultDataItem )
  294. {
  295. if( NULL == pResultDataItem )
  296. {
  297. return E_INVALIDARG;
  298. }
  299. HRESULT hr = S_OK;
  300. CDelegationBase *base = NULL;
  301. //
  302. // If they are asking for the RDI_STR we have one of those to give
  303. //
  304. if( pResultDataItem->lParam )
  305. {
  306. base = (CDelegationBase*) pResultDataItem->lParam;
  307. if( NULL == base )
  308. {
  309. return E_INVALIDARG;
  310. }
  311. if( pResultDataItem->mask & RDI_STR )
  312. {
  313. LPCTSTR pszT = base->GetDisplayName( pResultDataItem->nCol );
  314. if( NULL == pszT )
  315. {
  316. return E_OUTOFMEMORY;
  317. }
  318. pResultDataItem->str = const_cast<LPOLESTR>( pszT );
  319. }
  320. if( pResultDataItem->mask & RDI_IMAGE )
  321. {
  322. pResultDataItem->nImage = base->GetBitmapIndex();
  323. }
  324. }
  325. return hr;
  326. }
  327. STDMETHODIMP CComponent::CompareObjects(
  328. /* [in] */ LPDATAOBJECT lpDataObjectA,
  329. /* [in] */ LPDATAOBJECT lpDataObjectB )
  330. {
  331. if( ( NULL == lpDataObjectA ) || ( NULL == lpDataObjectB ) )
  332. {
  333. return E_INVALIDARG;
  334. }
  335. CDataObject *pDataObjectA = GetOurDataObject( lpDataObjectA );
  336. if( NULL == pDataObjectA )
  337. {
  338. return E_FAIL;
  339. }
  340. CDataObject *pDataObjectB = GetOurDataObject( lpDataObjectB );
  341. if( NULL == pDataObjectB )
  342. {
  343. return E_FAIL;
  344. }
  345. CDelegationBase *baseA = pDataObjectA->GetBaseNodeObject();
  346. if( NULL == baseA )
  347. {
  348. return E_FAIL;
  349. }
  350. CDelegationBase *baseB = pDataObjectB->GetBaseNodeObject();
  351. if( NULL == baseB )
  352. {
  353. return E_FAIL;
  354. }
  355. //
  356. // compare the object pointers
  357. //
  358. if( baseA->GetCookie() == baseB->GetCookie() )
  359. {
  360. return S_OK;
  361. }
  362. else
  363. {
  364. return S_FALSE;
  365. }
  366. }
  367. ///////////////////////////////////
  368. // Interface IExtendPropertySheet2
  369. ///////////////////////////////////
  370. HRESULT CComponent::CreatePropertyPages(
  371. /* [in] */ LPPROPERTYSHEETCALLBACK lpProvider,
  372. /* [in] */ LONG_PTR handle,
  373. /* [in] */ LPDATAOBJECT piDataObject )
  374. {
  375. if( ( NULL == lpProvider ) || ( NULL == handle ) || ( NULL == piDataObject ) )
  376. {
  377. return E_INVALIDARG;
  378. }
  379. CDataObject *pDataObject = GetOurDataObject( piDataObject );
  380. if( NULL == pDataObject )
  381. {
  382. return E_FAIL;
  383. }
  384. CDelegationBase *base = pDataObject->GetBaseNodeObject();
  385. if( NULL == base )
  386. {
  387. return E_FAIL;
  388. }
  389. return base->CreatePropertyPages( lpProvider, handle );
  390. }
  391. HRESULT CComponent::QueryPagesFor(/* [in] */ LPDATAOBJECT piDataObject )
  392. {
  393. if( NULL == piDataObject )
  394. {
  395. return E_INVALIDARG;
  396. }
  397. CDataObject *pDataObject = GetOurDataObject( piDataObject );
  398. if( NULL == pDataObject )
  399. {
  400. return E_FAIL;
  401. }
  402. CDelegationBase *base = pDataObject->GetBaseNodeObject();
  403. if( NULL == base )
  404. {
  405. return E_FAIL;
  406. }
  407. return base->HasPropertySheets();
  408. }
  409. HRESULT CComponent::GetWatermarks(
  410. /* [in] */ LPDATAOBJECT piDataObject,
  411. /* [out] */ HBITMAP __RPC_FAR *lphWatermark,
  412. /* [out] */ HBITMAP __RPC_FAR *lphHeader,
  413. /* [out] */ HPALETTE __RPC_FAR *lphPalette,
  414. /* [out] */ BOOL __RPC_FAR *bStretch)
  415. {
  416. if( ( NULL == piDataObject ) || ( NULL == lphWatermark ) || ( NULL == lphHeader ) || ( NULL == lphPalette ) || ( NULL == bStretch ) )
  417. {
  418. return E_INVALIDARG;
  419. }
  420. CDataObject *pDataObject = GetOurDataObject( piDataObject );
  421. if( NULL == pDataObject )
  422. {
  423. return E_FAIL;
  424. }
  425. CDelegationBase *base = pDataObject->GetBaseNodeObject();
  426. if( NULL == base )
  427. {
  428. return E_FAIL;
  429. }
  430. return base->GetWatermarks( lphWatermark, lphHeader, lphPalette, bStretch );
  431. }
  432. ///////////////////////////////
  433. // Interface IExtendControlBar
  434. ///////////////////////////////
  435. HRESULT CComponent::SetControlbar( /* [in] */ LPCONTROLBAR pControlbar )
  436. {
  437. HRESULT hr = S_OK;
  438. //
  439. // Clean up
  440. //
  441. //
  442. // If we've got a cached toolbar, release it
  443. //
  444. if( m_ipToolbar )
  445. {
  446. m_ipToolbar->Release();
  447. m_ipToolbar = NULL;
  448. }
  449. //
  450. // If we've got a cached control bar, release it
  451. //
  452. if( m_ipControlBar )
  453. {
  454. m_ipControlBar->Release();
  455. m_ipControlBar = NULL;
  456. }
  457. //
  458. // Install new pieces if necessary
  459. //
  460. //
  461. // if a new one came in, cache and AddRef
  462. //
  463. if( pControlbar )
  464. {
  465. m_ipControlBar = pControlbar;
  466. m_ipControlBar->AddRef();
  467. hr = m_ipControlBar->Create(
  468. TOOLBAR, // type of control to be created
  469. dynamic_cast<IExtendControlbar *>(this),
  470. reinterpret_cast<IUnknown **>(&m_ipToolbar) );
  471. _ASSERT(SUCCEEDED(hr));
  472. WCHAR szStart[ 100 ], szStop[ 100 ];
  473. WCHAR szStartDescription[ 256 ], szStopDescription[ 256 ];
  474. MMCBUTTON SnapinButtons1[] =
  475. {
  476. { 0, ID_BUTTONSTART, TBSTATE_ENABLED, TBSTYLE_GROUP, szStart, szStartDescription },
  477. { 1, ID_BUTTONSTOP, TBSTATE_ENABLED, TBSTYLE_GROUP, szStop, szStopDescription},
  478. };
  479. ::LoadStringW( g_hinst, IDS_WEBSERVER_START, szStart, ARRAYLEN( szStart ) );
  480. ::LoadStringW( g_hinst, IDS_WEBSERVER_START_DESCRIPTION, szStartDescription, ARRAYLEN( szStartDescription ) );
  481. ::LoadStringW( g_hinst, IDS_WEBSERVER_STOP, szStop, ARRAYLEN( szStop ) );
  482. ::LoadStringW( g_hinst, IDS_WEBSERVER_STOP_DESCRIPTION, szStopDescription, ARRAYLEN( szStopDescription ) );
  483. //
  484. // The IControlbar::Create AddRefs the toolbar object it created
  485. // so no need to do any addref on the interface.
  486. //
  487. //
  488. // Add the bitmap to the toolbar
  489. //
  490. HBITMAP hbmp = LoadBitmap( g_hinst, MAKEINTRESOURCE( IDR_TOOLBAR1 ) );
  491. hr = m_ipToolbar->AddBitmap( ARRAYLEN( SnapinButtons1 ), hbmp, 16, 16, RGB( 0, 128, 128 ) );
  492. _ASSERT( SUCCEEDED(hr) );
  493. //
  494. // Add the buttons to the toolbar
  495. //
  496. hr = m_ipToolbar->AddButtons( ARRAYLEN(SnapinButtons1), SnapinButtons1 );
  497. _ASSERT( SUCCEEDED(hr) );
  498. }
  499. return hr;
  500. }
  501. HRESULT CComponent::ControlbarNotify(
  502. /* [in] */ MMC_NOTIFY_TYPE event,
  503. /* [in] */ LPARAM arg,
  504. /* [in] */ LPARAM param )
  505. {
  506. HRESULT hr = S_OK;
  507. if( MMCN_SELECT == event )
  508. {
  509. BOOL bScope = (BOOL) LOWORD(arg);
  510. BOOL bSelect = (BOOL) HIWORD(arg);
  511. if( NULL == param )
  512. {
  513. return E_INVALIDARG;
  514. }
  515. CDataObject *pDataObject = GetOurDataObject( reinterpret_cast<IDataObject *>( param ) );
  516. if( NULL == pDataObject )
  517. {
  518. return E_FAIL;
  519. }
  520. CDelegationBase *base = pDataObject->GetBaseNodeObject();
  521. if( NULL == base )
  522. {
  523. return E_FAIL;
  524. }
  525. hr = base->OnSetToolbar( m_ipControlBar, m_ipToolbar, bScope, bSelect );
  526. }
  527. else if( MMCN_BTN_CLICK == event )
  528. {
  529. if( NULL == arg )
  530. {
  531. return E_INVALIDARG;
  532. }
  533. CDataObject *pDataObject = GetOurDataObject( reinterpret_cast<IDataObject *>( arg ) );
  534. if( NULL == pDataObject )
  535. {
  536. return E_FAIL;
  537. }
  538. CDelegationBase *base = pDataObject->GetBaseNodeObject();
  539. if( NULL == base )
  540. {
  541. return E_FAIL;
  542. }
  543. hr = base->OnToolbarCommand( m_pComponentData->m_ipConsole, (MMC_CONSOLE_VERB)param, reinterpret_cast<IDataObject *>(arg) );
  544. }
  545. return hr;
  546. }
  547. ///////////////////////////////
  548. // Interface IExtendContextMenu
  549. ///////////////////////////////
  550. HRESULT CComponent::AddMenuItems(
  551. LPDATAOBJECT piDataObject,
  552. LPCONTEXTMENUCALLBACK piCallback,
  553. long __RPC_FAR *pInsertionAllowed )
  554. {
  555. if( ( NULL == piDataObject ) || ( NULL == piCallback ) || ( NULL == pInsertionAllowed ) )
  556. {
  557. return E_INVALIDARG;
  558. }
  559. CDataObject *pDataObject = GetOurDataObject( piDataObject );
  560. if( NULL == pDataObject )
  561. {
  562. return E_FAIL;
  563. }
  564. CDelegationBase *base = pDataObject->GetBaseNodeObject();
  565. if( NULL == base )
  566. {
  567. return E_FAIL;
  568. }
  569. return base->OnAddMenuItems( piCallback, pInsertionAllowed );
  570. }
  571. HRESULT CComponent::Command( long lCommandID, LPDATAOBJECT piDataObject )
  572. {
  573. if( NULL == piDataObject )
  574. {
  575. return E_INVALIDARG;
  576. }
  577. CDataObject *pDataObject = GetOurDataObject( piDataObject );
  578. if( NULL == pDataObject )
  579. {
  580. return E_FAIL;
  581. }
  582. CDelegationBase *base = pDataObject->GetBaseNodeObject();
  583. if( NULL == base )
  584. {
  585. return E_FAIL;
  586. }
  587. return base->OnMenuCommand( m_ipConsole, NULL, lCommandID, piDataObject );
  588. }