⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filemon.c

📁 文件名:filemon4。34,文件过滤驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    //
    passedFilters = !ProcessFilters || ApplyFilters( text );
    if( passedFilters ) {

        //
        // Assign a sequence number if we weren't passed one
        //
        if( !SeqNum || (SeqNum && *SeqNum == (ULONG) -1)) {

            recordSequence = InterlockedIncrement( &Sequence );
            if( SeqNum ) *SeqNum = recordSequence;

        } else {

            recordSequence = *SeqNum;
        }

        //
        // If the current output buffer is near capacity, move to a new 
        // output buffer
        //
        if( CurrentLog->Len + len + sizeof(ENTRY) +1 >= LOGBUFSIZE ) {

            FilemonAllocateLog();
        }

        //
        // Log the entry
        //
        Entry = (void *)(CurrentLog->Data+CurrentLog->Len);
        Entry->seq = recordSequence;
        Entry->datetime.QuadPart = 0;
        Entry->perftime.QuadPart = 0;
        if( dateTime ) Entry->datetime = *dateTime;
        if( perfTime ) Entry->perftime = *perfTime;
        memcpy( Entry->text, text, len );
 
        //
        // Log the length of the string, plus 1 for the terminating
        // NULL  
        //   
        CurrentLog->Len += ((ULONG) (Entry->text - (PCHAR) Entry )) + len;
    }

    //
    // Release the output buffer lock
    //
    ExReleaseFastMutex( &LogMutex );
    return passedFilters;
}

//----------------------------------------------------------------------
//       H A S H   T A B L E   M A N A G E M E N T
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//
// FilemonHashCleanup
//
// Called when we are unloading to free any memory that we have 
// in our possession.
//
//----------------------------------------------------------------------
VOID
FilemonHashCleanup(
    VOID
    )
{
    PHASH_ENTRY		hashEntry, nextEntry;
    ULONG		    i;

    KeEnterCriticalRegion();
    ExAcquireResourceExclusiveLite( &HashResource, TRUE );

    //
    // Free the hash table entries
    //
    for( i = 0; i < NUMHASH; i++ ) {

        hashEntry = HashTable[i];

        while( hashEntry ) {
            nextEntry = hashEntry->Next;
            ExFreePool( hashEntry );
            hashEntry = nextEntry;
        }

        HashTable[i] = NULL;
    }
    ExReleaseResourceLite( &HashResource );
    KeLeaveCriticalRegion();
}


//----------------------------------------------------------------------
//
// FilemonFreeHashEntry
//
// When we see a file close, we can free the string we had associated
// with the fileobject being closed since we know it won't be used
// again.
//
//----------------------------------------------------------------------
VOID 
FilemonFreeHashEntry( 
    PFILE_OBJECT fileObject 
    )
{
    PHASH_ENTRY		hashEntry, prevEntry;

    KeEnterCriticalRegion();
    ExAcquireResourceExclusiveLite( &HashResource, TRUE );

    //
    // Look-up the entry
    //
    hashEntry = HashTable[ HASHOBJECT( fileObject ) ];
    prevEntry = NULL;

    while( hashEntry && hashEntry->FileObject != fileObject ) {

        prevEntry = hashEntry;
        hashEntry = hashEntry->Next;
    }
 
    //  
    // If we fall of the hash list without finding what we're looking
    // for, just return.
    //
    if( !hashEntry ) {

        ExReleaseResourceLite( &HashResource );
        KeLeaveCriticalRegion();
        return;
    }

    //
    // Got it! Remove it from the list
    //
    if( prevEntry ) {

        prevEntry->Next = hashEntry->Next;

    } else {

        HashTable[ HASHOBJECT( fileObject )] = hashEntry->Next;
    }

    //
    // Free the entry's memory
    //
    ExFreePool( hashEntry );

    ExReleaseResourceLite( &HashResource );
    KeLeaveCriticalRegion();
}

//----------------------------------------------------------------------
//       P A T H  A N D  P R O C E S S  N A M E  R O U T I N E S
//----------------------------------------------------------------------


//----------------------------------------------------------------------
//
// FilemonFreeFilters
//
// Fress storage we allocated for filter strings.
//
//----------------------------------------------------------------------
VOID 
FilemonFreeFilters(
    VOID
    )
{
    ULONG   i;

    for( i = 0; i < NumIncludeFilters; i++ ) {

        ExFreePool( IncludeFilters[i] );
    }
    for( i = 0; i < NumExcludeFilters; i++ ) {

        ExFreePool( ExcludeFilters[i] );
    }
    NumIncludeFilters = 0;
    NumExcludeFilters = 0;
}


//----------------------------------------------------------------------
//
// MakeFilterArray
//
// Takes a filter string and splits into components (a component
// is seperated with a ';')
//
//----------------------------------------------------------------------
VOID
MakeFilterArray( 
    PCHAR FilterString,
    PCHAR FilterArray[],
    PULONG NumFilters 
    )
{
    PCHAR filterStart;
    ULONG filterLength;
    CHAR  saveChar;

    //
    // Scan through the process filters
    //
    filterStart = FilterString;
    while( *filterStart ) {

        filterLength = 0;
        while( filterStart[filterLength] &&
               filterStart[filterLength] != ';' ) {

            filterLength++;
        }

        //
        // Ignore zero-length components
        //
        if( filterLength ) {

            //
            // Conservatively allocate so that we can prepend and append
            // wildcards
            //
            FilterArray[ *NumFilters ] = 
                ExAllocatePool( PagedPool, filterLength + 1 + 2*sizeof('*') );
            
            //
            // Only fill this in if there's enough memory
            //
            if( FilterArray[ *NumFilters] ) {

                saveChar = *(filterStart + filterLength );
                *(filterStart + filterLength) = 0;
                sprintf( FilterArray[ *NumFilters ], "%s%s%s",
                         *filterStart == '*' ? "" : "*",
                         filterStart,
                         *(filterStart + filterLength - 1 ) == '*' ? "" : "*" );
                *(filterStart + filterLength) = saveChar;
                (*NumFilters)++;
            }
        }
    
        //
        // Are we done?
        //
        if( !filterStart[filterLength] ) break;

        //
        // Move to the next component (skip over ';')
        //
        filterStart += filterLength + 1;
    }
}


//----------------------------------------------------------------------
//
// FilemonUpdateFilters
//
// Takes a new filter specification and updates the filter
// arrays with them.
//
//----------------------------------------------------------------------
VOID 
FilemonUpdateFilters(
    VOID
    )
{
    //
    // Free old filters (if any)
    //
    KeEnterCriticalRegion();
    ExAcquireResourceExclusiveLite( &FilterResource, TRUE );
    FilemonFreeFilters();

    //
    // Create new filter arrays
    //
    MakeFilterArray( FilterDef.includefilter,
                     IncludeFilters, &NumIncludeFilters );
    MakeFilterArray( FilterDef.excludefilter,
                     ExcludeFilters, &NumExcludeFilters );
    ExReleaseResourceLite( &FilterResource );
    KeLeaveCriticalRegion();
}


//----------------------------------------------------------------------
//
// ApplyFilters
//
// If the name matches the exclusion mask, we do not log it. Else if
// it doesn't match the inclusion mask we do not log it. 
//
//----------------------------------------------------------------------
BOOLEAN
ApplyFilters( 
    PCHAR Text
    )
{
    ULONG i;

    //
    // If no GUI or no filename return FALSE
    //
    if( !Text ) return FALSE;

    //   
    // If it matches the exclusion string, do not log it
    //
    KeEnterCriticalRegion();
    ExAcquireResourceSharedLite( &FilterResource, TRUE );

    for( i = 0; i < NumExcludeFilters; i++ ) {

        if( MatchWithPattern( ExcludeFilters[i], Text ) ) {

            ExReleaseResourceLite( &FilterResource );
            KeLeaveCriticalRegion();
            return FALSE;
        }
    }
 
    //
    // If it matches an include filter then log it
    //
    for( i = 0; i < NumIncludeFilters; i++ ) {

        if( MatchWithPattern( IncludeFilters[i], Text )) {

            ExReleaseResourceLite( &FilterResource );
            KeLeaveCriticalRegion();
            return TRUE;
        }
    }

    //
    // It didn't match any include filters so don't log
    //
    ExReleaseResourceLite( &FilterResource );
    KeLeaveCriticalRegion();
    return FALSE;
}


//----------------------------------------------------------------------
//
// FilemonQueryFileComplete
//
// This routine is used to handle I/O completion for our self-generated
// IRP that is used to query a file's name or number.
//
//----------------------------------------------------------------------
NTSTATUS 
FilemonQueryFileComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    )
{
    //
    // Copy the status information back into the "user" IOSB.
    //
    *Irp->UserIosb = Irp->IoStatus;
    if( !NT_SUCCESS(Irp->IoStatus.Status) ) {

        DbgPrint(("   ERROR ON IRP: %x\n", Irp->IoStatus.Status ));
    }
    
    //
    // Set the user event - wakes up the mainline code doing this.
    //
    KeSetEvent(Irp->UserEvent, 0, FALSE);
    
    //
    // Free the IRP now that we are done with it.
    //
    IoFreeIrp(Irp);
    
    //
    // We return STATUS_MORE_PROCESSING_REQUIRED because this "magic" return value
    // tells the I/O Manager that additional processing will be done by this driver
    // to the IRP - in fact, it might (as it is in this case) already BE done - and
    // the IRP cannot be completed.
    //
    return STATUS_MORE_PROCESSING_REQUIRED;
}


//----------------------------------------------------------------------
//
// FilemonQueryFile
//
// This function retrieves the "standard" information for the
// underlying file system, asking for the filename in particular.
//
//----------------------------------------------------------------------
BOOLEAN 
FilemonQueryFile( 
    PDEVICE_OBJECT DeviceObject, 
    PFILE_OBJECT FileObject,
    FILE_INFORMATION_CLASS FileInformationClass,
    PVOID FileQueryBuffer,
    ULONG FileQueryBufferLength
    )
{
    PIRP irp;
    KEVENT event;
    IO_STATUS_BLOCK IoStatusBlock;
    PIO_STACK_LOCATION ioStackLocation;

    DbgPrint(("Getting file name for %x\n", FileObject));

    //
    // Initialize the event
    //
    KeInitializeEvent(&event, SynchronizationEvent, FALSE);

    //
    // Allocate an irp for this request.  This could also come from a 
    // private pool, for instance.
    //
    irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    if(!irp) {

        //
        // Failure!
        //
        return FALSE;
    }
  
    //
    // Build the IRP's main body
    //  
    irp->AssociatedIrp.SystemBuffer = FileQueryBuffer;
    irp->UserEvent = &event;
    irp->UserIosb = &IoStatusBlock;
    irp->Tail.Overlay.Thread = PsGetCurrentThread();
    irp->Tail.Overlay.OriginalFileObject = FileObject;
    irp->RequestorMode = KernelMode;
    irp->Flags = 0;

    //
    // Set up the I/O stack location.
    //
    ioStackLocation = IoGetNextIrpStackLocation(irp);
    ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
    ioStackLocation->DeviceObject = DeviceObject;
    ioStackLocation->FileObject = FileObject;
    ioStackLocation->Parameters.QueryFile.Length = FileQueryBufferLength;
    ioStackLocation->Parameters.QueryFile.FileInformationClass = FileInformationClass;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -