home *** CD-ROM | disk | FTP | other *** search
/ Software Collection (I) / TOOLS.iso / b11 / 1.img / CHAP4.ZIP / TASKWLK2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-09  |  4.1 KB  |  140 lines

  1. /*
  2.     TASKWLK2.C
  3.  
  4.     From Chapter 4 of "Undocumented Windows" (Addison Wesley 1992)
  5.     by Andrew Schulman, Dave Maxey and Matt Pietrek
  6.         
  7.     Build using: WINIOBC TASKWLK2 (for Borland C++ v3.00)
  8.                  WINIOMS TASKWLK2 (for Microsoft C/SDK)
  9. */
  10.  
  11. #include <string.h>
  12. #include <dos.h>
  13. #include "windows.h"
  14. #include "wmhandlr.h"
  15. #include "winio.h"
  16.  
  17. /**********************************************************************/
  18.  
  19. #ifndef __BORLANDC__ 
  20. #define MK_FP(a,b)  ((void far *)(((unsigned long)(a) << 16) | (b))) 
  21. #endif 
  22. #define TD_SIGN     0x4454  /* 'TD' = Task Database */
  23. #define OFS_TD_SIGN 0xFA    /* location of 'TD' signature in Task DB */
  24.  
  25. BOOL IsValidTask(WORD w)
  26. {
  27.     extern DWORD FAR PASCAL GetSelectorLimit(WORD w);
  28.     WORD far *lpwMaybeTask;
  29.     if (! w)
  30.         return FALSE;
  31.     if (GetSelectorLimit(w) < (OFS_TD_SIGN + 2))
  32.         return FALSE;
  33.     lpwMaybeTask = (WORD far *) MK_FP(w, OFS_TD_SIGN);
  34.     return (*lpwMaybeTask == TD_SIGN);
  35. }
  36.  
  37. /* cheap version: no error checking */
  38. void GetTaskCurDir(HANDLE htask, char *buf)
  39. {
  40.     char far *fp = MK_FP(htask, 0x66);  // offset of pwd in TDB
  41.     buf[0] = *fp - 0x80 + 'A';          // drive letter - ignore warning!
  42.     buf[1] = ':';
  43.     _fstrncpy(&buf[2], &fp[1], 0x44);
  44.     buf[0x46] = '\0';
  45. }
  46.  
  47. /* cheap version does no error checking */
  48. void GetTaskModuleName(HANDLE htask, char *modname)
  49. {
  50.     char far *fp;
  51.     char *p=modname;
  52.     int i;
  53.     /* Copy the modname name at offset 0F2h in the Task Database */
  54.     for (i=0, fp=MK_FP(htask,0xf2); i<8; i++, p++, fp++)
  55.         *p = *fp;
  56.     *p = '\0';
  57. }
  58.  
  59. /**********************************************************************/
  60.     
  61. static HWND hwnd = 0;
  62. static WORD volatile numtasks = 0;
  63.  
  64. /* returns number of tasks found */
  65. int taskwalk(void)
  66. {
  67.     /* GetCurrentTask is documented, but only with WORD retval */
  68.     /* Ignore compiler warning about indirection to different types (MSC) */
  69.     /* or suspicious pointer conversion (BC) */
  70.     DWORD (FAR PASCAL *GetCurrentTaskD)(void) = GetCurrentTask;
  71.  
  72.     WORD wNextTask = HIWORD(GetCurrentTaskD()); // get base of linked list
  73.     WORD wNumTasks = 0;
  74.  
  75.     winio_clear(hwnd);
  76.     winio_setpaint(hwnd, FALSE); // no yield while walking task list
  77.     for (;;)
  78.     {
  79.         char modname[9];
  80.         GetTaskModuleName(wNextTask, modname);
  81.         printf("%04x\t%s", wNextTask, modname);
  82.         if (wNextTask == GetCurrentTask())
  83.             printf(" <== current task");
  84.         printf("\n");
  85.         wNumTasks++;
  86.         /* Get the handle of the next task from offset 0 in the Task DB */
  87.         if ((wNextTask = *((WORD far *) MK_FP(wNextTask, 0))) == 0)
  88.             break;
  89.     }
  90.     winio_setpaint(hwnd, TRUE);
  91.     return wNumTasks;
  92. }
  93.  
  94. long on_time(HWND hwnd, unsigned message, WORD wParam, LONG lParam)
  95. {
  96.     // sometimes task list is in unstable state
  97.     while (numtasks != GetNumTasks())
  98.     {
  99.         MessageBeep(0);
  100.         numtasks = taskwalk();
  101.     }
  102.     return 0;
  103. }
  104.  
  105. void clickfunc(HWND hwnd, LPSTR line, int linenum)
  106. {
  107.     char buf[256];
  108.     HANDLE htask;
  109.     _fstrcpy(buf, line);
  110.     sscanf(buf, "%04X", &htask);  // figure out what task was clicked on
  111.     if (! IsValidTask(htask))
  112.     {
  113.         winio_warn(FALSE, buf, "Stale task list: no longer valid");
  114.         numtasks = 0;   // force a new taskwalk
  115.     }
  116.     else
  117.     {
  118.         HWND prev = winio_setcurrent(winio_window(buf, 0, WW_HASMENU));
  119.         GetTaskCurDir(htask, buf);
  120.         printf("Current directory: %s\n", buf);
  121.         winio_setcurrent(prev);
  122.     }
  123. }
  124.         
  125. int main()
  126. {
  127.     winio_about("TASKWLK2\nIllustrates feature of GetCurrentTask return"
  128.         "\n\nFrom Chapter 4 of"
  129.         "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
  130.         "\nby Andrew Schulman, David Maxey and Matt Pietrek");
  131.     hwnd = winio_current();
  132.     winio_setlinefn(hwnd, clickfunc);
  133.     numtasks = taskwalk();
  134.     wmhandler_set(hwnd, WM_TIMER, on_time);
  135.     if (! SetTimer(hwnd, 1, 1000, NULL)) // once a second
  136.         fail("can't create timer");
  137.     return 0;
  138. }
  139.  
  140.