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.

449 lines
14 KiB

  1. /*======================================================================================//
  2. | Process Control //
  3. | //
  4. |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. //
  5. | //
  6. |File Name: JobFolder.cpp //
  7. | //
  8. |Description: Implementation of Job List node //
  9. | //
  10. |Created: Paul Skoglund 08-1998 //
  11. | //
  12. |Rev History: //
  13. | //
  14. |=======================================================================================*/
  15. #include "StdAfx.h"
  16. #include "BaseNode.h"
  17. #include "JobPages.h"
  18. #include "ManagementPages.h"
  19. #include "ManagementRuleWizards.h"
  20. #pragma warning(push)
  21. #include <algorithm>
  22. #pragma warning(pop)
  23. using std::list<PCJobListItem*>;
  24. using std::list<CBaseNode *>;
  25. using std::find;
  26. const GUID CJobFolder::m_GUID = {0xff9baf62,0x064e,0x11d2,{0x80, 0x14,0x00,0x10,0x4b,0x9a,0x31,0x06} };
  27. const TCHAR *const CJobFolder::m_szGUID = _T("{ff9baf62-064e-11d2-8014-00104b9a3106}");
  28. const CONTEXTMENUITEMBYID CJobFolder::ViewMenuItems[] =
  29. {
  30. { IDS_JOBVIEW_ALL, ID_JOBVIEW_ALL, ID_JOBVIEW_ALL, CCM_INSERTIONPOINTID_PRIMARY_VIEW },
  31. { IDS_JOBVIEW_RUN, ID_JOBVIEW_RUN, ID_JOBVIEW_RUN, CCM_INSERTIONPOINTID_PRIMARY_VIEW },
  32. { IDS_JOBVIEW_MANAGED, ID_JOBVIEW_MANAGED, ID_JOBVIEW_MANAGED, CCM_INSERTIONPOINTID_PRIMARY_VIEW },
  33. { 0, 0, 0, 0 }
  34. };
  35. CJobFolder::CJobFolder(CBaseNode *pParent) : CBaseNode(JOB_NODE, pParent), m_ID(0), m_fViewOption(ID_JOBVIEW_ALL)
  36. {
  37. LoadStringHelper(m_name, IDS_JOBS_FOLDER);
  38. }
  39. CJobFolder::~CJobFolder()
  40. {
  41. FreeNodes();
  42. ATLTRACE( _T("~CJobFolder end\n"));
  43. }
  44. void CJobFolder::FreeNodes()
  45. {
  46. ATLTRACE( _T("CJobFolder::FreeNodes()\n"));
  47. for (list<CBaseNode *>::iterator i = m_NodeList.begin(); i != m_NodeList.end(); ++i)
  48. {
  49. (*i)->Release();
  50. }
  51. m_NodeList.clear();
  52. }
  53. LPCTSTR CJobFolder::GetNodeName()
  54. {
  55. return m_name;
  56. }
  57. HRESULT CJobFolder::GetDisplayInfo(RESULTDATAITEM &ResultItem)
  58. {
  59. if (ResultItem.bScopeItem)
  60. {
  61. if( ResultItem.mask & RDI_STR )
  62. {
  63. if (0 == ResultItem.nCol)
  64. ResultItem.str = const_cast<LPOLESTR>(GetNodeName());
  65. else
  66. ResultItem.str = _T("");
  67. }
  68. if (ResultItem.mask & RDI_IMAGE)
  69. ResultItem.nImage = sImage();
  70. return S_OK;
  71. }
  72. ASSERT(FALSE);
  73. return E_UNEXPECTED;
  74. }
  75. HRESULT CJobFolder::OnExpand(BOOL bExpand, HSCOPEITEM hItem, IConsoleNameSpace2 *ipConsoleNameSpace2)
  76. {
  77. if (bExpand)
  78. {
  79. ASSERT(m_ID == hItem);
  80. RePopulateScopePane(ipConsoleNameSpace2);
  81. }
  82. return S_OK;
  83. }
  84. HRESULT CJobFolder::AddNode(IConsoleNameSpace2 *ipConsoleNameSpace2, CBaseNode *pSubNode)
  85. {
  86. HRESULT hr = S_OK;
  87. SCOPEDATAITEM sdi = {0};
  88. if (!pSubNode)
  89. return E_OUTOFMEMORY;
  90. // Place items into the scope pane
  91. sdi.mask = SDI_STR | // Displayname is valid
  92. SDI_PARAM | // lParam is valid
  93. SDI_IMAGE | // nImage is valid
  94. SDI_OPENIMAGE | // nOpenImage is valid
  95. SDI_CHILDREN | // cChildren is valid
  96. SDI_PARENT;
  97. sdi.displayname = (LPOLESTR)MMC_CALLBACK;
  98. sdi.nImage = pSubNode->sImage();
  99. sdi.nOpenImage = pSubNode->sOpenImage();
  100. //sdi.nState = ???
  101. sdi.cChildren = pSubNode->GetChildrenCount();
  102. sdi.lParam = reinterpret_cast <LPARAM> (pSubNode);
  103. sdi.relativeID = m_ID;
  104. hr = ipConsoleNameSpace2->InsertItem( &sdi );
  105. if (SUCCEEDED(hr))
  106. {
  107. pSubNode->SetID(sdi.ID);
  108. m_NodeList.push_front( pSubNode );
  109. }
  110. else
  111. {
  112. pSubNode->Release();
  113. }
  114. return hr;
  115. }
  116. HRESULT CJobFolder::OnShow(BOOL bSelecting, HSCOPEITEM hItem, IHeaderCtrl2* ipHeaderCtrl,
  117. IConsole2 *ipConsole2, IConsoleNameSpace2 *ipConsoleNameSpace2)
  118. {
  119. ASSERT(hItem == GetID());
  120. if (!bSelecting)
  121. return S_OK;
  122. ITEM_STR str;
  123. LoadStringHelper(str, IDS_JOB_HDR);
  124. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( JOB_COLUMN, str, 0, JOB_COLUMN_WIDTH ));
  125. LoadStringHelper(str, IDS_STATUS_HDR);
  126. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( STATUS_COLUMN, str, 0, STATUS_COLUMN_WIDTH ));
  127. LoadStringHelper(str, IDS_ACTIVE_PROCESS_COUNT_HDR);
  128. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( ACTIVE_PROCESS_COUNT_COLUMN, str, 0, ACTIVE_PROCESS_COUNT_COLUMN_WIDTH ));
  129. LoadStringHelper(str, IDS_AFFINITY_HDR);
  130. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( AFFINITY_COLUMN, str, 0, AFFINITY_COLUMN_WIDTH ));
  131. LoadStringHelper(str, IDS_PRIORITY_HDR);
  132. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PRIORITY_COLUMN, str, 0, PRIORITY_COLUMN_WIDTH ));
  133. LoadStringHelper(str, IDS_SCHEDULING_CLASS_HDR);
  134. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( SCHEDULING_CLASS_COLUMN, str, 0, SCHEDULING_CLASS_COLUMN_WIDTH ));
  135. LoadStringHelper(str, IDS_USER_TIME_HDR);
  136. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( USER_TIME_COLUMN, str, 0, USER_TIME_COLUMN_WIDTH ));
  137. LoadStringHelper(str, IDS_KERNEL_TIME_HDR);
  138. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( KERNEL_TIME_COLUMN, str, 0, KERNEL_TIME_COLUMN_WIDTH ));
  139. LoadStringHelper(str, IDS_PERIOD_USER_TIME_HDR);
  140. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PERIOD_USER_TIME_COLUMN, str, 0, PERIOD_USER_TIME_COLUMN_WIDTH ));
  141. LoadStringHelper(str, IDS_PERIOD_KERNEL_TIME_HDR);
  142. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PERIOD_KERNEL_TIME_COLUMN, str, 0, PERIOD_KERNEL_TIME_COLUMN_WIDTH ));
  143. LoadStringHelper(str, IDS_PAGE_FAULT_COUNT_HDR);
  144. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PAGE_FAULT_COUNT_COLUMN, str, 0, PAGE_FAULT_COUNT_COLUMN_WIDTH ));
  145. LoadStringHelper(str, IDS_PROCESS_COUNT_HDR);
  146. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PROCESS_COUNT_COLUMN, str, 0, PROCESS_COUNT_COLUMN_WIDTH ));
  147. LoadStringHelper(str, IDS_TERMINATED_PROCESS_COUNT_HDR);
  148. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( TERMINATED_PROCESS_COUNT_COLUMN, str, 0, TERMINATED_PROCESS_COUNT_COLUMN_WIDTH ));
  149. LoadStringHelper(str, IDS_READOP_COUNT_HDR);
  150. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( READOP_COUNT_COLUMN, str, 0, READOP_COUNT_COLUMN_WIDTH ));
  151. LoadStringHelper(str, IDS_WRITEOP_COUNT_HDR);
  152. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( WRITEOP_COUNT_COLUMN, str, 0, WRITEOP_COUNT_COLUMN_WIDTH ));
  153. LoadStringHelper(str, IDS_OTHEROP_COUNT_HDR);
  154. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( OTHEROP_COUNT_COLUMN, str, 0, OTHEROP_COUNT_COLUMN_WIDTH ));
  155. LoadStringHelper(str, IDS_READTRANS_COUNT_HDR);
  156. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( READTRANS_COUNT_COLUMN, str, 0, READTRANS_COUNT_COLUMN_WIDTH ));
  157. LoadStringHelper(str, IDS_WRITETRANS_COUNT_HDR);
  158. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( WRITETRANS_COUNT_COLUMN, str, 0, WRITETRANS_COUNT_COLUMN_WIDTH ));
  159. LoadStringHelper(str, IDS_OTHERTRANS_COUNT_HDR);
  160. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( OTHERTRANS_COUNT_COLUMN, str, 0, OTHERTRANS_COUNT_COLUMN_WIDTH ));
  161. LoadStringHelper(str, IDS_PEAK_PROC_MEM_HDR);
  162. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PEAK_PROC_MEM_COLUMN, str, 0, PEAK_PROC_MEM_COLUMN_WIDTH ));
  163. LoadStringHelper(str, IDS_PEAK_JOB_MEM_HDR);
  164. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PEAK_JOB_MEM_COLUMN, str, 0, PEAK_JOB_MEM_COLUMN_WIDTH ));
  165. return OnRefresh(ipConsole2, ipConsoleNameSpace2);
  166. }
  167. HRESULT CJobFolder::AddMenuItems(LPCONTEXTMENUCALLBACK piCallback, long * pInsertionAllowed)
  168. {
  169. HRESULT hr = S_OK;
  170. ITEM_STR name;
  171. ITEM_STR status;
  172. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  173. {
  174. CONTEXTMENUITEM m = { 0 };
  175. for (const CONTEXTMENUITEMBYID *M = ViewMenuItems; M->lCommandID; M++)
  176. {
  177. m.strName = const_cast<TCHAR *>(LoadStringHelper(name, M->strNameID));
  178. m.strStatusBarText = const_cast<TCHAR *>(LoadStringHelper(status, M->strStatusBarTextID));
  179. m.lCommandID = M->lCommandID;
  180. m.lInsertionPointID = M->lInsertionPointID;
  181. //m.fSpecialFlags = 0; // currently always 0, initialized to 0
  182. if (m.lCommandID == m_fViewOption)
  183. m.fFlags = MF_CHECKED | MF_ENABLED;
  184. else
  185. m.fFlags = MF_UNCHECKED | MF_ENABLED;
  186. hr = piCallback->AddItem(&m);
  187. if (FAILED(hr))
  188. break;
  189. }
  190. *pInsertionAllowed ^= CCM_INSERTIONALLOWED_VIEW;
  191. }
  192. return hr;
  193. }
  194. HRESULT CJobFolder::AddMenuItems(LPCONTEXTMENUCALLBACK piCallback, long * pInsertionAllowed, LPARAM Cookie)
  195. {
  196. ASSERT(FALSE);
  197. return S_OK;
  198. }
  199. HRESULT CJobFolder::OnMenuCommand(IConsole2 *ipConsole2, IConsoleNameSpace2 *ipConsoleNameSpace2, long nCommandID )
  200. {
  201. switch(nCommandID)
  202. {
  203. case ID_JOBVIEW_RUN:
  204. case ID_JOBVIEW_MANAGED:
  205. case ID_JOBVIEW_ALL:
  206. m_fViewOption = nCommandID;
  207. return OnRefresh(ipConsole2, ipConsoleNameSpace2);
  208. default:
  209. break;
  210. }
  211. return E_UNEXPECTED;
  212. }
  213. HRESULT CJobFolder::OnMenuCommand(IConsole2 *ipConsole2, long nCommandID, LPARAM Cookie )
  214. {
  215. ASSERT(FALSE);
  216. return S_OK;
  217. }
  218. HRESULT CJobFolder::OnHelpCmd(IDisplayHelp *ipDisplayHelp)
  219. {
  220. if (!ipDisplayHelp)
  221. return E_UNEXPECTED;
  222. ipDisplayHelp->ShowTopic(const_cast<TCHAR *>(HELP_jo_overview));
  223. return S_OK;
  224. }
  225. HRESULT CJobFolder::OnSelect(BOOL bScope, BOOL bSelect, IConsoleVerb* ipConsoleVerb)
  226. {
  227. ASSERT(bScope);
  228. if ( bSelect && bScope )
  229. {
  230. ATLTRACE(_T("CJobFolder::OnSelect Scope=%s, Select=%s\n"), bScope ? _T("true") : _T("false"), bSelect ? _T("true") : _T("false"));
  231. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE ) == S_OK);
  232. VERIFY( ipConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN ) == S_OK );
  233. }
  234. return S_OK;
  235. }
  236. HRESULT CJobFolder::OnSelect(BOOL bScope, BOOL bSelect, IConsoleVerb* ipConsoleVerb, LPARAM Cookie)
  237. {
  238. ASSERT(FALSE);
  239. return S_OK;
  240. }
  241. HRESULT CJobFolder::OnViewChange(IResultData *ipResultData, LPARAM thing, LONG_PTR hint)
  242. {
  243. ASSERT(ipResultData);
  244. if (!ipResultData)
  245. return E_UNEXPECTED;
  246. VERIFY(ipResultData->ModifyViewStyle(MMC_SINGLESEL, MMC_NOSORTHEADER) == S_OK);
  247. HRESULT hr = E_UNEXPECTED;
  248. switch (hint)
  249. {
  250. case PC_VIEW_UPDATEALL:
  251. hr = ShowAllItems(ipResultData, FALSE);
  252. break;
  253. case PC_VIEW_REDRAWALL:
  254. case PC_VIEW_ADDITEM:
  255. case PC_VIEW_UPDATEITEM:
  256. case PC_VIEW_SETITEM:
  257. case PC_VIEW_DELETEITEM:
  258. default:
  259. hr = E_UNEXPECTED;
  260. break;
  261. }
  262. ASSERT(hr == S_OK);
  263. return hr;
  264. }
  265. HRESULT CJobFolder::ShowAllItems(IResultData* ipResultData, BOOL bCacheValid)
  266. {
  267. VERIFY( S_OK == ipResultData->DeleteAllRsltItems() );
  268. ITEM_STR str;
  269. if (ID_JOBVIEW_RUN == m_fViewOption)
  270. ipResultData->SetDescBarText(const_cast<TCHAR *>(LoadStringHelper(str, IDS_RUNNING_JOBS)));
  271. else if (ID_JOBVIEW_MANAGED == m_fViewOption)
  272. ipResultData->SetDescBarText(const_cast<TCHAR *>(LoadStringHelper(str, IDS_MANAGED_JOBS)));
  273. else
  274. ipResultData->SetDescBarText(_T(""));
  275. return S_OK;
  276. }
  277. HRESULT CJobFolder::OnRefresh(IConsole2 *ipConsole2, IConsoleNameSpace2 *ipConsoleNameSpace2)
  278. {
  279. RePopulateScopePane(ipConsoleNameSpace2);
  280. return SendViewChange(ipConsole2, NULL, PC_VIEW_UPDATEALL);
  281. }
  282. HRESULT CJobFolder::RePopulateScopePane(IConsoleNameSpace2 *ipConsoleNameSpace2)
  283. {
  284. int counter = 0;
  285. ATLTRACE(_T("CJobFolder:: RePopulateScopePane\n"));
  286. ASSERT( 0 <= (counter = ScopeCount(m_ID, ipConsoleNameSpace2)) ); // Debugging aid only
  287. // delete the MMC scope pane items for all the jobs - NOT the
  288. // process groups folder itself but delete it's content
  289. VERIFY(S_OK == ipConsoleNameSpace2->DeleteItem(m_ID, FALSE));
  290. // free 'our' objects for the job items nodes
  291. FreeNodes();
  292. // debug purposes only
  293. ASSERT(0 == ScopeCount(m_ID, ipConsoleNameSpace2)); // Debugging aid only
  294. PCINT32 res = 0;
  295. PCULONG32 err = 0;
  296. PCINT32 last = 0;
  297. const int MINIMUM_ALLOCATION = min((COM_BUFFER_SIZE/sizeof(PCJobListItem)), 100);
  298. PCJobListItem tempjoblist[MINIMUM_ALLOCATION];
  299. PCid hID = GetPCid();
  300. if (!hID)
  301. {
  302. ReportPCError();
  303. return false;
  304. }
  305. do
  306. {
  307. if (last)
  308. memcpy(&tempjoblist[0], &tempjoblist[last], sizeof(PCJobListItem));
  309. else
  310. memset(&tempjoblist[0], 0, sizeof(PCJobListItem));
  311. res = PCGetJobList( hID, &tempjoblist[0], MINIMUM_ALLOCATION * sizeof(PCJobListItem));
  312. if (res < 0 )
  313. {
  314. err = GetLastPCError();
  315. break;
  316. }
  317. if (res > MINIMUM_ALLOCATION)
  318. {
  319. err = PCERROR_INVALID_RESPONSE;
  320. break;
  321. }
  322. if (res > 0)
  323. {
  324. last = res - 1 ;
  325. for (PCINT32 i = 0; i < res; i++)
  326. {
  327. if (ID_JOBVIEW_RUN == m_fViewOption && !(tempjoblist[i].lFlags & PCLFLAG_IS_RUNNING))
  328. continue;
  329. else if (ID_JOBVIEW_MANAGED == m_fViewOption && !(tempjoblist[i].lFlags & PCLFLAG_IS_MANAGED))
  330. continue;
  331. VERIFY( S_OK == AddNode(ipConsoleNameSpace2, new CJobItemFolder(this, tempjoblist[i]) ) );
  332. }
  333. }
  334. } while (res > 0 && PCERROR_MORE_DATA == GetLastPCError() );
  335. if (err)
  336. ReportPCError(err);
  337. ASSERT( 0 <= (counter = ScopeCount(m_ID, ipConsoleNameSpace2)) ); // Debugging aid only
  338. return S_OK;
  339. }
  340. int CJobFolder::ScopeCount(HSCOPEITEM ID, IConsoleNameSpace2 *ipConsoleNameSpace2)
  341. {
  342. HSCOPEITEM curID, prevID;
  343. MMC_COOKIE Cookie;
  344. int count = 0;
  345. HRESULT hr = ipConsoleNameSpace2->GetChildItem(ID, &curID, &Cookie);
  346. while(hr == S_OK && curID)
  347. {
  348. prevID = curID;
  349. count++;
  350. hr = ipConsoleNameSpace2->GetNextItem(prevID, &curID, &Cookie);
  351. }
  352. return count;
  353. }