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.

539 lines
15 KiB

  1. // toolbar.cpp : Implementation of toolbars for snapin
  2. #include "stdafx.h"
  3. #include "cookie.h"
  4. #include "cmponent.h"
  5. #include "compdata.h"
  6. #include "dataobj.h"
  7. #include <compuuid.h> // UUIDs for Computer Management
  8. #include "macros.h"
  9. USE_HANDLE_MACROS("FILEMGMT(toolbar.cpp)")
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  16. // We keep the strings in globals because multiple IComponents will all
  17. // have their own IToolbars. We do not keep the bitmaps in globals because
  18. // of difficulties with the global destruction mechanism, see compdata.h.
  19. // The MMCBUTTON structures contain resource IDs for the strings which will
  20. // be loaded into the CString array when the first instance of the toolbar
  21. // is loaded.
  22. //
  23. // CODEWORK We need a mechanism to free these strings.
  24. MMCBUTTON g_FileMgmtSnapinButtons[] =
  25. {
  26. { 0, IDS_BUTTON_NEWSHARE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  27. };
  28. CString* g_astrFileMgmtButtonStrings = NULL; // dynamic array of CStrings
  29. BOOL g_bLoadedFileMgmtStrings = FALSE;
  30. MMCBUTTON g_SvcMgmtSnapinButtons[] =
  31. {
  32. // The first button will be either Start or Resume.
  33. // One of these two entries will be removed later.
  34. { 0, cmServiceResume, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  35. { 0, cmServiceStart, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  36. { 1, cmServiceStop, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  37. { 2, cmServicePause, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  38. { 3, cmServiceRestart, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  39. };
  40. CString* g_astrSvcMgmtButtonStrings = NULL; // dynamic array of CStrings
  41. BOOL g_bLoadedSvcMgmtStrings = FALSE;
  42. void LoadButtonArray(
  43. MMCBUTTON* pButtonArray,
  44. BOOL* pbLoadedStrings,
  45. CString** pastrStringArray,
  46. UINT cButtons
  47. )
  48. {
  49. ASSERT( NULL != pbLoadedStrings &&
  50. NULL != pButtonArray &&
  51. NULL != pastrStringArray);
  52. if ( !*pbLoadedStrings )
  53. {
  54. // load strings
  55. MMCBUTTON* pLoadButtonArray = pButtonArray;
  56. UINT cLoadButtons = cButtons;
  57. *pastrStringArray = new CString[2*cButtons];
  58. for (UINT i = 0; i < cButtons; i++)
  59. {
  60. UINT iButtonTextId = 0, iTooltipTextId = 0;
  61. switch (pButtonArray[i].idCommand)
  62. {
  63. case IDS_BUTTON_NEWSHARE:
  64. iButtonTextId = IDS_BUTTON_NEWSHARE;
  65. iTooltipTextId = IDS_TOOLTIP_NEWSHARE;
  66. break;
  67. case cmServiceResume:
  68. iButtonTextId = IDS_BUTTON_SERVICE_RESUME;
  69. iTooltipTextId = IDS_TOOLTIP_SERVICE_RESUME;
  70. break;
  71. case cmServiceStart:
  72. iButtonTextId = IDS_BUTTON_SERVICE_START;
  73. iTooltipTextId = IDS_TOOLTIP_SERVICE_START;
  74. break;
  75. case cmServiceStop:
  76. iButtonTextId = IDS_BUTTON_SERVICE_STOP;
  77. iTooltipTextId = IDS_TOOLTIP_SERVICE_STOP;
  78. break;
  79. case cmServicePause:
  80. iButtonTextId = IDS_BUTTON_SERVICE_PAUSE;
  81. iTooltipTextId = IDS_TOOLTIP_SERVICE_PAUSE;
  82. break;
  83. case cmServiceRestart:
  84. iButtonTextId = IDS_BUTTON_SERVICE_RESTART;
  85. iTooltipTextId = IDS_TOOLTIP_SERVICE_RESTART;
  86. break;
  87. default:
  88. ASSERT(FALSE);
  89. break;
  90. }
  91. VERIFY( (*pastrStringArray)[i*2].LoadString(iButtonTextId) );
  92. pButtonArray[i].lpButtonText =
  93. const_cast<BSTR>((LPCTSTR)((*pastrStringArray)[i*2]));
  94. VERIFY( (*pastrStringArray)[(i*2)+1].LoadString(iTooltipTextId) );
  95. pButtonArray[i].lpTooltipText =
  96. const_cast<BSTR>((LPCTSTR)((*pastrStringArray)[(i*2)+1]));
  97. }
  98. *pbLoadedStrings = TRUE;
  99. }
  100. }
  101. HRESULT LoadToolbar(
  102. LPTOOLBAR pToolbar,
  103. CBitmap& refbitmap,
  104. MMCBUTTON* pButtonArray,
  105. UINT cButtons
  106. )
  107. {
  108. ASSERT( NULL != pToolbar &&
  109. NULL != pButtonArray );
  110. HRESULT hr = pToolbar->AddBitmap(cButtons, refbitmap, 16, 16, RGB(255,0,255) );
  111. if ( FAILED(hr) )
  112. {
  113. ASSERT(FALSE);
  114. return hr;
  115. }
  116. hr = pToolbar->AddButtons(cButtons, pButtonArray);
  117. if ( FAILED(hr) )
  118. {
  119. ASSERT(FALSE);
  120. return hr;
  121. }
  122. return hr;
  123. }
  124. STDMETHODIMP CFileMgmtComponent::SetControlbar(LPCONTROLBAR pControlbar)
  125. {
  126. MFC_TRY;
  127. SAFE_RELEASE(m_pControlbar); // just in case
  128. if (NULL != pControlbar)
  129. {
  130. m_pControlbar = pControlbar; // CODEWORK should use smartpointer
  131. m_pControlbar->AddRef();
  132. }
  133. return S_OK;
  134. MFC_CATCH;
  135. }
  136. STDMETHODIMP CFileMgmtComponent::ControlbarNotify(MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  137. {
  138. MFC_TRY;
  139. #ifdef SNAPIN_PROTOTYPER
  140. return S_OK;
  141. #endif
  142. HRESULT hr=S_OK;
  143. switch (event)
  144. {
  145. case MMCN_BTN_CLICK:
  146. TRACE(_T("CFileMgmtComponent::ControlbarNotify - MMCN_BTN_CLICK\n"));
  147. {
  148. LPDATAOBJECT pDataObject = reinterpret_cast<LPDATAOBJECT>(arg);
  149. UINT idButton = (UINT)param;
  150. hr = OnToolbarButton( pDataObject, idButton );
  151. }
  152. break;
  153. case MMCN_SELECT:
  154. TRACE(_T("CFileMgmtComponent::ControlbarNotify - MMCN_SELECT\n"));
  155. {
  156. if (!(LOWORD(arg))) // bScope
  157. {
  158. // result pane
  159. hr = UpdateToolbar(
  160. reinterpret_cast<LPDATAOBJECT>(param),
  161. !!(HIWORD(arg)) );
  162. }
  163. else
  164. {
  165. // scope pane
  166. hr = AddToolbar( reinterpret_cast<LPDATAOBJECT>(param),
  167. !!(HIWORD(arg)) );
  168. }
  169. }
  170. break;
  171. default:
  172. ASSERT(FALSE); // Unhandled event
  173. }
  174. return hr;
  175. MFC_CATCH;
  176. }
  177. HRESULT CFileMgmtComponent::ServiceToolbarButtonState(
  178. LPDATAOBJECT pServiceDataObject,
  179. BOOL fSelected )
  180. {
  181. BOOL rgfMenuFlags[iServiceActionMax];
  182. for (INT i = 0; i < iServiceActionMax; i++)
  183. rgfMenuFlags[i] = FALSE;
  184. if ( fSelected )
  185. {
  186. CString strMachineName;
  187. CString strServiceName;
  188. if (!QueryComponentDataRef().Service_FGetServiceInfoFromIDataObject(
  189. pServiceDataObject,
  190. OUT &strMachineName,
  191. OUT &strServiceName,
  192. NULL))
  193. {
  194. ASSERT(FALSE);
  195. }
  196. else
  197. {
  198. if (strMachineName.IsEmpty())
  199. strMachineName = g_strLocalMachine;
  200. // Get the menu flags
  201. {
  202. ASSERT(NULL != QueryComponentDataRef().m_hScManager);
  203. CWaitCursor wait;
  204. if (!Service_FGetServiceButtonStatus( // this will report errors itself
  205. QueryComponentDataRef().m_hScManager,
  206. strServiceName,
  207. OUT rgfMenuFlags,
  208. NULL, // pdwCurrentState
  209. TRUE)) // fSilentError
  210. {
  211. // let's not do this m_hScManager = NULL;
  212. }
  213. }
  214. }
  215. }
  216. // update toolbar
  217. ASSERT( NULL != m_pSvcMgmtToolbar );
  218. //
  219. // JonN 5/2/00 106431:
  220. // Services snapin calls DeleteButton with an index but never called InsertButton
  221. //
  222. // HRESULT hr = m_pSvcMgmtToolbar->DeleteButton(0);
  223. // if ( FAILED(hr) )
  224. // return hr;
  225. HRESULT hr = S_OK;
  226. // JonN 3/15/01 210065
  227. // Services snapin: "Resume service" toolbar button stays enabled after it is first displayed
  228. BOOL fShowResumeButton = !rgfMenuFlags[iServiceActionStart] &&
  229. rgfMenuFlags[iServiceActionResume];
  230. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  231. cmServiceStart, HIDDEN, fShowResumeButton)));
  232. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  233. cmServiceResume, HIDDEN, !fShowResumeButton)));
  234. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  235. cmServiceStart, ENABLED, rgfMenuFlags[iServiceActionStart])));
  236. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  237. cmServiceResume, ENABLED, rgfMenuFlags[iServiceActionResume])));
  238. hr = m_pSvcMgmtToolbar->SetButtonState(
  239. cmServiceStop, ENABLED, rgfMenuFlags[iServiceActionStop] );
  240. if ( FAILED(hr) )
  241. return hr;
  242. hr = m_pSvcMgmtToolbar->SetButtonState(
  243. cmServicePause, ENABLED, rgfMenuFlags[iServiceActionPause] );
  244. if ( FAILED(hr) )
  245. return hr;
  246. hr = m_pSvcMgmtToolbar->SetButtonState(
  247. cmServiceRestart, ENABLED, rgfMenuFlags[iServiceActionRestart] );
  248. return hr;
  249. }
  250. // CODEWORK The following algorithm is imperfect, but will do
  251. // for now. We ignore the old selection, and attach
  252. // our fixed toolbar iff the new selection is our type.
  253. HRESULT CFileMgmtComponent::AddToolbar(LPDATAOBJECT pdoScopeIsSelected,
  254. BOOL fSelected)
  255. {
  256. HRESULT hr = S_OK;
  257. int i = 0;
  258. GUID guidSelectedObject;
  259. do { // false loop
  260. if (NULL == pdoScopeIsSelected)
  261. {
  262. // toolbar will be automatically detached
  263. return S_OK;
  264. }
  265. if ( FAILED(ExtractObjectTypeGUID(pdoScopeIsSelected,
  266. &guidSelectedObject)) )
  267. {
  268. ASSERT(FALSE); // shouldn't have given me non-MMC data object
  269. return S_OK;
  270. }
  271. if (NULL == m_pControlbar)
  272. {
  273. ASSERT(FALSE);
  274. return S_OK;
  275. }
  276. #ifdef DEBUG
  277. if ( QueryComponentDataRef().IsExtendedNodetype(guidSelectedObject) )
  278. {
  279. ASSERT(FALSE && "shouldn't have given me extension parent nodetype");
  280. return S_OK;
  281. }
  282. #endif
  283. switch (CheckObjectTypeGUID( &guidSelectedObject ) )
  284. {
  285. case FILEMGMT_SHARES:
  286. if (QueryComponentDataRef().GetIsSimpleUI() || IsServiceSnapin())
  287. break;
  288. if (NULL == m_pFileMgmtToolbar)
  289. {
  290. hr = m_pControlbar->Create(
  291. TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&m_pFileMgmtToolbar) );
  292. if ( FAILED(hr) )
  293. {
  294. ASSERT(FALSE);
  295. break;
  296. }
  297. ASSERT(NULL != m_pFileMgmtToolbar);
  298. if ( !QueryComponentDataRef().m_fLoadedFileMgmtToolbarBitmap )
  299. {
  300. VERIFY( QueryComponentDataRef().m_bmpFileMgmtToolbar.LoadBitmap(
  301. IDB_FILEMGMT_TOOLBAR ) );
  302. QueryComponentDataRef().m_fLoadedFileMgmtToolbarBitmap = TRUE;
  303. }
  304. LoadButtonArray(
  305. g_FileMgmtSnapinButtons,
  306. &g_bLoadedFileMgmtStrings,
  307. &g_astrFileMgmtButtonStrings,
  308. ARRAYLEN(g_FileMgmtSnapinButtons)
  309. );
  310. hr = LoadToolbar(
  311. m_pFileMgmtToolbar,
  312. QueryComponentDataRef().m_bmpFileMgmtToolbar,
  313. g_FileMgmtSnapinButtons,
  314. ARRAYLEN(g_FileMgmtSnapinButtons)
  315. );
  316. }
  317. if (FAILED(hr))
  318. break;
  319. // New Share is always enabled
  320. VERIFY( SUCCEEDED(m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pFileMgmtToolbar)) );
  321. for (i = 0; i < ARRAYLEN(g_FileMgmtSnapinButtons); i++) {
  322. m_pFileMgmtToolbar->SetButtonState(
  323. g_FileMgmtSnapinButtons[i].idCommand,
  324. ENABLED,
  325. fSelected);
  326. }
  327. break;
  328. case FILEMGMT_SERVICES:
  329. if ( !IsServiceSnapin() )
  330. break;
  331. if (NULL == m_pSvcMgmtToolbar)
  332. {
  333. hr = m_pControlbar->Create(
  334. TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&m_pSvcMgmtToolbar) );
  335. if ( FAILED(hr) )
  336. {
  337. ASSERT(FALSE);
  338. break;
  339. }
  340. ASSERT(NULL != m_pSvcMgmtToolbar);
  341. if ( !QueryComponentDataRef().m_fLoadedSvcMgmtToolbarBitmap )
  342. {
  343. VERIFY( QueryComponentDataRef().m_bmpSvcMgmtToolbar.LoadBitmap(
  344. IDB_SVCMGMT_TOOLBAR ) );
  345. QueryComponentDataRef().m_fLoadedSvcMgmtToolbarBitmap = TRUE;
  346. }
  347. LoadButtonArray(
  348. g_SvcMgmtSnapinButtons,
  349. &g_bLoadedSvcMgmtStrings,
  350. &g_astrSvcMgmtButtonStrings,
  351. ARRAYLEN(g_SvcMgmtSnapinButtons)
  352. );
  353. // JonN 3/15/01 210065
  354. // "Resume service" toolbar button stays enabled after it is first displayed
  355. hr = LoadToolbar(
  356. m_pSvcMgmtToolbar,
  357. QueryComponentDataRef().m_bmpSvcMgmtToolbar,
  358. g_SvcMgmtSnapinButtons,
  359. ARRAYLEN(g_SvcMgmtSnapinButtons)
  360. );
  361. }
  362. if (FAILED(hr))
  363. break;
  364. VERIFY( SUCCEEDED(m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pSvcMgmtToolbar)) );
  365. break;
  366. case FILEMGMT_ROOT:
  367. case FILEMGMT_SESSIONS:
  368. case FILEMGMT_RESOURCES:
  369. if (m_pControlbar && m_pFileMgmtToolbar)
  370. {
  371. m_pControlbar->Detach(m_pFileMgmtToolbar);
  372. }
  373. break;
  374. #ifdef SNAPIN_PROTOTYPER
  375. case FILEMGMT_PROTOTYPER:
  376. break; // no toolbar
  377. case FILEMGMT_PROTOTYPER_LEAF:
  378. break; // no toolbar
  379. #endif
  380. default:
  381. ASSERT(FALSE); // unknown type
  382. break;
  383. }
  384. } while (FALSE); // false loop
  385. return hr;
  386. }
  387. HRESULT CFileMgmtComponent::UpdateToolbar(
  388. LPDATAOBJECT pdoResultIsSelected,
  389. BOOL fSelected )
  390. {
  391. int i = 0;
  392. GUID guidSelectedObject;
  393. HRESULT hr = S_OK;
  394. BOOL bMultiSelectObject = IsMultiSelectObject(pdoResultIsSelected);
  395. if (bMultiSelectObject)
  396. {
  397. //
  398. // pdoResultIsSelected is the composite data object (MMC_MS_DO) created by MMC.
  399. // We need to crack it to retrieve the multiselect data object (SI_MS_DO)
  400. // we provided to MMC in QueryDataObject().
  401. //
  402. IDataObject *piSIMSDO = NULL;
  403. hr = GetSnapinMultiSelectDataObject(pdoResultIsSelected, &piSIMSDO);
  404. if (SUCCEEDED(hr))
  405. {
  406. CFileMgmtDataObject *pDataObj = NULL;
  407. hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj));
  408. if (SUCCEEDED(hr))
  409. {
  410. //
  411. // get the internal list of data objects of selected items, operate on one of them.
  412. //
  413. CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList();
  414. ASSERT(!pMultiSelectObjList->empty());
  415. hr = ExtractObjectTypeGUID(*(pMultiSelectObjList->begin()), &guidSelectedObject);
  416. }
  417. piSIMSDO->Release();
  418. }
  419. } else
  420. {
  421. hr = ExtractObjectTypeGUID(pdoResultIsSelected, &guidSelectedObject);
  422. }
  423. if (FAILED(hr)) // shouldn't have given me non-MMC data object
  424. return hr;
  425. int objecttype = CheckObjectTypeGUID( &guidSelectedObject );
  426. switch (objecttype)
  427. {
  428. case FILEMGMT_SERVICE:
  429. ServiceToolbarButtonState( pdoResultIsSelected, fSelected );
  430. break;
  431. case FILEMGMT_SHARES:
  432. if (m_pControlbar && m_pFileMgmtToolbar && !QueryComponentDataRef().GetIsSimpleUI())
  433. {
  434. m_pControlbar->Attach(TOOLBAR, m_pFileMgmtToolbar);
  435. for (i = 0; i < ARRAYLEN(g_FileMgmtSnapinButtons); i++) {
  436. m_pFileMgmtToolbar->SetButtonState(
  437. g_FileMgmtSnapinButtons[i].idCommand,
  438. ENABLED,
  439. fSelected);
  440. }
  441. }
  442. break;
  443. case FILEMGMT_SHARE:
  444. case FILEMGMT_SESSIONS:
  445. case FILEMGMT_RESOURCES:
  446. if (m_pControlbar && m_pFileMgmtToolbar)
  447. {
  448. m_pControlbar->Detach(m_pFileMgmtToolbar);
  449. }
  450. case FILEMGMT_SESSION:
  451. case FILEMGMT_RESOURCE:
  452. break;
  453. default:
  454. break;
  455. }
  456. return S_OK;
  457. }
  458. HRESULT CFileMgmtComponent::OnToolbarButton(LPDATAOBJECT pDataObject, UINT idButton)
  459. {
  460. switch (idButton)
  461. {
  462. case IDS_BUTTON_NEWSHARE:
  463. {
  464. BOOL fRefresh = QueryComponentDataRef().NewShare( pDataObject );
  465. if (fRefresh)
  466. {
  467. // JonN 12/03/98 updated to use new method
  468. VERIFY(SUCCEEDED( RefreshAllViews(pDataObject) ));
  469. }
  470. }
  471. break;
  472. case cmServiceStart:
  473. case cmServiceStop:
  474. case cmServicePause:
  475. case cmServiceResume:
  476. case cmServiceRestart:
  477. VERIFY( SUCCEEDED(Command(idButton, pDataObject)) );
  478. break;
  479. default:
  480. ASSERT(FALSE);
  481. break;
  482. }
  483. return S_OK;
  484. }