FILEMON.C
上传用户:hmgghm
上传日期:2007-01-07
资源大小:335k
文件大小:162k
源码类别:

文件操作

开发平台:

Visual C++

  1.         strcpy( Buffer, "NOT A DIRECTORY" );
  2.         break;
  3.     case STATUS_NO_SUCH_FILE:
  4.         strcpy( Buffer, "NO SUCH FILE" );
  5.         break;
  6.     case STATUS_OBJECT_NAME_COLLISION:
  7.         strcpy( Buffer, "NAME COLLISION" );
  8.         break;
  9.     case STATUS_NONEXISTENT_SECTOR:
  10.         strcpy( Buffer, "NONEXISTENT SECTOR" );
  11.         break;
  12.     case STATUS_BAD_NETWORK_PATH:
  13.         strcpy( Buffer, "BAD NETWORK PATH" );
  14.         break;
  15.     case STATUS_OBJECT_PATH_NOT_FOUND:
  16.         strcpy( Buffer, "PATH NOT FOUND" );
  17.         break;
  18.     case STATUS_NO_SUCH_DEVICE:
  19.         strcpy( Buffer, "INVALID PARAMETER" );
  20.         break;
  21.     case STATUS_END_OF_FILE:
  22.         strcpy( Buffer, "END OF FILE" );
  23.         break;
  24.     case STATUS_NOTIFY_CLEANUP:
  25.         strcpy( Buffer, "NOTIFY CLEANUP" );
  26.         break;
  27.     case STATUS_BUFFER_OVERFLOW:
  28.         strcpy( Buffer, "BUFFER OVERFLOW" );
  29.         break;
  30.     case STATUS_NO_MORE_ENTRIES:
  31.         strcpy( Buffer, "NO MORE ENTRIES" );
  32.         break;
  33.     case STATUS_ACCESS_DENIED:
  34.         strcpy( Buffer, "ACCESS DENIED" );
  35.         break;
  36.     case STATUS_SHARING_VIOLATION:
  37.         strcpy( Buffer, "SHARING VIOLATION" );
  38.         break;       
  39.     case STATUS_INVALID_PARAMETER:
  40.         strcpy( Buffer, "INVALID PARAMETER" );
  41.         break;       
  42.     case STATUS_OPLOCK_BREAK_IN_PROGRESS:
  43.         strcpy( Buffer, "OPLOCK BREAK" );
  44.         break;        
  45.     case STATUS_OPLOCK_NOT_GRANTED:
  46.         strcpy( Buffer, "OPLOCK NOT GRANTED" );
  47.         break;
  48.     case STATUS_FILE_LOCK_CONFLICT:
  49.         strcpy( Buffer, "FILE LOCK CONFLICT" );
  50.         break;
  51.     case STATUS_PENDING:
  52.         strcpy( Buffer, "PENDING" );
  53.         break;       
  54.     case STATUS_REPARSE:
  55.         strcpy( Buffer, "REPARSE" );
  56.         break;       
  57.     case STATUS_MORE_ENTRIES:
  58.         strcpy( Buffer, "MORE" );
  59.         break;       
  60.     case STATUS_DELETE_PENDING:
  61.         strcpy( Buffer, "DELETE PEND" );
  62.         break;       
  63.     case STATUS_CANNOT_DELETE:
  64.         strcpy( Buffer, "CANNOT DELETE" );
  65.         break;       
  66.     case STATUS_LOCK_NOT_GRANTED:
  67.         strcpy( Buffer, "NOT GRANTED" );
  68.         break;       
  69.     case STATUS_FILE_IS_A_DIRECTORY:
  70.         strcpy( Buffer, "IS DIRECTORY" );
  71.         break;
  72.     case STATUS_ALREADY_COMMITTED:
  73.         strcpy( Buffer, "ALREADY COMMITTED" );
  74.         break;
  75.     case STATUS_INVALID_EA_FLAG:
  76.         strcpy( Buffer, "INVALID EA FLAG" );
  77.         break;
  78.     case STATUS_INVALID_INFO_CLASS:
  79.         strcpy( Buffer, "INVALID INFO CLASS" );
  80.         break;
  81.     case STATUS_INVALID_HANDLE:
  82.         strcpy( Buffer, "INVALID HANDLE" );
  83.         break;
  84.     case STATUS_INVALID_DEVICE_REQUEST:
  85.         strcpy( Buffer, "INVALID DEVICE REQUEST" );
  86.         break;
  87.     case STATUS_WRONG_VOLUME:
  88.         strcpy( Buffer, "WRONG VOLUME" );
  89.         break;
  90.     case STATUS_UNEXPECTED_NETWORK_ERROR:
  91.         strcpy( Buffer, "NETWORK ERROR" );
  92.         break;
  93.     case STATUS_DFS_UNAVAILABLE:
  94.         strcpy( Buffer, "DFS UNAVAILABLE" );
  95.         break;
  96.     case STATUS_LOG_FILE_FULL:
  97.         strcpy( Buffer, "LOG FILE FULL" );
  98.      break;
  99.         //
  100.         // Named pipe errors
  101.         //
  102.     case STATUS_INSTANCE_NOT_AVAILABLE:
  103.         strcpy( Buffer, "INSTANCE NOT AVAILABLE" );
  104.         break;
  105.     case STATUS_PIPE_NOT_AVAILABLE:
  106.         strcpy( Buffer, "PIPE NOT AVAILABLE" );
  107.         break;
  108.     case STATUS_INVALID_PIPE_STATE:
  109.         strcpy( Buffer, "INVALID PIPE STATE" );
  110.         break;
  111.     case STATUS_PIPE_BUSY:
  112.         strcpy( Buffer, "PIPE BUSY" );
  113.         break;
  114.     case STATUS_PIPE_DISCONNECTED:
  115.         strcpy( Buffer, "PIPE DISCONNECTED" );
  116.         break;
  117.     case STATUS_PIPE_CLOSING:
  118.         strcpy( Buffer, "PIPE CLOSING" );
  119.         break;
  120.     case STATUS_PIPE_CONNECTED:
  121.         strcpy( Buffer, "PIPE CONNECTED" );
  122.         break;
  123.     case STATUS_PIPE_LISTENING:
  124.         strcpy( Buffer, "PIPE LISTENING" );
  125.         break;
  126.     case STATUS_INVALID_READ_MODE:
  127.         strcpy( Buffer, "INVALID READ MODE" );
  128.         break;
  129.     case STATUS_PIPE_EMPTY:
  130.         strcpy( Buffer, "PIPE EMPTY" );
  131.         break;
  132.     case STATUS_PIPE_BROKEN:
  133.         strcpy( Buffer, "PIPE BROKEN" );
  134.         break;
  135.     case STATUS_IO_TIMEOUT:
  136.         strcpy( Buffer, "IO TIMEOUT" );
  137.         break;
  138.     default:
  139.         sprintf( Buffer, "* 0x%X", RetStat );
  140.         break;
  141.     }
  142.     return Buffer;
  143. }
  144. //----------------------------------------------------------------------
  145. //
  146. // CreateOptionsString
  147. //
  148. // Takes the options mask and returns a string that represents
  149. // the settings.
  150. //
  151. //----------------------------------------------------------------------
  152. PCHAR CreateOptionsString( ULONG Options, PCHAR Buffer )
  153. {
  154.     ULONG  disposition;
  155.     Buffer[0] = 0;
  156.     disposition = (Options >> 24) & 0xFF;
  157.     
  158.     switch( disposition ) {
  159.     case FILE_SUPERSEDE:
  160.         strcat( Buffer, "Supersede " );
  161.         break;
  162.     case FILE_CREATE:
  163.         strcat( Buffer, "Create " );
  164.         break;
  165.     case FILE_OPEN_IF:
  166.         strcat( Buffer, "OpenIf " );
  167.         break;
  168.     case FILE_OPEN:
  169.         strcat( Buffer, "Open " );
  170.         break;
  171.     case FILE_OVERWRITE:
  172.         strcat( Buffer, "Overwrite " );
  173.         break;
  174.     case FILE_OVERWRITE_IF:
  175.         strcat( Buffer, "OverwriteIf " );
  176.         break;
  177.     }
  178.     if( Options & FILE_DIRECTORY_FILE ) 
  179.         strcat( Buffer, "Directory " );
  180.     if( Options & FILE_WRITE_THROUGH )
  181.         strcat( Buffer, "WriteThrough " );
  182.     if( Options & FILE_SEQUENTIAL_ONLY )
  183.         strcat( Buffer, "Sequential " );
  184.     if( Options & FILE_NO_INTERMEDIATE_BUFFERING )
  185.         strcat( Buffer, "NoBuffer" );
  186.     return Buffer;
  187. }
  188. //----------------------------------------------------------------------
  189. //
  190. // CreateAttributesString
  191. //
  192. // Take attributes and return a string that represents them.
  193. //
  194. //----------------------------------------------------------------------
  195. PCHAR CreateAttributesString( USHORT Attributes, PCHAR Buffer )
  196. {
  197.     Buffer[0] = 0;
  198.     if( !Attributes ) {
  199.         strcat( Buffer, "Any" );
  200.         return Buffer;
  201.     }
  202.     if( Attributes & FILE_ATTRIBUTE_COMPRESSED) strcat( Buffer, "C" );
  203.     if( Attributes & FILE_ATTRIBUTE_TEMPORARY) strcat( Buffer, "T" );
  204.     if( Attributes & FILE_ATTRIBUTE_DIRECTORY) strcat( Buffer, "D" );
  205.     if( Attributes & FILE_ATTRIBUTE_READONLY) strcat( Buffer, "R" );
  206.     if( Attributes & FILE_ATTRIBUTE_HIDDEN )  strcat( Buffer, "H" );
  207.     if( Attributes & FILE_ATTRIBUTE_SYSTEM )  strcat( Buffer, "S" );
  208.     if( Attributes & FILE_ATTRIBUTE_ARCHIVE ) strcat( Buffer, "A" );
  209.     if( Attributes & FILE_ATTRIBUTE_NORMAL )  strcat( Buffer, "N" );
  210.     return Buffer;
  211. }
  212. //----------------------------------------------------------------------
  213. //                F A S T I O   R O U T I N E S
  214. //
  215. // NOTE: There is no need for us to worry about accessing fastio 
  216. // parameters within try/except because the I/O manager has either
  217. // probed the validity of the arguments or calls within its own 
  218. // try/except block (it doesn't trust us anyway :-) ).
  219. //
  220. //----------------------------------------------------------------------
  221. //----------------------------------------------------------------------
  222. //
  223. // FilemonFastIoCheckIfPossible
  224. //
  225. //----------------------------------------------------------------------
  226. BOOLEAN  FilemonFastIoCheckifPossible( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, 
  227.                                        IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation,
  228.                                        OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  229.     BOOLEAN         retval = FALSE;
  230.     PHOOK_EXTENSION hookExt;
  231.     CHAR            *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  232.     LARGE_INTEGER   timeStampStart, timeStampComplete, timeResult;
  233.     if( !DeviceObject ) return FALSE;
  234.     hookExt = DeviceObject->DeviceExtension;
  235.     if( FASTIOPRESENT( hookExt, FastIoCheckIfPossible ) ) {
  236.         GETPATHNAME(FALSE);
  237.         TIMESTAMPSTART();
  238.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoCheckIfPossible( 
  239.             FileObject, FileOffset, Length,
  240.             Wait, LockKey, CheckForReadOperation, IoStatus, hookExt->FileSystem );
  241.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  242.             TIMESTAMPSTOP();
  243.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  244.                          &timeResult,
  245.                          "%stFASTIO_CHECK_IF_POSSIBLEt%st%s Offset: %d Length: %dt%s", 
  246.                          name, fullPathName, 
  247.                          CheckForReadOperation ? "Read:" : "Write:",
  248.                          FileOffset->LowPart, Length, 
  249.                          retval?"SUCCESS":"FAILURE" ); 
  250.         }
  251.         if ( fullPathName ) ExFreePool( fullPathName );
  252.     }
  253.     return retval;
  254. }
  255. //----------------------------------------------------------------------
  256. // 
  257. // FilemonFastIoRead
  258. //
  259. //----------------------------------------------------------------------
  260. BOOLEAN  FilemonFastIoRead( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, 
  261.                             IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer,
  262.                             OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  263.     BOOLEAN             retval = FALSE;
  264.     PHOOK_EXTENSION     hookExt;
  265.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  266.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  267.     if( !DeviceObject ) return FALSE;
  268.     hookExt = DeviceObject->DeviceExtension;
  269.     if( FASTIOPRESENT( hookExt, FastIoRead ) ) {
  270.         GETPATHNAME(FALSE);
  271.         TIMESTAMPSTART();
  272.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoRead( 
  273.             FileObject, FileOffset, Length,
  274.             Wait, LockKey, Buffer, IoStatus, hookExt->FileSystem );
  275.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  276.             TIMESTAMPSTOP();
  277.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  278.                          &timeResult,
  279.                          "%stFASTIO_READt%stOffset: %d Length: %ldt%s", 
  280.                          name, fullPathName, 
  281.                          FileOffset->LowPart, Length, 
  282.                          retval?ErrorString( IoStatus->Status, errorBuf):"FAILURE" );
  283.         }
  284.         FREEPATHNAME();
  285.     }
  286.     return retval;
  287. }
  288. //----------------------------------------------------------------------
  289. //
  290. // FilemonFastIoWrite
  291. //
  292. //----------------------------------------------------------------------
  293. BOOLEAN  FilemonFastIoWrite( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, 
  294.                              IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer,
  295.                              OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  296.     BOOLEAN              retval = FALSE;
  297.     PHOOK_EXTENSION      hookExt;
  298.     CHAR                 *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  299.     LARGE_INTEGER        timeStampStart, timeStampComplete, timeResult;
  300.     if( !DeviceObject ) return FALSE;
  301.     hookExt = DeviceObject->DeviceExtension;
  302.     if( FASTIOPRESENT( hookExt, FastIoWrite )) {
  303.         GETPATHNAME(FALSE);
  304.         TIMESTAMPSTART();
  305.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoWrite( 
  306.             FileObject, FileOffset, Length, Wait, LockKey, 
  307.             Buffer, IoStatus, hookExt->FileSystem );
  308.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName ) ) {
  309.             TIMESTAMPSTOP();
  310.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  311.                          &timeResult,
  312.                          "%stFASTIO_WRITEt%stOffset: %d Length: %dt%s", 
  313.                          name, fullPathName, 
  314.                          FileOffset->LowPart, Length, 
  315.                          retval?ErrorString( IoStatus->Status, errorBuf ):"FAILURE" ); 
  316.         }
  317.         FREEPATHNAME();
  318.     }
  319.     return retval;
  320. }
  321. //----------------------------------------------------------------------
  322. //
  323. // FilemonFastIoQueryBasicinfo
  324. //
  325. //----------------------------------------------------------------------
  326. BOOLEAN  FilemonFastIoQueryBasicInfo( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, 
  327.                                       OUT PFILE_BASIC_INFORMATION Buffer,
  328.                                       OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  329.     BOOLEAN             retval = FALSE;
  330.     PHOOK_EXTENSION     hookExt;
  331.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  332.     CHAR                attributeString[ERRORLEN];
  333.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  334.     if( !DeviceObject ) return FALSE;
  335.     hookExt = DeviceObject->DeviceExtension;
  336.     if( FASTIOPRESENT( hookExt, FastIoQueryBasicInfo ) ) {
  337.         GETPATHNAME(FALSE);
  338.         TIMESTAMPSTART();
  339.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoQueryBasicInfo( 
  340.             FileObject, Wait, Buffer, IoStatus, hookExt->FileSystem );
  341.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  342.             TIMESTAMPSTOP();
  343.             if( retval ) {
  344.                 UpdateStore( MyInterlockedIncrement(&Sequence), 
  345.                              &timeResult,
  346.                              "%stFASTIO_QUERY_BASIC_INFOt%stAttributes: %st%s", 
  347.                              name, fullPathName, 
  348.                              NT_SUCCESS(IoStatus->Status) ? 
  349.                                     CreateAttributesString((USHORT)((PFILE_BASIC_INFORMATION) Buffer)->FileAttributes,
  350.                                                              attributeString ) :
  351.                                     "Error",
  352.                              retval?ErrorString( IoStatus->Status, errorBuf ):"FAILURE" );
  353.             } else { 
  354.                 UpdateStore( MyInterlockedIncrement(&Sequence), 
  355.                              &timeResult,
  356.                              "%stFASTIO_QUERY_BASIC_INFOt%stt%s", 
  357.                              name, fullPathName, retval?"SUCCESS":"FAILURE" );
  358.             }
  359.         }
  360.         FREEPATHNAME();
  361.     }
  362.     return retval;
  363. }
  364. //----------------------------------------------------------------------
  365. //
  366. // FilemonFastIoQueryStandardInfo
  367. //
  368. //----------------------------------------------------------------------
  369. BOOLEAN  FilemonFastIoQueryStandardInfo( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, 
  370.                                          OUT PFILE_STANDARD_INFORMATION Buffer,
  371.                                          OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  372.     BOOLEAN             retval = FALSE;
  373.     PHOOK_EXTENSION     hookExt;
  374.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  375.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  376.     if( !DeviceObject ) return FALSE;
  377.     hookExt = DeviceObject->DeviceExtension;
  378.     if( FASTIOPRESENT( hookExt, FastIoQueryStandardInfo ) ) {
  379.         GETPATHNAME(FALSE);
  380.         TIMESTAMPSTART();
  381.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoQueryStandardInfo( 
  382.             FileObject, Wait, Buffer, IoStatus, hookExt->FileSystem );
  383.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  384.             TIMESTAMPSTOP();
  385.             if( retval ) {
  386.                 UpdateStore( MyInterlockedIncrement(&Sequence), 
  387.                              &timeResult,
  388.                              "%stFASTIO_QUERY_STANDARD_INFOt%stSize: %dt%s", 
  389.                              name, fullPathName,
  390.                              ((PFILE_STANDARD_INFORMATION) Buffer)->EndOfFile.LowPart, 
  391.                              retval?"SUCCESS":"FAILURE" );
  392.             } else {
  393.                 UpdateStore( MyInterlockedIncrement(&Sequence), 
  394.                              &timeResult,
  395.                              "%stFASTIO_QUERY_STANDARD_INFOt%stt%s", 
  396.                              name, fullPathName, 
  397.                              retval?ErrorString( IoStatus->Status, errorBuf ):"FAILURE" );
  398.             }
  399.         }
  400.         FREEPATHNAME();
  401.     }
  402.     return retval;
  403. }
  404. //----------------------------------------------------------------------
  405. //
  406. // FilemonFastIoLock
  407. //
  408. //----------------------------------------------------------------------
  409. BOOLEAN  FilemonFastIoLock( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
  410.                             IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key,
  411.                             BOOLEAN FailImmediately, BOOLEAN ExclusiveLock,
  412.                             OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  413.     BOOLEAN             retval = FALSE;
  414.     PHOOK_EXTENSION     hookExt;
  415.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  416.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  417.     if( !DeviceObject ) return FALSE;
  418.     hookExt = DeviceObject->DeviceExtension;
  419.     if( FASTIOPRESENT( hookExt, FastIoLock )) {
  420.         GETPATHNAME(FALSE);
  421.         TIMESTAMPSTART();
  422.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoLock( 
  423.             FileObject, FileOffset, Length, ProcessId, Key, FailImmediately, 
  424.             ExclusiveLock, IoStatus, hookExt->FileSystem );
  425.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  426.             TIMESTAMPSTOP();
  427.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  428.                          &timeResult,
  429.                          "%stFASTIO_LOCKt%stExcl: %s Offset: %d Length: %dt%s", 
  430.                          name, fullPathName,
  431.                          ExclusiveLock ? "Yes":"No", FileOffset ? FileOffset->LowPart : 0,
  432.                          Length ? Length->LowPart : 0, retval?ErrorString( IoStatus->Status, errorBuf ):"FAILURE" );
  433.         }
  434.         FREEPATHNAME();
  435.     }
  436.     return retval;
  437. }
  438. //----------------------------------------------------------------------
  439. //
  440. // FilemonFastIoUnlockSingle
  441. //
  442. //----------------------------------------------------------------------
  443. BOOLEAN  FilemonFastIoUnlockSingle( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
  444.                                     IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key,
  445.                                     OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  446.     BOOLEAN             retval = FALSE;
  447.     PHOOK_EXTENSION     hookExt;
  448.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  449.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  450.     if( !DeviceObject ) return FALSE;
  451.     hookExt = DeviceObject->DeviceExtension;   
  452.     
  453.     if( FASTIOPRESENT( hookExt, FastIoUnlockSingle )) {
  454.         GETPATHNAME(FALSE);
  455.         TIMESTAMPSTART();
  456.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoUnlockSingle(
  457.             FileObject, FileOffset, Length, ProcessId, Key, 
  458.             IoStatus, hookExt->FileSystem );
  459.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  460.             TIMESTAMPSTOP();
  461.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  462.                          &timeResult,
  463.                          "%stFASTIO_UNLOCKt%stOffset: %d Length: %dt%s", 
  464.                          name, fullPathName, 
  465.                          FileOffset? FileOffset->LowPart : 0, Length ? Length->LowPart : 0,
  466.                          retval?ErrorString( IoStatus->Status, errorBuf ):"FAILURE" );
  467.         }
  468.         FREEPATHNAME();
  469.     }
  470.     return retval;
  471. }
  472. //----------------------------------------------------------------------
  473. //
  474. // FilemonFastIoUnlockAll
  475. //
  476. //----------------------------------------------------------------------
  477. BOOLEAN  FilemonFastIoUnlockAll( IN PFILE_OBJECT FileObject, PEPROCESS ProcessId,
  478.                                  OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  479.     BOOLEAN             retval = FALSE;
  480.     PHOOK_EXTENSION     hookExt;
  481.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  482.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  483.     if( !DeviceObject ) return FALSE;
  484.     hookExt = DeviceObject->DeviceExtension;
  485.     if ( FASTIOPRESENT(hookExt, FastIoUnlockAll ) ) {
  486.         GETPATHNAME(FALSE);
  487.         TIMESTAMPSTART();
  488.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoUnlockAll( 
  489.             FileObject, ProcessId, IoStatus, hookExt->FileSystem );
  490.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  491.             TIMESTAMPSTOP();
  492.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  493.                          &timeResult,
  494.                          "%stFASTIO_UNLOCK_ALLt%stt%s", 
  495.                          name, fullPathName, 
  496.                          retval?ErrorString( IoStatus->Status, errorBuf ):"FAILURE" );
  497.         }
  498.         FREEPATHNAME();
  499.     }
  500.     return retval;
  501. }
  502. //----------------------------------------------------------------------
  503. //
  504. // FilemonFastIoUnlockAllByKey
  505. //
  506. //----------------------------------------------------------------------    
  507. BOOLEAN  FilemonFastIoUnlockAllByKey( IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, ULONG Key,
  508.                                       OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  509.     BOOLEAN             retval = FALSE;
  510.     PHOOK_EXTENSION     hookExt;
  511.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  512.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  513.     if( !DeviceObject ) return FALSE;
  514.     hookExt = DeviceObject->DeviceExtension;
  515.     if( FASTIOPRESENT( hookExt, FastIoUnlockAllByKey )) {
  516.         GETPATHNAME(FALSE);
  517.         TIMESTAMPSTART();
  518.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoUnlockAllByKey( 
  519.             FileObject, ProcessId, Key, IoStatus, hookExt->FileSystem );
  520.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  521.             TIMESTAMPSTOP();
  522.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  523.                          &timeResult,
  524.                          "%stFASTIO_UNLOCK_ALL_BY_KEYt%stt%s", 
  525.                          name, fullPathName, 
  526.                          retval?ErrorString( IoStatus->Status, errorBuf):"FAILURE" );
  527.         }
  528.         FREEPATHNAME();
  529.     }
  530.     return retval;
  531. }
  532. //----------------------------------------------------------------------
  533. //
  534. // FilemonFastIoQueryNetworkOpenInfo
  535. //
  536. //----------------------------------------------------------------------    
  537. BOOLEAN FilemonFastIoQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject,
  538.                                           IN BOOLEAN Wait,
  539.                                           OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer,
  540.                                           OUT PIO_STATUS_BLOCK IoStatus,
  541.                                           IN PDEVICE_OBJECT DeviceObject )
  542. {
  543.     BOOLEAN             retval = FALSE;
  544.     PHOOK_EXTENSION     hookExt;
  545.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  546.     LARGE_INTEGER   timeStampStart, timeStampComplete, timeResult;
  547.     if( !DeviceObject ) return FALSE;
  548.     hookExt = DeviceObject->DeviceExtension;
  549.     if( FASTIOPRESENT( hookExt, FastIoQueryNetworkOpenInfo )) {
  550.         GETPATHNAME(FALSE);
  551.         TIMESTAMPSTART();
  552.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoQueryNetworkOpenInfo( 
  553.             FileObject, Wait, Buffer, IoStatus, hookExt->FileSystem );
  554.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  555.             TIMESTAMPSTOP();
  556.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  557.                          &timeResult,
  558.                          "%stFASTIO_QUERY_NETWORK_OPEN_INFOt%stt%s", 
  559.                          name, fullPathName, 
  560.                          retval ? ErrorString( IoStatus->Status, errorBuf ): "FAILURE" );
  561.         }
  562.         FREEPATHNAME();
  563.     }
  564.     return retval;
  565. }
  566. //----------------------------------------------------------------------
  567. //
  568. // FilemonFastIoAcquireForModWrite
  569. //
  570. //----------------------------------------------------------------------    
  571. NTSTATUS FilemonFastIoAcquireForModWrite( IN PFILE_OBJECT FileObject,
  572.                                           IN PLARGE_INTEGER EndingOffset,
  573.                                           OUT struct _ERESOURCE **ResourceToRelease,
  574.                                           IN PDEVICE_OBJECT DeviceObject )
  575. {
  576.     NTSTATUS            retval = STATUS_NOT_IMPLEMENTED;
  577.     PHOOK_EXTENSION     hookExt;
  578.     CHAR                *fullPathName, errval[ERRORLEN], name[PROCNAMELEN];
  579.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  580.     if( !DeviceObject ) return FALSE;
  581.     hookExt = DeviceObject->DeviceExtension;
  582.     if( FASTIOPRESENT( hookExt, AcquireForModWrite )) {
  583.         GETPATHNAME(FALSE);
  584.         TIMESTAMPSTART();
  585.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->AcquireForModWrite( 
  586.             FileObject, EndingOffset, ResourceToRelease, hookExt->FileSystem );
  587.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName ) ) {
  588.             TIMESTAMPSTOP();
  589.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  590.                          &timeResult,
  591.                          "%stFASTIO_ACQUIRE_FOR_MOD_WRITEt%stEndOffset: %dt%s", 
  592.                          name, fullPathName, EndingOffset, 
  593.                          ErrorString( retval, errval ) );
  594.         }
  595.         FREEPATHNAME();
  596.     }
  597.     return retval;
  598. }
  599. //----------------------------------------------------------------------
  600. //
  601. // FilemonFastIoMdlRead
  602. //
  603. //----------------------------------------------------------------------    
  604. BOOLEAN FilemonFastIoMdlRead( IN PFILE_OBJECT FileObject,
  605.                               IN PLARGE_INTEGER FileOffset, IN ULONG Length,
  606.                               IN ULONG LockKey, OUT PMDL *MdlChain,
  607.                               OUT PIO_STATUS_BLOCK IoStatus,
  608.                               IN PDEVICE_OBJECT DeviceObject )
  609. {
  610.     BOOLEAN             retval = FALSE;
  611.     PHOOK_EXTENSION     hookExt;
  612.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  613.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  614.     if( !DeviceObject ) return FALSE;
  615.     hookExt = DeviceObject->DeviceExtension;
  616.     if( FASTIOPRESENT( hookExt, MdlRead )) {
  617.         GETPATHNAME(FALSE);
  618.         TIMESTAMPSTART();
  619.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->MdlRead( 
  620.             FileObject, FileOffset, Length, LockKey, MdlChain, 
  621.             IoStatus, hookExt->FileSystem );
  622.         if( FilterDef.logreads && ApplyFilters( name, fullPathName ) ) {
  623.             TIMESTAMPSTOP();
  624.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  625.                          &timeResult,
  626.                          "%stFASTIO_MDL_READt%stOffset: %d Length: %dt%s", 
  627.                          name, fullPathName, 
  628.                          FileOffset->LowPart, Length, 
  629.                          retval ? ErrorString( IoStatus->Status, errorBuf ): "FAILURE" );
  630.         }
  631.         FREEPATHNAME();
  632.     }
  633.     return retval;
  634. }
  635. //----------------------------------------------------------------------
  636. //
  637. // FilemonFastIoMdlReadComplete
  638. //
  639. //----------------------------------------------------------------------    
  640. BOOLEAN FilemonFastIoMdlReadComplete( IN PFILE_OBJECT FileObject,
  641.                                       IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject )
  642. {
  643.     BOOLEAN             retval = FALSE;
  644.     PHOOK_EXTENSION     hookExt;
  645.     CHAR                *fullPathName, name[PROCNAMELEN];
  646.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  647.     if( !DeviceObject ) return FALSE;
  648.     hookExt = DeviceObject->DeviceExtension;
  649.     if( FASTIOPRESENT( hookExt, MdlReadComplete )) {
  650.         GETPATHNAME(FALSE);
  651.         TIMESTAMPSTART();
  652.         retval = (BOOLEAN) hookExt->FileSystem->DriverObject->FastIoDispatch->MdlReadComplete( FileObject, 
  653.                                                                                                MdlChain, hookExt->FileSystem );
  654.         if( FilterDef.logreads && ApplyFilters( name, fullPathName )) {
  655.             TIMESTAMPSTOP();
  656.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  657.                          &timeResult,
  658.                          "%stFASTIO_MDL_READ_COMPLETEt%stt%s", 
  659.                          name, fullPathName, "OK" );
  660.         }
  661.         FREEPATHNAME();
  662.     }
  663.     return retval;
  664. }
  665. //----------------------------------------------------------------------
  666. //
  667. // FilemonFastIoPrepareMdlWrite
  668. //
  669. //----------------------------------------------------------------------    
  670. BOOLEAN FilemonFastIoPrepareMdlWrite( IN PFILE_OBJECT FileObject,
  671.                                       IN PLARGE_INTEGER FileOffset, IN ULONG Length,
  672.                                       IN ULONG LockKey, OUT PMDL *MdlChain,
  673.                                       OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject )
  674. {
  675.     BOOLEAN             retval = FALSE;
  676.     PHOOK_EXTENSION     hookExt;
  677.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  678.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  679.     if( !DeviceObject ) return FALSE;
  680.     hookExt = DeviceObject->DeviceExtension;
  681.     IoStatus->Status      = STATUS_NOT_IMPLEMENTED;
  682.     IoStatus->Information = 0;
  683.     if( FASTIOPRESENT( hookExt, PrepareMdlWrite )) {
  684.         GETPATHNAME(FALSE);
  685.         TIMESTAMPSTART();
  686.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->PrepareMdlWrite( 
  687.             FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, 
  688.             hookExt->FileSystem );
  689.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName ) ) {
  690.             TIMESTAMPSTOP();
  691.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  692.                          &timeResult,
  693.                          "%stFASTIO_PREPARE_MDL_WRITEt%stOffset: %d Length: %dt%s", 
  694.                          name, fullPathName, 
  695.                          FileOffset->LowPart, Length, 
  696.                          retval ? ErrorString( IoStatus->Status, errorBuf ): "FAILURE" );
  697.         }
  698.         FREEPATHNAME();
  699.     } 
  700.     return retval;
  701. }
  702. //----------------------------------------------------------------------
  703. //
  704. // FilemonFastIoMdlWriteComplete
  705. //
  706. //----------------------------------------------------------------------    
  707. BOOLEAN FilemonFastIoMdlWriteComplete( IN PFILE_OBJECT FileObject,
  708.                                        IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, 
  709.                                        IN PDEVICE_OBJECT DeviceObject )
  710. {
  711.     BOOLEAN             retval = FALSE;
  712.     PHOOK_EXTENSION     hookExt;
  713.     CHAR                *fullPathName, name[PROCNAMELEN];
  714.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  715.     
  716.     if( !DeviceObject ) return FALSE;
  717.     hookExt = DeviceObject->DeviceExtension;
  718.     if( FASTIOPRESENT( hookExt, MdlWriteComplete )) { 
  719.         GETPATHNAME(FALSE);
  720.         TIMESTAMPSTART();
  721.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->MdlWriteComplete( 
  722.             FileObject, FileOffset, MdlChain, hookExt->FileSystem );
  723.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName ) ) {
  724.             TIMESTAMPSTOP();
  725.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  726.                          &timeResult,
  727.                          "%stFASTIO_MDL_WRITE_COMPLETEt%stOffset: %dtOK", 
  728.                          name, fullPathName, FileOffset->LowPart );
  729.         }
  730.         FREEPATHNAME();
  731.     }
  732.     return retval;
  733. }
  734. //----------------------------------------------------------------------
  735. //
  736. // FilemonFastIoReadCompressed
  737. //
  738. //----------------------------------------------------------------------    
  739. BOOLEAN FilemonFastIoReadCompressed( IN PFILE_OBJECT FileObject,
  740.                                      IN PLARGE_INTEGER FileOffset, IN ULONG Length,
  741.                                      IN ULONG LockKey, OUT PVOID Buffer,
  742.                                      OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
  743.                                      OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo,
  744.                                      IN ULONG CompressedDataInfoLength, IN PDEVICE_OBJECT DeviceObject )
  745. {
  746.     BOOLEAN             retval = FALSE;
  747.     PHOOK_EXTENSION     hookExt;
  748.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  749.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  750.     if( !DeviceObject ) return FALSE;
  751.     hookExt = DeviceObject->DeviceExtension;
  752.     if( FASTIOPRESENT( hookExt, FastIoReadCompressed )) {
  753.         GETPATHNAME(FALSE);
  754.         TIMESTAMPSTART();
  755.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoReadCompressed( 
  756.             FileObject, FileOffset, Length, LockKey, Buffer, MdlChain, IoStatus,
  757.             CompressedDataInfo, CompressedDataInfoLength, hookExt->FileSystem );
  758.         if( FilterDef.logreads && ApplyFilters( name, fullPathName )) {
  759.             TIMESTAMPSTOP();
  760.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  761.                          &timeResult,
  762.                          "%stFASTIO_READ_COMPRESSEDt%stOffset: %d Length: %dt%s", 
  763.                          name, fullPathName, 
  764.                          FileOffset->LowPart, Length,
  765.                          retval ? ErrorString( IoStatus->Status, errorBuf ) : "FAILURE" );
  766.         }
  767.         FREEPATHNAME();
  768.     }
  769.     return retval;
  770. }
  771. //----------------------------------------------------------------------
  772. //
  773. // FilemonFastIoWriteCompressed
  774. //
  775. //----------------------------------------------------------------------    
  776. BOOLEAN FilemonFastIoWriteCompressed( IN PFILE_OBJECT FileObject,
  777.                                       IN PLARGE_INTEGER FileOffset, IN ULONG Length,
  778.                                       IN ULONG LockKey, OUT PVOID Buffer,
  779.                                       OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
  780.                                       OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo,
  781.                                       IN ULONG CompressedDataInfoLength, IN PDEVICE_OBJECT DeviceObject )
  782. {
  783.     BOOLEAN             retval = FALSE;
  784.     PHOOK_EXTENSION     hookExt;
  785.     CHAR                *fullPathName, name[PROCNAMELEN], errorBuf[ERRORLEN];
  786.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  787.     if( !DeviceObject ) return FALSE;
  788.     hookExt = DeviceObject->DeviceExtension;
  789.     if( FASTIOPRESENT( hookExt, FastIoWriteCompressed )) {
  790.         GETPATHNAME(FALSE);
  791.         TIMESTAMPSTART();
  792.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoWriteCompressed( 
  793.             FileObject, FileOffset, Length, LockKey, Buffer, MdlChain, IoStatus,
  794.             CompressedDataInfo, CompressedDataInfoLength, hookExt->FileSystem );
  795.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName ) ) {
  796.             TIMESTAMPSTOP();
  797.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  798.                          &timeResult,
  799.                          "%stFASTIO_WRITE_COMPRESSEDt%stOffset: %d Length: %dt%s", 
  800.                          name, fullPathName, 
  801.                          FileOffset->LowPart, Length, 
  802.                          retval ? ErrorString( IoStatus->Status, errorBuf ) : "FAILURE" );
  803.         }
  804.         FREEPATHNAME();
  805.     }
  806.     return retval;
  807. }
  808. //----------------------------------------------------------------------
  809. //
  810. // FilemonFastIoMdlReadCompleteCompressed
  811. //
  812. //----------------------------------------------------------------------    
  813. BOOLEAN FilemonFastIoMdlReadCompleteCompressed( IN PFILE_OBJECT FileObject,
  814.                                                 IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject )
  815. {
  816.     BOOLEAN             retval = FALSE;
  817.     PHOOK_EXTENSION     hookExt;
  818.     CHAR                *fullPathName, name[PROCNAMELEN];
  819.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  820.     if( !DeviceObject ) return FALSE;
  821.     hookExt = DeviceObject->DeviceExtension;
  822.     if( FASTIOPRESENT( hookExt, MdlReadCompleteCompressed )) {
  823.         GETPATHNAME(FALSE);
  824.         TIMESTAMPSTART();
  825.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->MdlReadCompleteCompressed( 
  826.             FileObject, MdlChain, hookExt->FileSystem );
  827.         if( FilterDef.logreads && ApplyFilters( name, fullPathName )) {
  828.             TIMESTAMPSTOP();
  829.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  830.                          &timeResult,
  831.                          "%stFASTIO_MDL_READ_COMPLETE_COMPRESSEDt%stt%s", 
  832.                          name, fullPathName, "OK" );
  833.         }
  834.         FREEPATHNAME();
  835.     }
  836.     return retval;
  837. }
  838. //----------------------------------------------------------------------
  839. //
  840. // FilemonFastIoMdlWriteCompleteCompressed
  841. //
  842. //----------------------------------------------------------------------    
  843. BOOLEAN FilemonFastIoMdlWriteCompleteCompressed( IN PFILE_OBJECT FileObject,
  844.                                                  IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, 
  845.                                                  IN PDEVICE_OBJECT DeviceObject )
  846. {
  847.     BOOLEAN             retval = FALSE;
  848.     PHOOK_EXTENSION     hookExt;
  849.     CHAR                *fullPathName, name[PROCNAMELEN];
  850.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  851.     if( !DeviceObject ) return FALSE;
  852.     hookExt = DeviceObject->DeviceExtension; 
  853.     if( FASTIOPRESENT( hookExt, MdlWriteCompleteCompressed )) {
  854.         GETPATHNAME(FALSE);
  855.         TIMESTAMPSTART();
  856.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->MdlWriteCompleteCompressed( 
  857.             FileObject, FileOffset, MdlChain, hookExt->FileSystem );
  858.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName )) {
  859.             TIMESTAMPSTOP();
  860.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  861.                          &timeResult,
  862.                          "%stFASTIO_MDL_WRITE_COMPLETE_COMPRESSEDt%stOffset: %dt%s", 
  863.                          name, fullPathName, FileOffset->LowPart, "OK" );
  864.         }
  865.         FREEPATHNAME();
  866.     }
  867.     return retval;
  868. }
  869. //----------------------------------------------------------------------
  870. //
  871. // FilemonFastIoQueryOpen
  872. //
  873. // This call actually passes an IRP! 
  874. //
  875. //----------------------------------------------------------------------    
  876. BOOLEAN FilemonFastIoQueryOpen( IN PIRP Irp,
  877.                                 OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
  878.                                 IN PDEVICE_OBJECT DeviceObject )
  879. {
  880.     BOOLEAN             retval = FALSE;
  881.     PHOOK_EXTENSION     hookExt;
  882.     PFILE_OBJECT        FileObject;
  883.     CHAR                *fullPathName, name[PROCNAMELEN];
  884.     PIO_STACK_LOCATION  currentIrpStack;
  885.     PIO_STACK_LOCATION  nextIrpStack;
  886.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  887.     if( !DeviceObject ) return FALSE;
  888.     hookExt = DeviceObject->DeviceExtension;
  889.     if( FASTIOPRESENT( hookExt, FastIoQueryOpen )) {
  890.         currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
  891.         nextIrpStack    = IoGetNextIrpStackLocation(Irp);
  892.         FileObject      = currentIrpStack->FileObject;
  893.         //
  894.         // copy parameters down to next level in the stack
  895.         //
  896.         *nextIrpStack = *currentIrpStack;
  897.         nextIrpStack->DeviceObject = hookExt->FileSystem;
  898.         IoSetNextIrpStackLocation( Irp );
  899.         //
  900.         // Get path and timestamp
  901.         //
  902.         GETPATHNAME(TRUE);
  903.         TIMESTAMPSTART();
  904.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoQueryOpen( 
  905.             Irp, NetworkInformation, hookExt->FileSystem );
  906.         //
  907.         // Restore the stack location because pre-NT 5.0 checked builds complain
  908.         //
  909.         Irp->CurrentLocation++;
  910.         Irp->Tail.Overlay.CurrentStackLocation++;
  911.         if( FilterDef.logreads && ApplyFilters( name, fullPathName )) {
  912.             TIMESTAMPSTOP();
  913.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  914.                          &timeResult,
  915.                          "%stFASTIO_QUERY_OPENt%stt%s", 
  916.                          name, fullPathName, retval ? "SUCCESS" : "FAILURE" );
  917.         }
  918.         FREEPATHNAME();
  919.     }
  920.     return retval;
  921. }
  922. //----------------------------------------------------------------------
  923. //
  924. // FilemonFastIoReleaseForModWrite
  925. //
  926. //----------------------------------------------------------------------    
  927. NTSTATUS FilemonFastIoReleaseForModWrite( IN PFILE_OBJECT FileObject,
  928.                                           IN struct _ERESOURCE *ResourceToRelease,
  929.                                           IN PDEVICE_OBJECT DeviceObject )
  930. {
  931.     NTSTATUS            retval = STATUS_NOT_IMPLEMENTED;
  932.     PHOOK_EXTENSION     hookExt;
  933.     CHAR                *fullPathName, errval[ERRORLEN], name[PROCNAMELEN];
  934.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  935.     
  936.     if( !DeviceObject ) return STATUS_NOT_IMPLEMENTED;
  937.     hookExt = DeviceObject->DeviceExtension;
  938.     if( FASTIOPRESENT( hookExt, ReleaseForModWrite )) {
  939.         GETPATHNAME(FALSE);
  940.         TIMESTAMPSTART();
  941.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->ReleaseForModWrite( 
  942.             FileObject,  ResourceToRelease, hookExt->FileSystem );
  943.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName )) {
  944.             TIMESTAMPSTOP();
  945.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  946.                          &timeResult,
  947.                          "%stFASTIO_RELEASE_FOR_MOD_WRITEt%stt%s", 
  948.                          name, fullPathName, ErrorString( retval, errval ));
  949.         }
  950.         FREEPATHNAME();
  951.     }
  952.     return retval;
  953. }
  954. //----------------------------------------------------------------------
  955. //
  956. // FilemonFastIoAcquireForCcFlush
  957. //
  958. //----------------------------------------------------------------------    
  959. NTSTATUS FilemonFastIoAcquireForCcFlush( IN PFILE_OBJECT FileObject,
  960.                                          IN PDEVICE_OBJECT DeviceObject )
  961. {
  962.     NTSTATUS            retval = STATUS_NOT_IMPLEMENTED;
  963.     PHOOK_EXTENSION     hookExt;
  964.     CHAR                *fullPathName, errval[ERRORLEN], name[PROCNAMELEN];
  965.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  966.     if( !DeviceObject ) return STATUS_NOT_IMPLEMENTED;
  967.     hookExt = DeviceObject->DeviceExtension;
  968.     if( FASTIOPRESENT( hookExt, AcquireForCcFlush )) {
  969.         GETPATHNAME(FALSE);
  970.         TIMESTAMPSTART();
  971.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->AcquireForCcFlush( 
  972.             FileObject, hookExt->FileSystem );
  973.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName )) {
  974.             TIMESTAMPSTOP();
  975.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  976.                          &timeResult,
  977.                          "%stFASTIO_ACQUIRE_FOR_CC_FLUSHt%stt%s", 
  978.                          name, fullPathName, ErrorString( retval, errval));
  979.         }
  980.         if ( fullPathName) ExFreePool( fullPathName );
  981.     }
  982.     return retval;
  983. }
  984. //----------------------------------------------------------------------
  985. //
  986. // FilemonFastIoReleaseForCcFlush
  987. //
  988. //----------------------------------------------------------------------    
  989. NTSTATUS FilemonFastIoReleaseForCcFlush( IN PFILE_OBJECT FileObject,
  990.                                          IN PDEVICE_OBJECT DeviceObject )
  991. {
  992.     NTSTATUS            retval = STATUS_NOT_IMPLEMENTED;
  993.     PHOOK_EXTENSION     hookExt;
  994.     CHAR                *fullPathName, errval[ERRORLEN], name[PROCNAMELEN];
  995.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  996.     if( !DeviceObject ) return STATUS_NOT_IMPLEMENTED;
  997.     hookExt = DeviceObject->DeviceExtension;
  998.     if( FASTIOPRESENT( hookExt, ReleaseForCcFlush )) {
  999.         GETPATHNAME(FALSE);
  1000.         TIMESTAMPSTART();
  1001.         retval = hookExt->FileSystem->DriverObject->FastIoDispatch->ReleaseForCcFlush( 
  1002.             FileObject, hookExt->FileSystem );
  1003.         if( FilterDef.logwrites && ApplyFilters( name, fullPathName )) {
  1004.             TIMESTAMPSTOP();
  1005.             UpdateStore( MyInterlockedIncrement(&Sequence), 
  1006.                          &timeResult,
  1007.                          "%stFASTIO_RELEASE_FOR_CC_FLUSHt%stt%s", 
  1008.                          name, fullPathName, ErrorString( retval, errval) ); 
  1009.         }
  1010.         FREEPATHNAME();
  1011.     }
  1012.     return retval;
  1013. }
  1014. //----------------------------------------------------------------------
  1015. //
  1016. // FilemonFastIoDeviceControl
  1017. //
  1018. //----------------------------------------------------------------------
  1019. BOOLEAN  FilemonFastIoDeviceControl( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
  1020.                                      IN PVOID InputBuffer, IN ULONG InputBufferLength, 
  1021.                                      OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN ULONG IoControlCode,
  1022.                                      OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) {
  1023.     BOOLEAN             retval = FALSE;
  1024.     PHOOK_EXTENSION     hookExt;
  1025.     PSTORE_BUF          old;
  1026.     CHAR                fullPathName[MAXPATHLEN], name[PROCNAMELEN], errorBuf[ERRORLEN];
  1027.     KIRQL               oldirql;
  1028.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  1029.     if ( DeviceObject == GUIDevice )  {
  1030.         //
  1031.         // Its a message from our GUI!
  1032.         //
  1033.         IoStatus->Status      = STATUS_SUCCESS; // Assume success
  1034.         IoStatus->Information = 0;      // Assume nothing returned
  1035.         switch ( IoControlCode ) {
  1036.         case IOCTL_FILEMON_VERSION:
  1037.             //
  1038.             // Version #
  1039.             //
  1040.             if ( OutputBufferLength >= sizeof(ULONG)) {
  1041.                 *(ULONG *)OutputBuffer = FILEMONVERSION;
  1042.                 IoStatus->Information = sizeof(ULONG);
  1043.             } else {
  1044.                 IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
  1045.             }            
  1046.             break;
  1047.         case IOCTL_FILEMON_SETDRIVES:
  1048.             //
  1049.             // Hook and/or unhook drives
  1050.             //
  1051.             DbgPrint (("Filemon: set drivesn"));
  1052.             if ( InputBufferLength >= sizeof(ULONG) &&
  1053.                  OutputBufferLength >= sizeof(ULONG)) {
  1054.                 *(ULONG *)OutputBuffer = HookDriveSet( *(ULONG *)InputBuffer, DeviceObject->DriverObject );
  1055.                 IoStatus->Information = sizeof(ULONG);
  1056.             } else {
  1057.                 IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
  1058.             }
  1059.             break;
  1060.         case IOCTL_FILEMON_HOOKSPECIAL:
  1061.             if( InputBufferLength >= sizeof(FILE_SYSTEM_TYPE )) {
  1062.                 if( !HookSpecialFs( DeviceObject->DriverObject, *(PFILE_SYSTEM_TYPE) InputBuffer )) {
  1063.                 
  1064.                     IoStatus->Status = STATUS_UNSUCCESSFUL;
  1065.                 }
  1066.             } else {
  1067.                 IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
  1068.             }
  1069.             break;
  1070.         case IOCTL_FILEMON_UNHOOKSPECIAL:
  1071.             if( InputBufferLength >= sizeof(FILE_SYSTEM_TYPE )) {
  1072.                 UnhookSpecialFs( *(PFILE_SYSTEM_TYPE) InputBuffer );
  1073.             } else {
  1074.                 IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
  1075.             }
  1076.             break;
  1077.         case IOCTL_FILEMON_STOPFILTER:
  1078.             
  1079.             //
  1080.             // Turn off logging
  1081.             //
  1082.             DbgPrint(("Filemon: stop loggingn"));
  1083.             FilterOn = FALSE;
  1084.             break;
  1085.         case IOCTL_FILEMON_STARTFILTER:
  1086.           
  1087.             //
  1088.             // Turn on logging 
  1089.             //
  1090.             DbgPrint(("Filemon: start loggingn"));
  1091.             FilterOn = TRUE;
  1092.             break;
  1093.         case IOCTL_FILEMON_SETFILTER:
  1094.   
  1095.             //
  1096.             // Gui is updating the filter functions
  1097.             //
  1098.             DbgPrint(("Filemon: set filtern"));
  1099.             if( InputBufferLength >= sizeof(FILTER) ) {
  1100.                 FilterDef = *(PFILTER) InputBuffer;
  1101.                 FilemonUpdateFilters();
  1102.             } else {
  1103.                 IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
  1104.             }
  1105.             break;
  1106.         case IOCTL_FILEMON_TIMETYPE:
  1107.             //     
  1108.             // Set the timing type
  1109.             //     
  1110.             if( InputBufferLength >= sizeof(BOOLEAN) ) {
  1111.                 TimeIsDuration = *(PBOOLEAN) InputBuffer;
  1112.             } else {
  1113.                 IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
  1114.             }
  1115.             break;
  1116.         case IOCTL_FILEMON_UNLOADQUERY:
  1117.             //
  1118.             // Is it possible to unload?
  1119.             //
  1120.             KeAcquireSpinLock( &CountMutex, &oldirql );
  1121.             IoStatus->Information = OutstandingIRPCount;
  1122.             //
  1123.             // Any outstanding Irps?
  1124.             //
  1125.             if( !OutstandingIRPCount ) {
  1126.                 //
  1127.                 // Nope, so don't process anymore
  1128.                 //
  1129.                 UnloadInProgress = TRUE;
  1130.                 KeReleaseSpinLock( &CountMutex, oldirql );
  1131.                 //
  1132.                 // Disconnect from filesystems
  1133.                 //
  1134.                 HookDriveSet( 0, DeviceObject->DriverObject );
  1135.             } else {
  1136.                 KeReleaseSpinLock( &CountMutex, oldirql );
  1137.             }
  1138.             break;
  1139.         case IOCTL_FILEMON_ZEROSTATS:
  1140.             //
  1141.             // Reset all output buffers
  1142.             //
  1143.             DbgPrint (("Filemon: zero statsn"));
  1144.             ExAcquireFastMutex( &StoreMutex );
  1145.             while ( Store->Next )  {
  1146.                 //
  1147.                 // Free all but the first output buffer
  1148.                 //
  1149.                 old = Store->Next;
  1150.                 Store->Next = old->Next;
  1151.                 ExFreePool( old );
  1152.                 NumStore--;
  1153.             }
  1154.  
  1155.             //
  1156.             // Set the output pointer to the start of the output buffer
  1157.             //
  1158.             Store->Len = 0;
  1159.             Sequence = 0;
  1160.             ExReleaseFastMutex( &StoreMutex );
  1161.             break;
  1162.         case IOCTL_FILEMON_GETSTATS:
  1163.             //
  1164.             // Copy the oldest output buffer to the caller
  1165.             //
  1166.             DbgPrint (("Filemon: get statsn"));
  1167. //
  1168.             // If the output buffer is too large to fit into the caller's buffer
  1169.             //
  1170.             if ( MAX_STORE > OutputBufferLength )  {
  1171.                 IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
  1172.                 return FALSE;
  1173.             }
  1174.             //
  1175.             // Probe the output buffer
  1176.             //
  1177.             try {                 
  1178.                 ProbeForWrite( OutputBuffer,
  1179.                                OutputBufferLength,
  1180.                                sizeof( UCHAR ));
  1181.             } except( EXCEPTION_EXECUTE_HANDLER ) {
  1182.                 IoStatus->Status = STATUS_INVALID_PARAMETER;
  1183.                 return FALSE;
  1184.             }            
  1185.             //
  1186.             // We're okay, lock the buffer pool
  1187.             //
  1188.             ExAcquireFastMutex( &StoreMutex );
  1189.             if ( Store->Len  ||  Store->Next ) {
  1190.                 //
  1191.                 // Start output to a new output buffer
  1192.                 //
  1193.                 FilemonNewStore();
  1194.                 //
  1195.                 // Fetch the oldest to give to user
  1196.                 //
  1197.                 old = FilemonOldestStore();
  1198.                 ExReleaseFastMutex( &StoreMutex );
  1199.                 //
  1200.                 // Copy it to the caller's buffer
  1201.                 //
  1202.                 memcpy( OutputBuffer, old->Data, old->Len );
  1203.                 //
  1204.                 // Return length of copied info
  1205.                 //
  1206.                 IoStatus->Information = old->Len;
  1207.                 //
  1208.                 // Deallocate buffer
  1209.                 //
  1210.                 if( old != Store ) ExFreePool( old );
  1211.             } else {
  1212.                 //
  1213.                 // There is no unread data
  1214.                 //
  1215.                 ExReleaseFastMutex( &StoreMutex );
  1216. IoStatus->Information = 0;
  1217.             }
  1218.             break;
  1219.  
  1220.         default:
  1221.             //
  1222.             // Unknown control
  1223.             // 
  1224.             DbgPrint (("Filemon: unknown IRP_MJ_DEVICE_CONTROLn"));
  1225.             IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
  1226.             break;
  1227.         }
  1228.         retval = TRUE;
  1229.     } else {
  1230.         //
  1231.         // Its a call for a file system, so pass it through
  1232.         //
  1233.         hookExt = DeviceObject->DeviceExtension;
  1234.         if( FASTIOPRESENT( hookExt, FastIoDeviceControl )) {
  1235.         
  1236.             FilemonGetFullPath( FALSE, FileObject, hookExt, fullPathName );
  1237.             TIMESTAMPSTART();
  1238.             retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoDeviceControl( 
  1239.                 FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, 
  1240.                 OutputBufferLength, IoControlCode, IoStatus, hookExt->FileSystem );
  1241.             if( ApplyFilters( name, fullPathName )) {
  1242.                 TIMESTAMPSTOP();
  1243.                 UpdateStore( MyInterlockedIncrement(&Sequence), &timeResult, 
  1244.                              "%stFASTIO_DEVICE_CONTROLt%stIOCTL: 0x%Xt%s", 
  1245.                              name, fullPathName,
  1246.                              IoControlCode, 
  1247.                              retval ?  ErrorString( IoStatus->Status, errorBuf ) : "FAILURE" );
  1248.             }
  1249.         }
  1250.     }
  1251.     return retval;
  1252. }
  1253. //----------------------------------------------------------------------
  1254. //
  1255. // FilemonFastIoAcquireFile
  1256. //
  1257. //----------------------------------------------------------------------
  1258. VOID FilemonFastIoAcquireFile( PFILE_OBJECT FileObject ) {
  1259.     PDEVICE_OBJECT      deviceObject, checkDevice;
  1260.     PHOOK_EXTENSION     hookExt;
  1261.     CHAR                *fullPathName, name[PROCNAMELEN];
  1262.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  1263.     //
  1264.     // We've got to locate our own device object
  1265.     //
  1266.     checkDevice = FileObject->DeviceObject->Vpb->DeviceObject;
  1267.     while( checkDevice ) {
  1268.         if( checkDevice->DriverObject == FilemonDriver ) {
  1269.     
  1270.             //
  1271.             // Found it
  1272.             //
  1273.             deviceObject = checkDevice;
  1274.             hookExt = deviceObject->DeviceExtension;
  1275.             if( FASTIOPRESENT( hookExt, AcquireFileForNtCreateSection )) {
  1276.                 GETPATHNAME(FALSE);
  1277.                 TIMESTAMPSTART();
  1278.                 hookExt->FileSystem->DriverObject->FastIoDispatch->AcquireFileForNtCreateSection( 
  1279.                     FileObject );
  1280.                 if( FilterDef.logreads && ApplyFilters( name, fullPathName )) {
  1281.                     TIMESTAMPSTOP();
  1282.                     UpdateStore( MyInterlockedIncrement(&Sequence), &timeResult, 
  1283.                                  "%stFASTIO_ACQUIRE_FILEt%sttOK", name, 
  1284.                                  fullPathName );
  1285.                 }
  1286.                 FREEPATHNAME();
  1287.             }
  1288.             return;
  1289.         }
  1290.         checkDevice = checkDevice->AttachedDevice;
  1291.     }
  1292. }
  1293. //----------------------------------------------------------------------
  1294. //
  1295. // FilemonFastIoReleaseFile
  1296. //
  1297. //----------------------------------------------------------------------
  1298. VOID FilemonFastIoReleaseFile( PFILE_OBJECT FileObject ) {
  1299.     PDEVICE_OBJECT      deviceObject, checkDevice;
  1300.     PHOOK_EXTENSION     hookExt;
  1301.     CHAR                *fullPathName, name[PROCNAMELEN];
  1302.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  1303.     //
  1304.     // We've got to locate our own device object
  1305.     //
  1306.     checkDevice = FileObject->DeviceObject->Vpb->DeviceObject;
  1307.     while( checkDevice ) {
  1308.         if( checkDevice->DriverObject == FilemonDriver ) {
  1309.     
  1310.             deviceObject = IoGetRelatedDeviceObject( FileObject );
  1311.             hookExt = deviceObject->DeviceExtension;
  1312.             
  1313.             if( FASTIOPRESENT( hookExt, ReleaseFileForNtCreateSection )) {
  1314.                 GETPATHNAME(FALSE);
  1315.                 TIMESTAMPSTART();
  1316.                 hookExt->FileSystem->DriverObject->FastIoDispatch->ReleaseFileForNtCreateSection( FileObject );
  1317.                 if( FilterDef.logreads && ApplyFilters( name, fullPathName )) {
  1318.                     TIMESTAMPSTOP();
  1319.                     UpdateStore( MyInterlockedIncrement(&Sequence), &timeResult, 
  1320.                                  "%stFASTIO_RELEASE_FILEt%sttOK", name,
  1321.                                  fullPathName );
  1322.                 }
  1323.                 FREEPATHNAME();
  1324.             }
  1325.             return;
  1326.         }
  1327.         checkDevice = checkDevice->AttachedDevice;
  1328.     }
  1329. }
  1330. //----------------------------------------------------------------------
  1331. //
  1332. // FilemonFastIoDetachDevice
  1333. //
  1334. // We get this call when a device that we have hooked is being deleted.
  1335. // This happens when, for example, a floppy is formatted. We have
  1336. // to detach from it and delete our device. We should notify the GUI
  1337. // that the hook state has changed, but its not worth the trouble.
  1338. //
  1339. //----------------------------------------------------------------------
  1340. VOID FilemonFastIoDetachDevice( PDEVICE_OBJECT SourceDevice, PDEVICE_OBJECT TargetDevice ) {
  1341.     PHOOK_EXTENSION     hookExt;
  1342.     ULONG               i;
  1343.     CHAR                name[PROCNAMELEN];
  1344.     LARGE_INTEGER       timeStampStart, timeStampComplete, timeResult;
  1345.     //
  1346.     // See if a device (like a floppy) is being removed out from under us. If so,
  1347.     // we have to detach from it before it disappears  
  1348.     //
  1349.     for( i = 0; i < 26; i++ ) {
  1350.         if( SourceDevice == LDriveDevices[i] ) {
  1351.             //
  1352.             // We've hooked it, so we must detach
  1353.             //
  1354.             hookExt = SourceDevice->DeviceExtension;
  1355.             DbgPrint(("Filemon: Detaching from drive: %cn", 
  1356.                       hookExt->LogicalDrive ));
  1357.             IoDetachDevice( TargetDevice );
  1358.             IoDeleteDevice( SourceDevice );
  1359.             LDriveDevices[i] = NULL;
  1360.             LDriveMap[i] = 0;
  1361.             return;
  1362.         }
  1363.     }
  1364.     //
  1365.     // Now we can pass the call through
  1366.     //
  1367.     hookExt = SourceDevice->DeviceExtension;
  1368.     if( FASTIOPRESENT( hookExt, FastIoDetachDevice )) {
  1369.         TIMESTAMPSTART();
  1370.         hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoDetachDevice( 
  1371.             SourceDevice, TargetDevice );
  1372.         if( FilemonGetProcess( name ) ) {
  1373.             TIMESTAMPSTOP();
  1374.             UpdateStore( MyInterlockedIncrement(&Sequence), &timeResult, 
  1375.                          "%stFASTIO_DETACH_DEVICEtttOK", 
  1376.                          name);
  1377.         }
  1378.     }
  1379. }
  1380. //----------------------------------------------------------------------
  1381. //     D I S P A T C H   A N D   H O O K   E N T R Y   P O I N T S
  1382. //----------------------------------------------------------------------
  1383. //----------------------------------------------------------------------
  1384. // 
  1385. // FilemonHookDoneWork
  1386. //
  1387. // Worker routine that simply calls update store. Since we want
  1388. // to avoid using spin locks in order to improve SMP performance
  1389. // we need to do everything at passive. When our completion routine
  1390. // is called at dispatch, we queue the update off to a worker thread.
  1391. //
  1392. //----------------------------------------------------------------------
  1393. VOID FilemonHookDoneWork( PVOID Context )
  1394. {
  1395.     PFILEMON_WORK  filemonWork = (PFILEMON_WORK) Context;
  1396.     UpdateStore( filemonWork->Sequence,
  1397.                  &filemonWork->TimeResult,
  1398.                  filemonWork->ErrString );
  1399.     ExFreePool( filemonWork );
  1400. }
  1401. //----------------------------------------------------------------------
  1402. // 
  1403. // FilemonHookDone
  1404. //
  1405. // Gets control after a filesystem operation has completed so that
  1406. // we can get return status information about it.
  1407. //
  1408. //----------------------------------------------------------------------
  1409. NTSTATUS FilemonHookDone( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
  1410.                           IN PVOID Context )
  1411. {
  1412.     PIO_STACK_LOCATION   IrpSp;
  1413.     int                  seq = (int)Context;
  1414.     CHAR                 errval[ERRORLEN], errString[ERRORLEN];
  1415.     KIRQL                oldirql;
  1416.     LARGE_INTEGER        timeStampStart, timeStampComplete, timeResult;
  1417.     PFILEMON_WORK        filemonWorkContext;
  1418.     //
  1419.     // A request completed - look at the result 
  1420.     //
  1421.     IrpSp = IoGetCurrentIrpStackLocation( Irp );    
  1422.     //
  1423.     // Store the return status in the output buffer. Tag it with the 
  1424.     // sequence number so that the GUI can match it with the IRP input information.
  1425.     //
  1426.     if( FilterOn ) {
  1427.         //
  1428.         // Quick, get the completion time
  1429.         //
  1430.         timeStampStart = IrpSp->Parameters.Read.ByteOffset;
  1431.         if( IrpSp->Parameters.Read.Length ) {
  1432.             timeStampComplete   = KeQueryPerformanceCounter(NULL);
  1433.             timeResult.QuadPart = timeStampComplete.QuadPart - timeStampStart.QuadPart;
  1434.         } else {
  1435.             timeResult = timeStampStart;
  1436.         }
  1437.         //
  1438.         // Queue off to a worker thread if we have to 
  1439.         //
  1440.         if( KeGetCurrentIrql() == DISPATCH_LEVEL ) {
  1441.             filemonWorkContext = ExAllocatePool( NonPagedPool, sizeof(FILEMON_WORK));
  1442.             if( filemonWorkContext ) {
  1443.                 filemonWorkContext->Sequence   = seq;
  1444.                 filemonWorkContext->TimeResult = timeResult;
  1445.                 sprintf( filemonWorkContext->ErrString, "tttt%s", 
  1446.                          ErrorString( Irp->IoStatus.Status, errval ));
  1447.                 ExInitializeWorkItem( &filemonWorkContext->WorkItem, 
  1448.                                       FilemonHookDoneWork, filemonWorkContext );
  1449.                 ExQueueWorkItem( &filemonWorkContext->WorkItem, CriticalWorkQueue );
  1450.             } 
  1451.         } else {
  1452.             sprintf( errString, "tttt%s", ErrorString( Irp->IoStatus.Status, errval ));
  1453.             UpdateStore( seq, &timeResult, errString );
  1454.         }
  1455.     }
  1456.     //
  1457.     // If this was an error on a create call, we have to free the hash entry we
  1458.     // created for this name
  1459.     //
  1460.     if( (IrpSp->MajorFunction == IRP_MJ_CREATE ||
  1461.          IrpSp->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE ||
  1462.          IrpSp->MajorFunction == IRP_MJ_CREATE_MAILSLOT ) && 
  1463.         !NT_SUCCESS( Irp->IoStatus.Status )) {
  1464.         FilemonFreeHashEntry( IrpSp->FileObject );
  1465.     }
  1466.   
  1467.     //
  1468.     // We have finished processing an IRP so decrement oustanding IRP count
  1469.     //
  1470.     KeAcquireSpinLock( &CountMutex, &oldirql );
  1471.     OutstandingIRPCount--;
  1472.     KeReleaseSpinLock( &CountMutex, oldirql );
  1473.     //
  1474.     // Now we have to mark Irp as pending if necessary
  1475.     //
  1476.     if( Irp->PendingReturned ) {
  1477.         IoMarkIrpPending( Irp );
  1478.     }
  1479.     return Irp->IoStatus.Status;
  1480. }
  1481. //----------------------------------------------------------------------
  1482. //
  1483. // FilemonHookRoutine
  1484. //
  1485. // This routine is the main hook routine where we figure out what
  1486. // calls are being sent to the file system.
  1487. //
  1488. //----------------------------------------------------------------------
  1489. NTSTATUS FilemonHookRoutine( PDEVICE_OBJECT HookDevice, IN PIRP Irp )
  1490. {
  1491.     PIO_STACK_LOCATION  currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
  1492.     PIO_STACK_LOCATION  nextIrpStack    = IoGetNextIrpStackLocation(Irp);
  1493.     PFILE_OBJECT        fileObject;
  1494.     PHOOK_EXTENSION     hookExt;
  1495.     LARGE_INTEGER       timeStampStart;
  1496.     PCHAR               fullPathName;
  1497.     CHAR                controlCodeBuffer[ERRORLEN];
  1498.     CHAR                attributeString[ERRORLEN];
  1499.     CHAR                optionString[ERRORLEN];
  1500.     CHAR                name[PROCNAMELEN];
  1501.     ULONG               seq = MyInterlockedIncrement(&Sequence);
  1502.     KIRQL               oldirql;
  1503.     //
  1504.     // Allocate a buffer
  1505.     //
  1506.     if( fullPathName = ExAllocatePool( NonPagedPool, MAXPATHLEN ) ) {
  1507.         fullPathName[0] = 0;
  1508.     }
  1509.     //
  1510.     // Extract the file object from the IRP
  1511.     //
  1512.     fileObject    = currentIrpStack->FileObject;
  1513.     //
  1514.     // Point at the device extension, which contains information on which
  1515.     // file system this IRP is headed for
  1516.     //
  1517.     hookExt = HookDevice->DeviceExtension;
  1518.     //
  1519.     // If a GUI is up there, get the canonical pathname
  1520.     //
  1521.     if( FilterOn ) {
  1522.         if( currentIrpStack->MajorFunction == IRP_MJ_CREATE ||
  1523.             currentIrpStack->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE ||
  1524.             currentIrpStack->MajorFunction == IRP_MJ_CREATE_MAILSLOT ) {
  1525.             //
  1526.             // Clear any existing fileobject/name association stored in the
  1527.             // hash table
  1528.             //
  1529.             FilemonFreeHashEntry( fileObject );
  1530.         } 
  1531.         FilemonGetFullPath( (BOOLEAN) (currentIrpStack->MajorFunction == IRP_MJ_CREATE ||
  1532.                                        currentIrpStack->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE ||
  1533.                                        currentIrpStack->MajorFunction == IRP_MJ_CREATE_MAILSLOT ), 
  1534.                             fileObject, hookExt, fullPathName );
  1535.     }
  1536.     // 
  1537.     // If measuring absolute time go and get the timestamp.
  1538.     // 
  1539.     if( !TimeIsDuration ) KeQuerySystemTime( &timeStampStart );
  1540.     else                  timeStampStart.QuadPart = 0;
  1541.     //
  1542.     // Only log it if it passes the filter
  1543.     //
  1544.     if( ApplyFilters( name, fullPathName ) ) {
  1545.         //
  1546.         // Determine what function we're dealing with
  1547.         //
  1548.         switch( currentIrpStack->MajorFunction ) {
  1549.         case IRP_MJ_CREATE:
  1550.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_CREATEt%stAttributes: %s Options: %s", 
  1551.                          name, fullPathName,
  1552.                          CreateAttributesString( currentIrpStack->Parameters.Create.FileAttributes,
  1553.                                                  attributeString ),
  1554.                          CreateOptionsString( currentIrpStack->Parameters.Create.Options,
  1555.                                               optionString ));
  1556.             break;
  1557.         case IRP_MJ_CREATE_NAMED_PIPE:
  1558.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_CREATE_NAMED_PIPEt%stAttributes: %s Options: %s", 
  1559.                          name, fullPathName,
  1560.                          CreateAttributesString( currentIrpStack->Parameters.Create.FileAttributes,
  1561.                                                  attributeString ),
  1562.                          CreateOptionsString( currentIrpStack->Parameters.Create.Options,
  1563.                                               optionString ));
  1564.             break;
  1565.         case IRP_MJ_CREATE_MAILSLOT:
  1566.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_CREATE_MAILSLOTt%stAttributes: %s Options: %s", 
  1567.                          name, fullPathName,
  1568.                          CreateAttributesString( currentIrpStack->Parameters.Create.FileAttributes,
  1569.                                                  attributeString ),
  1570.                          CreateOptionsString( currentIrpStack->Parameters.Create.Options,
  1571.                                               optionString ));
  1572.             break;
  1573.         case IRP_MJ_READ:
  1574.             if( FilterDef.logreads ) {
  1575.                 UpdateStore( seq, &timeStampStart, "%stIRP_MJ_READ%ct%stOffset: %d Length: %d", 
  1576.                              name, 
  1577.                              (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ? '*' : ' ',
  1578.                              fullPathName, 
  1579.                              currentIrpStack->Parameters.Read.ByteOffset.LowPart,
  1580.                              currentIrpStack->Parameters.Read.Length );
  1581.             }
  1582.             break;
  1583.         case IRP_MJ_WRITE:
  1584.             if( FilterDef.logwrites ) {
  1585.                 UpdateStore( seq, &timeStampStart, "%stIRP_MJ_WRITE%ct%stOffset: %d Length: %d", 
  1586.                              name, 
  1587.                              (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ? '*' : ' ',
  1588.                              fullPathName, 
  1589.                              currentIrpStack->Parameters.Write.ByteOffset.LowPart,
  1590.                              currentIrpStack->Parameters.Write.Length );
  1591.             }
  1592.             break;
  1593.         case IRP_MJ_CLOSE:
  1594.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_CLOSEt%st", name, fullPathName );
  1595.             //
  1596.             // This fileobject/name association can be discarded now.
  1597.             //
  1598.             FilemonFreeHashEntry( fileObject );
  1599.             break;
  1600.         case IRP_MJ_FLUSH_BUFFERS:
  1601.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_FLUSHt%st", name, fullPathName );
  1602.             break;
  1603.         case IRP_MJ_QUERY_INFORMATION:
  1604.  
  1605.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_QUERY_INFORMATIONt%st%s", 
  1606.                          name, fullPathName, 
  1607.                          FileInformation[currentIrpStack->Parameters.QueryFile.FileInformationClass] );
  1608.             break;
  1609.         case IRP_MJ_SET_INFORMATION:
  1610.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_SET_INFORMATIONt%st%s", 
  1611.                          name, fullPathName,
  1612.                          FileInformation[currentIrpStack->Parameters.SetFile.FileInformationClass] );
  1613.             break;
  1614.         case IRP_MJ_QUERY_EA:
  1615.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_QUERY_EAt%st", name, fullPathName );
  1616.             break;
  1617.         case IRP_MJ_SET_EA:
  1618.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_SET_EAt%st", name, fullPathName );
  1619.             break;
  1620.         case IRP_MJ_QUERY_VOLUME_INFORMATION:
  1621.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_QUERY_VOLUME_INFORMATIONt%st%s", 
  1622.                          name, fullPathName,
  1623.                          VolumeInformation[currentIrpStack->Parameters.QueryVolume.FsInformationClass] );
  1624.             break;
  1625.         case IRP_MJ_SET_VOLUME_INFORMATION:
  1626.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_SET_VOLUME_INFORMATIONt%st", 
  1627.                          name, fullPathName );
  1628.             break;
  1629.         case IRP_MJ_DIRECTORY_CONTROL:
  1630.             switch( currentIrpStack->MinorFunction ) {
  1631.             case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
  1632.                 UpdateStore( seq, &timeStampStart, "%stIRP_MJ_DIRECTORY_CONTROLt%stChange Notify", 
  1633.                              name, fullPathName );
  1634.                 break;
  1635.             case IRP_MN_QUERY_DIRECTORY:
  1636.                 UpdateStore( seq, &timeStampStart, "%stIRP_MJ_DIRECTORY_CONTROLt%st%s", 
  1637.                              name, fullPathName, 
  1638.                              FileInformation[((PQUERY_DIRECTORY)&currentIrpStack->Parameters)->FileInformationClass]);
  1639.                 break; 
  1640.             default:
  1641.                 UpdateStore( seq, &timeStampStart, "%stIRP_MJ_DIRECTORY_CONTROLt%st", 
  1642.                              name, fullPathName );
  1643.                 break;
  1644.             }
  1645.             break;
  1646.         case IRP_MJ_FILE_SYSTEM_CONTROL:
  1647.             UpdateStore( seq, &timeStampStart, "%st%st%st%s", 
  1648.                          name, 
  1649.                          ControlCodeString( currentIrpStack, 
  1650.                                             currentIrpStack->Parameters.DeviceIoControl.IoControlCode,
  1651.                                             controlCodeBuffer, optionString ),
  1652.                          fullPathName, optionString );
  1653.             break;
  1654.         case IRP_MJ_SHUTDOWN:
  1655.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_SHUTDOWNtt", name );
  1656.             break;
  1657.         case IRP_MJ_LOCK_CONTROL:
  1658.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_LOCK_CONTROLt%stOffset: %d Length: %d",
  1659.                          name, fullPathName,
  1660.                          ((PLOCK_CONTROL)&currentIrpStack->Parameters)->ByteOffset.LowPart,
  1661.                          ((PLOCK_CONTROL)&currentIrpStack->Parameters)->Length ?
  1662.                          ((PLOCK_CONTROL)&currentIrpStack->Parameters)->Length->LowPart : 0 );
  1663.             break;
  1664.         case IRP_MJ_CLEANUP:
  1665.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_CLEANUPt%st", name, fullPathName );
  1666.             break;
  1667.         case IRP_MJ_DEVICE_CONTROL:
  1668.  
  1669.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_DEVICE_CONTROLt%stIOCTL: 0x%X", name, 
  1670.                          fullPathName, currentIrpStack->Parameters.DeviceIoControl.IoControlCode );
  1671.             break;
  1672.         case IRP_MJ_QUERY_SECURITY:
  1673.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_QUERY_SECURITYt%st", 
  1674.                          name, fullPathName );
  1675.             break;
  1676.         case IRP_MJ_SET_SECURITY:
  1677.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_SET_SECURITYt%st", 
  1678.                          name, fullPathName );
  1679.             break;
  1680.         case IRP_MJ_PNP_POWER:
  1681.             
  1682.             UpdateStore( seq, &timeStampStart, "%stIRP_MJ_PNP_POWERt%st",
  1683.                          name, fullPathName );
  1684.             break;
  1685.         default:
  1686.             UpdateStore( seq, &timeStampStart, "%st*UNKNOWN* 0x%Xtt", name, currentIrpStack->MajorFunction );
  1687.             break;
  1688.         }
  1689.     } else {
  1690.         //
  1691.         // Do name processing for the sake of keeping the hash table current
  1692.         //
  1693.         switch( currentIrpStack->MajorFunction ) {
  1694.         case IRP_MJ_CLOSE:
  1695.             //
  1696.             // This fileobject/name association can be discarded now.
  1697.             //
  1698.             FilemonFreeHashEntry( fileObject );
  1699.             break;
  1700.         }        
  1701.     }
  1702.     //
  1703.     // Free the buffer
  1704.     //
  1705.     if ( fullPathName ) {
  1706.         ExFreePool( fullPathName );
  1707.     }
  1708.     //
  1709.     // Copy parameters down to next level in the stack for the driver below us
  1710.     //
  1711.     *nextIrpStack = *currentIrpStack;
  1712.     //
  1713.     // If an unload isn't in progress, we should register a completion callback
  1714.     // so that the IRP's return status can be examined.
  1715.     //
  1716.     KeAcquireSpinLock( &CountMutex, &oldirql );
  1717.     if( !UnloadInProgress && FilterOn ) {
  1718.         //
  1719.         // Increment the outstanding IRP count since this IRP will be headed
  1720.         // for our completion routine
  1721.         //
  1722.         OutstandingIRPCount++;
  1723.         //
  1724.         // Grab the time stamp and store it in the current stack location. This
  1725.         // is legal since the stack location is ours, and we're done looking at 
  1726.         // the parameters. This makes it easy to pass this to the completion routine. The
  1727.         // DiskPerf example in the NT DDK uses this trick.
  1728.         //
  1729.         if( TimeIsDuration ) {
  1730.             currentIrpStack->Parameters.Read.ByteOffset = KeQueryPerformanceCounter((PVOID)NULL);
  1731.             currentIrpStack->Parameters.Read.Length     = 1;
  1732.         } else {
  1733.             currentIrpStack->Parameters.Read.ByteOffset = timeStampStart;
  1734.             currentIrpStack->Parameters.Read.Length     = 0;
  1735.         }
  1736.         IoSetCompletionRoutine( Irp, FilemonHookDone, (void *)seq, TRUE, TRUE, TRUE );
  1737.     } else {
  1738.         //
  1739.         // Set no completion routine
  1740.         //
  1741.         IoSetCompletionRoutine( Irp, FilemonHookDone, NULL, FALSE, FALSE, FALSE );
  1742.     }
  1743.     KeReleaseSpinLock( &CountMutex, oldirql );
  1744.     //
  1745.     // Return the results of the call to the caller
  1746.     //
  1747.     return IoCallDriver( hookExt->FileSystem, Irp );
  1748. }
  1749. //----------------------------------------------------------------------
  1750. //
  1751. // FilemonDeviceRoutine
  1752. //
  1753. // In this routine we handle requests to our own device. The only 
  1754. // requests we care about handling explicitely are IOCTL commands that
  1755. // we will get from the GUI. We also expect to get Create and Close 
  1756. // commands when the GUI opens and closes communications with us.
  1757. //
  1758. //----------------------------------------------------------------------
  1759. NTSTATUS FilemonDeviceRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
  1760. {
  1761.     PIO_STACK_LOCATION  irpStack;
  1762.     PVOID               inputBuffer;
  1763.     PVOID               outputBuffer;
  1764.     ULONG               inputBufferLength;
  1765.     ULONG               outputBufferLength;
  1766.     ULONG               ioControlCode;
  1767.     //
  1768.     // Go ahead and set the request up as successful
  1769.     //
  1770.     Irp->IoStatus.Status      = STATUS_SUCCESS;
  1771.     Irp->IoStatus.Information = 0;
  1772.     //
  1773.     // Get a pointer to the current location in the Irp. This is where
  1774.     // the function codes and parameters are located.
  1775.     //
  1776.     irpStack = IoGetCurrentIrpStackLocation (Irp);
  1777.     //
  1778.     // Get the pointer to the input/output buffer and its length
  1779.     //
  1780.     inputBuffer     = Irp->AssociatedIrp.SystemBuffer;
  1781.     inputBufferLength   = irpStack->Parameters.DeviceIoControl.InputBufferLength;
  1782.     outputBuffer    = Irp->AssociatedIrp.SystemBuffer;
  1783.     outputBufferLength  = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  1784.     ioControlCode   = irpStack->Parameters.DeviceIoControl.IoControlCode;
  1785.     switch (irpStack->MajorFunction) {
  1786.     case IRP_MJ_CREATE:
  1787.         DbgPrint(("Filemon: IRP_MJ_CREATEn"));
  1788.         // 
  1789.         // Start the sequence number at 0
  1790.         // 
  1791.         Sequence = 0;
  1792.         break;
  1793.     case IRP_MJ_CLOSE:
  1794.         DbgPrint(("Filemon: IRP_MJ_CLOSEn"));
  1795.         //
  1796.         // A GUI is closing communication
  1797.         //
  1798.         FilterOn  = FALSE;
  1799.         //
  1800.         // If the GUI has no more references to us, reset the output
  1801.         // buffers and hash table.
  1802.         //
  1803.         FilemonResetStore();
  1804.         FilemonHashCleanup();
  1805.         //
  1806.         // Disconnect from file systems
  1807.         //
  1808.         HookDriveSet( 0, DeviceObject->DriverObject );
  1809.         break;
  1810.     case IRP_MJ_DEVICE_CONTROL:
  1811.         //
  1812.         // This path will never execute because we have registered a 
  1813.         // fast I/O path for device control. That means that the fast I/O entry 
  1814.         // point will ALWAYS be called for Device Control operations
  1815.         //
  1816.         DbgPrint (("Filemon: IRP_MJ_DEVICE_CONTROLn"));
  1817.         //
  1818.         // Get output buffer if its passed as an MDL
  1819.         //
  1820.         if( Irp->MdlAddress ) {
  1821.             outputBuffer = MmGetSystemAddressForMdl( Irp->MdlAddress );
  1822.         }
  1823.         //
  1824.         // Its a request from the GUI. Simply call our fast handler.
  1825.         //
  1826.         FilemonFastIoDeviceControl( irpStack->FileObject, TRUE,
  1827.                                     inputBuffer, inputBufferLength, 
  1828.                                     outputBuffer, outputBufferLength,
  1829.                                     ioControlCode, &Irp->IoStatus, DeviceObject );
  1830.         break;
  1831.     }
  1832.     //
  1833.     // Complete the IRP
  1834.     //
  1835.     IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1836.     return STATUS_SUCCESS;   
  1837. }
  1838. //----------------------------------------------------------------------
  1839. //
  1840. // FilemonDispatch
  1841. //
  1842. // Based on which device the Irp is destined for we call either the
  1843. // filesystem filter function, or our own device handling routine.
  1844. //
  1845. //----------------------------------------------------------------------
  1846. NTSTATUS FilemonDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
  1847. {
  1848.     //
  1849.     // Determine if its a request from the GUI to us, or one that is
  1850.     // directed at a file system driver that we've hooked
  1851.     //
  1852.     if ( GUIDevice != DeviceObject ) {
  1853.         return( FilemonHookRoutine( DeviceObject, Irp ));
  1854.     } else {
  1855.         return( FilemonDeviceRoutine( DeviceObject, Irp ));
  1856.     }
  1857. }
  1858. //----------------------------------------------------------------------
  1859. //
  1860. // FilemonUnload
  1861. //
  1862. // Our job is done - time to leave.
  1863. //
  1864. //----------------------------------------------------------------------
  1865. VOID FilemonUnload( IN PDRIVER_OBJECT DriverObject )
  1866. {
  1867.     WCHAR                  deviceLinkBuffer[]  = L"\DosDevices\Filemon";
  1868.     UNICODE_STRING         deviceLinkUnicodeString;
  1869.     //
  1870.     // Disconnect from file systems
  1871.     //
  1872.     HookDriveSet( 0, DriverObject );
  1873.     UnhookSpecialFs( NPFS );
  1874.     UnhookSpecialFs( MSFS );
  1875.     //
  1876.     // Delete the symbolic link for our GUI device
  1877.     //
  1878.     RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer );
  1879.     IoDeleteSymbolicLink( &deviceLinkUnicodeString );
  1880.     DbgPrint(("Filemon.SYS: unloadingn"));
  1881.     //
  1882.     // Delete the device object, making sure that the GUI device
  1883.     // object is always deleted.
  1884.     //
  1885.     if ( GUIDevice == DriverObject->DeviceObject )  {
  1886.         IoDeleteDevice( DriverObject->DeviceObject );
  1887.     } else {
  1888.         IoDeleteDevice( DriverObject->DeviceObject );
  1889.         IoDeleteDevice( GUIDevice ); 
  1890.     }
  1891.     DbgPrint(("Filemon.SYS: deleted devicesn"));
  1892.     //
  1893.     // Now we can free any memory that is allocated
  1894.     //
  1895.     FilemonFreeFilters();
  1896.     FilemonHashCleanup();
  1897.     FilemonFreeStore();
  1898.     //
  1899.     // Delete the resources
  1900.     //
  1901.     ExDeleteResourceLite( &FilterResource );
  1902.     ExDeleteResourceLite( &HashResource );
  1903.     DbgPrint(("Filemon.SYS: freed memoryn"));
  1904. }
  1905. //----------------------------------------------------------------------
  1906. //
  1907. // DriverEntry
  1908. //
  1909. // Installable driver initialization. Here we just set ourselves up.
  1910. //
  1911. //----------------------------------------------------------------------
  1912. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
  1913. {
  1914.     NTSTATUS                ntStatus;
  1915.     WCHAR                   deviceNameBuffer[]  = L"\Device\Filemon";
  1916.     UNICODE_STRING          deviceNameUnicodeString;
  1917.     WCHAR                   deviceLinkBuffer[]  = L"\DosDevices\Filemon";
  1918.     UNICODE_STRING          deviceLinkUnicodeString;
  1919.     ULONG                   i;
  1920.     DbgPrint (("Filemon.SYS: entering DriverEntryn"));
  1921.     FilemonDriver = DriverObject;
  1922.     //
  1923.     // If not NT 4.0 Final Release, shorten the Fast I/O table so that Filemon 
  1924.     // will work on the Betas and Release Candidates
  1925.     //
  1926.     if( *NtBuildNumber < NT4FINAL ) {
  1927.         FastIOHook.SizeOfFastIoDispatch = (ULONG) &FastIOHook.FastIoQueryNetworkOpenInfo - 
  1928.             (ULONG) &FastIOHook;
  1929.     } 
  1930.     //    
  1931.     // Setup the device name
  1932.     //    
  1933.     RtlInitUnicodeString (&deviceNameUnicodeString,
  1934.                           deviceNameBuffer );
  1935.     //
  1936.     // Create the device used for GUI communications
  1937.     //
  1938.     ntStatus = IoCreateDevice ( DriverObject,
  1939.                                 0,
  1940.                                 &deviceNameUnicodeString,
  1941.                                 FILE_DEVICE_FILEMON,
  1942.                                 0,
  1943.                                 TRUE,
  1944.                                 &GUIDevice );
  1945.     //
  1946.     // If successful, make a symbolic link that allows for the device
  1947.     // object's access from Win32 programs
  1948.     //
  1949.     if (NT_SUCCESS(ntStatus)) {
  1950.         //
  1951.         // Create a symbolic link that the GUI can specify to gain access
  1952.         // to this driver/device
  1953.         //
  1954.         RtlInitUnicodeString (&deviceLinkUnicodeString,
  1955.                               deviceLinkBuffer );
  1956.         ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
  1957.                                          &deviceNameUnicodeString );
  1958.         if (!NT_SUCCESS(ntStatus)) {
  1959.             DbgPrint (("Filemon.SYS: IoCreateSymbolicLink failedn"));
  1960.         
  1961.         }
  1962.         //
  1963.         // Create dispatch points for all routines that must be handled. 
  1964.         // All entry points are registered since we might filter a
  1965.         // file system that processes all of them.
  1966.         //
  1967.         for( i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++ ) {
  1968.             DriverObject->MajorFunction[i] = FilemonDispatch;
  1969.         }
  1970. #if DBG        
  1971.         //
  1972.         // Driver unload is only set if we are debugging Filemon. This is 
  1973.         // because unloading a filter is not really safe - threads could
  1974.         // be in our fastio routines (or about to enter them), and there is 
  1975.         // no way to tell. When debugging, we can risk the occasional
  1976.         // unload crash as a trade-off for not having to reboot as often.
  1977.         //
  1978.         DriverObject->DriverUnload                          = FilemonUnload;
  1979. #endif
  1980.         //
  1981.         // Set up the Fast I/O dispatch table
  1982.         //
  1983.         DriverObject->FastIoDispatch = &FastIOHook;
  1984.     }
  1985.     //
  1986.     // If something went wrong, cleanup the device object and don't load
  1987.     //
  1988.     if (!NT_SUCCESS(ntStatus)) {
  1989.         DbgPrint(("Filemon: Failed to create our device!n"));
  1990.         if( GUIDevice ) {
  1991.             IoDeleteDevice( GUIDevice );
  1992.         }
  1993.         return ntStatus;
  1994.     }
  1995.     //
  1996.     // Initialize the drive map 
  1997.     //
  1998.     for(i = 0; i < 26; i++ )        LDriveMap[i] = 0;
  1999.     //
  2000.     // Initialize the name hash table
  2001.     //
  2002.     for(i = 0; i < NUMHASH; i++ )   HashTable[i] = NULL;
  2003.     //
  2004.     // Find the process name offset
  2005.     //
  2006.     ProcessNameOffset = FilemonGetProcessNameOffset();
  2007.     //
  2008.     // Initialize the synchronization objects
  2009.     //
  2010.     KeInitializeSpinLock( &CountMutex );
  2011.     ExInitializeFastMutex( &StoreMutex );
  2012.     ExInitializeResourceLite( &FilterResource );
  2013.     ExInitializeResourceLite( &HashResource );
  2014.     //
  2015.     // Allocate the first output buffer
  2016.     //
  2017.     Store   = ExAllocatePool( NonPagedPool, sizeof(*Store) );
  2018.     if ( !Store ) {
  2019.         // 
  2020.         // Oops - we can't do anything without at least one buffer
  2021.         // 
  2022.         IoDeleteDevice( GUIDevice );
  2023.         return STATUS_INSUFFICIENT_RESOURCES;
  2024.     }
  2025.     // 
  2026.     // Set the buffer pointer to the start of the buffer just allocated
  2027.     // 
  2028.     Store->Len  = 0;
  2029.     Store->Next = NULL;
  2030.     NumStore = 1;
  2031.     return ntStatus;
  2032. }