filemon.c
上传用户:ibmxxxxx
上传日期:2007-01-03
资源大小:35k
文件大小:12k
源码类别:

系统编程

开发平台:

Visual C++

  1. /*
  2. FILEMON.C -- File monitoring VxD for Windows 95
  3. For Win32 app: CONLDR.C
  4. Stan Mitchell
  5. See Stan Mitchell, "Monitoring Windows 95 File Activity in Ring 0,"
  6. Windows/DOS Developer's Journal, July 1995, pp. 6-24.
  7. Also see ftp://ftp.ora.com/pub/examples/windows/win95.update/regwiz.html
  8. */
  9. /*****    Listing 1    FILEMON.C   *****/
  10. #include <string.h>
  11. #define WANTVXDWRAPS
  12. #include <basedef.h>
  13. #include <vmm.h>
  14. #include <debug.h>
  15. #include <vwin32.h>
  16. #include <winerror.h>
  17. #include <vxdwraps.h>
  18. #include <ifs.h>
  19. enum IFSMGR_SERVICES { __UniToBCSPath=0x00400041,
  20.     __IFSMgr_InstallFileSystemApiHook=0x00400067,
  21.     __IFSMgr_RemoveFileSystemApiHook=0x00400068 };
  22. /* The buffer contains 256 LINEs, the first is reserved */
  23. /* for status, lines 0 through 254 are used for output lines */
  24. #define MAXLINE 254
  25. typedef char LINE[128];
  26. #pragma VxD_LOCKED_DATA_SEG
  27. char* szOp[] = { "Read", "Write", "FndNext", "FcnNext",
  28.   "?","?","?","?","?","?", "Seek", "Close", "Commit",
  29.   "FLocks", "FTimes", "PipeReq", "HdlInfo", "EnumHdl",
  30.   "FndClose", "FcnClose", "?","?","?","?","?","?","?",
  31.   "?","?","?", "Conn", "Delete", "Dir", "FAttrib",
  32.   "Flush", "DiskInfo", "Open", "Rename", "Search",
  33.   "Query", "DisConn", "UNCPipeReq", "Ioctl", "DiskParm",
  34.   "FndOpen", "Dasdio" };
  35. ppIFSFileHookFunc ppPrevHook; /* the previous hooker */
  36. HTIMEOUT hTimeOut  = 0;
  37. DWORD hVMEvent     = 0;
  38. HANDLE hEventRing0 = 0;
  39. HVM hSysVM;
  40. LINE* pLineBuf     = NULL; /* buffer for output lines */
  41. DWORD* pdw         = NULL;
  42. int nLastLine      = -1;
  43. #define DIOC_REQEVENTS 1
  44. #define DIOC_SHUTDOWN  2
  45. #pragma VxD_LOCKED_CODE_SEG
  46. #pragma intrinsic(strcpy,strcat,memcpy)
  47. /* Wrapper for the IFS Mgr Service, UniToBCSPath */
  48. UINT __declspec( naked )
  49. UniToBCSDrvPath( UCHAR* pStr, PathElement* pPth,
  50.                  UINT maxL, int cSet, int drv ) {
  51.     _asm push ebp      _asm mov ebp,esp
  52.     _asm push ebx
  53.     _asm mov  ebx,[pStr]
  54.     _asm mov  eax,[drv]
  55.     _asm cmp  al,0ffh /* UNC volume? */
  56.     _asm jz   skipdrv
  57.     _asm add  al,'@'
  58.     _asm mov  byte ptr [ebx],al
  59.     _asm inc  ebx
  60.     _asm mov  byte ptr [ebx],':'
  61.     _asm inc  ebx
  62.  skipdrv:
  63.     _asm push [cSet]  /* Arguments pushed */
  64.     _asm push [maxL]  /* in cdecl order */
  65.     _asm push [pPth]
  66.     _asm push ebx
  67.     VxDCall( UniToBCSPath );
  68.     _asm add esp,4*4
  69.     _asm pop ebx      /* eax returns byte cnt */
  70.     _asm leave   _asm ret
  71.     }
  72. /* Called as System VM Event */
  73. void __declspec( naked ) SetWin32Event( void ) {
  74.     _asm push ebp   _asm mov ebp,esp
  75.     _asm mov eax,[edx]
  76.     VxDCall( _VWIN32_SetWin32Event );
  77.     hVMEvent = 0;
  78.     _asm leave   _asm ret
  79.     }
  80. #define LPtr(a)        (&pLineBuf[idx][a])
  81. #ifdef SHOW_HANDLES
  82. #define AddResHdl(a)   _Sprintf(LPtr(a),"{%08lx} ",pir->ir_rh)
  83. #define AddFileHdl(a)  _Sprintf(LPtr(a),"[%08lx] ",pir->ir_fh)
  84. #define SkpFileHdl(a)  _Sprintf(LPtr(a), "%11s"," ")
  85. #else
  86. #define AddResHdl(a)   0
  87. #define AddFileHdl(a)  0
  88. #define SkpFileHdl(a)  0
  89. #endif
  90. #define AddUniPath(a,n) UniToBCSDrvPath( LPtr(a), pUniPath,
  91.                                        n, BCS_WANSI, drv)
  92. #define CatStr(s)      strcat(pLineBuf[idx],s)
  93. /* The FileSystem Hook Function */
  94. int __cdecl FileHook( pIFSFunc pfn,
  95.     int fn, int drv, int res,
  96.     int cp, pioreq pir )
  97.     {
  98.     int retc, idx, i;
  99.     PathElement* pUniPath;
  100.     unsigned short preOptions;
  101.     /* Go ahead and call down the chain to the FSD ...
  102.      *   we look at the IFSFunc only if it succeeds */
  103.     preOptions = pir->ir_options;
  104.     retc = (*(*ppPrevHook))( pfn, fn, drv, res, cp, pir );
  105.     if ( !hEventRing0 ) return retc;
  106.     // Functions which are included in this switch statement
  107.     //  are not monitored
  108.     switch( fn ) {
  109.         case IFSFN_FILETIMES:   /* "GetFTimes" */
  110.             if ( (pir->ir_flags != GET_MODIFY_DATETIME) &&
  111.                  (pir->ir_flags != GET_LAST_ACCESS_DATETIME) &&
  112.                  (pir->ir_flags != GET_CREATION_DATETIME) )
  113.                 break;
  114.         case IFSFN_READ:        /* "Read" */
  115.         case IFSFN_WRITE:       /* "Write" */
  116.         case IFSFN_SEEK:        /* "Seek" */
  117.         case IFSFN_CLOSE:       /* "Close" */
  118.         case IFSFN_FINDCLOSE:
  119.         case IFSFN_FCNCLOSE:
  120.         case IFSFN_FINDNEXT:    /* "Next" */
  121.         case IFSFN_FCNNEXT:
  122.             return retc;
  123.         }
  124.     /* Point to the Unicode path components of the file */
  125.     pUniPath = pir->ir_ppath->pp_elements;
  126.     _asm pushfd
  127.     _asm cli
  128.     if ( ++nLastLine > MAXLINE ) nLastLine=0;
  129.     idx = nLastLine;
  130.     _asm popfd
  131.     i = _Sprintf( pLineBuf[idx], " %3d %c %10s %c ",
  132.             idx, pir->ir_error ? 'e' : ' ', szOp[fn],
  133.             res & IFSFH_RES_CFSD ? 'c' : ' ' );
  134.     switch( fn )
  135.         {
  136.     case IFSFN_READ:    case IFSFN_WRITE:
  137.         i+=AddFileHdl(i); i+=AddResHdl(i);
  138.         _Sprintf( LPtr(i), "leng: %08lx %c%c",
  139.             pir->ir_length,
  140.             (preOptions & R0_SWAPPER_CALL) ? 's' : ' ',
  141.             (preOptions & R0_MM_READ_WRITE) ? 'm' : ' ' );
  142.         break;
  143.     case IFSFN_SEEK:        case IFSFN_CLOSE:
  144.     case IFSFN_FINDNEXT:    case IFSFN_FINDCLOSE:
  145.     case IFSFN_FCNNEXT:     case IFSFN_FCNCLOSE:
  146.     case IFSFN_COMMIT:      case IFSFN_ENUMHANDLE:
  147.     case IFSFN_FILELOCKS:
  148.         i+=AddFileHdl(i);  AddResHdl(i);
  149.         break;
  150.     case IFSFN_IOCTL16DRIVE: case IFSFN_SEARCH:
  151.         i+=SkpFileHdl(i);  i+=AddResHdl(i);
  152.         _Sprintf(LPtr(i),"SubFunction: %04X",pir->ir_flags);
  153.         break;
  154.     case IFSFN_QUERY:
  155.         i+=SkpFileHdl(i);  i+=AddResHdl(i);
  156.         i+=_Sprintf(LPtr(i),"Level %d ",preOptions);
  157.         break;
  158.     case IFSFN_DELETE:  case IFSFN_FINDOPEN:
  159.     case IFSFN_RENAME:
  160.         i+=SkpFileHdl(i);  i+=AddResHdl(i);
  161.         if ( fn == IFSFN_RENAME ) {
  162.             i+=AddUniPath(i,45);
  163.             pUniPath = pir->ir_ppath2->pp_elements;
  164.             if ( drv != 0xff ) i+=2;
  165.             CatStr(" -> "); i+=4;
  166.             AddUniPath(i,45);
  167.             }
  168.         else i+=AddUniPath(i,80);
  169.         break;
  170.     case IFSFN_CONNECT:
  171.         i+=SkpFileHdl(i);  AddResHdl(i);
  172.         switch( pir->ir_flags ) {
  173.         case RESTYPE_WILD:
  174.             CatStr("wild card"); break;
  175.         case RESTYPE_DISK:
  176.             CatStr("disk"); break;
  177.         case RESTYPE_SPOOL:
  178.             CatStr("spooled printer"); break;
  179.         case RESTYPE_CHARDEV:
  180.             CatStr("char device"); break;
  181.         case RESTYPE_IPC:
  182.             CatStr("ipc"); break;
  183.             }
  184.         break;
  185.     case IFSFN_FILEATTRIB:
  186.         if ( pir->ir_flags == GET_ATTRIBUTES )
  187.             memcpy( &pLineBuf[idx][8], "Get", 3 );
  188.         else memcpy( &pLineBuf[idx][8], "Set", 3 );
  189.         i+=SkpFileHdl(i);  i+=AddResHdl(i);
  190.         AddUniPath(i,80);
  191.         break;
  192.     case IFSFN_FILETIMES:
  193.         if ( (pir->ir_flags == GET_MODIFY_DATETIME) ||
  194.              (pir->ir_flags == GET_LAST_ACCESS_DATETIME) ||
  195.              (pir->ir_flags == GET_CREATION_DATETIME) )
  196.             memcpy( &pLineBuf[idx][9], "Get", 3 );
  197.         else memcpy( &pLineBuf[idx][9], "Set", 3 );
  198.         i+=AddFileHdl(i);  i+=AddResHdl(i);
  199.         break;
  200.     case IFSFN_DIR:
  201.         if ( pir->ir_flags == CREATE_DIR )
  202.             memcpy( &pLineBuf[idx][12], "Mk", 2 );
  203.         else if ( pir->ir_flags == DELETE_DIR )
  204.             memcpy( &pLineBuf[idx][12], "Rd", 2 );
  205.         else if ( pir->ir_flags == CHECK_DIR )
  206.             memcpy( &pLineBuf[idx][12], "Ck", 2 );
  207.         else memcpy( &pLineBuf[idx][11], "Qry", 3 );
  208.         i+=SkpFileHdl(i);  i+=AddResHdl(i);
  209.         AddUniPath(i,80);
  210.         break;
  211.     case IFSFN_OPEN:
  212.         i+=AddFileHdl(i); i+=AddResHdl(i);
  213.         AddUniPath(i,80);
  214.         if ( pir->ir_options == ACTION_CREATED )
  215.             memcpy( &pLineBuf[idx][11], "Create", 6 );
  216.         break;
  217.     case IFSFN_DISCONNECT:   case IFSFN_FLUSH:
  218.     case IFSFN_GETDISKINFO:  case IFSFN_GETDISKPARMS:
  219.     case IFSFN_DASDIO:
  220.         i+=SkpFileHdl(i);  AddResHdl(i);
  221.         break;
  222.         }
  223.     _asm pushfd
  224.     _asm cli
  225.     *pdw = idx; /* last completed line */
  226.     _asm popfd
  227.     return retc; /* make sure we return what the FSD did */
  228.     }
  229. void __declspec( naked ) DisplayFSDEvent( void )  {
  230.     _asm push ebp   _asm mov ebp,esp
  231.     hTimeOut = 0;
  232.     if ( hEventRing0 != 0 ) { 
  233.         _asm mov ebx,[hSysVM]
  234.         _asm mov esi,offset SetWin32Event
  235.         _asm mov edx,offset hEventRing0
  236.         VxDCall( Schedule_VM_Event );
  237.         _asm mov [hVMEvent],esi
  238.         }
  239.     _asm leave   _asm ret
  240.     }
  241. DWORD __stdcall W32_RequestEvents( DWORD dwDDB,
  242.                                    PDIOCPARAMETERS pD )
  243.     {
  244.     DWORD* pdwArgs;
  245.     if ( pdw == NULL ) { /* First time */
  246.         /* Check for valid arguments */
  247.         if ( pD->cbInBuffer != sizeof(DWORD)*2 )
  248.             return 1;
  249.         /* Get the parameters passed by the caller */
  250.         pdwArgs = (DWORD*)pD->lpvInBuffer;
  251.         /* hEventRing0, the handle to the ring 0 event */
  252.         hEventRing0 = (HANDLE)pdwArgs[0];
  253.         /* First line reserved for pointers */
  254.         pdw = (DWORD*)pdwArgs[1];
  255.         *pdw = *(pdw+1) = -1;
  256.         /* pLineBuf, circular buffer in which to
  257.          * store the file activity events */
  258.         pLineBuf = ((LINE*)pdwArgs[1])+1;
  259.         if (!_LinPageLock((DWORD)pdw>>12,8,PAGEMAPGLOBAL))
  260.             return 1; /* lock failed */
  261.         }
  262.     hTimeOut = Set_Global_Time_Out( DisplayFSDEvent, 250, 0 );
  263.     return 0;
  264.     }
  265. DWORD __stdcall
  266. W32_Shutdown( DWORD dwDDB, PDIOCPARAMETERS pD ) {
  267.     /* Remove our filesystem API hook */
  268.     _asm mov eax,OFFSET FileHook
  269.     _asm push eax
  270.     VxDCall( IFSMgr_RemoveFileSystemApiHook );
  271.     _asm add esp,4
  272.     return 0;
  273.     }
  274. /* Win32 interface for FileMon */
  275. int __stdcall
  276. CtrlMsg_W32DeviceIoControl( DWORD dwIoCtrlCode, /*ecx*/
  277.                             DWORD dwDDB,        /*ebx*/
  278.                             DWORD pDIOCParams ) /*esi*/
  279.     {
  280.     if ( dwIoCtrlCode == DIOC_OPEN ||
  281.          dwIoCtrlCode == DIOC_CLOSEHANDLE)
  282.         return 0L; /* tell Win32, VxD supports DEVIOCTL */
  283.     /* private Win32 API provided by FileMon */
  284.     if ( dwIoCtrlCode == DIOC_REQEVENTS )
  285.         return W32_RequestEvents(dwDDB,(PDIOCPARAMETERS)pDIOCParams);
  286.     if ( dwIoCtrlCode == DIOC_SHUTDOWN )
  287.         return W32_Shutdown(dwDDB,(PDIOCPARAMETERS)pDIOCParams);
  288.     return ERROR_NOT_SUPPORTED;
  289.     }
  290. #pragma VxD_PAGEABLE_CODE_SEG
  291. /*  Called when device is unloaded */
  292. int __stdcall CleanUp( void ) {
  293.     if (hTimeOut) Cancel_Time_Out(hTimeOut);
  294.     if (hVMEvent)  { _asm mov ebx,[hSysVM]
  295.                      _asm mov esi,[hVMEvent]
  296.                      VxDCall(Cancel_VM_Event);
  297.                    }
  298.     if (hEventRing0) { _asm mov eax,[hEventRing0]
  299.                        VxDCall(_VWIN32_CloseVxDHandle);
  300.                      }
  301.     _LinPageUnlock((DWORD)pdw>>12,8,PAGEMAPGLOBAL);
  302.     return(VXD_SUCCESS);
  303.     }
  304. /* Called when device is unloaded by VXDLDR */
  305. int __stdcall CtrlMsg_DynDeviceExit( void ) {
  306.     return CleanUp();
  307.     }
  308. /* Always called when the system is normally shutting down */
  309. int __stdcall
  310. CtrlMsg_SysVMTerminate( DWORD hSysVMHandle ) {
  311.     return CleanUp();
  312.     }
  313. #pragma VxD_ICODE_SEG
  314. /*  Called when Device is loaded by VXDLDR */
  315. int __stdcall CtrlMsg_DynDeviceInit( void ) {
  316.     /* Install the filesystem API hook */
  317.     hSysVM = Get_Sys_VM_Handle();
  318.     _asm mov eax,OFFSET FileHook
  319.     _asm push eax
  320.     VxDCall( IFSMgr_InstallFileSystemApiHook );
  321.     _asm add esp,4
  322.     _asm mov ppPrevHook,eax
  323.     return( ppPrevHook == 0 ? VXD_FAILURE
  324.                             : VXD_SUCCESS );
  325.     }
  326. /***************** end of file ******************/