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.

694 lines
20 KiB

  1. /*======================================================================================//
  2. | Process Control //
  3. | //
  4. |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. //
  5. | //
  6. |File Name: JobItemFolder.cpp //
  7. | //
  8. |Description: Implementation of a JobItem node //
  9. | //
  10. |Created: Paul Skoglund 04-1999 //
  11. | //
  12. |Rev History: //
  13. | //
  14. |=======================================================================================*/
  15. #include "StdAfx.h"
  16. #include "BaseNode.h"
  17. #include "JobPages.h"
  18. #include "ProcessPages.h"
  19. #include "ManagementPages.h"
  20. #include "ManagementRuleWizards.h"
  21. #pragma warning(push)
  22. #include <algorithm>
  23. #pragma warning(pop)
  24. using std::list<PCProcListItem*>;
  25. using std::list<CBaseNode *>;
  26. using std::find;
  27. const GUID CJobItemFolder::m_GUID = {0xff9baf66,0x064e,0x11d2,{0x80, 0x14,0x00,0x10,0x4b,0x9a,0x31,0x06} };
  28. const TCHAR *const CJobItemFolder::m_szGUID = _T("{ff9baf66-064e-11d2-8014-00104b9a3106}");
  29. const CONTEXTMENUITEMBYID CJobItemFolder::ResultsTopMenuItems[] =
  30. {
  31. { IDS_JRULE_DEFINE, ID_JRULE_DEFINE, ID_JRULE_DEFINE, CCM_INSERTIONPOINTID_PRIMARY_TOP },
  32. { IDS_ENDJOB, ID_ENDJOB, ID_ENDJOB, CCM_INSERTIONPOINTID_PRIMARY_TOP },
  33. { 0, 0, 0, 0 }
  34. };
  35. CJobItemFolder::CJobItemFolder(CBaseNode *pParent, const PCJobListItem &thejob)
  36. : CBaseNode(JOBITEM_NODE, pParent), m_JobItem(thejob), m_ID(0)
  37. {
  38. }
  39. CJobItemFolder::~CJobItemFolder()
  40. {
  41. ClearCache();
  42. ATLTRACE( _T("~CJobItemFolder end %p - %s\n"), this, GetNodeName());
  43. }
  44. LPCTSTR CJobItemFolder::GetNodeName()
  45. {
  46. return m_JobItem.jobName;
  47. }
  48. HRESULT CJobItemFolder::GetDisplayInfo(RESULTDATAITEM &ResultItem)
  49. {
  50. if (ResultItem.bScopeItem)
  51. {
  52. return PCJobListGetDisplayInfo(ResultItem, m_JobItem, m_ResultStr);
  53. }
  54. list<PCProcListItem*>::iterator item;
  55. item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcListItem*>(ResultItem.lParam) );
  56. if (item == Cache.end() )
  57. return E_UNEXPECTED;
  58. return PCProcListGetDisplayInfo(ResultItem, **item, m_ResultStr);
  59. }
  60. HRESULT CJobItemFolder::PCJobListGetDisplayInfo(RESULTDATAITEM &ResultItem, const PCJobListItem &ref, ITEM_STR &StorageStr)
  61. {
  62. if (ResultItem.mask & RDI_IMAGE)
  63. {
  64. if (ref.lFlags & PCLFLAG_IS_DEFINED)
  65. ResultItem.nImage = JOBITEMIMAGE;
  66. else
  67. ResultItem.nImage = JOBITEMIMAGE_NODEFINITION;
  68. }
  69. if (ResultItem.mask & RDI_STR)
  70. {
  71. LPCTSTR &pstr = ResultItem.str;
  72. switch (ResultItem.nCol)
  73. {
  74. case CJobFolder::JOB_COLUMN:
  75. pstr = ref.jobName;
  76. break;
  77. case CJobFolder::STATUS_COLUMN:
  78. if(ref.lFlags & PCLFLAG_IS_MANAGED)
  79. pstr = LoadStringHelper(StorageStr, IDS_MANAGED);
  80. else
  81. pstr = _T("");
  82. break;
  83. case CJobFolder::ACTIVE_PROCESS_COUNT_COLUMN:
  84. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  85. pstr = FormatProcCount(StorageStr, ref.jobStats.ActiveProcesses);
  86. else
  87. pstr = _T("");
  88. break;
  89. case CJobFolder::AFFINITY_COLUMN:
  90. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  91. pstr = FormatAffinity(StorageStr, ref.actualAffinity);
  92. else
  93. pstr = _T("");
  94. break;
  95. case CJobFolder::PRIORITY_COLUMN:
  96. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  97. pstr = FormatPriority(StorageStr, ref.actualPriority);
  98. else
  99. pstr = _T("");
  100. break;
  101. case CJobFolder::SCHEDULING_CLASS_COLUMN:
  102. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  103. pstr = FormatSchedulingClass(StorageStr, ref.actualSchedClass);
  104. else
  105. pstr = _T("");
  106. break;
  107. case CJobFolder::USER_TIME_COLUMN:
  108. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  109. pstr = FormatTimeToms(StorageStr, ref.jobStats.TotalUserTime);
  110. else
  111. pstr = _T("");
  112. break;
  113. case CJobFolder::KERNEL_TIME_COLUMN:
  114. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  115. pstr = FormatTimeToms(StorageStr, ref.jobStats.TotalKernelTime);
  116. else
  117. pstr = _T("");
  118. break;
  119. //case CJobFolder::CREATE_TIME_COLUMN:
  120. case CJobFolder::PERIOD_USER_TIME_COLUMN:
  121. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  122. pstr = FormatTimeToms(StorageStr, ref.jobStats.ThisPeriodTotalUserTime);
  123. else
  124. pstr = _T("");
  125. break;
  126. case CJobFolder::PERIOD_KERNEL_TIME_COLUMN:
  127. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  128. pstr = FormatTimeToms(StorageStr, ref.jobStats.ThisPeriodTotalKernelTime);
  129. else
  130. pstr = _T("");
  131. break;
  132. case CJobFolder::PAGE_FAULT_COUNT_COLUMN:
  133. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  134. pstr = FormatPCUINT64(StorageStr, ref.jobStats.TotalPageFaultCount);
  135. else
  136. pstr = _T("");
  137. break;
  138. case CJobFolder::PROCESS_COUNT_COLUMN:
  139. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  140. pstr = FormatPCUINT64(StorageStr, ref.jobStats.TotalProcesses);
  141. else
  142. pstr = _T("");
  143. break;
  144. case CJobFolder::TERMINATED_PROCESS_COUNT_COLUMN:
  145. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  146. pstr = FormatPCUINT64(StorageStr, ref.jobStats.TotalTerminatedProcesses);
  147. else
  148. pstr = _T("");
  149. break;
  150. case CJobFolder::READOP_COUNT_COLUMN:
  151. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  152. pstr = FormatPCUINT64(StorageStr, ref.jobStats.ReadOperationCount);
  153. else
  154. pstr = _T("");
  155. break;
  156. case CJobFolder::WRITEOP_COUNT_COLUMN:
  157. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  158. pstr = FormatPCUINT64(StorageStr, ref.jobStats.WriteOperationCount);
  159. else
  160. pstr = _T("");
  161. break;
  162. case CJobFolder::OTHEROP_COUNT_COLUMN:
  163. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  164. pstr = FormatPCUINT64(StorageStr, ref.jobStats.OtherOperationCount);
  165. else
  166. pstr = _T("");
  167. break;
  168. case CJobFolder::READTRANS_COUNT_COLUMN:
  169. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  170. pstr = FormatPCUINT64(StorageStr, ref.jobStats.ReadTransferCount);
  171. else
  172. pstr = _T("");
  173. break;
  174. case CJobFolder::WRITETRANS_COUNT_COLUMN:
  175. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  176. pstr = FormatPCUINT64(StorageStr, ref.jobStats.WriteTransferCount);
  177. else
  178. pstr = _T("");
  179. break;
  180. case CJobFolder::OTHERTRANS_COUNT_COLUMN:
  181. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  182. pstr = FormatPCUINT64(StorageStr, ref.jobStats.OtherTransferCount);
  183. else
  184. pstr = _T("");
  185. break;
  186. case CJobFolder::PEAK_PROC_MEM_COLUMN:
  187. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  188. pstr = FormatMemory(StorageStr, ref.jobStats.PeakProcessMemoryUsed);
  189. else
  190. pstr = _T("");
  191. break;
  192. case CJobFolder::PEAK_JOB_MEM_COLUMN:
  193. if (ref.lFlags & PCLFLAG_IS_RUNNING)
  194. pstr = FormatMemory(StorageStr, ref.jobStats.PeakJobMemoryUsed);
  195. else
  196. pstr = _T("");
  197. break;
  198. default:
  199. ASSERT(FALSE);
  200. pstr = _T("");
  201. break;
  202. }
  203. }
  204. return S_OK;
  205. }
  206. HRESULT CJobItemFolder::OnShow(BOOL bSelecting, HSCOPEITEM hItem, IHeaderCtrl2 *ipHeaderCtrl2, IConsole2 *ipConsole2, IConsoleNameSpace2 *ipConsoleNameSpace2)
  207. {
  208. ASSERT(hItem == GetID());
  209. if (!bSelecting)
  210. return S_OK;
  211. SCOPEDATAITEM sdi = {0};
  212. // Update the item's image in the scope pane
  213. sdi.mask = SDI_IMAGE | SDI_OPENIMAGE;
  214. sdi.nImage = sImage();
  215. sdi.nOpenImage = sOpenImage();
  216. sdi.ID = m_ID;
  217. VERIFY(S_OK == ipConsoleNameSpace2->SetItem(&sdi));
  218. InsertProcessHeaders(ipHeaderCtrl2);
  219. return OnRefresh(ipConsole2);
  220. }
  221. HRESULT CJobItemFolder::AddMenuItems(LPCONTEXTMENUCALLBACK piCallback, long * pInsertionAllowed)
  222. {
  223. HRESULT hr = S_OK;
  224. ITEM_STR name;
  225. ITEM_STR status;
  226. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  227. {
  228. CONTEXTMENUITEM m = { 0 };
  229. for (const CONTEXTMENUITEMBYID *M = ResultsTopMenuItems; M->lCommandID; M++)
  230. {
  231. m.strName = const_cast<TCHAR *>(LoadStringHelper(name, M->strNameID));
  232. m.strStatusBarText = const_cast<TCHAR *>(LoadStringHelper(status, M->strStatusBarTextID));
  233. m.lCommandID = M->lCommandID;
  234. m.lInsertionPointID = M->lInsertionPointID;
  235. //m.fSpecialFlags = 0; // currently always 0, initialized to 0
  236. m.fFlags = MF_GRAYED;
  237. if (M->lCommandID == ID_JRULE_DEFINE)
  238. {
  239. if ( !(PCLFLAG_IS_DEFINED & m_JobItem.lFlags) )
  240. m.fFlags = MF_ENABLED;
  241. }
  242. else if (M->lCommandID == ID_ENDJOB)
  243. {
  244. if ( (PCLFLAG_IS_RUNNING & m_JobItem.lFlags) )
  245. m.fFlags = MF_ENABLED;
  246. }
  247. hr = piCallback->AddItem(&m);
  248. if (FAILED(hr))
  249. break;
  250. }
  251. }
  252. return hr;
  253. }
  254. HRESULT CJobItemFolder::OnMenuCommand(IConsole2 *ipConsole2, long nCommandID)
  255. {
  256. ASSERT(FALSE);
  257. return S_OK;
  258. }
  259. HRESULT CJobItemFolder::OnMenuCommand(IConsole2 *ipConsole2, IConsoleNameSpace2 *ipConsoleNameSpace2, long nCommandID )
  260. {
  261. switch(nCommandID)
  262. {
  263. case ID_JRULE_DEFINE:
  264. {
  265. PCid hID = GetPCid();
  266. PCSystemInfo SystemInfo;
  267. if (!hID || !PCGetServiceInfo(hID, &SystemInfo, sizeof(SystemInfo)))
  268. {
  269. ReportPCError();
  270. return S_OK;
  271. }
  272. PCJobDetail JobDetail = { 0 };
  273. if (GroupRuleWizard(IDS_JRULE_DEFINE, JobDetail, SystemInfo.sysParms, &(m_JobItem.jobName) ) )
  274. {
  275. if (!PCAddJobDetail(hID, &JobDetail) )
  276. ReportPCError();
  277. else
  278. {
  279. PCJobListItem JobListInfo = { 0 };
  280. _tcscpy(JobListInfo.jobName, m_JobItem.jobName);
  281. PCINT32 count = PCGetJobList( GetPCid(), &JobListInfo, sizeof(PCJobListItem), PC_LIST_MATCH_ONLY);
  282. if (0 > count)
  283. {
  284. ReportPCError();
  285. return S_OK;
  286. }
  287. else if (1 == count) // the expected-usual case
  288. {
  289. m_JobItem = JobListInfo; // update local data
  290. SCOPEDATAITEM sdi = {0};
  291. // Update the item's image in the scope pane
  292. sdi.mask = SDI_IMAGE | SDI_OPENIMAGE;
  293. sdi.nImage = sImage();
  294. sdi.nOpenImage = sOpenImage();
  295. sdi.ID = m_ID;
  296. VERIFY(S_OK == ipConsoleNameSpace2->SetItem(&sdi));
  297. VERIFY(S_OK == SendViewChange(ipConsole2, NULL, PC_VIEW_UPDATEALL));
  298. return S_OK;
  299. }
  300. // the very unlikely case that a group rule was:
  301. // 1) added and then immediately deleted by another administrator
  302. // or
  303. // 2) bug resulted in PCGetJobList() not finding the just added item
  304. int ret;
  305. ITEM_STR str;
  306. LoadStringHelper(str, IDS_GROUP_NO_LONGER_EXISTS);
  307. ipConsole2->MessageBox( str, NULL, MB_OK | MB_ICONWARNING, &ret);
  308. // force a refresh of the Process Group folder
  309. ipConsole2->SelectScopeItem(GetParentNode()->GetID());
  310. return S_OK;
  311. }
  312. }
  313. }
  314. return S_OK;
  315. case ID_ENDJOB:
  316. ATLTRACE(_T("CJobItemFolder::end job %s\n"), GetNodeName());
  317. if (!GetPCid() || !PCKillJob(GetPCid(), m_JobItem.jobName ) )
  318. ReportPCError();
  319. else
  320. {
  321. ATLTRACE(_T("CJobItemFolder::job %s killed on server\n"), GetNodeName() );
  322. // MMC DeleteItem() on scope items is vunerable in certain cases.
  323. // in MMC handling of DeleteItem the snap-in is sent selection/show notifications
  324. // if those handlers call DeleteItem on scope items problems can arise
  325. // Original ProcCon problem:
  326. // when the child folder (a specific job) is deleted, the focus moves
  327. // up one level on the tree to the jobs folder (process groups), in our handling
  328. // of selection of the job folder we delete all the children(specific jobs)
  329. // of the folder and repopulate the child folders(list of jobs).
  330. // MMC appears to try and delete the org. child folder twice - unpredicable
  331. // results follow.
  332. //
  333. // the process group has already been ended on the server rather than
  334. // delete the individual item in MMC scope pane we will just change the selection
  335. // in the scope pane and rely on the select handlers to correct the
  336. // MMC namespace(scope pane display)
  337. // ipConsoleNameSpace2->DeleteItem(m_ID, TRUE);
  338. ipConsole2->SelectScopeItem(GetParentNode()->GetID());
  339. }
  340. return S_OK;
  341. default:
  342. break;
  343. }
  344. return E_UNEXPECTED;
  345. }
  346. HRESULT CJobItemFolder::OnHelpCmd(IDisplayHelp *ipDisplayHelp)
  347. {
  348. if (!ipDisplayHelp)
  349. return E_UNEXPECTED;
  350. ipDisplayHelp->ShowTopic(const_cast<TCHAR *>(HELP_jo_overview));
  351. return S_OK;
  352. }
  353. // folder select
  354. HRESULT CJobItemFolder::OnSelect(BOOL bScope, BOOL bSelect, IConsoleVerb* ipConsoleVerb)
  355. {
  356. ASSERT(bScope);
  357. if ( bSelect && bScope )
  358. {
  359. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE ) == S_OK);
  360. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE ) == S_OK);
  361. VERIFY( ipConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN ) == S_OK );
  362. }
  363. return S_OK;
  364. }
  365. HRESULT CJobItemFolder::OnSelect(BOOL bScope, BOOL bSelect, IConsoleVerb* ipConsoleVerb, LPARAM Cookie)
  366. {
  367. ASSERT(!bScope);
  368. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE ) == S_OK);
  369. if (bSelect && !bScope) // incase the rules are changed again leave !bScope test
  370. {
  371. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE ) == S_OK);
  372. VERIFY( ipConsoleVerb->SetDefaultVerb( MMC_VERB_PROPERTIES ) == S_OK );
  373. }
  374. return S_OK;
  375. }
  376. HRESULT CJobItemFolder::OnViewChange(IResultData *ipResultData, LPARAM thing, LONG_PTR hint)
  377. {
  378. ASSERT(ipResultData);
  379. if (!ipResultData)
  380. return E_UNEXPECTED;
  381. VERIFY(ipResultData->ModifyViewStyle(MMC_SINGLESEL, MMC_NOSORTHEADER) == S_OK);
  382. list<PCProcListItem*>::iterator item;
  383. HRESULT hr = E_UNEXPECTED;
  384. switch (hint)
  385. {
  386. case PC_VIEW_REDRAWALL:// not currently used
  387. hr = ShowAllItems(ipResultData, TRUE);
  388. break;
  389. case PC_VIEW_ADDITEM: // not currently used
  390. ASSERT(FALSE); // add smarter support for this hint...
  391. case PC_VIEW_UPDATEALL:
  392. hr = ShowAllItems(ipResultData, FALSE);
  393. break;
  394. case PC_VIEW_UPDATEITEM:
  395. {
  396. HRESULTITEM hItem;
  397. hr = ipResultData->FindItemByLParam(thing, &hItem);
  398. if (hr == S_OK)
  399. hr = ipResultData->UpdateItem(hItem);
  400. }
  401. break;
  402. case PC_VIEW_SETITEM:
  403. item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcListItem*>(thing) );
  404. if (item == Cache.end())
  405. hr = E_UNEXPECTED;
  406. else
  407. {
  408. HRESULTITEM hItem;
  409. hr = ipResultData->FindItemByLParam(thing, &hItem);
  410. if (hr == S_OK)
  411. {
  412. RESULTDATAITEM data = { 0 };
  413. data.mask = RDI_IMAGE;
  414. data.itemID = hItem;
  415. if ((*item)->lFlags & PCLFLAG_IS_DEFINED)
  416. data.nImage = PROCITEMIMAGE;
  417. else
  418. data.nImage = PROCITEMIMAGE_NODEFINITION;
  419. hr = ipResultData->SetItem(&data);
  420. if (hr == S_OK)
  421. hr = ipResultData->UpdateItem(hItem);
  422. }
  423. }
  424. break;
  425. case PC_VIEW_DELETEITEM:
  426. {
  427. HRESULTITEM hItem;
  428. hr = ipResultData->FindItemByLParam(thing, &hItem);
  429. if (hr == S_OK)
  430. hr = ipResultData->DeleteItem(hItem, 0);
  431. }
  432. break;
  433. default:
  434. hr = E_UNEXPECTED;
  435. break;
  436. }
  437. ASSERT(hr == S_OK);
  438. return hr;
  439. }
  440. HRESULT CJobItemFolder::ShowAllItems(IResultData* ipResultData, BOOL bCacheValid)
  441. {
  442. list<PCProcListItem*>::iterator item;
  443. LPARAM selected = 0;
  444. LPARAM focused = 0;
  445. RESULTDATAITEM data;
  446. if (bCacheValid)
  447. {
  448. memset(&data, 0, sizeof(data));
  449. data.nIndex = -1;
  450. data.nState = LVIS_SELECTED;
  451. data.mask = RDI_STATE;
  452. if (S_OK == ipResultData->GetNextItem(&data) && data.nIndex != -1 )
  453. {
  454. selected = data.lParam;
  455. }
  456. memset(&data, 0, sizeof(data));
  457. data.nIndex = -1;
  458. data.nState = LVIS_FOCUSED;
  459. data.mask = RDI_STATE;
  460. if (S_OK == ipResultData->GetNextItem(&data) && data.nIndex != -1)
  461. {
  462. focused = data.lParam;
  463. }
  464. }
  465. ipResultData->DeleteAllRsltItems();
  466. memset(&data, 0, sizeof(data));
  467. data.mask = RDI_STR | RDI_IMAGE | RDI_PARAM | RDI_STATE;
  468. data.bScopeItem = FALSE;
  469. //data.itemID;
  470. data.nIndex = 0;
  471. data.nCol = 0;
  472. data.str = (LPOLESTR)MMC_CALLBACK;
  473. data.nImage = JOBITEMIMAGE;
  474. data.iIndent = 0; //reserved
  475. HRESULT hr = S_OK;
  476. for (list<PCProcListItem*>::iterator i = Cache.begin(); i != Cache.end(); ++i)
  477. {
  478. data.lParam = reinterpret_cast<LPARAM>(*i);
  479. if ((*i)->lFlags & PCLFLAG_IS_DEFINED)
  480. data.nImage = PROCITEMIMAGE;
  481. else
  482. data.nImage = PROCITEMIMAGE_NODEFINITION;
  483. data.nState = 0;
  484. if (data.lParam == selected)
  485. data.nState |= LVIS_SELECTED;
  486. if (data.lParam == focused)
  487. data.nState |= LVIS_FOCUSED;
  488. hr = ipResultData->InsertItem(&data);
  489. if (hr != S_OK)
  490. break;
  491. }
  492. return hr;
  493. }
  494. void CJobItemFolder::ClearCache()
  495. {
  496. Cache.clear();
  497. for (list<PCProcListItem*>::iterator chunck = MemBlocks.begin(); chunck != MemBlocks.end(); ++chunck)
  498. {
  499. delete [] (*chunck);
  500. }
  501. MemBlocks.clear();
  502. }
  503. BOOL CJobItemFolder::RefreshCache(IConsole2 *ipConsole2)
  504. {
  505. PCINT32 res = 0;
  506. PCULONG32 err = 0;
  507. PCProcListItem *last = NULL;
  508. const int MINIMUM_ALLOCATION = min((COM_BUFFER_SIZE/sizeof(PCProcListItem)), 100);
  509. ClearCache();
  510. PCid hID = GetPCid();
  511. if (!hID)
  512. {
  513. ReportPCError();
  514. return false;
  515. }
  516. PCJobListItem JobListInfo = { 0 };
  517. _tcscpy(JobListInfo.jobName, m_JobItem.jobName);
  518. PCINT32 count = PCGetJobList( GetPCid(), &JobListInfo, sizeof(PCJobListItem), PC_LIST_MATCH_ONLY);
  519. if (0 > count)
  520. {
  521. ReportPCError();
  522. return false;
  523. }
  524. else if (0 == count)
  525. {
  526. int ret;
  527. ITEM_STR str;
  528. LoadStringHelper(str, IDS_GROUP_NO_LONGER_EXISTS);
  529. ipConsole2->MessageBox( str, NULL, MB_OK | MB_ICONWARNING, &ret);
  530. return false;
  531. }
  532. m_JobItem = JobListInfo;
  533. do
  534. {
  535. PCProcListItem *ptr = new PCProcListItem[MINIMUM_ALLOCATION];
  536. if (!ptr)
  537. {
  538. err = ERROR_OUTOFMEMORY;
  539. break;
  540. }
  541. if (last)
  542. memcpy(ptr, last, sizeof(PCProcListItem));
  543. else
  544. {
  545. memset(ptr, 0, sizeof(PCProcListItem));
  546. _tcscpy(ptr->jobName, m_JobItem.jobName);
  547. }
  548. res = PCGetProcList( hID, ptr, MINIMUM_ALLOCATION * sizeof(PCProcListItem), PC_LIST_MEMBERS_OF);
  549. if (res < 0 )
  550. {
  551. err = GetLastPCError();
  552. delete [] ptr;
  553. break;
  554. }
  555. if (res > 0)
  556. {
  557. last = &ptr[res - 1];
  558. MemBlocks.push_front(ptr);
  559. for (INT32 i = 0; i < res; i++)
  560. {
  561. Cache.insert(Cache.end(), ptr);
  562. ptr++;
  563. }
  564. }
  565. } while (res > 0 && PCERROR_MORE_DATA == GetLastPCError() );
  566. if (err)
  567. ReportPCError(err);
  568. return err == 0;
  569. }
  570. HRESULT CJobItemFolder::QueryPagesFor()
  571. {
  572. return S_OK;
  573. }
  574. HRESULT CJobItemFolder::QueryPagesFor(LPARAM Cookie)
  575. {
  576. list<PCProcListItem*>::iterator item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcListItem*>(Cookie) );
  577. if (item == Cache.end() )
  578. return E_UNEXPECTED;
  579. return S_OK;
  580. }
  581. HRESULT CJobItemFolder::OnCreatePropertyPages( LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, DATA_OBJECT_TYPES context)
  582. {
  583. return CreatePropertyPagesForJobListItem(m_JobItem, lpProvider, handle, this);
  584. }
  585. HRESULT CJobItemFolder::OnCreatePropertyPages( LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, DATA_OBJECT_TYPES context, LPARAM Cookie)
  586. {
  587. list<PCProcListItem*>::iterator item;
  588. item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcListItem*>(Cookie) );
  589. if (item == Cache.end() )
  590. return E_UNEXPECTED;
  591. return CreatePropertyPagesForProcListItem(**item, lpProvider, handle, this);
  592. }
  593. HRESULT CJobItemFolder::OnPropertyChange(PROPERTY_CHANGE_HDR *pUpdate, IConsole2 *ipConsole2)
  594. {
  595. return OnRefresh(ipConsole2);
  596. }
  597. HRESULT CJobItemFolder::OnRefresh(IConsole2 *ipConsole2)
  598. {
  599. RefreshCache(ipConsole2);
  600. return SendViewChange(ipConsole2, NULL, PC_VIEW_UPDATEALL);
  601. }