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.

643 lines
14 KiB

  1. /*++
  2. Module Name:
  3. IComData.cpp
  4. Abstract:
  5. This module contains the implementation for CDfsSnapinScopeManager.
  6. This class implements IComponentData and other related interfaces
  7. --*/
  8. #include "stdafx.h"
  9. #include "DfsGUI.h"
  10. #include "DfsScope.h"
  11. #include "MmcDispl.h"
  12. #include "DfsReslt.h"
  13. #include "Utils.h"
  14. #include "DfsNodes.h"
  15. STDMETHODIMP
  16. CDfsSnapinScopeManager::Initialize(
  17. IN LPUNKNOWN i_pUnknown
  18. )
  19. /*++
  20. Routine Description:
  21. Initialize the IComponentData interface.
  22. The variables needed later are QI'ed now
  23. Arguments:
  24. i_pUnknown - Pointer to the unknown object of IConsole2.
  25. Return value:
  26. S_OK, On success
  27. E_INVALIDARG, On incorrect input parameters
  28. HRESULT sent by methods called, if it is not S_OK.
  29. E_FAIL, on other errors.
  30. --*/
  31. {
  32. RETURN_INVALIDARG_IF_NULL(i_pUnknown);
  33. HRESULT hr = i_pUnknown->QueryInterface(IID_IConsole2, reinterpret_cast<void**>(&m_pConsole));
  34. RETURN_IF_FAILED(hr);
  35. hr = m_pMmcDfsAdmin->PutConsolePtr(m_pConsole);
  36. RETURN_IF_FAILED(hr);
  37. hr = i_pUnknown->QueryInterface(IID_IConsoleNameSpace, reinterpret_cast<void**>(&m_pScope));
  38. RETURN_IF_FAILED(hr);
  39. //The snap-in should also call IConsole2::QueryScopeImageList
  40. // to get the image list for the scope pane and add images
  41. // to be displayed on the scope pane side.
  42. CComPtr<IImageList> pScopeImageList;
  43. hr = m_pConsole->QueryScopeImageList(&pScopeImageList);
  44. RETURN_IF_FAILED(hr);
  45. HBITMAP pBMapSm = NULL;
  46. HBITMAP pBMapLg = NULL;
  47. if (!(pBMapSm = LoadBitmap(_Module.GetModuleInstance(),
  48. MAKEINTRESOURCE(IDB_SCOPE_IMAGES_16x16))) ||
  49. !(pBMapLg = LoadBitmap(_Module.GetModuleInstance(),
  50. MAKEINTRESOURCE(IDB_SCOPE_IMAGES_32x32))))
  51. {
  52. hr = HRESULT_FROM_WIN32(GetLastError());
  53. } else
  54. {
  55. hr = pScopeImageList->ImageListSetStrip(
  56. (LONG_PTR *)pBMapSm,
  57. (LONG_PTR *)pBMapLg,
  58. 0,
  59. RGB(255, 0, 255)
  60. );
  61. }
  62. if (pBMapSm)
  63. DeleteObject(pBMapSm);
  64. if (pBMapLg)
  65. DeleteObject(pBMapLg);
  66. RETURN_IF_FAILED(hr);
  67. HandleCommandLineParameters(); // Internal method to check, if any command line parameters were passed
  68. return hr;
  69. }
  70. STDMETHODIMP
  71. CDfsSnapinScopeManager::CreateComponent(
  72. OUT LPCOMPONENT* o_ppComponent
  73. )
  74. /*++
  75. Routine Description:
  76. Creates the IComponent object
  77. Arguments:
  78. o_ppComponent - Pointer to the object in which the pointer to IComponent object
  79. is stored.
  80. Return value:
  81. S_OK, On success
  82. E_INVALIDARG, On incorrect input parameters
  83. HRESULT sent by methods called, if it is not S_OK.
  84. --*/
  85. {
  86. RETURN_INVALIDARG_IF_NULL(o_ppComponent);
  87. HRESULT hr = E_FAIL;
  88. CComObject<CDfsSnapinResultManager>* pResultManager;
  89. CComObject<CDfsSnapinResultManager>::CreateInstance(&pResultManager);
  90. if (NULL == pResultManager)
  91. {
  92. return(E_FAIL);
  93. }
  94. pResultManager->m_pScopeManager = this;
  95. hr = pResultManager->QueryInterface(IID_IComponent, (void**) o_ppComponent);
  96. _ASSERT(NULL != *o_ppComponent);
  97. RETURN_IF_FAILED(hr);
  98. return S_OK;
  99. }
  100. STDMETHODIMP
  101. CDfsSnapinScopeManager::Notify(
  102. IN LPDATAOBJECT i_lpDataObject,
  103. IN MMC_NOTIFY_TYPE i_Event,
  104. IN LPARAM i_lArg,
  105. IN LPARAM i_lParam
  106. )
  107. /*++
  108. Routine Description:
  109. Handles different events in form of notify
  110. Arguments:
  111. i_lpDataObject - The data object for the node for which the event occured
  112. i_Event - The type of event for which notify has occurred
  113. i_lArg - Argument for the event
  114. i_lParam - Parameters for the event.
  115. Return value:
  116. S_OK, On success
  117. HRESULT sent by methods called, if it is not S_OK.
  118. --*/
  119. {
  120. HRESULT hr = S_FALSE;
  121. switch(i_Event)
  122. {
  123. case MMCN_EXPAND: // Expand the node. Time to add the items to the console
  124. {
  125. hr = DoNotifyExpand(i_lpDataObject, (BOOL) i_lArg, (HSCOPEITEM) i_lParam);
  126. break;
  127. }
  128. case MMCN_DELETE: // Delete the node. Time to remove item
  129. {
  130. hr = DoNotifyDelete(i_lpDataObject);
  131. break;
  132. }
  133. case MMCN_ADD_IMAGES:
  134. {
  135. CMmcDisplay* pCMmcDisplayObj = NULL;
  136. hr = GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  137. if (SUCCEEDED(hr))
  138. hr = pCMmcDisplayObj->OnAddImages((IImageList *)i_lArg, (HSCOPEITEM)i_lParam);
  139. break;
  140. }
  141. case MMCN_PROPERTY_CHANGE: // Handle the property change
  142. {
  143. hr = DoNotifyPropertyChange(i_lpDataObject, i_lParam);
  144. break;
  145. }
  146. default:
  147. break;
  148. }
  149. return hr;
  150. }
  151. STDMETHODIMP
  152. CDfsSnapinScopeManager::DoNotifyExpand(
  153. IN LPDATAOBJECT i_lpDataObject,
  154. IN BOOL i_bExpanding,
  155. IN HSCOPEITEM i_hParent
  156. )
  157. /*++
  158. Routine Description:
  159. Take action on Notify with the event MMCN_EXPAND.
  160. Arguments:
  161. i_lpDataObject - The IDataObject pointer which is used to get the DisplayObject.
  162. i_bExpanding - TRUE, if the node is expanding. FALSE otherwise
  163. i_hParent - HSCOPEITEM of the node that received this event
  164. Return value:
  165. S_OK, if successful.
  166. E_INVALIDARG, if one of the arguments is null.
  167. HRESULT sent by methods called, if it is not S_OK.
  168. --*/
  169. {
  170. RETURN_INVALIDARG_IF_NULL(i_lpDataObject);
  171. CMmcDisplay* pCMmcDisplayObj = NULL;
  172. HRESULT hr = GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  173. RETURN_IF_FAILED(hr);
  174. if (!i_bExpanding)
  175. {
  176. return(S_OK);
  177. }
  178. CWaitCursor WaitCursor; // An object to set\reset the cursor to wait cursor
  179. // Add the items to the Scope pane
  180. // Call the method even if the node is not expanding as we need to cache the scope
  181. // and parent
  182. hr = pCMmcDisplayObj->EnumerateScopePane(m_pScope, i_hParent);
  183. return hr;
  184. }
  185. STDMETHODIMP
  186. CDfsSnapinScopeManager::DoNotifyDelete(
  187. IN LPDATAOBJECT i_lpDataObject
  188. )
  189. /*++
  190. Routine Description:
  191. Take action on Notify with the event MMCN_DELETE.
  192. Arguments:
  193. i_lpDataObject - The IDataObject pointer which is used to get the DisplayObject.
  194. Return value:
  195. S_OK, if successful.
  196. E_INVALIDARG, if one of the arguments is null.
  197. HRESULT sent by methods called, if it is not S_OK.
  198. --*/
  199. {
  200. RETURN_INVALIDARG_IF_NULL(i_lpDataObject);
  201. HRESULT hr = E_FAIL;
  202. CMmcDisplay* pCMmcDisplayObj = NULL;
  203. hr = GetDisplayObject(i_lpDataObject, &pCMmcDisplayObj);
  204. RETURN_IF_FAILED(hr);
  205. hr = pCMmcDisplayObj->DoDelete(); // Delete the the item.
  206. RETURN_IF_FAILED(hr);
  207. return S_OK;
  208. }
  209. STDMETHODIMP
  210. CDfsSnapinScopeManager::Destroy(
  211. )
  212. /*++
  213. Routine Description:
  214. The IComponentData object is about to be destroyed. Explicitely release all interface pointers,
  215. otherwise, MMC may not call the destructor.
  216. Arguments:
  217. None.
  218. Return value:
  219. S_OK.
  220. --*/
  221. {
  222. m_pScope.Release();
  223. m_pConsole.Release();
  224. return S_OK;
  225. }
  226. STDMETHODIMP
  227. CDfsSnapinScopeManager::QueryDataObject(
  228. IN MMC_COOKIE i_lCookie,
  229. IN DATA_OBJECT_TYPES i_DataObjectType,
  230. OUT LPDATAOBJECT* o_ppDataObject
  231. )
  232. /*++
  233. Routine Description:
  234. Returns the IDataObject for the specified node.
  235. Arguments:
  236. i_lCookie - This parameter identifies the node for which IDataObject is
  237. being queried.
  238. i_DataObjectType - The context in which the IDataObject is being queried.
  239. Eg., Result or Scope or Snapin(Node) Manager.
  240. o_ppDataObject - The data object will be returned in this pointer.
  241. Return value:
  242. S_OK, On success
  243. E_INVALIDARG, On incorrect input parameters
  244. HRESULT sent by methods called, if it is not S_OK.
  245. --*/
  246. {
  247. RETURN_INVALIDARG_IF_NULL(o_ppDataObject);
  248. HRESULT hr = S_FALSE;
  249. CMmcDisplay* pMmcDisplay = NULL;
  250. *o_ppDataObject = NULL;
  251. // We get back the cookie we stored in lparam of the scopeitem.
  252. // The cookie is the MmcDisplay pointer.
  253. // For the static(root) node, Use m_pMmcDfsAdmin as no lparam is stored.
  254. if (0 == i_lCookie)
  255. {
  256. pMmcDisplay = reinterpret_cast<CMmcDisplay *>(m_pMmcDfsAdmin);
  257. }
  258. else
  259. {
  260. pMmcDisplay = reinterpret_cast<CMmcDisplay *>(i_lCookie);
  261. }
  262. hr = pMmcDisplay->put_CoClassCLSID(CLSID_DfsSnapinScopeManager);
  263. if (S_OK != hr)
  264. {
  265. return(hr);
  266. }
  267. hr = pMmcDisplay->QueryInterface(IID_IDataObject, (void **)o_ppDataObject);
  268. return hr;
  269. }
  270. STDMETHODIMP
  271. CDfsSnapinScopeManager::GetDisplayInfo(
  272. IN OUT SCOPEDATAITEM* io_pScopeDataItem
  273. )
  274. /*++
  275. Routine Description:
  276. Returns the display information being asked for by MMC.
  277. Arguments:
  278. io_pScopeDataItem - Contains details about what information is being asked for.
  279. The information being asked in returned in this object itself.
  280. Return value:
  281. S_OK, On success
  282. E_INVALIDARG, On incorrect input parameters
  283. HRESULT sent by methods called, if it is not S_OK.
  284. --*/
  285. {
  286. RETURN_INVALIDARG_IF_NULL(io_pScopeDataItem);
  287. // This (cookie) is null for static node.
  288. // Static node display name is returned through IDataObject Clipboard.
  289. if (NULL == io_pScopeDataItem->lParam)
  290. {
  291. return(S_OK);
  292. }
  293. // Get display object. We had stored this while creating the object
  294. CMmcDisplay* pCMmcDisplayObj = reinterpret_cast<CMmcDisplay*>(io_pScopeDataItem->lParam);
  295. // Calling the virtual method in the base class
  296. HRESULT hr = pCMmcDisplayObj->GetScopeDisplayInfo(io_pScopeDataItem);
  297. RETURN_IF_FAILED(hr);
  298. return S_OK;
  299. }
  300. STDMETHODIMP
  301. CDfsSnapinScopeManager::CompareObjects(
  302. IN LPDATAOBJECT lpDataObjectA,
  303. IN LPDATAOBJECT lpDataObjectB
  304. )
  305. {
  306. if (NULL == lpDataObjectA || NULL == lpDataObjectB)
  307. {
  308. return(S_FALSE);
  309. }
  310. HRESULT hr = S_FALSE;
  311. CMmcDisplay* pMmcDisplayA = NULL;
  312. CMmcDisplay* pMmcDisplayB = NULL;
  313. FORMATETC fmte = {
  314. CMmcDisplay::mMMC_CF_Dfs_Snapin_Internal,
  315. NULL,
  316. DVASPECT_CONTENT,
  317. -1,
  318. TYMED_HGLOBAL
  319. };
  320. STGMEDIUM medium = {
  321. TYMED_HGLOBAL,
  322. NULL,
  323. NULL
  324. };
  325. // Get the this pointer of the display object using private clipboard format.
  326. medium.hGlobal = ::GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE | GMEM_NODISCARD,
  327. (sizeof(ULONG_PTR)));
  328. if (medium.hGlobal == NULL)
  329. {
  330. return STG_E_MEDIUMFULL;
  331. }
  332. hr = lpDataObjectA->GetDataHere(&fmte, &medium);
  333. RETURN_IF_FAILED(hr);
  334. ULONG_PTR* pulVal = (ULONG_PTR*) (GlobalLock(medium.hGlobal));
  335. pMmcDisplayA = reinterpret_cast<CMmcDisplay *>(*pulVal);
  336. GlobalUnlock(medium.hGlobal);
  337. hr = lpDataObjectB->GetDataHere(&fmte, &medium);
  338. RETURN_IF_FAILED(hr);
  339. pulVal = (ULONG_PTR*) (GlobalLock(medium.hGlobal));
  340. pMmcDisplayB = reinterpret_cast<CMmcDisplay *>(*pulVal);
  341. GlobalUnlock(medium.hGlobal);
  342. GlobalFree(medium.hGlobal);
  343. if (pMmcDisplayA == pMmcDisplayB)
  344. {
  345. return(S_OK);
  346. }
  347. else
  348. {
  349. return (S_FALSE);
  350. }
  351. }
  352. STDMETHODIMP
  353. CDfsSnapinScopeManager::GetDisplayObject(
  354. IN LPDATAOBJECT i_lpDataObject,
  355. OUT CMmcDisplay** o_ppMmcDisplay
  356. )
  357. /*++
  358. Routine Description:
  359. Get the Display Object from the IDataObject. This is a derived object that is used for a
  360. lot of purposes
  361. Arguments:
  362. i_lpDataObject - The IDataObject pointer which is used to get the DisplayObject.
  363. o_ppMmcDisplay - The MmcDisplayObject written by us. Used as a callback for Mmc
  364. related display operations.
  365. --*/
  366. {
  367. RETURN_INVALIDARG_IF_NULL(i_lpDataObject);
  368. RETURN_INVALIDARG_IF_NULL(o_ppMmcDisplay);
  369. HRESULT hr = E_FAIL;
  370. *o_ppMmcDisplay = NULL;
  371. FORMATETC fmte = {
  372. CMmcDisplay::mMMC_CF_Dfs_Snapin_Internal,
  373. NULL,
  374. DVASPECT_CONTENT,
  375. -1,
  376. TYMED_HGLOBAL
  377. };
  378. STGMEDIUM medium = {
  379. TYMED_HGLOBAL,
  380. NULL,
  381. NULL
  382. };
  383. // Get the this pointer of the display object using private clipboard format.
  384. medium.hGlobal = ::GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE | GMEM_NODISCARD,
  385. (sizeof(ULONG_PTR)));
  386. if (medium.hGlobal == NULL)
  387. {
  388. return STG_E_MEDIUMFULL;
  389. }
  390. hr = i_lpDataObject->GetDataHere(&fmte, &medium);
  391. RETURN_IF_FAILED(hr);
  392. ULONG_PTR* pulVal = (ULONG_PTR*) (GlobalLock(medium.hGlobal));
  393. *o_ppMmcDisplay = reinterpret_cast<CMmcDisplay *>(*pulVal);
  394. GlobalUnlock(medium.hGlobal);
  395. GlobalFree(medium.hGlobal);
  396. return hr;
  397. }
  398. STDMETHODIMP
  399. CDfsSnapinScopeManager::HandleCommandLineParameters(
  400. )
  401. /*++
  402. Routine Description:
  403. check if any command line parameters are passed to us and if so take appropriate
  404. action.
  405. Currently suuported parameters:
  406. \DfsRoot:DfsRootName ,
  407. where DfsRootName can be ComputerName\DfsRootName or DomainName\DfsRootName
  408. Arguments:
  409. None
  410. Return value:
  411. S_OK, if successful.
  412. Any error returned by called methods
  413. --*/
  414. {
  415. HRESULT hr = E_FAIL;
  416. LPTSTR szCommandLine = ::GetCommandLine();
  417. CComBSTR bstrCommandLine = szCommandLine;
  418. LPCTSTR szSeparators = _T(" ,\t");
  419. LPTSTR szCurrentParameter = NULL;
  420. CComBSTR bstrParameterPrefix;
  421. hr = LoadStringFromResource(IDS_COMMANDLINE_PARAMETER_PREFIX, &bstrParameterPrefix);
  422. RETURN_IF_FAILED(hr);
  423. szCurrentParameter = _tcstok(bstrCommandLine, szSeparators);
  424. while(szCurrentParameter)
  425. {
  426. ATLTRACE(_T("\nCommand line parameter = %s\n"), szCurrentParameter);
  427. // Check if this token contains the required prefix
  428. if (0 == mylstrncmpi(szCurrentParameter, bstrParameterPrefix, bstrParameterPrefix.Length()) )
  429. {
  430. LPTSTR szParamValue = _tcschr(szCurrentParameter, bstrParameterPrefix.m_str[bstrParameterPrefix.Length() - 1]);
  431. if (NULL != szParamValue)
  432. {
  433. szParamValue++; // Skip the ':'
  434. if (NULL != szParamValue) // Check again just to be sure
  435. {
  436. hr = m_pMmcDfsAdmin->AddDfsRoot(szParamValue); // Add the dfsroot to the console
  437. // Ignoring the return value right now as we want to handle the remaining parameters
  438. }
  439. } // if (NULL != szParamValue)
  440. }
  441. // Get the next token
  442. szCurrentParameter = _tcstok(NULL, szSeparators);
  443. }
  444. return S_OK;
  445. }