home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / taman002.zip / TASKMANA.ZIP / src / kSFNContainer.cpp < prev    next >
C/C++ Source or Header  |  2000-04-29  |  18KB  |  529 lines

  1. /* $Id: kSFNContainer.cpp,v 1.1 2000/04/29 19:06:35 stknut Exp $
  2.  *
  3.  * kSFNContainer (kTaskMgr) - generic SystemFileNumber (SFN) container.
  4.  *
  5.  * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  6.  *
  7.  */
  8.  
  9. /*******************************************************************************
  10. *   Defined Constants And Macros                                               *
  11. *******************************************************************************/
  12. #define INCL_WIN
  13. #define INCL_GPI
  14. #define INCL_BASE
  15.  
  16.  
  17. /*******************************************************************************
  18. *   Header Files                                                               *
  19. *******************************************************************************/
  20. #include <os2.h>
  21. #ifdef USE_KLIB
  22.     #include <kAssert.h>
  23.     #include <kLog.h>
  24.     #include <kHeap.h>
  25. #else
  26.     #include <malloc.h>
  27. #endif
  28. #include <memory.h>
  29. #include <string.h>
  30. #include <stddef.h>
  31. #include <stdio.h>
  32.  
  33. #include "kBase.h"
  34. #include "kError.h"
  35. #include "kDlgBase.h"
  36. #include "kMenuBase.h"
  37. #include "kClickDlg.h"
  38. #include "kContainer.h"
  39.  
  40. #include "kQuerySysState.h"
  41. #include "kNotebookBase.h"
  42. #include "kNotebookPageBase.h"
  43. #include "kSFNRecord.h"
  44. #include "kSFNContainer.h"
  45. #include "kTaskMgr.h"
  46. #include "kTaskMgr_defs.h"
  47.  
  48.  
  49. /**
  50.  * Updates the content of the container - inserts SFN a single process.
  51.  * @returns   success indicator.
  52.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  53.  */
  54. BOOL   kSFNContainer::insertSFNsPid()
  55. {
  56.     int             c,                  /* Count of SFNs in this FS record. */
  57.                     i;                  /* Loop variable */
  58.     kSFNRecord    * pCurCnrRec,         /* Current container record. */
  59.                   * pCnrRec;            /* Pointer to first container record. */
  60.     PPROCESSDATA    pProcData;          /* Pointer to process data. */
  61.  
  62.     ASSERT(usPid < 0xFFFF);
  63.  
  64.     /*
  65.      * Remove all existing container records!
  66.      */
  67.     removeAllRecords();
  68.  
  69.     /*
  70.      * Get process data
  71.      */
  72.     pProcData = QSGetProcessData(usPid);
  73.     if (pProcData == NULL)
  74.         return FALSE;
  75.  
  76.  
  77.     /*
  78.      * Allocate container records for all the objects.
  79.      *
  80.      * FEATURE/BUGBUG: cFH isn't correct - it don't match with the number of
  81.      *      entries in the pFSRec array. (qsProc_t)
  82.      *
  83.      *      This is verified! There is a "bug" in the _qsProcFS worker (this
  84.      *      is the function which generates the SFT table pointed to by pFSRec).
  85.      *      cFH is set to JFN_Length by _qsReadPtda. While _qsProcFS skips the
  86.      *      entries containing 0xFFFF (unused handle placeholder).
  87.      *      This way the cFH is really the maximum number of handles and the
  88.      *      size of the pFSRec table has to be determined by checking pointers
  89.      *      to the next structure. Thread records are by specifications
  90.      *      following the FS records, pointer to these is used to do this.
  91.      *
  92.      *      Note. JFN is not equal to the index into the SFN table due to this bug.
  93.      */
  94.     if ((char*)&pProcData->pProcRec->pFSRec[pProcData->pProcRec->cFH] > (char*)pProcData->pProcRec->pThrdRec)
  95.         c = (int)((char*)pProcData->pProcRec->pThrdRec - (char*)pProcData->pProcRec->pFSRec) / sizeof(pProcData->pProcRec->pFSRec[0]);
  96.     else
  97.         c = (int)pProcData->pProcRec->cFH;
  98.     pCurCnrRec = pCnrRec = (kSFNRecord*)allocMiniRec(sizeof(kSFNRecord), c);
  99.     if (pCurCnrRec == NULL)
  100.         return FALSE;               /* FIXME: complain about this! */
  101.  
  102.     /*
  103.      * Loop thru all SFNs for this MFT (Main(?)FileTable).
  104.      */
  105.     for (i = 0; i < c; i++, pCurCnrRec = (kSFNRecord*)pCurCnrRec->getNext())
  106.     {
  107.         qsSft_t         SFTDummy;       /* Dummy SFT record. (used when FS data isn't found) */
  108.         struct _FSDummy
  109.         {
  110.             qsFrec_t    rec;
  111.             char        name[64];
  112.         }           FSDummy;            /* Dummy FS record with filename. (used when FS data isn't found) */
  113.         qsFrec_t *      pFSData;        /* Pointer to FS data record. */
  114.         qsSft_t *       pSFTData;       /* Pointer to SFT data record. */
  115.  
  116.  
  117.         /*
  118.          * Get FS and SFT data.
  119.          */
  120.         pFSData = QSGetSfnData(pProcData->pProcRec->pFSRec[i]);
  121.         if (pFSData != NULL)
  122.         {
  123.             int j;
  124.             /* find the correct SFT record in this FS record */
  125.             for (j = 0, pSFTData = pFSData->pSft; j < pFSData->ctSft; j++)
  126.                 if (pSFTData->sfn == pProcData->pProcRec->pFSRec[i])
  127.                     break;
  128.             ASSERT(pSFTData != NULL);
  129.         }
  130.         else
  131.         {   /* create dummy FS and SFT records */
  132.             memset(&SFTDummy, 0, sizeof(SFTDummy));
  133.             SFTDummy.sfn = pProcData->pProcRec->pFSRec[i];
  134.             FSDummy.rec.RecType = QS_FILESYS;
  135.             FSDummy.rec.pNextRec = NULL;
  136.             FSDummy.rec.ctSft = 1;
  137.             FSDummy.rec.pSft = &SFTDummy;
  138.             if (SFTDummy.sfn == 0xffff)
  139.                 strcpy(FSDummy.name, "<unused>");
  140.             else
  141.                 strcpy(FSDummy.name, "<Not found due to BUGBUG in DosQuerySysState / _qsReadMFT ???>");
  142.             pFSData = &FSDummy.rec;
  143.             pSFTData = &SFTDummy;
  144.         }
  145.  
  146.  
  147.         /*
  148.          * Init and set the record.
  149.          */
  150.         pCurCnrRec->init();
  151.         pCurCnrRec->set(pSFTData, (char*)pFSData + sizeof(*pFSData), (USHORT)i);
  152.     }
  153.  
  154.  
  155.     /*
  156.      * Insert the record at bottom of the container.
  157.      */
  158.     if (!insertAtTop(pCnrRec, c))
  159.         return FALSE;
  160.  
  161.     /* resort container */
  162.     return enableSorting();
  163. }
  164.  
  165.  
  166. /**
  167.  * Updates the content of the container - inserts SFN for the entire system
  168.  * @returns   success indicator.
  169.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  170.  */
  171. BOOL   kSFNContainer::insertSFNsAll()
  172. {
  173.     qsFrec_t *      pFSData;            /* Pointer to current FS data record. */
  174.     int             cRecords;           /* Count of records to allocate / allocated. */
  175.     kSFNRecord    * pCurCnrRec,
  176.                   * pCnrRec;
  177.  
  178.     /*
  179.      * Remove all existing container records!
  180.      */
  181.     removeAllRecords();
  182.  
  183.     /*
  184.      * Get data for this MTE and get the count of files.
  185.      */
  186.     cRecords = 0;
  187.     pFSData = QSGetFSFirstData();
  188.     while (pFSData != NULL && pFSData->RecType == QS_FILESYS)
  189.     {
  190.         /*
  191.          * BUGBUG! - ctSft isn't correct, or rather Sft records are missing!!! (qsFrec_t)
  192.          *      The number of qsSft_t records is always 1, no matter what the
  193.          *      ctSft member says!
  194.          *      This is verified! The defect is located in _qsReadMFT. When
  195.          *      writing the qsSft_t records the record pointer is always
  196.          *      initialized to _pCurCache in each iteration. This is probably
  197.          *      correct, but _pCurCache is _NOT_ changed during the iteration.
  198.          *      With the excelent result that the next Sft record overwrites
  199.          *      the previous one.
  200.          *
  201.          *      Solution: To move the call to _qsUpdatePtrs into the loopbody,
  202.          *                after the Sft record is written.
  203.          *                This way _pCurCache will be updated at end of each
  204.          *                iteration.
  205.          *      This is a problem on Aurora, Warp 4 and Warp 3.
  206.          */
  207.         if (pFSData->ctSft > 1 && &pFSData->pSft[pFSData->ctSft] > pFSData->pNextRec && pFSData->pNextRec != NULL)
  208.         {
  209.             fprintf(stderr, "- start - pFSData->ctSft correction - end -\nold pFSData->ctSft = %d\n", pFSData->ctSft);
  210.             pFSData->ctSft = (((char*)pFSData->pNextRec - (char*)pFSData->pSft)) / SIZEOFQSSFT_T;
  211.             fprintf(stderr, "new pFSData->ctSft = %d\n- end   - pFSData->ctSft correction - end -\n", pFSData->ctSft);
  212.         }
  213.  
  214.         /* Add; Next record */
  215.         cRecords += pFSData->ctSft;
  216.         pFSData = (qsFrec_t*)pFSData->pNextRec;
  217.     }
  218.  
  219.  
  220.     /*
  221.      * Allocate container records for all the objects.
  222.      */
  223.     pCurCnrRec = pCnrRec = (kSFNRecord*)allocMiniRec(sizeof(kSFNRecord), cRecords);
  224.     if (pCurCnrRec == NULL)
  225.         return FALSE;               /* FIXME: complain about this! */
  226.  
  227.  
  228.     /*
  229.      * Loop thru all filesystem records insering all system filenumbers.
  230.      */
  231.     pFSData = QSGetFSFirstData();
  232.     while (pFSData != NULL && pFSData->RecType == QS_FILESYS)
  233.     {
  234.         int         i;                  /* Inner SFN loop variable */
  235.         qsSft_t *   pSftRec;            /* Pointer to current Sft data */
  236.  
  237.  
  238.         /*
  239.          * Loop thru all SFNs for this MFT (Main(?)FileTable).
  240.          */
  241.         for (i = 0, pSftRec = pFSData->pSft;
  242.              i < pFSData->ctSft;
  243.              i++, pCurCnrRec = (kSFNRecord*)pCurCnrRec->getNext(), pSftRec = (qsSft_t*)((char*)pSftRec + SIZEOFQSSFT_T)
  244.              )
  245.         {
  246.             /*
  247.              * Init and set the record.
  248.              */
  249.             pCurCnrRec->init();
  250.             pCurCnrRec->set(pSftRec, (char*)pFSData + sizeof(*pFSData));
  251.         }
  252.  
  253.         /*
  254.          * Next filesystem record.
  255.          */
  256.         pFSData = (qsFrec_t*)pFSData->pNextRec;
  257.     }
  258.  
  259.     /*
  260.      * Insert the records.
  261.      */
  262.     if (!insertAtTop(pCnrRec, cRecords))
  263.         return FALSE;
  264.  
  265.     /* resort container */
  266.     return enableSorting();
  267. }
  268.  
  269.  
  270. /**
  271.  * Menu is closing. Remove emphasis.
  272.  * @param     usMenuId  Menu id.
  273.  * @param     hwndMnu   Handle to menu window.
  274.  */
  275. VOID kSFNContainer::menuEnd(USHORT usMenuId, HWND hwndMnu)
  276. {
  277.     setRecordEmphasis(pCurRecord, FALSE, CRA_SOURCE);
  278.     hwndMnu = hwndMnu;
  279.     usMenuId = usMenuId;
  280. }
  281.  
  282.  
  283. /**
  284.  * Command events - none yet.
  285.  * @param     usCmd     Control id which send/posted the message.
  286.  * @param     usSource  Source id.
  287.  * @param     fPointer  Mouse pointer flag.
  288.  */
  289. VOID  kSFNContainer::command(USHORT usCmd, USHORT usSource, BOOL fPointer)
  290. {
  291.     switch (usCmd)
  292.     {
  293.         /*
  294.          * Refresh menu item were selected - update the container!
  295.          */
  296.         case IDM_CNR_SFN_ALL_REFRESH:
  297.             update();
  298.             break;
  299.  
  300.  
  301.         /*
  302.          * One of the sort menu items were selected.
  303.          *      If it's an uncheck request Then
  304.          *          Set back to default sorting. (if allready default sorting - do nothing - break)
  305.          *      Endif.
  306.          *      Save new sort id.
  307.          *      Update menuitems.
  308.          *      (re)Enable sorting.
  309.          */
  310.         case IDM_CNR_SFN_ALL_SORT_JFN:
  311.         case IDM_CNR_SFN_ALL_SORT_SFN:
  312.         case IDM_CNR_SFN_ALL_SORT_REFCNT:
  313.         case IDM_CNR_SFN_ALL_SORT_FLAGS:
  314.         case IDM_CNR_SFN_ALL_SORT_FLAGS2:
  315.         case IDM_CNR_SFN_ALL_SORT_MODE:
  316.         case IDM_CNR_SFN_ALL_SORT_MODE2:
  317.         case IDM_CNR_SFN_ALL_SORT_SIZE:
  318.         case IDM_CNR_SFN_ALL_SORT_HVPB:
  319.         case IDM_CNR_SFN_ALL_SORT_ATTR:
  320.         case IDM_CNR_SFN_ALL_SORT_NAME:
  321.             if (usCmd == usSortId)
  322.             {
  323.                 #if 0 //JFN is disabled due to Bug/Feature in _qsProcFS.
  324.                 if (usCmd == IDM_CNR_SFN_ALL_SORT_SFN && usPid >= 0xFFFF
  325.                     || usCmd == IDM_CNR_SFN_ALL_SORT_JFN && usPid < 0xFFFF
  326.                     )
  327.                     break;
  328.                 usCmd = (USHORT)(usPid < 0xFFFF ? IDM_CNR_SFN_ALL_SORT_JFN : IDM_CNR_SFN_ALL_SORT_SFN);
  329.                 #else
  330.                 if (usCmd == IDM_CNR_SFN_ALL_SORT_SFN)
  331.                     break;
  332.                 usCmd = IDM_CNR_SFN_ALL_SORT_SFN;
  333.                 #endif
  334.             }
  335.             usSortId = usCmd;
  336.  
  337.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_JFN   , usCmd == IDM_CNR_SFN_ALL_SORT_JFN   );
  338.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_SFN   , usCmd == IDM_CNR_SFN_ALL_SORT_SFN   );
  339.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_REFCNT, usCmd == IDM_CNR_SFN_ALL_SORT_REFCNT);
  340.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_FLAGS , usCmd == IDM_CNR_SFN_ALL_SORT_FLAGS );
  341.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_FLAGS2, usCmd == IDM_CNR_SFN_ALL_SORT_FLAGS2);
  342.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_MODE  , usCmd == IDM_CNR_SFN_ALL_SORT_MODE  );
  343.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_MODE2 , usCmd == IDM_CNR_SFN_ALL_SORT_MODE2 );
  344.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_SIZE  , usCmd == IDM_CNR_SFN_ALL_SORT_SIZE  );
  345.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_HVPB  , usCmd == IDM_CNR_SFN_ALL_SORT_HVPB  );
  346.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_ATTR  , usCmd == IDM_CNR_SFN_ALL_SORT_ATTR  );
  347.             pMenuCnrAll->checkMenuItem(IDM_CNR_SFN_ALL_SORT_NAME  , usCmd == IDM_CNR_SFN_ALL_SORT_NAME  );
  348.  
  349.             /* resort container */
  350.             enableSorting();
  351.             break;
  352.     }
  353.     usSource = usSource;
  354.     fPointer = fPointer;
  355. }
  356.  
  357.  
  358. /**
  359.  * Record sort callback function - compares two records.
  360.  * @returns   >  0  when pRecord1  >  pRecord2
  361.  *            <  0  when pRecord1  <  pRecord2
  362.  *            == 0  when pRecord1 ==  pRecord2
  363.  * @param     pRecord1  Pointer to first record.
  364.  * @param     pRecord2  Pointer to second record.
  365.  */
  366. SHORT  kSFNContainer::sortCallBack(kCnrMiniRecord *pRecord1, kCnrMiniRecord *pRecord2)
  367. {
  368.     kSFNRecord *    pRec1 = (kSFNRecord *)pRecord1;
  369.     kSFNRecord *    pRec2 = (kSFNRecord *)pRecord2;
  370.  
  371.     if (pRec1 != NULL && pRec2 != NULL)
  372.     {
  373.         int iTmp = 1;
  374.         switch (usSortId)
  375.         {
  376.             case IDM_CNR_SFN_ALL_SORT_JFN:
  377.                 iTmp = pRec1->getJFN() - pRec2->getJFN();
  378.                 break;
  379.  
  380.             case IDM_CNR_SFN_ALL_SORT_SFN:
  381.                 iTmp = pRec1->getSFN() - pRec2->getSFN();
  382.                 break;
  383.  
  384.             case IDM_CNR_SFN_ALL_SORT_REFCNT:
  385.                 iTmp = strcmp(pRec1->getRefCnt(), pRec2->getRefCnt());
  386.                 break;
  387.  
  388.             case IDM_CNR_SFN_ALL_SORT_FLAGS:
  389.                 iTmp = strcmp(pRec1->getFlags(), pRec2->getFlags());
  390.                 break;
  391.  
  392.             case IDM_CNR_SFN_ALL_SORT_FLAGS2:
  393.                 iTmp = strcmp(pRec1->getFlags2(), pRec2->getFlags2());
  394.                 break;
  395.  
  396.             case IDM_CNR_SFN_ALL_SORT_MODE:
  397.                 iTmp = strcmp(pRec1->getMode(), pRec2->getMode());
  398.                 break;
  399.  
  400.             case IDM_CNR_SFN_ALL_SORT_MODE2:
  401.                 iTmp = strcmp(pRec1->getMode2(), pRec2->getMode2());
  402.                 break;
  403.  
  404.             case IDM_CNR_SFN_ALL_SORT_SIZE:
  405.                 iTmp = strcmp(pRec1->getSize(), pRec2->getSize());
  406.                 break;
  407.  
  408.             case IDM_CNR_SFN_ALL_SORT_HVPB:
  409.                 iTmp = strcmp(pRec1->gethVPB(), pRec2->gethVPB());
  410.                 break;
  411.  
  412.             case IDM_CNR_SFN_ALL_SORT_ATTR:
  413.                 iTmp = strcmp(pRec1->getAttr(), pRec2->getAttr());
  414.                 break;
  415.  
  416.             case IDM_CNR_SFN_ALL_SORT_NAME:
  417.                 iTmp = strcmp(pRec1->getName(), pRec2->getName());
  418.                 break;
  419.         }
  420.         return (SHORT)((iTmp > 0) ? 1 : (iTmp < 0) ? -1 : 0);
  421.     }
  422.     return 1;
  423. }
  424.  
  425.  
  426.  
  427.  
  428.  
  429. /**
  430.  * Constructor.
  431.  * @param     hwndDlg   Handle to dialog window.
  432.  * @param     ulCnrId   ID of the container dialog item in hwndDlg.
  433.  * @param     usPid      = 0xFFFF: View all SFNs.
  434.  *                      != 0:      View only SFNs for the given process.
  435.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  436.  */
  437. kSFNContainer::kSFNContainer(HWND hwndDlg, ULONG ulCnrId, USHORT usPid /* = 0xFFFF*/) throw(kError)
  438.     : kDetailCnr(WinWindowFromID(hwndDlg, ulCnrId),
  439.                  0,
  440.                  "System File Numbers (SFN) Overview",
  441. #if 0 //JFN is disabled due to Bug/Feature in _qsProcFS.
  442.                  kSFNRecord::cFieldInfo - (usPid < 0xFFFF ? 0 : 1),
  443.                  (PFIELDINFO)&kSFNRecord::aFieldInfo[usPid < 0xFFFF ? 0 : 1]),
  444. #else
  445.                  kSFNRecord::cFieldInfo - 1,
  446.                  (PFIELDINFO)&kSFNRecord::aFieldInfo[1]),
  447. #endif
  448.     usPid(usPid), pCurRecord(NULL), pMenuCnrAll(NULL), usSortId(0xFFFF)
  449. {
  450.     /*
  451.      * Create menu, set default sorting and enable sorting.
  452.      */
  453.     pMenuCnrAll = new kMenuBase(IDM_CNR_SFN_ALL, NULLHANDLE, hwndCnr);
  454.     #if 0 //JFN is disabled due to Bug/Feature in _qsProcFS.
  455.     if (usPid < 0xFFFF)
  456.         usSortId = IDM_CNR_SFN_ALL_SORT_JFN;
  457.     else
  458.     #endif
  459.     {
  460.         pMenuCnrAll->enableMenuItem(IDM_CNR_SFN_ALL_SORT_JFN, FALSE);
  461.         usSortId = IDM_CNR_SFN_ALL_SORT_SFN;
  462.     }
  463.     enableSorting();
  464.     pMenuCnrAll->checkMenuItem(usSortId, TRUE);
  465. }
  466.  
  467.  
  468. /**
  469.  * Destructor.
  470.  */
  471. kSFNContainer::~kSFNContainer()
  472. {
  473. }
  474.  
  475.  
  476. /**
  477.  * Displays the popup menu for the container.
  478.  * @param     usId     Container id.
  479.  * @param     pRecord  Pointer to the record which is selected by either the key
  480.  */
  481. VOID kSFNContainer::cnrContextMenu(USHORT usId, PRECORDCORE pRecord)
  482. {
  483.     if (pMenuCnrAll)
  484.     {
  485.         pCurRecord = (kSFNRecord*)pRecord;
  486.         setRecordEmphasis(pCurRecord, TRUE, CRA_SOURCE);
  487.         if (pRecord == NULL)
  488.             pMenuCnrAll->popup();
  489.         /*
  490.         else
  491.             pMenuModule->popup();
  492.         */
  493.     }
  494.     usId = usId;
  495. }
  496.  
  497.  
  498. /**
  499.  * Enter or double click on record in the container.
  500.  * This action will bring up the detail dialog for the record.
  501.  */
  502. VOID kSFNContainer::cnrEnter(USHORT usId, HWND hwndCnr, PRECORDCORE pRecord, ULONG fKey)
  503. {
  504.     if (pRecord != NULL)
  505.     {
  506.         pCurRecord = (kSFNRecord*)pRecord;
  507.         /* command(IDM_CNR_MOD_DETAILS, 0, 0); */
  508.     }
  509.     usId = usId;
  510.     fKey = fKey;
  511.     hwndCnr = hwndCnr;
  512. }
  513.  
  514.  
  515.  
  516. /**
  517.  * Updates the contents of the container.
  518.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  519.  */
  520. VOID  kSFNContainer::update()
  521. {
  522.     if (usPid < 0xFFFF)
  523.         insertSFNsPid();
  524.     else
  525.         insertSFNsAll();
  526. }
  527.  
  528.  
  529.