home *** CD-ROM | disk | FTP | other *** search
- /*
- TASKWLK2.C
-
- From Chapter 4 of "Undocumented Windows" (Addison Wesley 1992)
- by Andrew Schulman, Dave Maxey and Matt Pietrek
-
- Build using: WINIOBC TASKWLK2 (for Borland C++ v3.00)
- WINIOMS TASKWLK2 (for Microsoft C/SDK)
- */
-
- #include <string.h>
- #include <dos.h>
- #include "windows.h"
- #include "wmhandlr.h"
- #include "winio.h"
-
- /**********************************************************************/
-
- #ifndef __BORLANDC__
- #define MK_FP(a,b) ((void far *)(((unsigned long)(a) << 16) | (b)))
- #endif
- #define TD_SIGN 0x4454 /* 'TD' = Task Database */
- #define OFS_TD_SIGN 0xFA /* location of 'TD' signature in Task DB */
-
- BOOL IsValidTask(WORD w)
- {
- extern DWORD FAR PASCAL GetSelectorLimit(WORD w);
- WORD far *lpwMaybeTask;
- if (! w)
- return FALSE;
- if (GetSelectorLimit(w) < (OFS_TD_SIGN + 2))
- return FALSE;
- lpwMaybeTask = (WORD far *) MK_FP(w, OFS_TD_SIGN);
- return (*lpwMaybeTask == TD_SIGN);
- }
-
- /* cheap version: no error checking */
- void GetTaskCurDir(HANDLE htask, char *buf)
- {
- char far *fp = MK_FP(htask, 0x66); // offset of pwd in TDB
- buf[0] = *fp - 0x80 + 'A'; // drive letter - ignore warning!
- buf[1] = ':';
- _fstrncpy(&buf[2], &fp[1], 0x44);
- buf[0x46] = '\0';
- }
-
- /* cheap version does no error checking */
- void GetTaskModuleName(HANDLE htask, char *modname)
- {
- char far *fp;
- char *p=modname;
- int i;
- /* Copy the modname name at offset 0F2h in the Task Database */
- for (i=0, fp=MK_FP(htask,0xf2); i<8; i++, p++, fp++)
- *p = *fp;
- *p = '\0';
- }
-
- /**********************************************************************/
-
- static HWND hwnd = 0;
- static WORD volatile numtasks = 0;
-
- /* returns number of tasks found */
- int taskwalk(void)
- {
- /* GetCurrentTask is documented, but only with WORD retval */
- /* Ignore compiler warning about indirection to different types (MSC) */
- /* or suspicious pointer conversion (BC) */
- DWORD (FAR PASCAL *GetCurrentTaskD)(void) = GetCurrentTask;
-
- WORD wNextTask = HIWORD(GetCurrentTaskD()); // get base of linked list
- WORD wNumTasks = 0;
-
- winio_clear(hwnd);
- winio_setpaint(hwnd, FALSE); // no yield while walking task list
- for (;;)
- {
- char modname[9];
- GetTaskModuleName(wNextTask, modname);
- printf("%04x\t%s", wNextTask, modname);
- if (wNextTask == GetCurrentTask())
- printf(" <== current task");
- printf("\n");
- wNumTasks++;
- /* Get the handle of the next task from offset 0 in the Task DB */
- if ((wNextTask = *((WORD far *) MK_FP(wNextTask, 0))) == 0)
- break;
- }
- winio_setpaint(hwnd, TRUE);
- return wNumTasks;
- }
-
- long on_time(HWND hwnd, unsigned message, WORD wParam, LONG lParam)
- {
- // sometimes task list is in unstable state
- while (numtasks != GetNumTasks())
- {
- MessageBeep(0);
- numtasks = taskwalk();
- }
- return 0;
- }
-
- void clickfunc(HWND hwnd, LPSTR line, int linenum)
- {
- char buf[256];
- HANDLE htask;
- _fstrcpy(buf, line);
- sscanf(buf, "%04X", &htask); // figure out what task was clicked on
- if (! IsValidTask(htask))
- {
- winio_warn(FALSE, buf, "Stale task list: no longer valid");
- numtasks = 0; // force a new taskwalk
- }
- else
- {
- HWND prev = winio_setcurrent(winio_window(buf, 0, WW_HASMENU));
- GetTaskCurDir(htask, buf);
- printf("Current directory: %s\n", buf);
- winio_setcurrent(prev);
- }
- }
-
- int main()
- {
- winio_about("TASKWLK2\nIllustrates feature of GetCurrentTask return"
- "\n\nFrom Chapter 4 of"
- "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
- "\nby Andrew Schulman, David Maxey and Matt Pietrek");
- hwnd = winio_current();
- winio_setlinefn(hwnd, clickfunc);
- numtasks = taskwalk();
- wmhandler_set(hwnd, WM_TIMER, on_time);
- if (! SetTimer(hwnd, 1, 1000, NULL)) // once a second
- fail("can't create timer");
- return 0;
- }
-
-