home *** CD-ROM | disk | FTP | other *** search
- /* $Id: kProcessContainer.cpp,v 1.1 2000/04/29 19:06:35 stknut Exp $
- *
- * kProcessContainer - General process container.
- *
- * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
- *
- */
-
- /*******************************************************************************
- * Defined Constants And Macros *
- *******************************************************************************/
- #define INCL_WIN
- #define INCL_GPI
- #define INCL_BASE
-
-
- /*******************************************************************************
- * Header Files *
- *******************************************************************************/
- #include <os2.h>
- #ifdef USE_KLIB
- #include <kAssert.h>
- #include <kLog.h>
- #include <kHeap.h>
- #else
- #include <malloc.h>
- #endif
- #include <memory.h>
- #include <string.h>
- #include <stddef.h>
- #include <stdio.h>
-
- #include "kBase.h"
- #include "kError.h"
- #include "kDlgBase.h"
- #include "kMenuBase.h"
- #include "kClickDlg.h"
- #include "kContainer.h"
- //#include "kAbout.h"
- #include "kNotebookBase.h"
- #include "kNotebookPageBase.h"
-
- #include "kQuerySysState.h"
- #include "kDetailBase.h"
- #include "kThreadRecord.h"
- #include "kThreadContainer.h"
- #include "kProcessRecord.h"
- #include "kProcessContainer.h"
- #include "kProcessDetails.h"
- #include "kProcessPriority.h"
- #include "kTaskMgr.h"
- #include "kTaskMgr_defs.h"
-
-
-
-
- /**
- * Updates the container. This update routine is for the container with all processes. (usPid = 0xFFFF)
- * @returns Success indicator.
- * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
- */
- BOOL kProcessContainer::kUpdateAllProcesses()
- {
- BOOL fRet;
- PPROCESSDATA pCur;
- kProcessRecord *apInvalidRecs[256];
- unsigned cpInvalidRecs = 0;
- kProcessRecord *apDeadRecs[64];
- unsigned cpDeadRecs = 0;
-
- /*
- * Update status information.
- */
- if (!QSUpdateStateData())
- return FALSE;
-
- /*
- * Loop thru the list of processes and update the container.
- */
- pCur = QSGetFirstProcessDataNode();
- disableUpdate();
- while (pCur != NULL)
- {
- kProcessRecord *pRec;
- BOOL fNew = FALSE;
- PPROCESSDATA pToFree = NULL;
-
- /*
- * Find the record. If not found, create a new one.
- */
- pRec = (kProcessRecord *)pCur->pvRecordCore;
- if (pRec == NULL)
- { /* new records */
- pCur->pvRecordCore = pRec = (kProcessRecord*)allocMiniRec(sizeof(kProcessRecord));
- if (pRec == NULL)
- break;
- pRec->init();
- fNew = TRUE;
- }
-
- /*
- * Update data?
- */
- if (pCur->fDirty)
- {
- /*
- * Update record data.
- */
- pRec->set(pCur);
-
- /*
- * Update container content.
- * If this is a new process we'll have to add it
- * If this is an existing process we'll have to refresh it.
- */
- if (fNew)
- insertAtBottom(pRec, 1);
- else
- {
- if (cpInvalidRecs >= 256)
- {
- fRet = invalidateRecords(CMA_TEXTCHANGED,
- cpInvalidRecs,
- (kCnrMiniRecord **)&apInvalidRecs);
- ASSERT(fRet);
- cpInvalidRecs = 0;
- }
-
- apInvalidRecs[cpInvalidRecs++] = pRec;
- }
- }
-
- /*
- * Dead? Remove it!
- */
- if (pCur->fDead)
- {
- if (cpDeadRecs >= 64)
- {
- fRet = removeRecords((PPVOID)&apDeadRecs[0], cpDeadRecs);
- ASSERT(fRet);
- cpDeadRecs = 0;
- }
- apDeadRecs[cpDeadRecs++] = pRec;
- pToFree = pCur;
- }
-
-
- /* next */
- pCur = pCur->pNext;
- if (pToFree != NULL)
- QSRemoveProcessData(pToFree);
- }
-
- /*
- * Invalidate records
- */
- if (cpInvalidRecs != 0)
- {
- fRet = invalidateRecords(CMA_TEXTCHANGED,
- cpInvalidRecs,
- (kCnrMiniRecord **)&apInvalidRecs);
- ASSERT(fRet);
- }
-
- /*
- * Dead records
- */
- if (cpDeadRecs != 0)
- {
- fRet = removeRecords((PPVOID)&apDeadRecs[0], cpDeadRecs);
- ASSERT(fRet);
- }
- enableUpdate();
-
- return pCur == NULL;
- }
-
-
-
- /**
- * Updates the container with children if usPid.
- * @returns Success indicator.
- * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
- */
- BOOL kProcessContainer::kUpdateChildProcesses()
- {
- PPROCESSDATA pCur;
- kProcessRecord * pCnrRecs,
- * pCurCnrRec;
- int cRecords;
-
- /*
- * Update status information.
- */
- if (!QSUpdateStateData())
- return FALSE;
-
- /*
- * Remove all records in container.
- */
- this->removeAllRecords();
-
- /*
- * Loop thru the list of processes and update the container.
- */
- cRecords = 0;
- pCnrRecs = pCurCnrRec = NULL;
- pCur = QSGetFirstProcessDataNode();
- while (pCur != NULL)
- {
- if (pCur->pProcRec->ppid == usPid)
- {
- /*
- * Allocate and set new process record
- */
- if (pCnrRecs == NULL)
- pCnrRecs = pCurCnrRec = (kProcessRecord*)allocMiniRec(sizeof(kProcessRecord));
- else
- pCurCnrRec = (kProcessRecord*)pCurCnrRec->setNext(allocMiniRec(sizeof(kProcessRecord)));
- if (pCurCnrRec == NULL)
- break;
-
- pCurCnrRec->init();
- pCurCnrRec->set(pCur);
- cRecords++;
- }
-
- /* next */
- pCur = pCur->pNext;
- }
-
-
- /*
- * Insert records (if any) and return.
- */
- return cRecords > 0 ? insertAtBottom(pCnrRecs, cRecords) : TRUE;
- }
-
-
-
-
-
- /**
- * Menu is closing. Remove emphasis.
- * @param usMenuId Menu id.
- * @param hwndMnu Handle to menu window.
- */
- VOID kProcessContainer::menuEnd(USHORT usMenuId, HWND hwndMnu)
- {
- setRecordEmphasis(pCurRecord, FALSE, CRA_SOURCE);
- hwndMnu = hwndMnu;
- usMenuId = usMenuId;
- }
-
-
- /**
- * Command events.
- * @param usCmd Control id which send/posted the message.
- * @param usSource Source id.
- * @param fPointer Mouse pointer flag.
- * @remark dismisses the dialog if DID_OK or DID_CANCEL.
- */
- VOID kProcessContainer::command(USHORT usCmd, USHORT usSource, BOOL fPointer)
- {
- ULONG ulRet; /* Return value from WinMessageBox usually. */
- APIRET rc; /* Return code from Dos API. */
- char szBuffer[1024]; /* String buffer used for formating messages. */
-
- switch (usCmd)
- {
- case IDM_CNR_PROC_DETAILS:
- if (pCurRecord != NULL)
- {
- try
- {
- new kProcessDetails(pCurRecord->getPid(), hwndCnr)->show();
- }
- catch(kError err)
- {
- err.logError();
- err.showError(kTaskMgr::pszErrorTitle);
- }
- }
- break;
-
-
- case IDM_CNR_PROC_KILL:
- if (pCurRecord != NULL)
- {
- sprintf(szBuffer, "Are you sure you like to kill the process '%s'(pid %#x)?",
- pCurRecord->getName(),
- pCurRecord->getPid());
- ulRet = WinMessageBox(HWND_DESKTOP,
- hwndCnr,
- szBuffer,
- "kTaskMgr - Sure?",
- 0,
- MB_YESNO|MB_CUAWARNING);
- if (ulRet == MBID_YES)
- {
- rc = DosKillProcess(DKP_PROCESS, pCurRecord->getPid());
- sprintf(szBuffer, "rc=%d", rc);
- WinMessageBox(HWND_DESKTOP,
- hwndCnr,
- szBuffer,
- "kTaskMgr - debug",
- 0,
- MB_OK);
- }
- }
- break;
-
- case IDM_CNR_PROC_KILLXF86:
- if (pCurRecord != NULL)
- {
- HFILE hFastIO;
- ULONG ulAction;
-
- rc = DosOpen("/dev/fastio$",
- &hFastIO,
- &ulAction,
- (ULONG)0,
- FILE_SYSTEM,
- FILE_OPEN,
- OPEN_SHARE_DENYNONE | OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY,
- NULL);
- if (rc == NO_ERROR)
- {
- sprintf(szBuffer, "Are you sure you like to kill the process '%s'(pid %#x)?",
- pCurRecord->getName(),
- pCurRecord->getPid()
- );
- ulRet = WinMessageBox(HWND_DESKTOP,
- hwndCnr,
- szBuffer,
- "kTaskMgr- Sure?",
- 0,
- MB_YESNO|MB_CUAWARNING);
- if (ulRet == MBID_YES)
- {
- ULONG ulLen;
- USHORT usPid = pCurRecord->getPid();
- rc = DosDevIOCtl(hFastIO,
- (ULONG)0x76,
- (ULONG)0x65,
- &usPid, sizeof(usPid), &ulLen,
- NULL, 0, NULL);
- }
- DosClose(hFastIO);
- }
- else
- {
- sprintf(szBuffer,
- "Failed to open fastio$, rc = %d.\r"
- "XF86SUP.SYS is probably not installed.",
- rc);
- WinMessageBox(HWND_DESKTOP,
- hwndCnr,
- szBuffer,
- kTaskMgr::pszErrorTitle,
- 0,
- MB_CUACRITICAL | MB_OK);
- }
- }
- break;
-
- case IDM_CNR_PROC_PRIORITY:
- if (pCurRecord != NULL)
- {
- try
- {
- kProcessPriority *pDlg = new kProcessPriority(pCurRecord->getPid(), hwndCnr);
- pDlg->showModal();
- }
- catch(kError err)
- {
- err.logError();
- err.showError(kTaskMgr::pszErrorTitle);
- }
- }
- break;
-
- case IDM_CNR_PROC_ALL_REFRESH:
- update();
- break;
-
- case IDM_CNR_PROC_ALL_SORT_PID:
- case IDM_CNR_PROC_ALL_SORT_PPID:
- case IDM_CNR_PROC_ALL_SORT_SYSTIME:
- case IDM_CNR_PROC_ALL_SORT_USERTIME:
- case IDM_CNR_PROC_ALL_SORT_NAME:
- if (usSortId != usCmd)
- {
- usSortId = usCmd;
- pMenuCnrAll->checkMenuItem(IDM_CNR_PROC_ALL_SORT_PID , usCmd == IDM_CNR_PROC_ALL_SORT_PID);
- pMenuCnrAll->checkMenuItem(IDM_CNR_PROC_ALL_SORT_PPID , usCmd == IDM_CNR_PROC_ALL_SORT_PPID);
- pMenuCnrAll->checkMenuItem(IDM_CNR_PROC_ALL_SORT_SYSTIME , usCmd == IDM_CNR_PROC_ALL_SORT_SYSTIME);
- pMenuCnrAll->checkMenuItem(IDM_CNR_PROC_ALL_SORT_USERTIME, usCmd == IDM_CNR_PROC_ALL_SORT_USERTIME);
- pMenuCnrAll->checkMenuItem(IDM_CNR_PROC_ALL_SORT_NAME , usCmd == IDM_CNR_PROC_ALL_SORT_NAME);
-
- /* resort container */
- enableSorting();
- }
- else
- {
- usSortId = 0xFFFF;
- disableSorting();
- pMenuCnrAll->checkMenuItem(usCmd, FALSE);
- }
- break;
- }
-
- usSource = usSource;
- fPointer = fPointer;
- }
-
-
- /**
- * Record sort callback function - compares two records.
- * @returns > 0 when pRecord1 > pRecord2
- * < 0 when pRecord1 < pRecord2
- * == 0 when pRecord1 == pRecord2
- * @param pRecord1 Pointer to first record.
- * @param pRecord2 Pointer to second record.
- */
- SHORT kProcessContainer::sortCallBack(kCnrMiniRecord *pRecord1, kCnrMiniRecord *pRecord2)
- {
- kProcessRecord * pRec1 = (kProcessRecord *)pRecord1;
- kProcessRecord * pRec2 = (kProcessRecord *)pRecord2;
-
- if (pRec1 != NULL && pRec2 != NULL)
- {
- int iTmp = 1;
- switch (usSortId)
- {
- case IDM_CNR_PROC_ALL_SORT_PID:
- iTmp = pRec1->getPid() - pRec2->getPid();
- break;
-
- case IDM_CNR_PROC_ALL_SORT_PPID:
- iTmp = strcmp(pRec1->getPPid(), pRec2->getPPid());
- break;
-
- case IDM_CNR_PROC_ALL_SORT_SYSTIME:
- iTmp = strcmp(pRec1->getSysTime(), pRec2->getSysTime());
- break;
-
- case IDM_CNR_PROC_ALL_SORT_USERTIME:
- iTmp = strcmp(pRec1->getUserTime(), pRec2->getUserTime());
- break;
-
- case IDM_CNR_PROC_ALL_SORT_NAME:
- iTmp = strcmp(pRec1->getName(), pRec2->getName());
- break;
- }
- return (SHORT)((iTmp > 0) ? 1 : (iTmp < 0) ? -1 : 0);
- }
- return 1;
- }
-
-
- /**
- * Constructor.
- * @returns
- * @param hwndDlg Handle to dialog window.
- * @param ulCnrId ID of the container dialog item in hwndDlg.
- * @param usPid usPid = 0xFFFF: View all processes.
- * usPid != 0: View all children of the given process id.
- * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
- */
- kProcessContainer::kProcessContainer(HWND hwndDlg, ULONG ulCnrId, USHORT usPid/* = 0xFFFF*/) throw(kError)
- : kDetailCnr(WinWindowFromID(hwndDlg, ulCnrId),
- 0,
- usPid == 0xFFFF ? "Process Overview" : "Child Processes",
- kProcessRecord::cFieldInfo,
- (PFIELDINFO)&kProcessRecord::aFieldInfo[0]),
- usPid(usPid), pCurRecord(NULL)
- {
- /*
- * Create menus.
- */
- pMenuProcess = new kMenuBase(IDM_CNR_PROCESS, NULLHANDLE, hwndCnr, TRUE);
- pMenuCnrAll = new kMenuBase(IDM_CNR_PROCESS_ALL, NULLHANDLE, hwndCnr, TRUE);
- enableSorting();
- }
-
-
- /**
- * Destructor.
- */
- kProcessContainer::~kProcessContainer()
- {
- if (pMenuProcess != NULL)
- delete pMenuProcess;
- if (pMenuCnrAll != NULL)
- delete pMenuCnrAll;
- }
-
-
- /**
- * Displays the popup menu for the container.
- * @param usId Container id.
- * @param pRecord Pointer to the record which is selected by either the key
- */
- VOID kProcessContainer::cnrContextMenu(USHORT usId, PRECORDCORE pRecord)
- {
- if (pMenuProcess && pMenuCnrAll)
- {
- pCurRecord = (kProcessRecord*)pRecord;
- setRecordEmphasis(pCurRecord, TRUE, CRA_SOURCE);
- if (pRecord != NULL)
- pMenuProcess->popup();
- else
- pMenuCnrAll->popup();
- }
- usId = usId;
- }
-
-
- /**
- * Enter or double click on record in the container.
- * This action will bring up the detail dialog for the record.
- */
- VOID kProcessContainer::cnrEnter(USHORT usId, HWND hwndCnr, PRECORDCORE pRecord, ULONG fKey)
- {
- if (pRecord != NULL)
- {
- pCurRecord = (kProcessRecord*)pRecord;
- command(IDM_CNR_PROC_DETAILS, 0, 0);
- }
- usId = usId;
- fKey = fKey;
- hwndCnr = hwndCnr;
- }
-
-
-
- /**
- * Updates the contents of the container.
- * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
- */
- VOID kProcessContainer::update()
- {
- /*
- * Insert records
- */
- if (usPid == 0xFFFF)
- kUpdateAllProcesses();
- else
- kUpdateChildProcesses();
- }
-
-