Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Помогите с Драйвером, драйвер-фильтр файловой системы  (Прочитано 40886 раз)
0 Пользователей и 1 Гость смотрят эту тему.
YouROK
Интересующийся

ru
Offline Offline

« : 21-01-2010 12:38 » 

Начал изучать тему драйверов,
хочу написать фильтр, для файловой системы, что бы при открытии файла 123.txt для примера выходило окно доступ запрещен.
За основу взял пример из WDK (7600.16385.0)  scanner, в нем изменил функцию, и при запуске вылетает в бсод,
Код:
FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
{
    PFLT_FILE_NAME_INFORMATION nameInfo;
    NTSTATUS status;
    BOOLEAN scanFile;
    const UNICODE_STRING *filename;
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    PAGED_CODE();

   
    status = FltGetFileNameInformation( Data,
                                        FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,
                                        &nameInfo );
    FltParseFileNameInformation( nameInfo );
   
    if (!NT_SUCCESS( status )) {

        return FLT_PREOP_SUCCESS_WITH_CALLBACK;
    }

    FltParseFileNameInformation( nameInfo ); // если эту стр. за комментировать то в nameInfo->Name будет мусор, с ней вылетает в бсод
    filename = (L"123.txt\0");
    DbgPrint("FileCreate %wS \n",nameInfo->Name);
    DbgPrint("Our file %wS \n",filename);
    scanFile = RtlCompareUnicodeString(&nameInfo->Name,&filename,TRUE);
   
    if(scanFile)
    {
        DbgPrint("FileCreate STATUS_ACCESS_DENIED\n");
        Data->IoStatus.Status=STATUS_ACCESS_DENIED;
    }

    if (IoThreadToProcess( Data->Thread ) == ScannerData.UserProcess) {

        DbgPrint( "!!! scanner.sys -- allowing create for trusted process \n" );

        return FLT_PREOP_SUCCESS_NO_CALLBACK;
    }

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Подскажите, где проблема?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 21-01-2010 13:12 » 

1. FltParseFileNameInformation( nameInfo ) - неплохо бы статус проверять.

2. FltParseFileNameInformation(nameInfo) - зачем она вызывается два раза подряд?

3. RtlCompareUnicodeString() почитайте про возвращаемые значения http://msdn.microsoft.com/en-us/library/ms804321.aspx

4. IRQL при вызове - какой стоит?

внимательнее надо быть)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #2 : 21-01-2010 13:37 » 

Переделал, вот так
выкладываю весь код, так как пока еще не знаю как определить IRQL и только в теории представляю что это такое
Код:
/*++

Copyright (c) 1999-2002  Microsoft Corporation

Module Name:

    scanner.c

Abstract:

    This is the main module of the scanner filter.

    This filter scans the data in a file before allowing an open to proceed.  This is similar
    to what virus checkers do.

Environment:

    Kernel mode

--*/

#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>
#include "scanuk.h"
#include "scanner.h"

#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")

//
//  Structure that contains all the global data structures
//  used throughout the scanner.
//

SCANNER_DATA ScannerData;

//
//  This is a static list of file name extensions files we are interested in scanning
//

const UNICODE_STRING ScannerExtensionsToScan[] =
    { RTL_CONSTANT_STRING( L"doc"),
      RTL_CONSTANT_STRING( L"txt"),
      RTL_CONSTANT_STRING( L"bat"),
      RTL_CONSTANT_STRING( L"cmd"),
      RTL_CONSTANT_STRING( L"inf"),
      /*RTL_CONSTANT_STRING( L"ini"),   Removed, to much usage*/
      {0, 0, NULL}
    };


//
//  Function prototypes
//

NTSTATUS
ScannerPortConnect (
    __in PFLT_PORT ClientPort,
    __in_opt PVOID ServerPortCookie,
    __in_bcount_opt(SizeOfContext) PVOID ConnectionContext,
    __in ULONG SizeOfContext,
    __deref_out_opt PVOID *ConnectionCookie
    );

VOID
ScannerPortDisconnect (
    __in_opt PVOID ConnectionCookie
    );

NTSTATUS
ScannerpScanFileInUserMode (
    __in PFLT_INSTANCE Instance,
    __in PFILE_OBJECT FileObject,
    __out PBOOLEAN SafeToOpen
    );

BOOLEAN
ScannerpCheckExtension (
    __in PUNICODE_STRING Extension
    );

//
//  Assign text sections for each routine.
//

#ifdef ALLOC_PRAGMA
    #pragma alloc_text(INIT, DriverEntry)
    #pragma alloc_text(PAGE, ScannerInstanceSetup)
    #pragma alloc_text(PAGE, ScannerPreCreate)
    #pragma alloc_text(PAGE, ScannerPortConnect)
    #pragma alloc_text(PAGE, ScannerPortDisconnect)
#endif


//
//  Constant FLT_REGISTRATION structure for our filter.  This
//  initializes the callback routines our filter wants to register
//  for.  This is only used to register with the filter manager
//

const FLT_OPERATION_REGISTRATION Callbacks[] = {

    { IRP_MJ_CREATE,
      0,
      ScannerPreCreate,
      ScannerPostCreate},

    { IRP_MJ_CLEANUP,
      0,
      ScannerPreCleanup,
      NULL},

    { IRP_MJ_WRITE,
      0,
      ScannerPreWrite,
      NULL},

    { IRP_MJ_OPERATION_END}
};


const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {

    { FLT_STREAMHANDLE_CONTEXT,
      0,
      NULL,
      sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
      'chBS' },

    { FLT_CONTEXT_END }
};

const FLT_REGISTRATION FilterRegistration = {

    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    0,                                  //  Flags
    ContextRegistration,                //  Context Registration.
    Callbacks,                          //  Operation callbacks
    ScannerUnload,                      //  FilterUnload
    ScannerInstanceSetup,               //  InstanceSetup
    ScannerQueryTeardown,               //  InstanceQueryTeardown
    NULL,                               //  InstanceTeardownStart
    NULL,                               //  InstanceTeardownComplete
    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent
};

////////////////////////////////////////////////////////////////////////////
//
//    Filter initialization and unload routines.
//
////////////////////////////////////////////////////////////////////////////

NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This is the initialization routine for the Filter driver.  This
    registers the Filter with the filter manager and initializes all
    its global data structures.

Arguments:

    DriverObject - Pointer to driver object created by the system to
        represent this driver.

    RegistryPath - Unicode string identifying where the parameters for this
        driver are located in the registry.

Return Value:

    Returns STATUS_SUCCESS.
--*/
{
    OBJECT_ATTRIBUTES oa;
    UNICODE_STRING uniString;
    PSECURITY_DESCRIPTOR sd;
    NTSTATUS status;

    UNREFERENCED_PARAMETER( RegistryPath );

    //
    //  Register with filter manager.
    //

    status = FltRegisterFilter( DriverObject,
                                &FilterRegistration,
                                &ScannerData.Filter );


    if (!NT_SUCCESS( status )) {

        return status;
    }

    //
    //  Create a communication port.
    //

    RtlInitUnicodeString( &uniString, ScannerPortName );

    //
    //  We secure the port so only ADMINs & SYSTEM can acecss it.
    //

    status = FltBuildDefaultSecurityDescriptor( &sd, FLT_PORT_ALL_ACCESS );

    if (NT_SUCCESS( status )) {

        InitializeObjectAttributes( &oa,
                                    &uniString,
                                    OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                    NULL,
                                    sd );

        status = FltCreateCommunicationPort( ScannerData.Filter,
                                             &ScannerData.ServerPort,
                                             &oa,
                                             NULL,
                                             ScannerPortConnect,
                                             ScannerPortDisconnect,
                                             NULL,
                                             1 );
        //
        //  Free the security descriptor in all cases. It is not needed once
        //  the call to FltCreateCommunicationPort() is made.
        //

        FltFreeSecurityDescriptor( sd );

        if (NT_SUCCESS( status )) {

            //
            //  Start filtering I/O.
            //

            status = FltStartFiltering( ScannerData.Filter );

            if (NT_SUCCESS( status )) {

                return STATUS_SUCCESS;
            }

            FltCloseCommunicationPort( ScannerData.ServerPort );
        }
    }

    FltUnregisterFilter( ScannerData.Filter );

    return status;
}


NTSTATUS
ScannerPortConnect (
    __in PFLT_PORT ClientPort,
    __in_opt PVOID ServerPortCookie,
    __in_bcount_opt(SizeOfContext) PVOID ConnectionContext,
    __in ULONG SizeOfContext,
    __deref_out_opt PVOID *ConnectionCookie
    )
/*++

Routine Description

    This is called when user-mode connects to the server port - to establish a
    connection

Arguments

    ClientPort - This is the client connection port that will be used to
        send messages from the filter

    ServerPortCookie - The context associated with this port when the
        minifilter created this port.

    ConnectionContext - Context from entity connecting to this port (most likely
        your user mode service)

    SizeofContext - Size of ConnectionContext in bytes

    ConnectionCookie - Context to be passed to the port disconnect routine.

Return Value

    STATUS_SUCCESS - to accept the connection

--*/
{
    PAGED_CODE();

    UNREFERENCED_PARAMETER( ServerPortCookie );
    UNREFERENCED_PARAMETER( ConnectionContext );
    UNREFERENCED_PARAMETER( SizeOfContext);
    UNREFERENCED_PARAMETER( ConnectionCookie );

    ASSERT( ScannerData.ClientPort == NULL );
    ASSERT( ScannerData.UserProcess == NULL );

    //
    //  Set the user process and port.
    //

    ScannerData.UserProcess = PsGetCurrentProcess();
    ScannerData.ClientPort = ClientPort;

    DbgPrint( "!!! scanner.sys --- connected, port=0x%p\n", ClientPort );

    return STATUS_SUCCESS;
}


VOID
ScannerPortDisconnect(
     __in_opt PVOID ConnectionCookie
     )
/*++

Routine Description

    This is called when the connection is torn-down. We use it to close our
    handle to the connection

Arguments

    ConnectionCookie - Context from the port connect routine

Return value

    None

--*/
{
    UNREFERENCED_PARAMETER( ConnectionCookie );

    PAGED_CODE();

    DbgPrint( "!!! scanner.sys --- disconnected, port=0x%p\n", ScannerData.ClientPort );

    //
    //  Close our handle to the connection: note, since we limited max connections to 1,
    //  another connect will not be allowed until we return from the disconnect routine.
    //

    FltCloseClientPort( ScannerData.Filter, &ScannerData.ClientPort );

    //
    //  Reset the user-process field.
    //

    ScannerData.UserProcess = NULL;
}


NTSTATUS
ScannerUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    )
/*++

Routine Description:

    This is the unload routine for the Filter driver.  This unregisters the
    Filter with the filter manager and frees any allocated global data
    structures.

Arguments:

    None.

Return Value:

    Returns the final status of the deallocation routines.

--*/
{
    UNREFERENCED_PARAMETER( Flags );

    //
    //  Close the server port.
    //

    FltCloseCommunicationPort( ScannerData.ServerPort );

    //
    //  Unregister the filter
    //

    FltUnregisterFilter( ScannerData.Filter );

    return STATUS_SUCCESS;
}

NTSTATUS
ScannerInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
/*++

Routine Description:

    This routine is called by the filter manager when a new instance is created.
    We specified in the registry that we only want for manual attachments,
    so that is all we should receive here.

Arguments:

    FltObjects - Describes the instance and volume which we are being asked to
        setup.

    Flags - Flags describing the type of attachment this is.

    VolumeDeviceType - The DEVICE_TYPE for the volume to which this instance
        will attach.

    VolumeFileSystemType - The file system formatted on this volume.

Return Value:

  FLT_NOTIFY_STATUS_ATTACH              - we wish to attach to the volume
  FLT_NOTIFY_STATUS_DO_NOT_ATTACH       - no, thank you

--*/
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );

    PAGED_CODE();

    ASSERT( FltObjects->Filter == ScannerData.Filter );

    //
    //  Don't attach to network volumes.
    //

    if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) {

       return STATUS_FLT_DO_NOT_ATTACH;
    }

    return STATUS_SUCCESS;
}

NTSTATUS
ScannerQueryTeardown (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    )
/*++

Routine Description:

    This is the instance detach routine for the filter. This
    routine is called by filter manager when a user initiates a manual instance
    detach. This is a 'query' routine: if the filter does not want to support
    manual detach, it can return a failure status

Arguments:

    FltObjects - Describes the instance and volume for which we are receiving
        this query teardown request.

    Flags - Unused

Return Value:

    STATUS_SUCCESS - we allow instance detach to happen

--*/
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );

    return STATUS_SUCCESS;
}


FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
/*++

Routine Description:

    Pre create callback.  We need to remember whether this file has been
    opened for write access.  If it has, we'll want to rescan it in cleanup.
    This scheme results in extra scans in at least two cases:
    -- if the create fails (perhaps for access denied)
    -- the file is opened for write access but never actually written to
    The assumption is that writes are more common than creates, and checking
    or setting the context in the write path would be less efficient than
    taking a good guess before the create.

Arguments:

    Data - The structure which describes the operation parameters.

    FltObject - The structure which describes the objects affected by this
        operation.

    CompletionContext - Output parameter which can be used to pass a context
        from this pre-create callback to the post-create callback.

Return Value:

   FLT_PREOP_SUCCESS_WITH_CALLBACK - If this is not our user-mode process.
   FLT_PREOP_SUCCESS_NO_CALLBACK - All other threads.

--*/
{
PFLT_FILE_NAME_INFORMATION nameInfo;
NTSTATUS status;
BOOLEAN scanFile;
const UNICODE_STRING *filename;
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    PAGED_CODE();


status = FltGetFileNameInformation( Data,
                                         FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,
                                         &nameInfo );
if (!NT_SUCCESS( status )) {
DbgPrint("FltGetFileNameInformation Error");
         return FLT_PREOP_SUCCESS_WITH_CALLBACK;
     }

status = FltParseFileNameInformation( nameInfo );

if (!NT_SUCCESS( status )) {
DbgPrint("FltParseFileNameInformation Error");
         return FLT_PREOP_SUCCESS_WITH_CALLBACK;
     }

filename = (L"123.txt\0");
DbgPrint("FileCreate %wS \n",nameInfo->Name);
DbgPrint("Our file %wS \n",filename);
scanFile = RtlCompareUnicodeString(&nameInfo->Name,&filename,TRUE) == 0;

if(scanFile)
{
DbgPrint("FileCreate STATUS_ACCESS_DENIED\n");
Data->IoStatus.Status=STATUS_ACCESS_DENIED;
}

    //
    //  See if this create is being done by our user process.
    //

    if (IoThreadToProcess( Data->Thread ) == ScannerData.UserProcess) {

        DbgPrint( "!!! scanner.sys -- allowing create for trusted process \n" );

        return FLT_PREOP_SUCCESS_NO_CALLBACK;
    }

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

BOOLEAN
ScannerpCheckExtension (
    __in PUNICODE_STRING Extension
    )
/*++

Routine Description:

    Checks if this file name extension is something we are interested in

Arguments

    Extension - Pointer to the file name extension

Return Value

    TRUE - Yes we are interested
    FALSE - No
--*/
{
    const UNICODE_STRING *ext;

    if (Extension->Length == 0) {

        return FALSE;
    }

    //
    //  Check if it matches any one of our static extension list
    //

    ext = ScannerExtensionsToScan;

    while (ext->Buffer != NULL) {

        if (RtlCompareUnicodeString( Extension, ext, TRUE ) == 0) {

            //
            //  A match. We are interested in this file
            //

            return TRUE;
        }
        ext++;
    }

    return FALSE;
}


FLT_POSTOP_CALLBACK_STATUS
ScannerPostCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
    )
/*++

Routine Description:

    Post create callback.  We can't scan the file until after the create has
    gone to the filesystem, since otherwise the filesystem wouldn't be ready
    to read the file for us.

Arguments:

    Data - The structure which describes the operation parameters.

    FltObject - The structure which describes the objects affected by this
        operation.

    CompletionContext - The operation context passed fron the pre-create
        callback.

    Flags - Flags to say why we are getting this post-operation callback.

Return Value:

    FLT_POSTOP_FINISHED_PROCESSING - ok to open the file or we wish to deny
                                     access to this file, hence undo the open

--*/
{
    PSCANNER_STREAM_HANDLE_CONTEXT scannerContext;
    FLT_POSTOP_CALLBACK_STATUS returnStatus = FLT_POSTOP_FINISHED_PROCESSING;
    PFLT_FILE_NAME_INFORMATION nameInfo;
    NTSTATUS status;
    BOOLEAN safeToOpen, scanFile;

    UNREFERENCED_PARAMETER( CompletionContext );
    UNREFERENCED_PARAMETER( Flags );

    //
    //  If this create was failing anyway, don't bother scanning now.
    //

    if (!NT_SUCCESS( Data->IoStatus.Status ) ||
        (STATUS_REPARSE == Data->IoStatus.Status)) {

        return FLT_POSTOP_FINISHED_PROCESSING;
    }

    //
    //  Check if we are interested in this file.
    //

    status = FltGetFileNameInformation( Data,
                                        FLT_FILE_NAME_NORMALIZED |
                                            FLT_FILE_NAME_QUERY_DEFAULT,
                                        &nameInfo );

    if (!NT_SUCCESS( status )) {

        return FLT_POSTOP_FINISHED_PROCESSING;
    }

    FltParseFileNameInformation( nameInfo );
    //
    //  Check if the extension matches the list of extensions we are interested in
    //

    scanFile = ScannerpCheckExtension( &nameInfo->Extension );

    //
    //  Release file name info, we're done with it
    //

    FltReleaseFileNameInformation( nameInfo );

    if (!scanFile) {

        //
        //  Not an extension we are interested in
        //

        return FLT_POSTOP_FINISHED_PROCESSING;
    }

    (VOID) ScannerpScanFileInUserMode( FltObjects->Instance,
                                       FltObjects->FileObject,
                                       &safeToOpen );

    if (!safeToOpen) {

        //
        //  Ask the filter manager to undo the create.
        //

        DbgPrint( "!!! scanner.sys -- foul language detected in postcreate !!!\n" );

        DbgPrint( "!!! scanner.sys -- undoing create \n" );

        FltCancelFileOpen( FltObjects->Instance, FltObjects->FileObject );

        Data->IoStatus.Status = STATUS_ACCESS_DENIED;
        Data->IoStatus.Information = 0;

        returnStatus = FLT_POSTOP_FINISHED_PROCESSING;

    } else if (FltObjects->FileObject->WriteAccess) {

        //
        //
        //  The create has requested write access, mark to rescan the file.
        //  Allocate the context.
        //

        status = FltAllocateContext( ScannerData.Filter,
                                     FLT_STREAMHANDLE_CONTEXT,
                                     sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
                                     PagedPool,
                                     &scannerContext );

        if (NT_SUCCESS(status)) {

            //
            //  Set the handle context.
            //

            scannerContext->RescanRequired = TRUE;

            (VOID) FltSetStreamHandleContext( FltObjects->Instance,
                                              FltObjects->FileObject,
                                              FLT_SET_CONTEXT_REPLACE_IF_EXISTS,
                                              scannerContext,
                                              NULL );

            //
            //  Normally we would check the results of FltSetStreamHandleContext
            //  for a variety of error cases. However, The only error status
            //  that could be returned, in this case, would tell us that
            //  contexts are not supported.  Even if we got this error,
            //  we just want to release the context now and that will free
            //  this memory if it was not successfully set.
            //

            //
            //  Release our reference on the context (the set adds a reference)
            //

            FltReleaseContext( scannerContext );
        }
    }

    return returnStatus;
}


FLT_PREOP_CALLBACK_STATUS
ScannerPreCleanup (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
/*++

Routine Description:

    Pre cleanup callback.  If this file was opened for write access, we want
    to rescan it now.

Arguments:

    Data - The structure which describes the operation parameters.

    FltObject - The structure which describes the objects affected by this
        operation.

    CompletionContext - Output parameter which can be used to pass a context
        from this pre-cleanup callback to the post-cleanup callback.

Return Value:

    Always FLT_PREOP_SUCCESS_NO_CALLBACK.

--*/
{
    NTSTATUS status;
    PSCANNER_STREAM_HANDLE_CONTEXT context;
    BOOLEAN safe;

    UNREFERENCED_PARAMETER( Data );
    UNREFERENCED_PARAMETER( CompletionContext );

    status = FltGetStreamHandleContext( FltObjects->Instance,
                                        FltObjects->FileObject,
                                        &context );

    if (NT_SUCCESS( status )) {

        if (context->RescanRequired) {

            (VOID) ScannerpScanFileInUserMode( FltObjects->Instance,
                                               FltObjects->FileObject,
                                               &safe );

            if (!safe) {

                DbgPrint( "!!! scanner.sys -- foul language detected in precleanup !!!\n" );
            }
        }

        FltReleaseContext( context );
    }


    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

FLT_PREOP_CALLBACK_STATUS
ScannerPreWrite (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
/*++

Routine Description:

    Pre write callback.  We want to scan what's being written now.

Arguments:

    Data - The structure which describes the operation parameters.

    FltObject - The structure which describes the objects affected by this
        operation.

    CompletionContext - Output parameter which can be used to pass a context
        from this pre-write callback to the post-write callback.

Return Value:

    Always FLT_PREOP_SUCCESS_NO_CALLBACK.

--*/
{
    FLT_PREOP_CALLBACK_STATUS returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
    NTSTATUS status;
    PSCANNER_NOTIFICATION notification = NULL;
    PSCANNER_STREAM_HANDLE_CONTEXT context = NULL;
    ULONG replyLength;
    BOOLEAN safe = TRUE;
    PUCHAR buffer;

    UNREFERENCED_PARAMETER( CompletionContext );

    //
    //  If not client port just ignore this write.
    //

    if (ScannerData.ClientPort == NULL) {

        return FLT_PREOP_SUCCESS_NO_CALLBACK;
    }

    status = FltGetStreamHandleContext( FltObjects->Instance,
                                        FltObjects->FileObject,
                                        &context );

    if (!NT_SUCCESS( status )) {

        //
        //  We are not interested in this file
        //

        return FLT_PREOP_SUCCESS_NO_CALLBACK;

    }

    //
    //  Use try-finally to cleanup
    //

    try {

        //
        //  Pass the contents of the buffer to user mode.
        //

        if (Data->Iopb->Parameters.Write.Length != 0) {

            //
            //  Get the users buffer address.  If there is a MDL defined, use
            //  it.  If not use the given buffer address.
            //

            if (Data->Iopb->Parameters.Write.MdlAddress != NULL) {

                buffer = MmGetSystemAddressForMdlSafe( Data->Iopb->Parameters.Write.MdlAddress,
                                                       NormalPagePriority );

                //
                //  If we have a MDL but could not get and address, we ran out
                //  of memory, report the correct error
                //

                if (buffer == NULL) {

                    Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    Data->IoStatus.Information = 0;
                    returnStatus = FLT_PREOP_COMPLETE;
                    leave;
                }

            } else {

                //
                //  Use the users buffer
                //

                buffer  = Data->Iopb->Parameters.Write.WriteBuffer;
            }

            //
            //  In a production-level filter, we would actually let user mode scan the file directly.
            //  Allocating & freeing huge amounts of non-paged pool like this is not very good for system perf.
            //  This is just a sample!
            //

            notification = ExAllocatePoolWithTag( NonPagedPool,
                                                  sizeof( SCANNER_NOTIFICATION ),
                                                  'nacS' );
            if (notification == NULL) {

                Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                Data->IoStatus.Information = 0;
                returnStatus = FLT_PREOP_COMPLETE;
                leave;
            }

            notification->BytesToScan = min( Data->Iopb->Parameters.Write.Length, SCANNER_READ_BUFFER_SIZE );

            //
            //  The buffer can be a raw user buffer. Protect access to it
            //

            try  {

                RtlCopyMemory( &notification->Contents,
                               buffer,
                               notification->BytesToScan );

            } except( EXCEPTION_EXECUTE_HANDLER ) {

                //
                //  Error accessing buffer. Complete i/o with failure
                //

                Data->IoStatus.Status = GetExceptionCode() ;
                Data->IoStatus.Information = 0;
                returnStatus = FLT_PREOP_COMPLETE;
                leave;
            }

            //
            //  Send message to user mode to indicate it should scan the buffer.
            //  We don't have to synchronize between the send and close of the handle
            //  as FltSendMessage takes care of that.
            //

            replyLength = sizeof( SCANNER_REPLY );

            status = FltSendMessage( ScannerData.Filter,
                                     &ScannerData.ClientPort,
                                     notification,
                                     sizeof( SCANNER_NOTIFICATION ),
                                     notification,
                                     &replyLength,
                                     NULL );

            if (STATUS_SUCCESS == status) {

               safe = ((PSCANNER_REPLY) notification)->SafeToOpen;

           } else {

               //
               //  Couldn't send message. This sample will let the i/o through.
               //

               DbgPrint( "!!! scanner.sys --- couldn't send message to user-mode to scan file, status 0x%X\n", status );
           }
        }

        if (!safe) {

            //
            //  Block this write if not paging i/o (as a result of course, this scanner will not prevent memory mapped writes of contaminated
            //  strings to the file, but only regular writes). The effect of getting ERROR_ACCESS_DENIED for many apps to delete the file they
            //  are trying to write usually.
            //  To handle memory mapped writes - we should be scanning at close time (which is when we can really establish that the file object
            //  is not going to be used for any more writes)
            //

            DbgPrint( "!!! scanner.sys -- foul language detected in write !!!\n" );

            if (!FlagOn( Data->Iopb->IrpFlags, IRP_PAGING_IO )) {

                DbgPrint( "!!! scanner.sys -- blocking the write !!!\n" );

                Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                Data->IoStatus.Information = 0;
                returnStatus = FLT_PREOP_COMPLETE;
            }
        }

    } finally {

        if (notification != NULL) {

            ExFreePoolWithTag( notification, 'nacS' );
        }

        if (context) {

            FltReleaseContext( context );
        }
    }

    return returnStatus;
}

//////////////////////////////////////////////////////////////////////////
//  Local support routines.
//
/////////////////////////////////////////////////////////////////////////

NTSTATUS
ScannerpScanFileInUserMode (
    __in PFLT_INSTANCE Instance,
    __in PFILE_OBJECT FileObject,
    __out PBOOLEAN SafeToOpen
    )
/*++

Routine Description:

    This routine is called to send a request up to user mode to scan a given
    file and tell our caller whether it's safe to open this file.

    Note that if the scan fails, we set SafeToOpen to TRUE.  The scan may fail
    because the service hasn't started, or perhaps because this create/cleanup
    is for a directory, and there's no data to read & scan.

    If we failed creates when the service isn't running, there'd be a
    bootstrapping problem -- how would we ever load the .exe for the service?

Arguments:

    Instance - Handle to the filter instance for the scanner on this volume.

    FileObject - File to be scanned.

    SafeToOpen - Set to FALSE if the file is scanned successfully and it contains
                 foul language.

Return Value:

    The status of the operation, hopefully STATUS_SUCCESS.  The common failure
    status will probably be STATUS_INSUFFICIENT_RESOURCES.

--*/

{
    NTSTATUS status = STATUS_SUCCESS;
    PVOID buffer = NULL;
    ULONG bytesRead;
    PSCANNER_NOTIFICATION notification = NULL;
    FLT_VOLUME_PROPERTIES volumeProps;
    LARGE_INTEGER offset;
    ULONG replyLength, length;
    PFLT_VOLUME volume = NULL;

    *SafeToOpen = TRUE;

    //
    //  If not client port just return.
    //

    if (ScannerData.ClientPort == NULL) {

        return STATUS_SUCCESS;
    }

    try {

        //
        //  Obtain the volume object .
        //

        status = FltGetVolumeFromInstance( Instance, &volume );

        if (!NT_SUCCESS( status )) {

            leave;
        }

        //
        //  Determine sector size. Noncached I/O can only be done at sector size offsets, and in lengths which are
        //  multiples of sector size. A more efficient way is to make this call once and remember the sector size in the
        //  instance setup routine and setup an instance context where we can cache it.
        //

        status = FltGetVolumeProperties( volume,
                                         &volumeProps,
                                         sizeof( volumeProps ),
                                         &length );
        //
        //  STATUS_BUFFER_OVERFLOW can be returned - however we only need the properties, not the names
        //  hence we only check for error status.
        //

        if (NT_ERROR( status )) {

            leave;
        }

        length = max( SCANNER_READ_BUFFER_SIZE, volumeProps.SectorSize );

        //
        //  Use non-buffered i/o, so allocate aligned pool
        //

        buffer = FltAllocatePoolAlignedWithTag( Instance,
                                                NonPagedPool,
                                                length,
                                                'nacS' );

        if (NULL == buffer) {

            status = STATUS_INSUFFICIENT_RESOURCES;
            leave;
        }

        notification = ExAllocatePoolWithTag( NonPagedPool,
                                              sizeof( SCANNER_NOTIFICATION ),
                                              'nacS' );

        if(NULL == notification) {

            status = STATUS_INSUFFICIENT_RESOURCES;
            leave;
        }

        //
        //  Read the beginning of the file and pass the contents to user mode.
        //

        offset.QuadPart = bytesRead = 0;
        status = FltReadFile( Instance,
                              FileObject,
                              &offset,
                              length,
                              buffer,
                              FLTFL_IO_OPERATION_NON_CACHED |
                               FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
                              &bytesRead,
                              NULL,
                              NULL );

        if (NT_SUCCESS( status ) && (0 != bytesRead)) {

            notification->BytesToScan = (ULONG) bytesRead;

            //
            //  Copy only as much as the buffer can hold
            //

            RtlCopyMemory( &notification->Contents,
                           buffer,
                           min( notification->BytesToScan, SCANNER_READ_BUFFER_SIZE ) );

            replyLength = sizeof( SCANNER_REPLY );

            status = FltSendMessage( ScannerData.Filter,
                                     &ScannerData.ClientPort,
                                     notification,
                                     sizeof(SCANNER_NOTIFICATION),
                                     notification,
                                     &replyLength,
                                     NULL );

            if (STATUS_SUCCESS == status) {

                *SafeToOpen = ((PSCANNER_REPLY) notification)->SafeToOpen;

            } else {

                //
                //  Couldn't send message
                //

                DbgPrint( "!!! scanner.sys --- couldn't send message to user-mode to scan file, status 0x%X\n", status );
            }
        }

    } finally {

        if (NULL != buffer) {

            FltFreePoolAlignedWithTag( Instance, buffer, 'nacS' );
        }

        if (NULL != notification) {

            ExFreePoolWithTag( notification, 'nacS' );
        }

        if (NULL != volume) {

            FltObjectDereference( volume );
        }
    }

    return status;
}

В функции FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
где происходит вся обработка, почему то
DbgPrint("FileCreate %wS \n",nameInfo->Name); выводит вопросики пример, FileCreate Не понялНе понялНе понялНе понялНе понял?? что то такое, думаю из-за этого и не происходит блокировка,
    DbgPrint("Our file %wS \n",filename); а эта выводит нормальный текст

подскажите как исправить?
Записан
YouROK
Интересующийся

ru
Offline Offline

« Ответ #3 : 21-01-2010 13:38 » 

Ochkarik,
1,2,3 исправил, просто голова уже кругом идет
Записан
YouROK
Интересующийся

ru
Offline Offline

« Ответ #4 : 21-01-2010 13:49 » 

Сейчас в DebugView увидел вот такое
Код:
FileCreate апка имели бы одно и то же имя. Проверьте список записываемых файлов и убедитесь, что в нем нет повторяющихся имен.?Записываемый диск несовместим с используемым устройством записи компакт-дисков или DVD-дисков. Вставьте другой тип записываемого диска и повторите попытку.Записать аудио компакт-дискПодготовить этот дискГотовность к стиранию диска Вставьте дискПожалуйста, подождите...'Все файлы успешно записаны на этот диск Вставьте диск0Обнаружена проблема при записи оптического диска#Недоста	
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 21-01-2010 15:14 » 

Это что за сообщение?))) вобще то BSOD должен был быть Скромно так...
для начала отключите вашу блокировку файла и проверьте что оно вообще работает.

проверка IRQL - KeGetCurrentIrql().

Цитата
DbgPrint
Format
Specifies a pointer to the format string to print. The Format string supports all the printf-style formatting codes.
However, the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, and %wZ) can only be used with IRQL = PASSIVE_LEVEL.

If successful, DbgPrint returns the NTSTATUS code STATUS_SUCCESS; otherwise it returns the appropriate error code.
проверьте статус.

и наконец главное, UNICODE_STRING:
 http://www.google.ru/search?sourceid=navclient&hl=ru&ie=UTF-8&rlz=1T4ADBF_ruRU321RU322&q=DBGPrint+UNICODE_STRING

PS а голова - это нормально) главное внимательно DDK читать, и все статусы и возвращаемые значения проверять)
« Последнее редактирование: 21-01-2010 19:05 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #6 : 22-01-2010 07:16 » 

Ochkarik, при огромнейшее тебе спасибо,
сам набирал поиск тупо глядел и не понимал что написано,
сделал проверку на пассивный уровень, и сделал вывод буфера,
теперь все понятно,
вот вывод в DBGView
IRQL PASSIVE_LEVELFileCreate \Device\HarddiskVolume1\fsFilter\filter\objchk_win7_x86\i386\123.txt
а можно сделать чтобы все вызовы были в пассивном режиме, так сказать а вдруг будет не пассивный вызов и процедура не сработает или не стоит боятся?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 22-01-2010 09:02 » 

IRQL сделать - нельзя. его выставляет операционка. в зависимости от того, в какой своей внутренней функции она находится.... ну немного посложнее - дам ссылку почитать)  этот уровень можно только контроллировать - не все функции можно вызывать на том или ином уровне. обычно условие ставится такое - функция выполняется если текущий IRQL не выше чем такой-то.
основных уровней всего 4 (с ними наиболее часто сталкиваются). по возрастанию:

PASSIVE_LEVEL - пользовательские потоки ring-3. части кода драйверов. на этом уровне возможно переключение контекста(задач, процессов и т.д.) работает подкачка виртуальной памяти с диска,
APC_LEVEL  - уровень синхронизации APC процедур,
DISPATCH_LEVEL - переключение контекста запрещено, подкачка страниц памяти с диска - блокирована, можно обращаться только к несвопируемой памяти, нельзя ожидать событий синхронизации (WFSO и т.д.),
DIRQL (класс) - выполнение функций обработки аппаратных прерываний.

это одна из тех вещей которые надо постоянно помнить.
проверку на IRQL не обязательно выполнять в каждой функции. текущий уровень зависит от того, из какого места ОС вызывает ваш код. а это -  как правило в 99.9% случаев описано в DDK. правда не всегда легко найти)
то есть смотрим в DDK - на каком уровне IRQL, ОС может вызывать тот или иной IRP-запрос, и контролируем чтобы не вызывать в нашем коде обработки этого IRP, функции, которые нельзя на этом уровне вызывать.

http://www.google.ru/search?hl=ru&q=IRQL&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+Google&lr=
очень хорошо и подробно  об этом написано у Руссиновича.
« Последнее редактирование: 22-01-2010 09:11 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 22-01-2010 09:17 » 

кстати проверку текущего IRQL обычно делают только в дебаговой версии  драйвера, путем вклчюения макроса типа
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
или
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
и т.д. в зависимости от требований.
макрос при не выполнении условия, если не ошибаюсь, вызывает BSOD (или выпадение в отладчик ядра). но по крайней мере это предсказуемый BSOD - его проще обнаружить чем если операционка будет непредсказуемо падать.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #9 : 22-01-2010 13:42 » 

А можно, как-нибудь отглаживать драйвера не в режиме ядра, мож как-то через линуксовский wine,
перезагружаться надоело,

Код:
FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
{
    PFLT_FILE_NAME_INFORMATION nameInfo;
    NTSTATUS status;
    BOOLEAN scanFile;
    ULONG i;
    const UNICODE_STRING *filename;
    UNICODE_STRING blockfile;
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );
   
   
    PAGED_CODE();

     status = FltGetFileNameInformation( Data,
                                         FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,
                                         &nameInfo );
    if (!NT_SUCCESS( status )) {
        DbgPrint("FltGetFileNameInformation Error");
         return FLT_PREOP_SUCCESS_WITH_CALLBACK;
     }
     
     status = FltParseFileNameInformation( nameInfo );
   
     if (!NT_SUCCESS( status )) {
        DbgPrint("FltParseFileNameInformation Error");
         return FLT_PREOP_SUCCESS_WITH_CALLBACK;
     }

     filename = (L"123.txt\0");
//   RtlInitUnicodeString(&blockfile,"");
     
     for(i=nameInfo->Name.Length;i>0;i--)
        if(nameInfo->Name.Buffer[i]=='\\')
        {
            RtlInitUnicodeString(&blockfile,&nameInfo->Name.Buffer[i]); // если за комментировать то BSOD вылазит не сразу.
            break;
        }
     
     scanFile = RtlEqualUnicodeString(&nameInfo->Name,&filename,TRUE);
     DbgPrint("scanner %d, %wS \n",blockfile.Length,blockfile.Buffer);
     
     if(scanFile)
     {
         DbgPrint("FileCreate STATUS_ACCESS_DENIED\n");
         Data->IoStatus.Status=STATUS_ACCESS_DENIED;
     }
     
    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

Какие есть процедуры для работы со строками в ядре, есть ли поиск и можно ли использовать стандартные процедуры?
Или где ошибка в цикле, BSOD выскакивает с номером 0x50, вроде все правильно сделал.
Если в цикле за комментировать RtlInitUnicodeString... то BSOD выскакивает не сразу даже можно посмотреть в dbgview  Да-да.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 22-01-2010 18:30 » 

не делайте ошибок - не надо будет перезагружать операционку)))
можно отлаживать, но... я ни разу не пробовал) ...теоретически говорят можно) VMWare  и прочие аналоги. в форуме были обсуждения

перезагружатся надоело - скажу честно. нефиг делать ошибки при написание кода.
в DDK все написано - не поверните - ВСЕ!!!
основной принцип написания драйвера - если что то не получилось - вернуть все в исходное состояние. то-есть, проверка ошибок, точное следование всем инструкциям.

смиритесь с тем что 90% кода драйвера - обработка ошибок.
ЭТО-НОРМАЛЬНО! уверяю вас, если вы точно последуете всем требованиям DDK - никаких перезагрузок не потребуется.
насчет обработки строк - ищите в DDK)))) уверяю вас - это будет полезней, чем если я найду вам готовые решения)
ключевое слово для поиска только найдите правильно)

последний код  - не очень...)))
 напишите словами - что вы хотите сделать)
« Последнее редактирование: 23-01-2010 10:17 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #11 : 26-01-2010 19:11 » 

Ochkarik,
начал с нуля, взял пример нульфильтр, пытаюсь добавить туда функции фильтра, но чета они не отрабатываются
в dbgview выдает вход в драйвер и все вроде как без ошибок, регистрирует и запускает, и при выгрузке драйвера тоже показывает и все.
Код:
#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>

#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")

//---------------------------------------------------------------------------
//      Global variables
//---------------------------------------------------------------------------

#define NULL_FILTER_FILTER_NAME     L"NullFilter"

typedef struct _NULL_FILTER_DATA {

    //
    //  The filter handle that results from a call to
    //  FltRegisterFilter.
    //
PDRIVER_OBJECT DriverObject;

    PFLT_FILTER FilterHandle;

} NULL_FILTER_DATA, *PNULL_FILTER_DATA;


/*************************************************************************
    Prototypes for the startup and unload routines used for
    this Filter.

    Implementation in nullFilter.c
*************************************************************************/

DRIVER_INITIALIZE DriverEntry;
NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    );

NTSTATUS
NullUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    );

NTSTATUS
NullQueryTeardown (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    );

FLT_PREOP_CALLBACK_STATUS
NullPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    );

NTSTATUS
NullInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    );
//
//  Structure that contains all the global data structures
//  used throughout NullFilter.
//

NULL_FILTER_DATA NullFilterData;

//
//  Assign text sections for each routine.
//

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, NullUnload)
#pragma alloc_text(PAGE, NullInstanceSetup)
#pragma alloc_text(PAGE, NullQueryTeardown)
#pragma alloc_text(PAGE, NullPreCreate)
#endif


//
//  This defines what we want to filter with FltMgr
//

const FLT_OPERATION_REGISTRATION Callbacks[] = {

    {IRP_MJ_CREATE,
     0,
     NullPreCreate,
     NULL},

    { IRP_MJ_OPERATION_END}
};

typedef struct _SCANNER_STREAM_HANDLE_CONTEXT {

    BOOLEAN RescanRequired;
    
} SCANNER_STREAM_HANDLE_CONTEXT, *PSCANNER_STREAM_HANDLE_CONTEXT;

const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {

    { FLT_STREAMHANDLE_CONTEXT,
      0,
      NULL,
      sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
      'chBS' },

    { FLT_CONTEXT_END }
};

CONST FLT_REGISTRATION FilterRegistration = {

    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    0,                                  //  Flags

    ContextRegistration,                               //  Context
    Callbacks,                               //  Operation callbacks

    NullUnload,                         //  FilterUnload

    NullInstanceSetup,                               //  InstanceSetup
    NullQueryTeardown,                  //  InstanceQueryTeardown
    NULL,                               //  InstanceTeardownStart
    NULL,                               //  InstanceTeardownComplete

    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent

};


/*************************************************************************
    Filter initialization and unload routines.
*************************************************************************/

NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This is the initialization routine for this miniFilter driver. This
    registers the miniFilter with FltMgr and initializes all
    its global data structures.

Arguments:

    DriverObject - Pointer to driver object created by the system to
        represent this driver.
    RegistryPath - Unicode string identifying where the parameters for this
        driver are located in the registry.

Return Value:

    Returns STATUS_SUCCESS.

--*/
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER( RegistryPath );
DbgPrint("Null Filter, DriverEntry\n");
    //
    //  Register with FltMgr
    //

DbgPrint("FltRegisterFilter\n");
    status = FltRegisterFilter( DriverObject,
                                &FilterRegistration,
                                &NullFilterData.FilterHandle );

    ASSERT( NT_SUCCESS( status ) );

    if (NT_SUCCESS( status )) {

        //
        //  Start filtering i/o
        //
DbgPrint("FltStartFiltering\n");
        status = FltStartFiltering( NullFilterData.FilterHandle );

        if (!NT_SUCCESS( status )) {
DbgPrint("Error FltStartFiltering\n");
            FltUnregisterFilter( NullFilterData.FilterHandle );
        }
    }

    return status;
}

NTSTATUS
NullUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    )
/*++

Routine Description:

    This is the unload routine for this miniFilter driver. This is called
    when the minifilter is about to be unloaded. We can fail this unload
    request if this is not a mandatory unloaded indicated by the Flags
    parameter.

Arguments:

    Flags - Indicating if this is a mandatory unload.

Return Value:

    Returns the final status of this operation.

--*/
{
    UNREFERENCED_PARAMETER( Flags );

    PAGED_CODE();

    FltUnregisterFilter( NullFilterData.FilterHandle );
DbgPrint("Null Filter, NullUnload\n");
    return STATUS_SUCCESS;
}

NTSTATUS
NullInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
/*++

Routine Description:

    This routine is called by the filter manager when a new instance is created.
    We specified in the registry that we only want for manual attachments,
    so that is all we should receive here.

Arguments:

    FltObjects - Describes the instance and volume which we are being asked to
        setup.

    Flags - Flags describing the type of attachment this is.

    VolumeDeviceType - The DEVICE_TYPE for the volume to which this instance
        will attach.

    VolumeFileSystemType - The file system formatted on this volume.

Return Value:

  FLT_NOTIFY_STATUS_ATTACH              - we wish to attach to the volume
  FLT_NOTIFY_STATUS_DO_NOT_ATTACH       - no, thank you

--*/
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );

    PAGED_CODE();
DbgPrint("Null Filter, NullInstanceSetup\n");
    ASSERT( FltObjects->Filter == NullFilterData.FilterHandle );

    //
    //  Don't attach to network volumes.
    //

    if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) {

       return STATUS_FLT_DO_NOT_ATTACH;
    }

    return STATUS_SUCCESS;
}

NTSTATUS
NullQueryTeardown (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    )
/*++

Routine Description:

    This is the instance detach routine for this miniFilter driver.
    This is called when an instance is being manually deleted by a
    call to FltDetachVolume or FilterDetach thereby giving us a
    chance to fail that detach request.

Arguments:

    FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
        opaque handles to this filter, instance and its associated volume.

    Flags - Indicating where this detach request came from.

Return Value:

    Returns the status of this operation.

--*/
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );

    PAGED_CODE();
DbgPrint("Null Filter, NullQueryTeardown\n");
    return STATUS_SUCCESS;
}

FLT_PREOP_CALLBACK_STATUS
NullPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
/*++

Routine Description:

    Pre create callback.  We need to remember whether this file has been
    opened for write access.  If it has, we'll want to rescan it in cleanup.
    This scheme results in extra scans in at least two cases:
    -- if the create fails (perhaps for access denied)
    -- the file is opened for write access but never actually written to
    The assumption is that writes are more common than creates, and checking
    or setting the context in the write path would be less efficient than
    taking a good guess before the create.

Arguments:

    Data - The structure which describes the operation parameters.

    FltObject - The structure which describes the objects affected by this
        operation.

    CompletionContext - Output parameter which can be used to pass a context
        from this pre-create callback to the post-create callback.

Return Value:

   FLT_PREOP_SUCCESS_WITH_CALLBACK - If this is not our user-mode process.
   FLT_PREOP_SUCCESS_NO_CALLBACK - All other threads.

--*/
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    PAGED_CODE();
DbgPrint("Null Filter, NullPreCreate\n");
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
В чем может быть проблема?
И еще вопрос что есть почитать про фильтры файловой системы на русском, мож че подскажешь?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 26-01-2010 20:06 » 

дома DDK не стоит, а к последнему примеру - файлов не хватает.
погодите, а чем первая попытка не удалась?) код с которого начали? негоже бросать на пол пути)
насчет литературы - не видел... кое что из общего описания и структуры взаимодействия должно быть у руссиновича. возможно что то есть у Орвик, хотя и для KMDF.

итак ваш предпоследний пост. продолжим исправление ошибок:
1. https://forum.shelek.ru/index.php/topic,1892.0.html - обратите внимание на инициализацию UNICODE строки с которой проводится сравнение.
вы вообще на warning-и при компиляции внимание обращаете?))) признавайтесь, сколько варнингов выскакивает?)

2. список функций работы с строковыми переменными (ANSI/UNICODE) в режиме ядра (следите за IRQL - большая часть функций сравнения и преобразования строк только при IRQL == PASSIVE_LEVEL)
http://msdn.microsoft.com/en-us/library/ms796247.aspx

3. спродолжение списка "safe"-функций копирования и объединения строк в режиме ядра:
http://msdn.microsoft.com/en-us/library/ms806697.aspx

4. конвертация строк в целочисленные и обратно
http://msdn.microsoft.com/en-us/library/ms796766.aspx

5. и посмотрели бы по форуму... темы подобные уже открывали. пусть целикового кода может там нет, но проглядеть то можно было?)
« Последнее редактирование: 26-01-2010 20:29 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #13 : 27-01-2010 06:20 » 

Бросил, потому что там уже все готово, только изменить чуть-чуть функцию и все, хотел сделать все с начала и немного разобраться, немного разобрался, осталось понять, где ошибка, лучше буду делать с нуля и понимать потихоньку, что к чему.
Кстати, в прошлом коде я исправил все предупреждения, но удалил лишние функции, которые мне не нужны, а так как я во всем не разобрался, вылетала ошибка, теперь я понял, что они там регистрировались, а на самом деле их там не было.

Когда будет IRQL != PASSIVE_LEVEL? У меня все время вызывалась функция в пассивном уровне.

Попробую старый код очистить от ненужных функций и сравнить с новым.
« Последнее редактирование: 27-01-2010 07:08 от Sel » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 27-01-2010 08:47 » 

ну... если разобраться, тогда - вариант)
начинайте с DDK)
http://msdn.microsoft.com/en-us/library/ms793583.aspx

про IRQL как я говорил - он повышается только в частных случаях.... почитайте Руссиновича. ОЧЕНЬ советую)
если очень хочется посмотреть что будет - добавьте в какой нибудь рабочий код
временное повышение IRQL (важно вручную - IRQL можно только временно повысить и после обязательно вернуть на прежний уровень)
http://msdn.microsoft.com/en-us/library/ms801898.aspx
Код:
KIRQL  PrewIrql;
  KeRaiseIrql(DISPATCH_LEVEL,& PrewIrql);
...какой то ваш код, который надо выполнить на повышенном IRQL...
//после чего ОБЯЗАТЕЛЬНО:
  KeLowerIrql(PrewIrql);
приведенный пример кода, например, может быть использован для временного блокирования переключения контекста.
например, в случае необходимости - позволяет сделать блокировку к каким-то расшаренным переменным или для выполнения операций, которые надо гарантированно завершить в одном потоке, прежде чем произойдет переключение контекста.
« Последнее редактирование: 27-01-2010 08:50 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #15 : 27-01-2010 09:02 » 

Привел свой первый код ко второму и сравнил все построчно в тупую, и все идентично, подумал а в чем может быть еще проблема,
и тут на глаза попался inf файл вот и сравнил, почти все тоже только отличается Instances specific information
я так понимаю эта информация отвечает за приатачивание устройств с фс, как-то так.
И да, в этом был проблема, изменил и все заработало.
Буду дальше экспериментировать.
Большое спасибо за помощь.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 27-01-2010 13:43 » 

всегда пожалуйста)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #17 : 28-01-2010 13:26 » 

Ochkarik, нужна помощь,

вот код, в конце идет фильтр и в нем ошибка или не в нем
Код:
#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>

#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")

DRIVER_INITIALIZE DriverEntry;
NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    );

NTSTATUS
NullUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    );

NTSTATUS
NullQueryTeardown (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    );

FLT_PREOP_CALLBACK_STATUS
NullPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    );

NTSTATUS
NullInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    );


typedef struct _NULL_FILTER_DATA {

PDRIVER_OBJECT DriverObject;
PFLT_FILTER FilterHandle;

} NULL_FILTER_DATA, *PNULL_FILTER_DATA;

NULL_FILTER_DATA NullFilterData;

//
//  Assign text sections for each routine.
//

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, NullInstanceSetup)
#pragma alloc_text(PAGE, NullPreCreate)
#pragma alloc_text(PAGE, NullUnload)
#endif

const FLT_OPERATION_REGISTRATION Callbacks[] = {

    { IRP_MJ_CREATE,
      0,
      NullPreCreate,
      NULL},
    { IRP_MJ_OPERATION_END}
};

typedef struct _SCANNER_STREAM_HANDLE_CONTEXT {

    BOOLEAN RescanRequired;
    
} SCANNER_STREAM_HANDLE_CONTEXT, *PSCANNER_STREAM_HANDLE_CONTEXT;

const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {

    { FLT_STREAMHANDLE_CONTEXT,
      0,
      NULL,
      sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
      'chBS' },

    { FLT_CONTEXT_END }
};

CONST FLT_REGISTRATION FilterRegistration = {

    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    0,                                  //  Flags
    ContextRegistration,                               //  Context
    Callbacks,                               //  Operation callbacks
    NullUnload,                         //  FilterUnload
    NullInstanceSetup,                               //  InstanceSetup
    NullQueryTeardown,                  //  InstanceQueryTeardown
    NULL,                               //  InstanceTeardownStart
    NULL,                               //  InstanceTeardownComplete
    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent
};


/*************************************************************************
    Filter initialization and unload routines.
*************************************************************************/

NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This is the initialization routine for this miniFilter driver. This
    registers the miniFilter with FltMgr and initializes all
    its global data structures.

Arguments:

    DriverObject - Pointer to driver object created by the system to
        represent this driver.
    RegistryPath - Unicode string identifying where the parameters for this
        driver are located in the registry.


Return Value:

    Returns STATUS_SUCCESS.

--*/
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER( RegistryPath );

    //
    //  Register with FltMgr
    //

    status = FltRegisterFilter( DriverObject,
                                &FilterRegistration,
                                &NullFilterData.FilterHandle );


    if (NT_SUCCESS( status )) {

        //
        //  Start filtering i/o
        //

        status = FltStartFiltering( NullFilterData.FilterHandle );

        if (!NT_SUCCESS( status )) {
            FltUnregisterFilter( NullFilterData.FilterHandle );
        }
    }
DbgPrint("Null Filter, DriverEntry");
    return status;
}

NTSTATUS
NullUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    )
/*++

Routine Description:

    This is the unload routine for this miniFilter driver. This is called
    when the minifilter is about to be unloaded. We can fail this unload
    request if this is not a mandatory unloaded indicated by the Flags
    parameter.

Arguments:

    Flags - Indicating if this is a mandatory unload.

Return Value:

    Returns the final status of this operation.

--*/
{
    UNREFERENCED_PARAMETER( Flags );

    PAGED_CODE();

    FltUnregisterFilter( NullFilterData.FilterHandle );
DbgPrint("Null Filter, NullUnload");
    return STATUS_SUCCESS;
}

NTSTATUS
NullInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
/*++

Routine Description:

    This routine is called by the filter manager when a new instance is created.
    We specified in the registry that we only want for manual attachments,
    so that is all we should receive here.

Arguments:

    FltObjects - Describes the instance and volume which we are being asked to
        setup.

    Flags - Flags describing the type of attachment this is.

    VolumeDeviceType - The DEVICE_TYPE for the volume to which this instance
        will attach.

    VolumeFileSystemType - The file system formatted on this volume.

Return Value:

  FLT_NOTIFY_STATUS_ATTACH              - we wish to attach to the volume
  FLT_NOTIFY_STATUS_DO_NOT_ATTACH       - no, thank you

--*/
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );

    PAGED_CODE();
DbgPrint("Null Filter, NullInstanceSetup");
    ASSERT( FltObjects->Filter == NullFilterData.FilterHandle );

    //
    //  Don't attach to network volumes.
    //

    if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) {

       return STATUS_FLT_DO_NOT_ATTACH;
    }

    return STATUS_SUCCESS;
}

NTSTATUS
NullQueryTeardown (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    )
/*++

Routine Description:

    This is the instance detach routine for this miniFilter driver.
    This is called when an instance is being manually deleted by a
    call to FltDetachVolume or FilterDetach thereby giving us a
    chance to fail that detach request.

Arguments:

    FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
        opaque handles to this filter, instance and its associated volume.

    Flags - Indicating where this detach request came from.

Return Value:

    Returns the status of this operation.

--*/
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );
DbgPrint("Null Filter, NullQueryTeardown");
    return STATUS_SUCCESS;
}

FLT_PREOP_CALLBACK_STATUS
NullPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
/*++

Routine Description:

    Pre create callback.  We need to remember whether this file has been
    opened for write access.  If it has, we'll want to rescan it in cleanup.
    This scheme results in extra scans in at least two cases:
    -- if the create fails (perhaps for access denied)
    -- the file is opened for write access but never actually written to
    The assumption is that writes are more common than creates, and checking
    or setting the context in the write path would be less efficient than
    taking a good guess before the create.

Arguments:

    Data - The structure which describes the operation parameters.

    FltObject - The structure which describes the objects affected by this
        operation.

    CompletionContext - Output parameter which can be used to pass a context
        from this pre-create callback to the post-create callback.

Return Value:

   FLT_PREOP_SUCCESS_WITH_CALLBACK - If this is not our user-mode process.
   FLT_PREOP_SUCCESS_NO_CALLBACK - All other threads.

--*/
{
PFLT_FILE_NAME_INFORMATION nameInfo;
    NTSTATUS status;
    BOOLEAN scanFile;
    ULONG i,j;
    UNICODE_STRING filename;
    UNICODE_STRING blockfile;
WCHAR buf[300];
    
UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    PAGED_CODE();

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

status = FltGetFileNameInformation( Data,
                                        FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,
                                        &nameInfo );
if (!NT_SUCCESS( status )) {
       DbgPrint("FltGetFileNameInformation Error\n");
        return FLT_PREOP_SUCCESS_WITH_CALLBACK;
    }
    
    status = FltParseFileNameInformation( nameInfo );
    
    if (!NT_SUCCESS( status )) {
       DbgPrint("FltParseFileNameInformation Error\n");
        return FLT_PREOP_SUCCESS_WITH_CALLBACK;
    }

buf[0]=0;
if(nameInfo->Name.Length<300)
{
DbgPrint("NullFilter: Copy to buf %d bytes\n",nameInfo->Name.Length);
RtlCopyMemory(&buf, nameInfo->Name.Buffer, nameInfo->Name.Length);
DbgPrint("%wS\n",&buf);
}
else
{
DbgPrint("NullFilter: Length is big\n");
}
if(buf[0]!=0)
{
DbgPrint("NullFilter: Get file name\n");
buf[nameInfo->Name.Length / sizeof(WCHAR)] = L'\0';
DbgPrint("%wS\n",&buf);
for(i=nameInfo->Name.Length / sizeof(WCHAR);i>0;i--)
{
if(buf[i]=='\\')
{
DbgPrint("nullfilter:  %wS\n",&buf[i+1]);
RtlInitUnicodeString(&blockfile,&buf[i+1]);
break;
}
}
if(blockfile.Length>0)
{
DbgPrint("nullfilter:   %wS\n",&buf);
RtlInitUnicodeString(&filename,L"123.txt\0");
scanFile = RtlEqualUnicodeString(&blockfile,&filename,TRUE);
DbgPrint("scanFile = FALSE;\n");
if(scanFile)
{
DbgPrint("NullFilter: FileCreate STATUS_ACCESS_DENIED\n");
Data->IoStatus.Status=STATUS_ACCESS_DENIED;
}
DbgPrint("if(scanFile)\n");
}else DbgPrint("NullFilter: File name not found\n");
}else DbgPrint("NullFilter: buf is empty\n");
DbgPrint("NullFilter: PreCreate end\n");
    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

}

Вылетает в бсод при запуске драйвера, в windbg пишет вот это
Код:
Null Filter, NullInstanceSetupNull Filter, NullInstanceSetupNull Filter, NullInstanceSetupNull Filter, NullInstanceSetupNull Filter, DriverEntryNullFilter: Copy to buf 116 bytes
\Device\HarddiskVolume1\WINDOWS\system32\wbem\wbemcons.dll??D
NullFilter: Get file name
\Device\HarddiskVolume1\WINDOWS\system32\wbem\wbemcons.dll
nullfilter:  wbemcons.dll
nullfilter:   \Device\HarddiskVolume1\WINDOWS\system32\wbem\wbemcons.dll
scanFile = FALSE;
if(scanFile)
NullFilter: PreCreate end

*** Fatal System Error: 0x000000f5
                       (0x00000066,0x825C0B3C,0x00000000,0x00000000)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

Connected to Windows XP 2600 x86 compatible target at (Thu Jan 28 16:21:44.968 2010 (GMT+3)), ptr64 FALSE
DBGHELP: nt - public symbols  
         c:\sym\ntoskrnl.pdb\8592B6763F34476B9BB560395A383F962\ntoskrnl.pdb
Loading Kernel Symbols
...............................................................
........................................
Loading User Symbols
................................................................
................................................................

Loading unloaded module list
...........
DBGHELP: c:\sym\ntdll.dll\41228EE4b1000\ntdll.dll - OK
DBGENG:  Partial symbol load found image c:\sym\ntdll.dll\41228EE4b1000\ntdll.dll.
DBGHELP: ntdll - public symbols  
         c:\sym\ntdll.pdb\36515FB5D04345E491F672FA2E2878C02\ntdll.pdb

*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck F5, {66, 825c0b3c, 0, 0}

DBGHELP: fltMgr - public symbols  
         c:\sym\fltMgr.pdb\A3669C0E41994AC2AD2BD6F85D4B1A041\fltMgr.pdb
DBGHELP: mssmbios - public symbols  
         c:\sym\mssmbios.pdb\CEAE494998B24A458588AE7866D1B9421\mssmbios.pdb
DBGHELP: c:\sym\kernel32.dll\41228EE4f6000\kernel32.dll - OK
DBGENG:  Partial symbol load found image c:\sym\kernel32.dll\41228EE4f6000\kernel32.dll.
DBGHELP: kernel32 - public symbols  
         c:\sym\kernel32.pdb\FB334FB28FA34128BDE9229285BE4C2F2\kernel32.pdb
DBGHELP: c:\sym\ole32.dll\41228EF013c000\ole32.dll - OK
DBGENG:  Partial symbol load found image c:\sym\ole32.dll\41228EF013c000\ole32.dll.
DBGHELP: ole32 - public symbols  
         c:\sym\ole32.pdb\092F43621A1A4763AF651D154C2AEEE02\ole32.pdb
DBGHELP: wmiprvsd - public symbols  
         c:\sym\WmiPrvSD.pdb\655D6B89EB65482CBF45F5B0AB0CC9B71\WmiPrvSD.pdb
DBGHELP: wbemess - public symbols  
         c:\sym\wbemess.pdb\29494B656E1E4F84825715933C1738D51\wbemess.pdb
DBGHELP: wbemcomn - public symbols  
         c:\sym\wbemcomn.pdb\9FACE9F49CCD48B7839D85E2213907872\wbemcomn.pdb
DBGHELP: c:\sym\ntoskrnl.exe\41108004214e80\ntoskrnl.exe - OK
DBGHELP: hal - public symbols  
         c:\sym\halacpi.pdb\BECA5A4012524CD290B45877E8FC674F1\halacpi.pdb
DBGHELP: c:\sym\ntoskrnl.exe\41108004214e80\ntoskrnl.exe - OK
//////////////////////Тут все виснет и я нажимаю ctrl + break
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: kernel32!pNlsUserInfo                         ***
***                                                                   ***
*************************************************************************
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: kernel32!pNlsUserInfo                         ***
***                                                                   ***
*************************************************************************
Probably caused by : memory_corruption

Followup: memory_corruption
---------

nt!RtlpBreakWithStatusInstruction:
804e3b25 cc              int     3
kd> g
Shutdown occurred at (Thu Jan 28 16:22:57.371 2010 (GMT+3))...unloading all symbol tables.
Waiting to reconnect...
////////////////////////Тут пошел перезапуск
В Visual Studio сделал консольное приложение и отработал по циклу, все нормально, вроде не выходит за пределы
По выводу в дебаг видно что вся функция проходит, но что может быть не так? Почему BSOD?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 28-01-2010 13:30 » 

говорит память повреждена... выход за пределы массива видимо где то.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 28-01-2010 13:33 » 

for(i=nameInfo->Name.Length / sizeof(WCHAR);i>0;i--)
неверно помоему. индексация элементов масива с 0 до nameInfo->Name.Length/2 - 1
хотя могу ошибаться. посмотрите сами внимательней
« Последнее редактирование: 28-01-2010 13:36 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #20 : 28-01-2010 13:44 » 

неверно помоему. индексация элементов масива с 0 до nameInfo->Name.Length/2- 1
Когда проверял в Visual цикл начинал с конца массива и там был 0 ща попробую -1 сделать мож правда,
а если где нибудь в коде сделать int 1 то меня выбросит в отладчик?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 28-01-2010 14:06 » 

YouROK, смотря какой отладчик там настраивалось.
обычно используют int 1 или int 3.. сейчас уже забыл какой куда)

Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #22 : 28-01-2010 14:29 » 

с
for((i=nameInfo->Name.Length / 2)-1;i>0;i--)
ниче не вышло, но по любому ошибка где то здесь,
завтра буду разбираться.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 28-01-2010 15:21 » 

а это что такое?!
RtlCopyMemory(&buf, nameInfo->Name.Buffer, nameInfo->Name.Length);
после нее не стоит для buf - DbgPrint делать... nameInfo->Name.Length- длина строки в байтах БЕЗ завершающего нуля. у вас и в логе после имени случайный мусор выведен. хорошо бы почистить для начала. кстати там еще MaximumLength есть...

и кстати максимальная длинна полного имени файла сколько? 256 вроде было? а если wchar? умножить на 2?

кстати PAGED_CODE() - это тоже проверка IRQL)  только, по моему, чтобы ниже DISPATCH_LEVEL. - это проверка на возможность использовать свопируемую память.

серьезных багов не вижу... хотя я бы сделал жестче проверку входной строки. на всякий пожарный)

« Последнее редактирование: 28-01-2010 21:25 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #24 : 29-01-2010 12:22 » 

Не получается уже три способа попробовал,
пробовал убрать все DBGPRINTы,
пробовал выделять память динамически и копировать туда из nameInfo->Name.Buffe, и просто инициировать строку из буфера nameInfo->Name.Buffer
  • предварительно ставя ноль в конце его длины и все равно все отрабатывает и вызывает ошибку но не понятно где, мне кажется не из этой процедуры.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 29-01-2010 15:46 » 

тогда отключайте весь свой код - для проверки что оно вобще все работало до этого.
когда убедитесь что все было ок - потихоньку включайте свои участки кода до момента когда все начнет падать.
то что не в этой процедуре - может быть да, может быть нет. если чужая память порушена - все может быть.

PS кстати в стеке ring-0 больше 4кб нельзя выделять.(или что то навроде этого). я правда не уверен что это именно этот случай, но так... на будущее.
« Последнее редактирование: 29-01-2010 15:48 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
YouROK
Интересующийся

ru
Offline Offline

« Ответ #26 : 02-02-2010 10:51 » 

Так и не разобрался с буфером, но все же у меня получилось,
я блокирую доступ к файлу,
вот код для будущих поколений, может в нем есть ошибки?
Код:
#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>

#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")

//---------------------------------------------------------------------------
//      Global variables
//---------------------------------------------------------------------------

#define NULL_FILTER_FILTER_NAME     L"NullFilter"
#define FS_PAGED_ALLOC(size) (ExAllocatePoolWithTag(PagedPool, (size), 'ypSF'))
#define FS_FREE_POOL(p) (ExFreePoolWithTag((p), 'ypSF'))

typedef struct _NULL_FILTER_DATA {

    PDRIVER_OBJECT DriverObject;
    
    PFLT_FILTER FilterHandle;

} NULL_FILTER_DATA, *PNULL_FILTER_DATA;


/*************************************************************************
    Prototypes for the startup and unload routines used for
    this Filter.

    Implementation in nullFilter.c
*************************************************************************/

DRIVER_INITIALIZE DriverEntry;
NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    );

NTSTATUS
NullUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    );

NTSTATUS
NullQueryTeardown (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    );
    
FLT_PREOP_CALLBACK_STATUS
NullPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    );
    
NTSTATUS
NullInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    );
//
//  Structure that contains all the global data structures
//  used throughout NullFilter.
//

NULL_FILTER_DATA NullFilterData;

//
//  Assign text sections for each routine.
//

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, NullUnload)
#pragma alloc_text(PAGE, NullInstanceSetup)
#pragma alloc_text(PAGE, NullQueryTeardown)
#pragma alloc_text(PAGE, NullPreCreate)
#endif


//
//  This defines what we want to filter with FltMgr
//

const FLT_OPERATION_REGISTRATION Callbacks[] = {

    { IRP_MJ_CREATE,
      0,
      NullPreCreate,
      NULL},

    { IRP_MJ_OPERATION_END}
};

typedef struct _SCANNER_STREAM_HANDLE_CONTEXT {

    BOOLEAN RescanRequired;
    
} SCANNER_STREAM_HANDLE_CONTEXT, *PSCANNER_STREAM_HANDLE_CONTEXT;

const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {

    { FLT_STREAMHANDLE_CONTEXT,
      0,
      NULL,
      sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
      'chBS' },

    { FLT_CONTEXT_END }
};

CONST FLT_REGISTRATION FilterRegistration = {

    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    0,                                  //  Flags

    ContextRegistration,                               //  Context
    Callbacks,                               //  Operation callbacks

    NullUnload,                         //  FilterUnload

    NullInstanceSetup,                               //  InstanceSetup
    NullQueryTeardown,                  //  InstanceQueryTeardown
    NULL,                               //  InstanceTeardownStart
    NULL,                               //  InstanceTeardownComplete

    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent

};


/*************************************************************************
    Filter initialization and unload routines.
*************************************************************************/

NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    )

{
    NTSTATUS status;

    UNREFERENCED_PARAMETER( RegistryPath );

    //
    //  Register with FltMgr
    //

    status = FltRegisterFilter( DriverObject,
                                &FilterRegistration,
                                &NullFilterData.FilterHandle );

    ASSERT( NT_SUCCESS( status ) );

    if (NT_SUCCESS( status )) {

        //
        //  Start filtering i/o
        //

        status = FltStartFiltering( NullFilterData.FilterHandle );

        if (!NT_SUCCESS( status )) {
            FltUnregisterFilter( NullFilterData.FilterHandle );
        }
    }
    DbgPrint("Null Filter, DriverEntry");
    return status;
}

NTSTATUS
NullUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    )

{
    UNREFERENCED_PARAMETER( Flags );

    PAGED_CODE();

    FltUnregisterFilter( NullFilterData.FilterHandle );
    DbgPrint("Null Filter, NullUnload");
    return STATUS_SUCCESS;
}

NTSTATUS
NullInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );

    PAGED_CODE();
    DbgPrint("Null Filter, NullInstanceSetup");
    ASSERT( FltObjects->Filter == NullFilterData.FilterHandle );

    //
    //  Don't attach to network volumes.
    //

    if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) {

       return STATUS_FLT_DO_NOT_ATTACH;
    }

    return STATUS_SUCCESS;
}

NTSTATUS
NullQueryTeardown (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    )

{
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );

    PAGED_CODE();
    DbgPrint("Null Filter, NullQueryTeardown");
    return STATUS_SUCCESS;
}

FLT_PREOP_CALLBACK_STATUS
NullPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )

{
   PFLT_FILE_NAME_INFORMATION nameInfo;
    NTSTATUS status;
    BOOLEAN scanFile;
    UNICODE_STRING filename;
    
UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    PAGED_CODE();

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
status = FltGetFileNameInformation( Data,
                                        FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,
                                        &nameInfo );
if (!NT_SUCCESS( status )) {
        return FLT_PREOP_SUCCESS_WITH_CALLBACK;
    }
    
    status = FltParseFileNameInformation( nameInfo );
    
    if (!NT_SUCCESS( status )) {
        return FLT_PREOP_SUCCESS_WITH_CALLBACK;
    }

if(nameInfo->FinalComponent.Length>0)
{
RtlInitUnicodeString(&filename,L"123.txt\0");
scanFile = RtlEqualUnicodeString(&nameInfo->FinalComponent,&filename,TRUE);
if(scanFile)
{
Data->IoStatus.Status=STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
}
}
    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
доступ блокируется весь, теперь буду разбираться как сделать чтобы не весь
« Последнее редактирование: 02-02-2010 10:53 от YouROK » Записан
YouROK
Интересующийся

ru
Offline Offline

« Ответ #27 : 02-02-2010 12:41 » 

Еще вопрос а как узнать, запускается файл или читается или пишется?
Туплю по немного,
Есть ли способ узнать будет ли файл читаться для запуска?
« Последнее редактирование: 02-02-2010 12:51 от YouROK » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 02-02-2010 18:01 » 

в каком смысле - читаться для запуска?
ааа.... понял. не знаю... либо поля IRP пакетов попробовать смотреть. либо следить за вызывающим процессом....
или Read/Write отлавливать. или Create...
или все вместе)
« Последнее редактирование: 02-02-2010 21:49 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 03-02-2010 22:29 » 

PS посмотрите соседнюю ветку https://forum.shelek.ru/index.php/topic,22523.msg218866.html  может натолкнет на мысли...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines