home *** CD-ROM | disk | FTP | other *** search
- /*
- STEALCDR.C -- Circumventing FileCdr to hook file system events
-
- Copyright (c) Dave Maxey 1992
-
- From Chapter 5 of "Undocumented Windows" (Addison-Wesley 1992)
- by Andrew Schulman, Dave Maxey and Matt Pietrek
-
- Build using: WINIOBC STEALCDR HANDLES (for Borland C++ v3.00)
- WINIOMS STEALCDR HANDLES (for Microsoft C/SDK)
- */
-
- #include <windows.h>
- #include <toolhelp.h>
- #include <dos.h>
- #include "wmhandlr.h"
- #include "winio.h"
- #include "handles.h"
-
-
- #define WM_FILESYSCHANGE 0x0034
-
- //extern FARPROC FAR PASCAL FileCdr(FARPROC lpfnFileSysChangeNotifyProc);
- void GetSetFileCdr(BOOL bSet, FARPROC *lpfn, HANDLE *ph);
- BOOL IsATask(HANDLE h);
- WORD far *GetTHH(void);
-
- FARPROC lpfnCallbackPrev = NULL;
- FARPROC lpfnCallbackOurs;
- HANDLE hTaskPrev = NULL;
- HANDLE hTaskOurs;
- LPVOID lpTHH;
-
- typedef struct { BYTE byAction; LPSTR szAction; } ACTION;
- ACTION action[] = {
- { 0x3C, "Create file" },
- { 0x41, "Delete file" },
- { 0x56, "Rename file/directory" },
- { 0x5A, "Create unique file" },
- { 0x43, "Get/set file attrs" },
- { 0x57, "Set file date/time" },
- { 0x5B, "Create new file" },
- { 0x39, "Create directory" },
- { 0x3A, "Delete directory" },
- { 0x6C, "Extended open" },
- { 0, 0 } };
-
-
- #define THH_OFS_FILECDR_30 0x0185
- #define THH_OFS_FILECDR_31 0x00FE
-
- void GetSetFileCdr(BOOL bSet, FARPROC *lpfn, HANDLE *ph)
- {
- LPVOID lp = lpTHH;
-
- (DWORD) lp += (GetVersion() >= 0x0a03) ? THH_OFS_FILECDR_31
- : THH_OFS_FILECDR_30;
-
- if (bSet)
- {
- *((FARPROC FAR *) lp)++ = *lpfn;
- *((HANDLE FAR *) lp) = *ph;
- }
- else
- {
- *lpfn = *((FARPROC FAR *) lp)++;
- *ph = *((HANDLE FAR *) lp);
- }
- }
-
-
-
- void PutBackPrev(HWND hwnd)
- {
- // Deinstall our callback function and reinstall whoever was
- // there before if they are still there
- if (! IsATask(hTaskPrev))
- {
- lpfnCallbackPrev = NULL;
- hTaskPrev = NULL;
- }
- GetSetFileCdr(TRUE, &lpfnCallbackPrev, &hTaskPrev);
-
- FreeProcInstance(lpfnCallbackOurs);
- }
-
-
- long fsc_handler(HWND hwnd, WORD wMsg, WORD wParam, DWORD lParam)
- {
- printf("WM_FILESYSCHANGE %Fs, l=%08X\n",
- action[wParam].szAction, lParam);
- return 0;
- }
-
-
- char *GetModuleNameFromTask(HANDLE handle)
- {
- TASKENTRY te;
- static char name[40];
-
- te.dwSize = sizeof(te);
- if ( TaskFindHandle(&te, handle) )
- {
- lstrcpy(name, te.szModule);
- return name;
- }
-
- lstrcpy(name, "**UNKNOWN**");
- return name;
- }
-
- void FAR PASCAL _export FileSysChange(WORD wActionCode, LPSTR lpszFilestring)
- {
- int i;
- static char buf[128];
-
- // Locate string representation of action code
- for (i = 0; action[i].byAction; i++)
- if (HIBYTE(wActionCode) == action[i].byAction) break;
-
- // We can't call anything that will use vsprintf, since it
- // relies on SS == DS which is not true in SMALL model
- wsprintf(buf,
- action[i].byAction ? "Module %s, %s: %s" : "Module %s, %04lX: %s",
- (LPSTR) GetModuleNameFromTask(GetCurrentTask()),
- action[i].byAction ? action[i].szAction : (DWORD) wActionCode,
- lpszFilestring);
- puts(buf);
-
- // Trying to be generous, but may backfire
- if (lpfnCallbackPrev)
- if (IsATask(hTaskPrev))
- (*lpfnCallbackPrev)(wActionCode, lpszFilestring);
- else
- {
- lpfnCallbackPrev = NULL;
- hTaskPrev = NULL;
- }
- }
-
-
- int main()
- {
- winio_about("STEALCDR"
- "\nCircumventing FileCdr to hook file system events"
- "\n\nFrom Chapter 5 of"
- "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
- "\nby Andrew Schulman, David Maxey and Matt Pietrek"
- );
-
- lpfnCallbackOurs = MakeProcInstance((FARPROC) FileSysChange, __hInst);
- hTaskOurs = GetCurrentTask();
-
- if (! (lpTHH = GetTHH()))
- fail("Could not locate KERNEL's DGROUP.");
-
- GetSetFileCdr(FALSE, &lpfnCallbackPrev, &hTaskPrev);
- if (lpfnCallbackPrev != NULL)
- printf("Someone already had FileCdr!\n");
-
- printf("Installing our callback function.\n");
- GetSetFileCdr(TRUE, &lpfnCallbackOurs, &hTaskOurs);
-
- wmhandler_set(__hMainWnd, WM_FILESYSCHANGE, (WMHANDLER) fsc_handler);
-
- winio_onclose(__hMainWnd, (DESTROY_FUNC) PutBackPrev);
- return 0;
- }
-
-
- #define TDB_SIGNATURE 0x4454
- #define TDB_OFS_SIGNATURE 0xFA
-
- BOOL IsATask(HANDLE h)
- {
- WORD wLen = 0;
-
- // Is handle a valid selector
- _asm mov bx, [h];
- _asm or bx, bx;
- _asm jz done;
- _asm lsl ax, bx
- _asm jnz done;
- _asm mov [wLen], ax;
- done:
- if (!wLen || (wLen < TDB_OFS_SIGNATURE + 2))
- return FALSE;
-
- return *((WORD far *) MK_FP(h, TDB_OFS_SIGNATURE)) == TDB_SIGNATURE;
- }
-
-
- #define THH_OFS 0x10
-
- #define NEMAGIC 0x454E
-
- #define MAGIC(lpNEhdr) *((WORD FAR *) &lpNEhdr[0])
- #define DGROUP(lpNEhdr) *((WORD FAR *) &lpNEhdr[0x0e])
- #define SEGTAB(lpNEhdr) *((WORD FAR *) &lpNEhdr[0x22])
-
- typedef struct {
- WORD ns_sector, ns_cbseg, ns_flags, ns_minalloc, ns_seg;
- } SEG;
-
- WORD far *GetTHH(void)
- {
- HANDLE hMod;
- BYTE far *nehdr;
- SEG far *segtab;
- WORD dgroup;
-
- if (GetVersion() >= 0x0a03)
- return (WORD far *)
- GetProcAddress(GetModuleHandle("KERNEL"), "THHOOK");
-
- nehdr = MK_FP(hMod = GetModuleHandle("KERNEL"), 0);
-
- if (MAGIC(nehdr) != NEMAGIC) return 0;
-
- segtab = MK_FP(hMod, SEGTAB(nehdr));
- dgroup = DGROUP(nehdr);
-
- return MK_FP(segtab[dgroup - 1].ns_seg, THH_OFS);
- }
-
-
-