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.

597 lines
18 KiB

  1. /*++
  2. Module Name:
  3. ICompont.cpp
  4. Abstract:
  5. This module contains the IComponent Interface implementation for Dfs Admin snapin,
  6. Implementation for the CDfsSnapinResultManager class
  7. --*/
  8. #include "stdafx.h"
  9. #include "DfsGUI.h"
  10. #include "DfsCore.h" // For IDfsRoot
  11. #include "DfsScope.h" // For CDfsScopeManager
  12. #include "DfsReslt.h" // IComponent and other declarations
  13. #include "MMCAdmin.h" // For CMMCDfsAdmin
  14. #include "Utils.h"
  15. #include <htmlHelp.h>
  16. STDMETHODIMP
  17. CDfsSnapinResultManager::Initialize(
  18. IN LPCONSOLE i_lpConsole
  19. )
  20. /*++
  21. Routine Description:
  22. Initializes the Icomponent interface. Allows the interface to save pointers,
  23. interfaces that are required later.
  24. Arguments:
  25. i_lpConsole - Pointer to the IConsole object.
  26. --*/
  27. {
  28. RETURN_INVALIDARG_IF_NULL(i_lpConsole);
  29. HRESULT hr = i_lpConsole->QueryInterface(IID_IConsole2, reinterpret_cast<void**>(&m_pConsole));
  30. RETURN_IF_FAILED(hr);
  31. hr = i_lpConsole->QueryInterface(IID_IHeaderCtrl2, reinterpret_cast<void**>(&m_pHeader));
  32. RETURN_IF_FAILED(hr);
  33. hr = i_lpConsole->QueryInterface (IID_IResultData, (void**)&m_pResultData);
  34. RETURN_IF_FAILED(hr);
  35. hr = i_lpConsole->QueryConsoleVerb(&m_pConsoleVerb);
  36. return hr;
  37. }
  38. STDMETHODIMP
  39. CDfsSnapinResultManager::Notify(
  40. IN LPDATAOBJECT i_lpDataObject,
  41. IN MMC_NOTIFY_TYPE i_Event,
  42. IN LPARAM i_lArg,
  43. IN LPARAM i_lParam
  44. )
  45. /*++
  46. Routine Description:
  47. Handles different events in form of notify
  48. Arguments:
  49. i_lpDataObject - The data object for the node for which the event occured
  50. i_Event - The type of event for which notify has occurred
  51. i_lArg - Argument for the event
  52. i_lParam - Parameters for the event.
  53. --*/
  54. {
  55. // The snap-in should return S_FALSE for any notification it does not handle.
  56. // MMC then performs a default operation for the notification.
  57. HRESULT hr = S_FALSE;
  58. switch(i_Event)
  59. {
  60. case MMCN_SHOW:
  61. {
  62. // The notification is sent to the snap-in's IComponent implementation
  63. // when a scope item is selected or deselected.
  64. //
  65. // arg: TRUE if selecting. Indicates that the snap-in should set up the
  66. // result pane and add the enumerated items. FALSE if deselecting.
  67. // Indicates that the snap-in is going out of focus and that it
  68. // should clean up all result item cookies, because the current
  69. // result pane will be replaced by a new one.
  70. // param: The HSCOPEITEM of the selected or deselected item.
  71. hr = DoNotifyShow(i_lpDataObject, i_lArg, i_lParam);
  72. break;
  73. }
  74. case MMCN_ADD_IMAGES:
  75. {
  76. // The MMCN_ADD_IMAGES notification is sent to the snap-in's IComponent
  77. // implementation to add images for the result pane.
  78. //
  79. // lpDataObject: [in] Pointer to the data object of the currently selected scope item.
  80. // arg: Pointer to the result pane's image list (IImageList).
  81. // This pointer is valid only while the specific MMCN_ADD_IMAGES notification is
  82. // being processed and should not be stored for later use. Additionally, the
  83. // snap-in must not call the Release method of IImageList because MMC is responsible
  84. // for releasing it.
  85. // param: Specifies the HSCOPEITEM of the currently selected scope item. The snap-in
  86. // can use this parameter to add images that apply specifically to the result
  87. // items of this scope item, or the snap-in can ignore this parameter and add
  88. // all possible images.
  89. CMmcDisplay* pCMmcDisplayObj = NULL;
  90. hr = m_pScopeManager->GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  91. if (SUCCEEDED(hr))
  92. hr = pCMmcDisplayObj->OnAddImages((IImageList *)i_lArg, (HSCOPEITEM)i_lParam);
  93. break;
  94. }
  95. case MMCN_SELECT:
  96. {
  97. // The MMCN_SELECT notification is sent to the snap-in's IComponent::Notify
  98. // or IExtendControlbar::ControlbarNotify method when an item is selected in
  99. // either the scope pane or result pane.
  100. //
  101. // lpDataObject: [in] Pointer to the data object of the currently
  102. // selected/deselected scope pane or result item.
  103. // arg: BOOL bScope = (BOOL) LOWORD(arg); BOOL bSelect = (BOOL) HIWORD(arg);
  104. // bScope is TRUE if the selected item is a scope item, or FALSE if
  105. // the selected item is a result item. For bScope = TRUE, MMC does
  106. // not provide information about whether the scope item is selected
  107. // in the scope pane or in the result pane. bSelect is TRUE if the
  108. // item is selected, or FALSE if the item is deselected.
  109. // param: ignored.
  110. hr = DoNotifySelect(i_lpDataObject, i_lArg, i_lParam);
  111. break;
  112. }
  113. case MMCN_DBLCLICK: // Ask MMC to use the default verb. Non documented feature
  114. {
  115. // The MMCN_DBLCLICK notification is sent to the snap-in's IComponent
  116. // implementation when a user double-clicks a mouse button on a list
  117. // view item or on a scope item in the result pane. Pressing enter
  118. // while the list item or scope item has focus in the list view also
  119. // generates an MMCN_DBLCLICK notification message.
  120. //
  121. // lpDataObject: [in] Pointer to the data object of the currently selected item.
  122. // arg: Not used.
  123. // param: Not used.
  124. CMmcDisplay* pCMmcDisplayObj = NULL;
  125. hr = m_pScopeManager->GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  126. if (SUCCEEDED(hr))
  127. hr = pCMmcDisplayObj->DoDblClick();
  128. break;
  129. }
  130. case MMCN_DELETE: // Delete the node. Time to remove item
  131. {
  132. // The MMCN_DELETE notification message is sent to the snap-in's IComponent
  133. // and IComponentData implementations to inform the snap-in that the object
  134. // should be deleted. This message is generated when the user presses the
  135. // delete key or uses the mouse to click the toolbar's delete button. The
  136. // snap-in should delete the items specified in the data object.
  137. //
  138. // lpDataObject: [in] Pointer to the data object of the currently selected
  139. // scope or result item, provided by the snap-in.
  140. // arg: Not used.
  141. // param: Not used.
  142. CMmcDisplay* pCMmcDisplayObj = NULL;
  143. hr = m_pScopeManager->GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  144. if (SUCCEEDED(hr))
  145. hr = pCMmcDisplayObj->DoDelete(); // Delete the the item.
  146. break;
  147. }
  148. case MMCN_SNAPINHELP:
  149. case MMCN_CONTEXTHELP:
  150. {
  151. // The MMCN_CONTEXTHELP notification message is sent to the snap-in's
  152. // IComponent implementation when the user requests help about a selected
  153. // item by pressing the F1 key or Help button. A snap-in responds to
  154. // MMCN_CONTEXTHELP by displaying a Help topic for the particular context
  155. // by calling the IDisplayHelp::ShowTopic method.
  156. //
  157. // lpDataObject: [in] Pointer to the data object of the currently selected
  158. // scope or result item.
  159. // arg: Zero.
  160. // param: Zero.
  161. hr = DfsHelp();
  162. break;
  163. }
  164. case MMCN_VIEW_CHANGE:
  165. {
  166. // The MMCN_VIEW_CHANGE notification message is sent to the snap-in's
  167. // IComponent implementation so it can update the view when a change occurs.
  168. // This notification is generated when the snap-in (IComponent or IComponentData)
  169. // calls IConsole2::UpdateAllViews.
  170. //
  171. // lpDataObject: [in] Pointer to the data object passed to IConsole::UpdateAllViews.
  172. // arg: [in] The data parameter passed to IConsole::UpdateAllViews.
  173. // param: [in] The hint parameter passed to IConsole::UpdateAllViews.
  174. hr = DoNotifyViewChange(i_lpDataObject, (LONG_PTR)i_lArg, (LONG_PTR)i_lParam);
  175. break;
  176. }
  177. case MMCN_REFRESH:
  178. {
  179. // The MMCN_REFRESH notification message is sent to a snap-in's IComponent
  180. // implementation when the refresh verb is selected. Refresh can be invoked
  181. // through the context menu, through the toolbar, or by pressing F5.
  182. //
  183. // lpDataObject: [in] Pointer to the data object of the currently selected scope item.
  184. // arg: Not used.
  185. // param: Not used.
  186. CMmcDisplay* pCMmcDisplayObj = NULL;
  187. hr = m_pScopeManager->GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  188. if (SUCCEEDED(hr))
  189. (void)pCMmcDisplayObj->OnRefresh();
  190. break;
  191. }
  192. default:
  193. break;
  194. }
  195. return hr;
  196. }
  197. STDMETHODIMP
  198. CDfsSnapinResultManager::DoNotifyShow(
  199. IN LPDATAOBJECT i_lpDataObject,
  200. IN BOOL i_bShow,
  201. IN HSCOPEITEM i_hParent
  202. )
  203. /*++
  204. Routine Description:
  205. Take action on Notify with the event MMCN_SHOW.
  206. Do add the column headers to result pane and add items to result pane.
  207. Arguments:
  208. i_lpDataObject - The IDataObject pointer which identifies the node for which
  209. the event is taking place
  210. i_bShow - TRUE, if the node is being showed. FALSE otherwise
  211. i_hParent - HSCOPEITEM of the node that received this event
  212. --*/
  213. {
  214. RETURN_INVALIDARG_IF_NULL(i_lpDataObject);
  215. m_pSelectScopeDisplayObject = NULL;
  216. if(FALSE == i_bShow) // If the item is being deselected.
  217. return S_OK;
  218. // This node is being shown.
  219. CMmcDisplay* pCMmcDisplayObj = NULL;
  220. HRESULT hr = m_pScopeManager->GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  221. RETURN_IF_FAILED(hr);
  222. m_pSelectScopeDisplayObject = pCMmcDisplayObj;
  223. DISPLAY_OBJECT_TYPE DisplayObType = pCMmcDisplayObj->GetDisplayObjectType();
  224. if (DISPLAY_OBJECT_TYPE_ADMIN == DisplayObType)
  225. {
  226. CComPtr<IUnknown> spUnknown;
  227. hr = m_pConsole->QueryResultView(&spUnknown);
  228. if (SUCCEEDED(hr))
  229. {
  230. CComPtr<IMessageView> spMessageView;
  231. hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
  232. if (SUCCEEDED(hr))
  233. {
  234. CComBSTR bstrTitleText;
  235. CComBSTR bstrBodyText;
  236. LoadStringFromResource(IDS_APPLICATION_NAME, &bstrTitleText);
  237. LoadStringFromResource(IDS_MSG_DFS_INTRO, &bstrBodyText);
  238. spMessageView->SetTitleText(bstrTitleText);
  239. spMessageView->SetBodyText(bstrBodyText);
  240. spMessageView->SetIcon(Icon_Information);
  241. }
  242. }
  243. return hr;
  244. }
  245. CWaitCursor WaitCursor;
  246. hr = pCMmcDisplayObj->SetColumnHeader(m_pHeader); // Call the method SetColumnHeader in the Display callback
  247. if (SUCCEEDED(hr))
  248. hr = pCMmcDisplayObj->EnumerateResultPane (m_pResultData); // Add the items to the Result pane
  249. return hr;
  250. }
  251. STDMETHODIMP
  252. CDfsSnapinResultManager::Destroy(
  253. IN MMC_COOKIE i_lCookie
  254. )
  255. /*++
  256. Routine Description:
  257. The IComponent object is about to be destroyed. Explicitely release all interface pointers,
  258. otherwise, MMC may not call the destructor.
  259. Arguments:
  260. None.
  261. --*/
  262. {
  263. m_pHeader.Release();
  264. m_pResultData.Release();
  265. m_pConsoleVerb.Release();
  266. m_pConsole.Release();
  267. m_pControlbar.Release();
  268. m_pMMCAdminToolBar.Release();
  269. m_pMMCRootToolBar.Release();
  270. m_pMMCJPToolBar.Release();
  271. m_pMMCReplicaToolBar.Release();
  272. return S_OK;
  273. }
  274. STDMETHODIMP
  275. CDfsSnapinResultManager::GetResultViewType(
  276. IN MMC_COOKIE i_lCookie,
  277. OUT LPOLESTR* o_ppViewType,
  278. OUT LPLONG o_lpViewOptions
  279. )
  280. /*++
  281. Routine Description:
  282. Used to describe to MMC the type of view the result pane has.
  283. --*/
  284. {
  285. RETURN_INVALIDARG_IF_NULL(o_lpViewOptions);
  286. // The callee (snap-in) allocates the view type string using the COM API function
  287. // CoTaskMemAlloc and the caller (MMC) frees it using CoTaskMemFree.
  288. if (i_lCookie == 0) // the static node
  289. {
  290. *o_lpViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  291. StringFromCLSID(CLSID_MessageView, o_ppViewType);
  292. return S_OK;
  293. }
  294. *o_lpViewOptions = MMC_VIEW_OPTIONS_NONE | MMC_VIEW_OPTIONS_EXCLUDE_SCOPE_ITEMS_FROM_LIST; // Use the default list view
  295. *o_ppViewType = NULL;
  296. return S_FALSE; // return S_FALSE if a standard list view should be used.
  297. }
  298. STDMETHODIMP
  299. CDfsSnapinResultManager::QueryDataObject(
  300. IN MMC_COOKIE i_lCookie,
  301. IN DATA_OBJECT_TYPES i_DataObjectType,
  302. OUT LPDATAOBJECT* o_ppDataObject
  303. )
  304. /*++
  305. Routine Description:
  306. Returns the IDataObject for the specified node.
  307. --*/
  308. {
  309. return m_pScopeManager->QueryDataObject(i_lCookie, i_DataObjectType, o_ppDataObject);
  310. }
  311. STDMETHODIMP
  312. CDfsSnapinResultManager::GetDisplayInfo(
  313. IN OUT RESULTDATAITEM* io_pResultDataItem
  314. )
  315. /*++
  316. Routine Description:
  317. Returns the display information being asked for by MMC.
  318. Arguments:
  319. io_pResultDataItem - Contains details about what information is being asked for.
  320. The information being asked is returned in this object itself.
  321. --*/
  322. {
  323. RETURN_INVALIDARG_IF_NULL(io_pResultDataItem);
  324. RETURN_INVALIDARG_IF_NULL(io_pResultDataItem->lParam);
  325. return ((CMmcDisplay*)(io_pResultDataItem->lParam))->GetResultDisplayInfo(io_pResultDataItem);
  326. }
  327. STDMETHODIMP
  328. CDfsSnapinResultManager::CompareObjects(
  329. IN LPDATAOBJECT i_lpDataObjectA,
  330. IN LPDATAOBJECT i_lpDataObjectB
  331. )
  332. {
  333. return m_pScopeManager->CompareObjects(i_lpDataObjectA, i_lpDataObjectB);
  334. }
  335. STDMETHODIMP
  336. CDfsSnapinResultManager::DoNotifySelect(
  337. IN LPDATAOBJECT i_lpDataObject,
  338. IN BOOL i_bSelect,
  339. IN HSCOPEITEM i_hParent
  340. )
  341. /*++
  342. Routine Description:
  343. Take action on Notify with the event MMCN_SELECT.
  344. Calling the Display object method to set the console verbs like Copy\Paste\Properties, etc
  345. Arguments:
  346. i_lpDataObject - The IDataObject pointer which is used to get the DisplayObject.
  347. i_bSelect - Used to identify whether the item is in scope and if the item is
  348. being selected or deselected
  349. i_hParent - Not used.
  350. --*/
  351. {
  352. RETURN_INVALIDARG_IF_NULL(i_lpDataObject);
  353. if (DOBJ_CUSTOMOCX == i_lpDataObject)
  354. return S_OK;
  355. HRESULT hr = S_OK;
  356. BOOL bSelected = HIWORD(i_bSelect);
  357. if (TRUE == bSelected)
  358. {
  359. CMmcDisplay* pCMmcDisplayObj = NULL;
  360. hr = m_pScopeManager->GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  361. if (SUCCEEDED(hr))
  362. {
  363. // Set MMC Console verbs like Cut\Paste\Properties, etc
  364. if ((IConsoleVerb *)m_pConsoleVerb)
  365. pCMmcDisplayObj->SetConsoleVerbs(m_pConsoleVerb);
  366. // Set the text in the description bar above the result view
  367. pCMmcDisplayObj->SetDescriptionBarText(m_pResultData);
  368. pCMmcDisplayObj->SetStatusText(m_pConsole);
  369. }
  370. } else
  371. {
  372. // Clear previous text
  373. m_pResultData->SetDescBarText(NULL);
  374. m_pConsole->SetStatusText(NULL);
  375. }
  376. return hr;
  377. }
  378. //+--------------------------------------------------------------
  379. //
  380. // Function: CDfsSnapinResultManager::DfsHelp
  381. //
  382. // Synopsis: Display dfs help topic.
  383. //
  384. //---------------------------------------------------------------
  385. STDMETHODIMP
  386. CDfsSnapinResultManager::DfsHelp()
  387. {
  388. CComPtr<IDisplayHelp> sp;
  389. HRESULT hr = m_pConsole->QueryInterface(IID_IDisplayHelp, (void**)&sp);
  390. if (SUCCEEDED(hr))
  391. {
  392. CComBSTR bstrTopic;
  393. hr = LoadStringFromResource(IDS_MMC_HELP_FILE_TOPIC, &bstrTopic);
  394. if (SUCCEEDED(hr))
  395. {
  396. USES_CONVERSION;
  397. hr = sp->ShowTopic(T2OLE(bstrTopic));
  398. }
  399. }
  400. return hr;
  401. }
  402. STDMETHODIMP CDfsSnapinResultManager::DoNotifyViewChange(
  403. IN LPDATAOBJECT i_lpDataObject,
  404. IN LONG_PTR i_lArg,
  405. IN LONG_PTR i_lParam
  406. )
  407. /*++
  408. Routine Description:
  409. Take action on Notify with the event MMCN_VIEW_CHANGE
  410. Arguments:
  411. i_lpDataObject - The IDataObject pointer which is used to get the DisplayObject.
  412. i_lArg - If this is present then the view change is for replica and this parameter
  413. contains the DisplayObject (CMmcDfsReplica*) pointer of the replica.
  414. i_lParam - This is the lHint used by Root and Link. 0 means clean up the result pane only.
  415. 1 means to enumerate the result items and redisplay.
  416. --*/
  417. {
  418. RETURN_INVALIDARG_IF_NULL(i_lpDataObject);
  419. CMmcDisplay* pCMmcDisplayObj = NULL;
  420. HRESULT hr = m_pScopeManager->GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  421. RETURN_IF_FAILED(hr);
  422. // Return if the view change node is NOT the currently selected node
  423. if (pCMmcDisplayObj != m_pSelectScopeDisplayObject)
  424. return S_OK;
  425. if (i_lArg)
  426. {
  427. // The view change is for a replica result item.
  428. ((CMmcDisplay*)i_lArg)->ViewChange(m_pResultData, i_lParam);
  429. if ((IToolbar *)m_pMMCReplicaToolBar)
  430. ((CMmcDisplay*)i_lArg)->ToolbarSelect(MAKELONG(0, 1), m_pMMCReplicaToolBar);
  431. return S_OK;
  432. }
  433. pCMmcDisplayObj->ViewChange(m_pResultData, i_lParam);
  434. IToolbar *piToolbar = NULL;
  435. switch (pCMmcDisplayObj->GetDisplayObjectType())
  436. {
  437. case DISPLAY_OBJECT_TYPE_ADMIN:
  438. piToolbar = m_pMMCAdminToolBar;
  439. break;
  440. case DISPLAY_OBJECT_TYPE_ROOT:
  441. pCMmcDisplayObj->SetStatusText(m_pConsole);
  442. piToolbar = m_pMMCRootToolBar;
  443. break;
  444. case DISPLAY_OBJECT_TYPE_JUNCTION:
  445. piToolbar = m_pMMCJPToolBar;
  446. break;
  447. default:
  448. break;
  449. }
  450. if (piToolbar)
  451. (void)pCMmcDisplayObj->ToolbarSelect(MAKELONG(0, 1), piToolbar);
  452. return S_OK;
  453. }